@woosh/meep-engine 2.33.24 → 2.33.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/binary/BitSet.js +151 -167
- package/core/binary/BitSet.spec.js +99 -1
- package/core/binary/ValidatingBitSetWrapper.js +81 -0
- package/core/bvh2/aabb3/AABB3.js +3 -10
- package/core/bvh2/binary/IndexedBinaryBVH.js +1 -1
- package/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +5 -1
- package/core/bvh2/traversal/__detailed_box_volume_intersection.js +22 -5
- package/core/cache/Cache.d.ts +4 -2
- package/core/cache/Cache.js +5 -2
- package/core/collection/HashMap.d.ts +9 -2
- package/core/collection/HashSet.d.ts +7 -2
- package/core/collection/HashSet.js +7 -2
- package/core/collection/array/binarySearchHighIndex.js +1 -1
- package/core/collection/array/copyArray.js +2 -2
- package/core/collection/array/typed/typed_array_copy.js +1 -1
- package/core/geom/3d/frustum/array_setFromProjectionMatrix.js +3 -3
- package/core/geom/3d/normal/hemioct/unit_hemioct.spec.js +1 -1
- package/core/geom/3d/shape/AbstractShape3D.js +37 -1
- package/core/geom/3d/shape/TransformedShape3D.js +121 -10
- package/core/geom/3d/shape/TransformedShape3D.spec.js +33 -0
- package/core/geom/3d/shape/UnionShape3D.js +255 -0
- package/core/geom/3d/shape/UnitCubeShape3D.js +88 -0
- package/core/geom/3d/shape/UnitCubeShape3D.spec.js +42 -0
- package/core/geom/3d/shape/UnitSphereShape3D.js +39 -0
- package/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.js +48 -0
- package/core/geom/3d/shape/util/shape_to_visual_entity.js +159 -0
- package/core/geom/random/randomPointInSphere.js +3 -2
- package/core/json/resolvePathByArray.js +2 -2
- package/core/model/ObservedBoolean.d.ts +2 -0
- package/core/parser/simple/Token.d.ts +13 -0
- package/core/parser/simple/Token.js +61 -27
- package/{engine/graphics/render/forward_plus/materials → core/primitives/strings}/insert_after.js +3 -0
- package/core/primitives/strings/insert_after_or_replace.js +27 -0
- package/editor/process/symbolic/makeHelperBoxGeometry.js +44 -0
- package/editor/tools/FoliagePaintTool.js +4 -4
- package/editor/view/ecs/EntityEditor.js +2 -2
- package/editor/view/ecs/components/particles/ParticleEmitterController.js +2 -2
- package/engine/EngineHarness.js +1 -0
- package/engine/animation/AnimationUtils.js +5 -5
- package/engine/asset/loaders/GLTFAssetLoader.js +52 -1
- package/engine/asset/loaders/image/ImageDecoderWorker.js +4 -3
- package/engine/asset/loaders/image/ImageRGBADataAsset.js +3 -2
- package/engine/asset/loaders/image/ImageRGBADataLoader.js +3 -3
- package/engine/asset/loaders/image/codec/NativeImageDecoder.js +2 -1
- package/engine/asset/loaders/image/png/PNG.js +113 -6
- package/engine/asset/loaders/image/png/PNGReader.js +5 -0
- package/engine/asset/loaders/material/bitmap2sampler_gl.js +1 -1
- package/engine/asset/loaders/material/computeImageBitmapEquality.js +6 -1
- package/engine/asset/loaders/material/computeTextureEquality.js +40 -49
- package/engine/ecs/EntityBuilder.js +25 -5
- package/engine/ecs/EntityComponentDataset.js +1 -1
- package/engine/ecs/attachment/AttachmentBinding.js +8 -0
- package/engine/ecs/attachment/AttachmentSystem.js +4 -0
- package/engine/ecs/attachment/TransformAttachmentBinding.js +14 -44
- package/engine/ecs/components/Tag.js +27 -6
- package/engine/ecs/foliage/InstancedFoliage.js +277 -266
- package/engine/ecs/foliage/ecs/Foliage2System.js +7 -7
- package/engine/ecs/foliage/ecs/InstancedMeshComponent.js +37 -0
- package/engine/ecs/foliage/ecs/{Foliage2.js → InstancedMeshLayer.js} +3 -45
- package/engine/ecs/foliage/ecs/InstancedMeshSerializationAdapter.js +6 -5
- package/engine/ecs/foliage/ecs/InstancedMeshUtils.js +7 -6
- package/engine/ecs/fow/FogOfWar.js +4 -0
- package/engine/ecs/fow/FogOfWarSystem.js +2 -0
- package/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +2 -0
- package/engine/ecs/storage/binary/BinarySerializationRegistry.js +1 -1
- package/engine/ecs/system/AbstractContextSystem.js +1 -1
- package/engine/ecs/systems/TagSystem.js +17 -0
- package/engine/ecs/terrain/ecs/layers/TerrainLayer.js +12 -16
- package/engine/ecs/transform/Transform.js +19 -6
- package/engine/graphics/GraphicsEngine.js +11 -6
- package/engine/graphics/composit/CompositLayer.js +17 -4
- package/engine/graphics/composit/CompositingStages.js +8 -0
- package/engine/graphics/composit/LayerCompositer.js +35 -6
- package/engine/graphics/ecs/highlight/plugin/OutlineRenderPlugin.js +11 -7
- package/engine/graphics/ecs/light/Light.js +2 -0
- package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +5 -1
- package/engine/graphics/ecs/mesh-v2/DrawMode.js +5 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +32 -18
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +14 -72
- package/engine/graphics/geometry/instancing/rewriteMaterial.js +70 -0
- package/engine/graphics/material/manager/MaterialManager.js +2 -1
- package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +6 -4
- package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +0 -2
- package/engine/graphics/particles/ParticleEmitterLibrary.js +3 -0
- package/engine/graphics/particles/ecs/{ParticleEmitterSystem2.js → ParticleEmitterSystem.js} +17 -9
- package/engine/graphics/particles/particular/engine/ParticularEngine.js +8 -2
- package/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +14 -25
- package/engine/graphics/particles/particular/engine/emitter/ParticleEmitterFlag.js +5 -0
- package/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +90 -2
- package/engine/graphics/particles/particular/engine/emitter/ParticlePool.spec.js +7 -7
- package/engine/graphics/particles/particular/engine/renderers/billboard/BILLBOARD_PARTICLE_SPECIFICATION.js +15 -12
- package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +262 -51
- package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +81 -48
- package/engine/graphics/particles/particular/engine/shader/debugAtlas.js +14 -0
- package/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +141 -0
- package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +148 -54
- package/engine/graphics/particles/particular/engine/utils/volume/lut_to_sampler.js +27 -0
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +544 -164
- package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +15 -10
- package/engine/graphics/render/forward_plus/materials/FP_INJECTION_POINT_ACCUMULATION.js +1 -0
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +32 -0
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_DECODE_PARS.js +51 -0
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +25 -0
- package/engine/graphics/render/forward_plus/materials/FPlusDebugMaterial.js +3 -3
- package/engine/graphics/render/forward_plus/materials/ForwardPlusThreeMaterial.js +1 -1
- package/engine/graphics/render/forward_plus/materials/fp_build_fragment_shader.js +31 -120
- package/engine/graphics/render/forward_plus/materials/fp_build_vertex_lighting_shared.js +35 -0
- package/engine/graphics/render/forward_plus/materials/fp_build_vertex_shader.js +4 -5
- package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +10 -3
- package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +588 -53
- package/engine/graphics/render/forward_plus/prototypeLightManager.js +31 -6
- package/engine/graphics/render/forward_plus/query/point_light_inside_volume.js +10 -9
- package/engine/graphics/shaders/TerrainShader.js +4 -5
- package/engine/graphics/shadows/ShadowMapRenderer.js +8 -2
- package/engine/graphics/texture/atlas/ManagedTextureAtlas.js +12 -1
- package/engine/graphics/texture/sampler/Sampler2D.js +3 -1
- package/engine/graphics/texture/sampler/convertTexture2Sampler2D.js +1 -1
- package/engine/graphics/texture/sampler/copy_Sampler2D_channel_data.js +66 -0
- package/engine/graphics/util/composeMatrix4.js +33 -23
- package/engine/graphics/util/decompose_matrix_4_array.js +61 -0
- package/engine/intelligence/behavior/ecs/BehaviorComponent.js +30 -14
- package/engine/knowledge/database/StaticKnowledgeDataTable.js +6 -1
- package/engine/navigation/ecs/components/Path.js +0 -5
- package/package.json +1 -1
- package/view/minimap/gl/MinimapWorldGL.js +12 -5
- package/core/geom/3d/shape/CompositeShape.js +0 -60
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Debug tool to verify correct behavior of a BitSet
|
|
5
|
+
*/
|
|
6
|
+
export class ValidatingBitSetWrapper {
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {BitSet} source
|
|
10
|
+
*/
|
|
11
|
+
constructor(source) {
|
|
12
|
+
this.__source = source;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
preventShrink() {
|
|
16
|
+
this.__source.preventShrink();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
setShrinkFactor(x) {
|
|
20
|
+
this.__source.setShrinkFactor(x);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
setCapacity(x) {
|
|
24
|
+
this.__source.setCapacity(x);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
size() {
|
|
28
|
+
return this.__source.size();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
capacity() {
|
|
32
|
+
return this.__source.capacity();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
previousSetBit(i) {
|
|
36
|
+
const bit = this.__source.previousSetBit(i);
|
|
37
|
+
|
|
38
|
+
if (bit !== -1 && (this.__source.get(bit) !== true || bit > i)) {
|
|
39
|
+
debugger;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return bit;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
nextSetBit(i) {
|
|
46
|
+
const bit = this.__source.nextSetBit(i);
|
|
47
|
+
|
|
48
|
+
if (bit !== -1 && (this.__source.get(bit) !== true || bit < i)) {
|
|
49
|
+
debugger;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return bit;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
nextClearBit(i) {
|
|
56
|
+
const bit = this.__source.nextClearBit(i);
|
|
57
|
+
|
|
58
|
+
if (bit !== -1 && (this.__source.get(bit) !== false || bit < i)) {
|
|
59
|
+
debugger;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return bit;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
set(x, y) {
|
|
66
|
+
this.__source.set(x, y);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
clear(i) {
|
|
70
|
+
this.__source.clear(i);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get(i) {
|
|
74
|
+
return this.__source.get(i);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
reset() {
|
|
79
|
+
this.__source.reset();
|
|
80
|
+
}
|
|
81
|
+
}
|
package/core/bvh2/aabb3/AABB3.js
CHANGED
|
@@ -761,16 +761,9 @@ AABB3.prototype.computePlaneSide = function computePlaneSide(plane) {
|
|
|
761
761
|
const normal = plane.normal;
|
|
762
762
|
|
|
763
763
|
return computeAABB3PlaneSide(
|
|
764
|
-
normal.x,
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
plane.constant,
|
|
768
|
-
this.x0,
|
|
769
|
-
this.y0,
|
|
770
|
-
this.z0,
|
|
771
|
-
this.x1,
|
|
772
|
-
this.y1,
|
|
773
|
-
this.z1
|
|
764
|
+
normal.x, normal.y, normal.z, plane.constant,
|
|
765
|
+
this.x0, this.y0, this.z0,
|
|
766
|
+
this.x1, this.y1, this.z1
|
|
774
767
|
);
|
|
775
768
|
};
|
|
776
769
|
|
|
@@ -344,7 +344,7 @@ function writeBox(array, address, x0, y0, z0, x1, y1, z1) {
|
|
|
344
344
|
* @param {Float32Array} array
|
|
345
345
|
*/
|
|
346
346
|
function copyBox(from, to, array) {
|
|
347
|
-
array_copy(
|
|
347
|
+
array_copy(array, from, array, to, 6);
|
|
348
348
|
}
|
|
349
349
|
|
|
350
350
|
/**
|
|
@@ -7,37 +7,54 @@ import { __process_point_if_within_planes } from "./__process_point_if_within_pl
|
|
|
7
7
|
import { plane_computeConvex3PlaneIntersection } from "../../geom/3d/plane/plane_computeConvex3PlaneIntersection.js";
|
|
8
8
|
import { EPSILON } from "../../math/MathUtils.js";
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Common piece of continuous memory for better cache coherence
|
|
12
|
+
* @type {ArrayBuffer}
|
|
13
|
+
* @private
|
|
14
|
+
*/
|
|
15
|
+
const __scratch_buffer = new ArrayBuffer(
|
|
16
|
+
24 * 4
|
|
17
|
+
+ 24 * 4
|
|
18
|
+
+ 8 * 4
|
|
19
|
+
+ 3 * 4
|
|
20
|
+
);
|
|
21
|
+
|
|
10
22
|
/**
|
|
11
23
|
*
|
|
12
24
|
* @type {number[]}
|
|
13
25
|
*/
|
|
14
|
-
const scratch_aabb_corners = new Float32Array(24);
|
|
26
|
+
const scratch_aabb_corners = new Float32Array(__scratch_buffer, 0, 24);
|
|
15
27
|
|
|
16
28
|
/**
|
|
17
29
|
*
|
|
18
30
|
* @type {number[]}
|
|
19
31
|
*/
|
|
20
|
-
const scratch_aabb_planes = new Float32Array(24);
|
|
32
|
+
const scratch_aabb_planes = new Float32Array(__scratch_buffer, 96, 24);
|
|
21
33
|
|
|
22
34
|
/**
|
|
23
35
|
*
|
|
24
36
|
* @type {number[]}
|
|
25
37
|
*/
|
|
26
|
-
const scratch_corner_out_bitfields = new Uint32Array(8);
|
|
38
|
+
const scratch_corner_out_bitfields = new Uint32Array(__scratch_buffer, 192, 8);
|
|
27
39
|
|
|
28
40
|
/**
|
|
29
41
|
*
|
|
30
42
|
* @type {number[]}
|
|
31
43
|
*/
|
|
32
|
-
const scratch_v3_array = new Float32Array(3);
|
|
44
|
+
const scratch_v3_array = new Float32Array(__scratch_buffer, 224, 3);
|
|
33
45
|
|
|
34
46
|
/**
|
|
47
|
+
* Figures out intersection volume between an AABB and a frustum for much tighter bounds
|
|
48
|
+
*
|
|
49
|
+
* Especially beneficial when trying to intersect a large AABB against a small frustum,
|
|
50
|
+
* where where traditionally only AABB corners would be considered,
|
|
51
|
+
* we're instead able to compute minimum bounds of the overlap of the two
|
|
35
52
|
*
|
|
36
53
|
* @param {AABB3} box
|
|
37
54
|
* @param {number[]} planes
|
|
38
55
|
* @param {number} plane_count
|
|
39
56
|
* @param {number} plane_mask
|
|
40
|
-
* @param {function} callback
|
|
57
|
+
* @param {function(x:number,y:number,z:number)} callback
|
|
41
58
|
* @param {*} [thisArg]
|
|
42
59
|
* @private
|
|
43
60
|
*/
|
package/core/cache/Cache.d.ts
CHANGED
|
@@ -4,13 +4,15 @@ export class Cache<K, V> {
|
|
|
4
4
|
keyWeigher,
|
|
5
5
|
valueWeigher,
|
|
6
6
|
keyHashFunction,
|
|
7
|
-
keyEqualityFunction
|
|
7
|
+
keyEqualityFunction,
|
|
8
|
+
capacity
|
|
8
9
|
}?: {
|
|
9
10
|
maxWeight?: number,
|
|
10
11
|
keyWeigher?: (key: K) => number,
|
|
11
12
|
valueWeigher?: (value: V) => number,
|
|
12
13
|
keyHashFunction?: (key: K) => number,
|
|
13
|
-
keyEqualityFunction?: (a: K, b: K) => boolean
|
|
14
|
+
keyEqualityFunction?: (a: K, b: K) => boolean,
|
|
15
|
+
capacity?: number
|
|
14
16
|
})
|
|
15
17
|
|
|
16
18
|
size(): number
|
package/core/cache/Cache.js
CHANGED
|
@@ -16,6 +16,7 @@ export class Cache {
|
|
|
16
16
|
* @param {function(key:Key, value:Value)} [removeListener] will be notified when element is either explicitly removed or evicted
|
|
17
17
|
* @param {function(Key):number} [keyHashFunction]
|
|
18
18
|
* @param {function(Key, Key):boolean} [keyEqualityFunction]
|
|
19
|
+
* @param {number} capacity initial capacity for the cache, helps prevent early resizing
|
|
19
20
|
* @constructor
|
|
20
21
|
* @template Key, Value
|
|
21
22
|
*/
|
|
@@ -25,7 +26,8 @@ export class Cache {
|
|
|
25
26
|
valueWeigher = returnOne,
|
|
26
27
|
removeListener = noop,
|
|
27
28
|
keyHashFunction = returnZero,
|
|
28
|
-
keyEqualityFunction = strictEquals
|
|
29
|
+
keyEqualityFunction = strictEquals,
|
|
30
|
+
capacity
|
|
29
31
|
} = {}) {
|
|
30
32
|
|
|
31
33
|
assert.isNumber(maxWeight, 'maxWeight');
|
|
@@ -95,7 +97,8 @@ export class Cache {
|
|
|
95
97
|
*/
|
|
96
98
|
this.data = new HashMap({
|
|
97
99
|
keyHashFunction,
|
|
98
|
-
keyEqualityFunction
|
|
100
|
+
keyEqualityFunction,
|
|
101
|
+
capacity
|
|
99
102
|
});
|
|
100
103
|
|
|
101
104
|
/**
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
export class HashMap<K, V> implements Iterable<[V, K]> {
|
|
2
|
-
constructor({
|
|
2
|
+
constructor({
|
|
3
|
+
keyHashFunction,
|
|
4
|
+
keyEqualityFunction,
|
|
5
|
+
capacity,
|
|
6
|
+
loadFactor
|
|
7
|
+
}: {
|
|
3
8
|
keyHashFunction: (k: K) => number,
|
|
4
|
-
keyEqualityFunction: (a: K, b: K) => boolean
|
|
9
|
+
keyEqualityFunction: (a: K, b: K) => boolean,
|
|
10
|
+
capacity?: number,
|
|
11
|
+
loadFactor?: number
|
|
5
12
|
})
|
|
6
13
|
|
|
7
14
|
constructor()
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
export class HashSet<T> {
|
|
2
|
-
constructor({
|
|
2
|
+
constructor({
|
|
3
|
+
keyHashFunction,
|
|
4
|
+
keyEqualityFunction,
|
|
5
|
+
capacity
|
|
6
|
+
}: {
|
|
3
7
|
keyHashFunction: (k: T) => number,
|
|
4
|
-
keyEqualityFunction: (a: T, b: T) => boolean
|
|
8
|
+
keyEqualityFunction: (a: T, b: T) => boolean,
|
|
9
|
+
capacity?: number
|
|
5
10
|
})
|
|
6
11
|
|
|
7
12
|
constructor()
|
|
@@ -11,7 +11,11 @@ export class HashSet {
|
|
|
11
11
|
/**
|
|
12
12
|
* @template T
|
|
13
13
|
*/
|
|
14
|
-
constructor({
|
|
14
|
+
constructor({
|
|
15
|
+
keyHashFunction = invokeObjectHash,
|
|
16
|
+
keyEqualityFunction = invokeObjectEquals,
|
|
17
|
+
capacity
|
|
18
|
+
} = {}) {
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* Using HashMap as a backing, this is not the most efficient approach, but it works
|
|
@@ -20,7 +24,8 @@ export class HashSet {
|
|
|
20
24
|
*/
|
|
21
25
|
this.__map = new HashMap({
|
|
22
26
|
keyHashFunction,
|
|
23
|
-
keyEqualityFunction
|
|
27
|
+
keyEqualityFunction,
|
|
28
|
+
capacity
|
|
24
29
|
});
|
|
25
30
|
}
|
|
26
31
|
|
|
@@ -25,9 +25,9 @@ export function copyArray(source, target) {
|
|
|
25
25
|
* Follows Java System.arraycopy interface
|
|
26
26
|
* Copy data from one array to another
|
|
27
27
|
* @template T
|
|
28
|
-
* @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array} source The source array
|
|
28
|
+
* @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array|Float32Array|Float64Array} source The source array
|
|
29
29
|
* @param {number} source_position Starting position where to copy from inside the source array
|
|
30
|
-
* @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array} destination The destination array
|
|
30
|
+
* @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array|Float32Array|Float64Array} destination The destination array
|
|
31
31
|
* @param {number} destination_position Starting position where to copy to inside the destination array
|
|
32
32
|
* @param {number} length How many elements should be copied
|
|
33
33
|
*/
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { v3_length } from "../../v3_length.js";
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
*
|
|
5
3
|
* @param {number[]} destination
|
|
@@ -10,10 +8,12 @@ import { v3_length } from "../../v3_length.js";
|
|
|
10
8
|
* @param {number} w
|
|
11
9
|
*/
|
|
12
10
|
function array_set_plane_normalized(destination, destination_offset, x, y, z, w) {
|
|
13
|
-
|
|
11
|
+
// compute vector length
|
|
12
|
+
const length = Math.hypot(x, y, z);
|
|
14
13
|
|
|
15
14
|
const inverseNormalLength = 1.0 / length;
|
|
16
15
|
|
|
16
|
+
// apply normalization
|
|
17
17
|
destination[destination_offset] = x * inverseNormalLength;
|
|
18
18
|
destination[destination_offset + 1] = y * inverseNormalLength;
|
|
19
19
|
destination[destination_offset + 2] = z * inverseNormalLength;
|
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
export class AbstractShape3D {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Signed distance to boundary of the shape from the given point
|
|
4
|
+
* @param {number[]} point
|
|
5
|
+
* @returns {number}
|
|
6
|
+
*/
|
|
7
|
+
signed_distance_at_point(point) {
|
|
8
|
+
throw new Error('Not Implemented');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Samples both distances as well as the gradient
|
|
13
|
+
* @param {number[]} result resulting gradient is written here
|
|
14
|
+
* @param {number[]} point sampling point
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
17
|
+
signed_distance_gradient_at_point(result, point) {
|
|
18
|
+
throw new Error('Not Implemented');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @param {number[]} result where the resulting point is stored
|
|
24
|
+
* @param {number[]} reference reference point from which to go
|
|
25
|
+
* @returns {void}
|
|
26
|
+
*/
|
|
27
|
+
nearest_point_on_surface(result, reference) {
|
|
28
|
+
throw new Error('Not Implemented');
|
|
3
29
|
}
|
|
4
30
|
|
|
5
31
|
/**
|
|
@@ -7,11 +33,21 @@ export class AbstractShape3D {
|
|
|
7
33
|
* @param {number[]} result
|
|
8
34
|
* @param {number} result_offset
|
|
9
35
|
* @param {function} random
|
|
36
|
+
* @returns {void}
|
|
10
37
|
*/
|
|
11
38
|
sample_random_point_in_volume(result, result_offset, random) {
|
|
12
39
|
throw new Error('Not Implemented');
|
|
13
40
|
}
|
|
14
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Whether or not given point is inside the shape
|
|
44
|
+
* @param {number[]} point
|
|
45
|
+
* @returns {boolean}
|
|
46
|
+
*/
|
|
47
|
+
contains_point(point) {
|
|
48
|
+
throw new Error('Not Implemented');
|
|
49
|
+
}
|
|
50
|
+
|
|
15
51
|
/**
|
|
16
52
|
* Total volume of the shape
|
|
17
53
|
* @returns {number}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { mat4, vec3 } from "gl-matrix";
|
|
2
2
|
import { AbstractShape3D } from "./AbstractShape3D.js";
|
|
3
|
+
import { sign } from "../../../math/sign.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
*
|
|
6
7
|
* @type {number[]|Float32Array|vec3}
|
|
7
8
|
*/
|
|
8
|
-
const
|
|
9
|
+
const scratch_v3_0 = [];
|
|
9
10
|
|
|
10
11
|
export class TransformedShape3D extends AbstractShape3D {
|
|
11
12
|
constructor() {
|
|
@@ -17,6 +18,14 @@ export class TransformedShape3D extends AbstractShape3D {
|
|
|
17
18
|
* @private
|
|
18
19
|
*/
|
|
19
20
|
this.__matrix = new Float32Array(16);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @type {Float32Array|mat4}
|
|
25
|
+
* @private
|
|
26
|
+
*/
|
|
27
|
+
this.__inverse_matrix = new Float32Array(16);
|
|
28
|
+
|
|
20
29
|
/**
|
|
21
30
|
*
|
|
22
31
|
* @type {AbstractShape3D|null}
|
|
@@ -27,7 +36,15 @@ export class TransformedShape3D extends AbstractShape3D {
|
|
|
27
36
|
|
|
28
37
|
/**
|
|
29
38
|
*
|
|
30
|
-
* @
|
|
39
|
+
* @returns {AbstractShape3D|null}
|
|
40
|
+
*/
|
|
41
|
+
get subject() {
|
|
42
|
+
return this.__subject;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param {number[]|Float32Array|mat4} m4
|
|
31
48
|
* @param {AbstractShape3D} subject
|
|
32
49
|
* @returns {TransformedShape3D}
|
|
33
50
|
*/
|
|
@@ -35,36 +52,130 @@ export class TransformedShape3D extends AbstractShape3D {
|
|
|
35
52
|
const r = new TransformedShape3D();
|
|
36
53
|
|
|
37
54
|
r.__subject = subject;
|
|
38
|
-
r.
|
|
55
|
+
r.transform = m4;
|
|
39
56
|
|
|
40
57
|
return r;
|
|
41
58
|
}
|
|
42
59
|
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
* @param {AbstractShape3D} subject
|
|
63
|
+
* @param {number[]} translation
|
|
64
|
+
* @param {number[]} scale
|
|
65
|
+
*/
|
|
66
|
+
static from_translation_scale(subject, translation, scale) {
|
|
67
|
+
|
|
68
|
+
const mat = mat4.create();
|
|
69
|
+
mat4.fromRotationTranslationScale(mat, [0, 0, 0, 1], translation, scale);
|
|
70
|
+
|
|
71
|
+
return TransformedShape3D.from_m4(subject, mat);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
*
|
|
76
|
+
* @returns {TransformedShape3D}
|
|
77
|
+
* @param {AbstractShape3D} subject
|
|
78
|
+
* @param {number[]|Float32Array|vec3} scale
|
|
79
|
+
*/
|
|
80
|
+
static from_scale(subject, scale) {
|
|
81
|
+
const mat = mat4.create();
|
|
82
|
+
mat4.fromScaling(mat, scale);
|
|
83
|
+
|
|
84
|
+
return TransformedShape3D.from_m4(subject, mat);
|
|
85
|
+
}
|
|
86
|
+
|
|
43
87
|
/**
|
|
44
88
|
*
|
|
45
89
|
* @param {number[]|Float32Array} m
|
|
46
90
|
*/
|
|
47
91
|
set transform(m) {
|
|
48
92
|
this.__matrix.set(m);
|
|
93
|
+
|
|
94
|
+
mat4.invert(this.__inverse_matrix, this.__matrix);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
get transform() {
|
|
98
|
+
return this.__matrix;
|
|
49
99
|
}
|
|
50
100
|
|
|
51
101
|
get volume() {
|
|
52
|
-
mat4.getScaling(
|
|
102
|
+
mat4.getScaling(scratch_v3_0, this.__matrix);
|
|
53
103
|
|
|
54
|
-
const scale_modifier =
|
|
104
|
+
const scale_modifier = scratch_v3_0[0] * scratch_v3_0[1] * scratch_v3_0[2];
|
|
55
105
|
|
|
56
106
|
return this.__subject.volume * scale_modifier;
|
|
57
107
|
}
|
|
58
108
|
|
|
109
|
+
signed_distance_gradient_at_point(result, point) {
|
|
110
|
+
// transform point to subject's local space
|
|
111
|
+
vec3.transformMat4(scratch_v3_0, point, this.__inverse_matrix);
|
|
112
|
+
|
|
113
|
+
const subject = this.__subject;
|
|
114
|
+
|
|
115
|
+
// sample gradient at the point
|
|
116
|
+
const distance = subject.signed_distance_gradient_at_point(scratch_v3_0, scratch_v3_0);
|
|
117
|
+
|
|
118
|
+
const m = this.__matrix;
|
|
119
|
+
|
|
120
|
+
const m11 = m[0];
|
|
121
|
+
const m12 = m[1];
|
|
122
|
+
const m13 = m[2];
|
|
123
|
+
|
|
124
|
+
const m21 = m[4];
|
|
125
|
+
const m22 = m[5];
|
|
126
|
+
const m23 = m[6];
|
|
127
|
+
|
|
128
|
+
const m31 = m[8];
|
|
129
|
+
const m32 = m[9];
|
|
130
|
+
const m33 = m[10];
|
|
131
|
+
|
|
132
|
+
const scale_x = Math.hypot(m11, m12, m13);
|
|
133
|
+
const scale_y = Math.hypot(m21, m22, m23);
|
|
134
|
+
const scale_z = Math.hypot(m31, m32, m33);
|
|
135
|
+
|
|
136
|
+
const scaled_gx = scratch_v3_0[0] * scale_x;
|
|
137
|
+
const scaled_gy = scratch_v3_0[1] * scale_y;
|
|
138
|
+
const scaled_gz = scratch_v3_0[2] * scale_z;
|
|
139
|
+
|
|
140
|
+
// normalize gradient
|
|
141
|
+
const gd = distance / Math.hypot(scratch_v3_0[0], scratch_v3_0[1], scratch_v3_0[2]);
|
|
142
|
+
|
|
143
|
+
const scaled_dx = scaled_gx * gd ;
|
|
144
|
+
const scaled_dy = scaled_gy * gd ;
|
|
145
|
+
const scaled_dz = scaled_gz * gd ;
|
|
146
|
+
|
|
147
|
+
// determine sign
|
|
148
|
+
const result_sign = sign(distance);
|
|
149
|
+
|
|
150
|
+
const scaled_distance = result_sign * Math.sqrt(scaled_dx * scaled_dx + scaled_dy * scaled_dy + scaled_dz * scaled_dz);
|
|
151
|
+
|
|
152
|
+
result[0] = scaled_gx;
|
|
153
|
+
result[1] = scaled_gy;
|
|
154
|
+
result[2] = scaled_gz;
|
|
155
|
+
|
|
156
|
+
return scaled_distance;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
signed_distance_at_point(point) {
|
|
160
|
+
return this.signed_distance_gradient_at_point(scratch_v3_0, point);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
contains_point(point) {
|
|
164
|
+
// transform point to subject's local space
|
|
165
|
+
vec3.transformMat4(scratch_v3_0, point, this.__inverse_matrix);
|
|
166
|
+
|
|
167
|
+
return this.__subject.contains_point(scratch_v3_0);
|
|
168
|
+
}
|
|
169
|
+
|
|
59
170
|
sample_random_point_in_volume(result, result_offset, random) {
|
|
60
|
-
this.__subject.sample_random_point_in_volume(
|
|
171
|
+
this.__subject.sample_random_point_in_volume(scratch_v3_0, 0, random);
|
|
61
172
|
|
|
62
173
|
// apply transform
|
|
63
|
-
vec3.transformMat4(
|
|
174
|
+
vec3.transformMat4(scratch_v3_0, scratch_v3_0, this.__matrix);
|
|
64
175
|
|
|
65
176
|
// write out
|
|
66
|
-
result[0] =
|
|
67
|
-
result[1] =
|
|
68
|
-
result[2] =
|
|
177
|
+
result[0] = scratch_v3_0[0];
|
|
178
|
+
result[1] = scratch_v3_0[1];
|
|
179
|
+
result[2] = scratch_v3_0[2];
|
|
69
180
|
}
|
|
70
181
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { UnitCubeShape3D } from "./UnitCubeShape3D.js";
|
|
2
|
+
import { TransformedShape3D } from "./TransformedShape3D.js";
|
|
3
|
+
|
|
4
|
+
test('signed distance identity transform', () => {
|
|
5
|
+
|
|
6
|
+
const s = TransformedShape3D.from_translation_scale(new UnitCubeShape3D(), [0, 0, 0], [1, 1, 1]);
|
|
7
|
+
|
|
8
|
+
expect(s.signed_distance_at_point([0, 0, 0])).toBeCloseTo(-0.5);
|
|
9
|
+
|
|
10
|
+
expect(s.signed_distance_at_point([1, 0, 0])).toBeCloseTo(0.5);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('signed distance translation', () => {
|
|
14
|
+
|
|
15
|
+
const s = TransformedShape3D.from_translation_scale(new UnitCubeShape3D(), [1, 0, 0], [1, 1, 1]);
|
|
16
|
+
|
|
17
|
+
expect(s.signed_distance_at_point([0, 0, 0])).toBeCloseTo(0.5);
|
|
18
|
+
|
|
19
|
+
expect(s.signed_distance_at_point([-1, 0, 0])).toBeCloseTo(1.5);
|
|
20
|
+
|
|
21
|
+
expect(s.signed_distance_at_point([1, 0, 0])).toBeCloseTo(-0.5);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('signed distance scale', () => {
|
|
25
|
+
|
|
26
|
+
const s = TransformedShape3D.from_translation_scale(new UnitCubeShape3D(), [0, 0, 0], [2, 2, 2]);
|
|
27
|
+
|
|
28
|
+
expect(s.signed_distance_at_point([0, 0, 0])).toBeCloseTo(-1);
|
|
29
|
+
|
|
30
|
+
expect(s.signed_distance_at_point([1, 0, 0])).toBeCloseTo(0);
|
|
31
|
+
|
|
32
|
+
expect(s.signed_distance_at_point([2, 0, 0])).toBeCloseTo(1);
|
|
33
|
+
});
|