@woosh/meep-engine 2.34.48 → 2.35.1
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 +7 -2
- package/core/bvh2/BinaryNode.js +19 -35
- package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +5 -5
- package/core/bvh2/aabb3_combined_surface_area.js +21 -0
- package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +24 -12
- package/core/cache/Cache.d.ts +2 -0
- package/core/cache/Cache.js +27 -23
- package/core/geom/3d/frustum/frustum_from_projection_matrix_array.js +29 -24
- package/core/math/max2.js +2 -6
- package/core/math/min2.js +2 -6
- package/engine/asset/loaders/geometry/geometry/computeGeometryEquality.js +3 -2
- package/engine/asset/loaders/geometry/geometry/computeGeometryHash.js +9 -1
- package/engine/ecs/EntityComponentDataset.js +7 -2
- package/engine/ecs/foliage/ViewState.js +13 -3
- package/engine/ecs/parent/EntityNode.js +23 -11
- package/engine/ecs/transform/Transform.js +15 -13
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +63 -26
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +63 -3
- package/engine/graphics/ecs/mesh-v2/render/AbstractRenderAdapter.js +67 -0
- package/engine/graphics/ecs/mesh-v2/render/GenericRendererAdapter.js +48 -0
- package/engine/graphics/ecs/mesh-v2/render/InstancedRendererAdapter.js +110 -0
- package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +98 -0
- package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +5 -0
- package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +23 -5
- package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +8 -3
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +23 -85
- package/engine/graphics/geometry/instancing/rewriteMaterial.js +9 -45
- package/engine/graphics/material/optimization/BUFFER_GEOMETRY_UVS.js +10 -0
- package/engine/graphics/material/optimization/MaterialDescriptor.js +46 -0
- package/engine/graphics/material/optimization/MaterialOptimizationContext.js +470 -201
- package/engine/graphics/material/optimization/UvContext.js +18 -0
- package/engine/graphics/material/optimization/is_compliant_mesh.js +71 -0
- package/engine/graphics/material/optimization/prepare_atlas_texture.js +23 -0
- package/engine/graphics/material/optimization/prototypeMaterialOptimizer.js +127 -0
- package/engine/graphics/micron/convert_three_object_to_micron.js +0 -2
- package/engine/graphics/micron/format/MicronGeometryPatch.js +34 -24
- package/engine/graphics/micron/format/VirtualGeometry.js +47 -11
- package/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js +22 -0
- package/engine/graphics/micron/prototypeVirtualGeometry.js +6 -3
- package/engine/graphics/micron/render/VirtualGeometryBuilder.js +9 -18
- package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +1 -45
- package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +18 -7
- package/engine/graphics/micron/render/refinement/RefinementSpec.js +0 -12
- package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +19 -24
- package/engine/graphics/micron/render/v1/MaterialContext.js +3 -2
- package/engine/graphics/micron/render/v1/VGThreeRenderer.js +19 -4
- package/engine/graphics/render/utils/ThreeBypassRenderer.js +3 -2
- package/engine/graphics/render/visibility/IncrementalDeltaSet.js +1 -0
- package/engine/graphics/texture/normalized_internal_format.js +48 -0
- package/engine/graphics/texture/sampler/Sampler2D.js +6 -0
- package/engine/graphics/texture/sampler/sampler2d_copy_channel_data.js +25 -0
- package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -0
- package/engine/graphics/texture/sampler/util/drawSamplerHTML.js +14 -1
- package/package.json +1 -1
package/core/binary/BitSet.js
CHANGED
|
@@ -59,7 +59,6 @@ const SHRINK_FACTOR = 0.5;
|
|
|
59
59
|
*/
|
|
60
60
|
const RESIZE_COUNT_THRESHOLD = 128;
|
|
61
61
|
|
|
62
|
-
|
|
63
62
|
/**
|
|
64
63
|
* Dynamically sized bit field
|
|
65
64
|
* @constructor
|
|
@@ -389,6 +388,7 @@ BitSet.prototype.set = function (bitIndex, value) {
|
|
|
389
388
|
const bitIndexInc = bitIndex + 1;
|
|
390
389
|
|
|
391
390
|
if (bitIndexInc > this.__length) {
|
|
391
|
+
// ensure capacity
|
|
392
392
|
this.__setLength(bitIndexInc);
|
|
393
393
|
}
|
|
394
394
|
|
|
@@ -401,6 +401,7 @@ BitSet.prototype.set = function (bitIndex, value) {
|
|
|
401
401
|
this.__data_uint32[word_offset] &= ~word_mask;
|
|
402
402
|
|
|
403
403
|
if (bitIndex === this.__length - 1) {
|
|
404
|
+
// trim down set size potentially
|
|
404
405
|
const newLastSetBit = this.previousSetBit(bitIndex);
|
|
405
406
|
|
|
406
407
|
this.__setLength(newLastSetBit + 1);
|
|
@@ -538,9 +539,13 @@ BitSet.prototype.reset = function () {
|
|
|
538
539
|
if (current_length <= 0) {
|
|
539
540
|
// no action required
|
|
540
541
|
return;
|
|
542
|
+
} else if (current_length <= 32) {
|
|
543
|
+
// one word, set first word to 0 manually
|
|
544
|
+
this.__data_uint32[0] = 0;
|
|
545
|
+
} else {
|
|
546
|
+
this.__data_uint32.fill(0, 0, Math.ceil(current_length / 32));
|
|
541
547
|
}
|
|
542
548
|
|
|
543
|
-
this.__data_uint32.fill(0, 0, Math.ceil(current_length / 32));
|
|
544
549
|
this.__length = 0;
|
|
545
550
|
};
|
|
546
551
|
|
package/core/bvh2/BinaryNode.js
CHANGED
|
@@ -15,7 +15,7 @@ import { BVHVisitor } from "./traversal/BVHVisitor.js";
|
|
|
15
15
|
import { traverseBinaryNodeUsingVisitor } from "./traversal/traverseBinaryNodeUsingVisitor.js";
|
|
16
16
|
import { aabb3_intersect_aabb3 } from "./aabb3/aabb3_intersect_aabb3.js";
|
|
17
17
|
import { aabb3_box_surface_area_2 } from "./aabb3/aabb3_box_surface_area_2.js";
|
|
18
|
-
import {
|
|
18
|
+
import { aabb3_combined_surface_area } from "./aabb3_combined_surface_area.js";
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -206,6 +206,7 @@ export class BinaryNode extends Node {
|
|
|
206
206
|
/**
|
|
207
207
|
* For incremental insertion, a sibling needs to be found, newly inserted node will be parented together with this sibling
|
|
208
208
|
* @see https://github.com/erincatto/box2d/blob/9dc24a6fd4f32442c4bcf80791de47a0a7d25afb/src/collision/b2_dynamic_tree.cpp#L197
|
|
209
|
+
* @private
|
|
209
210
|
* @param {AABB3} box
|
|
210
211
|
* @returns {BinaryNode|LeafNode}
|
|
211
212
|
*/
|
|
@@ -215,13 +216,13 @@ export class BinaryNode extends Node {
|
|
|
215
216
|
let cost_left = 0;
|
|
216
217
|
let cost_right = 0;
|
|
217
218
|
|
|
218
|
-
while (node.isBinaryNode) {
|
|
219
|
+
while (node.isBinaryNode === true) {
|
|
219
220
|
const left = node.left;
|
|
220
221
|
const right = node.right;
|
|
221
222
|
|
|
222
223
|
const area = aabb3_box_surface_area_2(node);
|
|
223
224
|
|
|
224
|
-
const combined_area =
|
|
225
|
+
const combined_area = aabb3_combined_surface_area(node, box);
|
|
225
226
|
|
|
226
227
|
//cost of creating a new parent for this node and the new leaf
|
|
227
228
|
const cost = combined_area;
|
|
@@ -231,10 +232,11 @@ export class BinaryNode extends Node {
|
|
|
231
232
|
|
|
232
233
|
// cost of descending left
|
|
233
234
|
if (left !== null) {
|
|
235
|
+
const combined_left = aabb3_combined_surface_area(left, box);
|
|
234
236
|
if (left.isLeafNode) {
|
|
235
|
-
cost_left =
|
|
237
|
+
cost_left = combined_left + inheritance_cost;
|
|
236
238
|
} else {
|
|
237
|
-
cost_left =
|
|
239
|
+
cost_left = combined_left - aabb3_box_surface_area_2(left) + inheritance_cost;
|
|
238
240
|
}
|
|
239
241
|
} else {
|
|
240
242
|
cost_left = Infinity;
|
|
@@ -243,10 +245,11 @@ export class BinaryNode extends Node {
|
|
|
243
245
|
// cost of descending right
|
|
244
246
|
if (right !== null) {
|
|
245
247
|
|
|
248
|
+
const combined_right = aabb3_combined_surface_area(right, box);
|
|
246
249
|
if (right.isLeafNode) {
|
|
247
|
-
cost_right =
|
|
250
|
+
cost_right = combined_right + inheritance_cost;
|
|
248
251
|
} else {
|
|
249
|
-
cost_right =
|
|
252
|
+
cost_right = combined_right - aabb3_box_surface_area_2(right) + inheritance_cost;
|
|
250
253
|
}
|
|
251
254
|
} else {
|
|
252
255
|
cost_right = Infinity;
|
|
@@ -1045,10 +1048,9 @@ export class BinaryNode extends Node {
|
|
|
1045
1048
|
|
|
1046
1049
|
const sibling = this.__insertion_findSiblingFor(child);
|
|
1047
1050
|
|
|
1048
|
-
|
|
1049
|
-
let parent = sibling_parent;
|
|
1051
|
+
let parent = sibling.parentNode;
|
|
1050
1052
|
|
|
1051
|
-
if (
|
|
1053
|
+
if (parent === null) {
|
|
1052
1054
|
// "sibling" is the root node
|
|
1053
1055
|
|
|
1054
1056
|
parent = sibling;
|
|
@@ -1069,15 +1071,15 @@ export class BinaryNode extends Node {
|
|
|
1069
1071
|
|
|
1070
1072
|
// non-root
|
|
1071
1073
|
|
|
1072
|
-
if (
|
|
1074
|
+
if (parent.left === sibling && parent.right === null) {
|
|
1073
1075
|
|
|
1074
1076
|
// right node is free, take it
|
|
1075
|
-
|
|
1077
|
+
parent.setChildRight(child);
|
|
1076
1078
|
|
|
1077
|
-
} else if (
|
|
1079
|
+
} else if (parent.right === sibling && parent.left === null) {
|
|
1078
1080
|
|
|
1079
1081
|
// left node is free, take it
|
|
1080
|
-
|
|
1082
|
+
parent.setChildLeft(child);
|
|
1081
1083
|
|
|
1082
1084
|
} else {
|
|
1083
1085
|
|
|
@@ -1088,7 +1090,7 @@ export class BinaryNode extends Node {
|
|
|
1088
1090
|
}
|
|
1089
1091
|
|
|
1090
1092
|
// walk back up the tree fixing heights and bounds
|
|
1091
|
-
|
|
1093
|
+
do {
|
|
1092
1094
|
// parent = this.balance();
|
|
1093
1095
|
|
|
1094
1096
|
const left = parent.left;
|
|
@@ -1098,7 +1100,7 @@ export class BinaryNode extends Node {
|
|
|
1098
1100
|
parent.refit();
|
|
1099
1101
|
|
|
1100
1102
|
parent = parent.parentNode;
|
|
1101
|
-
}
|
|
1103
|
+
} while (parent !== null);
|
|
1102
1104
|
}
|
|
1103
1105
|
|
|
1104
1106
|
/**
|
|
@@ -1152,25 +1154,7 @@ BinaryNode.prototype.isBinaryNode = true;
|
|
|
1152
1154
|
* @returns {number}
|
|
1153
1155
|
*/
|
|
1154
1156
|
function inclusion_surface_area_heuristic(node, addition) {
|
|
1155
|
-
return
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
/**
|
|
1159
|
-
*
|
|
1160
|
-
* @param {AABB3} node
|
|
1161
|
-
* @param {AABB3} addition
|
|
1162
|
-
* @returns {number}
|
|
1163
|
-
*/
|
|
1164
|
-
function combined_surface_area(node, addition) {
|
|
1165
|
-
const x0 = min2(node.x0, addition.x0);
|
|
1166
|
-
const y0 = min2(node.y0, addition.y0);
|
|
1167
|
-
const z0 = min2(node.z0, addition.z0);
|
|
1168
|
-
|
|
1169
|
-
const x1 = max2(node.x1, addition.x1);
|
|
1170
|
-
const y1 = max2(node.y1, addition.y1);
|
|
1171
|
-
const z1 = max2(node.z1, addition.z1);
|
|
1172
|
-
|
|
1173
|
-
return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
|
|
1157
|
+
return aabb3_combined_surface_area(node, addition) - aabb3_box_surface_area_2(node);
|
|
1174
1158
|
}
|
|
1175
1159
|
|
|
1176
1160
|
/**
|
|
@@ -32,13 +32,13 @@ export function aabb3_intersects_frustum_array(aabb, frustum) {
|
|
|
32
32
|
export function aabb3_intersects_frustum(x0, y0, z0, x1, y1, z1, frustum) {
|
|
33
33
|
for (let i = 0; i < 24; i += 4) {
|
|
34
34
|
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
const
|
|
35
|
+
const plane_x = frustum[i];
|
|
36
|
+
const plane_y = frustum[i + 1];
|
|
37
|
+
const plane_z = frustum[i + 2];
|
|
38
|
+
const plane_w = frustum[i + 3];
|
|
39
39
|
|
|
40
40
|
const plane_distance = aabb3_computeDistanceAbovePlane(
|
|
41
|
-
|
|
41
|
+
plane_x, plane_y, plane_z, plane_w,
|
|
42
42
|
x0, y0, z0,
|
|
43
43
|
x1, y1, z1
|
|
44
44
|
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { min2 } from "../math/min2.js";
|
|
2
|
+
import { max2 } from "../math/max2.js";
|
|
3
|
+
import { aabb3_compute_half_surface_area } from "./aabb3/aabb3_compute_half_surface_area.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {AABB3} a
|
|
8
|
+
* @param {AABB3} b
|
|
9
|
+
* @returns {number}
|
|
10
|
+
*/
|
|
11
|
+
export function aabb3_combined_surface_area(a, b) {
|
|
12
|
+
const x0 = min2(a.x0, b.x0);
|
|
13
|
+
const y0 = min2(a.y0, b.y0);
|
|
14
|
+
const z0 = min2(a.z0, b.z0);
|
|
15
|
+
|
|
16
|
+
const x1 = max2(a.x1, b.x1);
|
|
17
|
+
const y1 = max2(a.y1, b.y1);
|
|
18
|
+
const z1 = max2(a.z1, b.z1);
|
|
19
|
+
|
|
20
|
+
return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
|
|
21
|
+
}
|
|
@@ -8,45 +8,57 @@ const stack = [];
|
|
|
8
8
|
/**
|
|
9
9
|
* @template T
|
|
10
10
|
* @param {T[]} destination
|
|
11
|
-
* @param {number}
|
|
11
|
+
* @param {number} destination_offset
|
|
12
12
|
* @param {BinaryNode<T>} root
|
|
13
13
|
* @param {ArrayLike<number>|number[]|Float32Array} frustum
|
|
14
14
|
* @returns {number} Number of results
|
|
15
15
|
*/
|
|
16
|
-
export function queryBinaryNode_FrustumIntersections_Data(destination,
|
|
16
|
+
export function queryBinaryNode_FrustumIntersections_Data(destination, destination_offset, root, frustum) {
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @type {BinaryNode<T>|LeafNode<T>}
|
|
20
|
+
*/
|
|
17
21
|
let n;
|
|
18
|
-
let
|
|
22
|
+
let offset = destination_offset;
|
|
19
23
|
let stackPointer = 1;
|
|
20
24
|
|
|
21
25
|
stack[0] = root;
|
|
22
26
|
|
|
23
27
|
while (stackPointer > 0) {
|
|
28
|
+
|
|
24
29
|
stackPointer--;
|
|
25
30
|
|
|
26
31
|
n = stack[stackPointer];
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
const node_intersects_frustum = n.intersectFrustum_array(frustum);
|
|
34
|
+
|
|
35
|
+
if (!node_intersects_frustum) {
|
|
29
36
|
continue;
|
|
30
37
|
}
|
|
31
38
|
|
|
32
|
-
if (n.isBinaryNode) {
|
|
39
|
+
if (n.isBinaryNode === true) {
|
|
33
40
|
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
const right = n.right;
|
|
42
|
+
|
|
43
|
+
if (right !== null) {
|
|
44
|
+
stack[stackPointer++] = right;
|
|
36
45
|
}
|
|
37
46
|
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
const left = n.left;
|
|
48
|
+
|
|
49
|
+
if (left !== null) {
|
|
50
|
+
stack[stackPointer++] = left;
|
|
40
51
|
}
|
|
41
52
|
|
|
42
53
|
} else {
|
|
54
|
+
// leaf node
|
|
43
55
|
|
|
44
|
-
destination[
|
|
56
|
+
destination[offset] = n.object;
|
|
45
57
|
|
|
46
|
-
|
|
58
|
+
offset++;
|
|
47
59
|
}
|
|
48
60
|
|
|
49
61
|
}
|
|
50
62
|
|
|
51
|
-
return
|
|
63
|
+
return offset - destination_offset;
|
|
52
64
|
}
|
package/core/cache/Cache.d.ts
CHANGED
package/core/cache/Cache.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { assert } from "../assert.js";
|
|
2
2
|
import { HashMap } from "../collection/HashMap.js";
|
|
3
3
|
import Signal from "../events/signal/Signal.js";
|
|
4
|
-
import {
|
|
4
|
+
import { returnOne, returnZero, strictEquals } from "../function/Functions.js";
|
|
5
5
|
import { CacheElement } from "./CacheElement.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -14,33 +14,25 @@ export class Cache {
|
|
|
14
14
|
* @param {number} [maxWeight=Number.POSITIVE_INFINITY]
|
|
15
15
|
* @param {function(key:Key):number} [keyWeigher= key=>0]
|
|
16
16
|
* @param {function(value:Value):number} [valueWeigher= value=>1]
|
|
17
|
-
* @param {function(key:Key, value:Value)} [removeListener] will be notified when element is either explicitly removed or evicted
|
|
18
17
|
* @param {function(Key):number} [keyHashFunction]
|
|
19
18
|
* @param {function(Key, Key):boolean} [keyEqualityFunction]
|
|
20
19
|
* @param {number} capacity initial capacity for the cache, helps prevent early resizing
|
|
21
20
|
* @constructor
|
|
22
|
-
* @template Key, Value
|
|
23
21
|
*/
|
|
24
22
|
constructor({
|
|
25
23
|
maxWeight = Number.POSITIVE_INFINITY,
|
|
26
24
|
keyWeigher = returnZero,
|
|
27
25
|
valueWeigher = returnOne,
|
|
28
|
-
removeListener = noop,
|
|
29
26
|
keyHashFunction = returnZero,
|
|
30
27
|
keyEqualityFunction = strictEquals,
|
|
31
28
|
capacity
|
|
32
29
|
} = {}) {
|
|
33
30
|
|
|
34
31
|
assert.isNumber(maxWeight, 'maxWeight');
|
|
35
|
-
assert.
|
|
36
|
-
assert.
|
|
37
|
-
assert.
|
|
38
|
-
assert.
|
|
39
|
-
assert.typeOf(keyEqualityFunction, 'function', 'keyEqualityFunction');
|
|
40
|
-
|
|
41
|
-
if (removeListener !== noop) {
|
|
42
|
-
console.warn('removalListener is deprecated, use onRemoved signal instead');
|
|
43
|
-
}
|
|
32
|
+
assert.isFunction(keyWeigher, 'keyWeigher');
|
|
33
|
+
assert.isFunction(valueWeigher, 'valueWeigher');
|
|
34
|
+
assert.isFunction(keyHashFunction, 'keyHashFunction');
|
|
35
|
+
assert.isFunction(keyEqualityFunction, 'keyEqualityFunction');
|
|
44
36
|
|
|
45
37
|
/**
|
|
46
38
|
*
|
|
@@ -70,13 +62,6 @@ export class Cache {
|
|
|
70
62
|
*/
|
|
71
63
|
this.valueWeigher = valueWeigher;
|
|
72
64
|
|
|
73
|
-
/**
|
|
74
|
-
*
|
|
75
|
-
* @type {function(Key, Value)}
|
|
76
|
-
* @private
|
|
77
|
-
*/
|
|
78
|
-
this.removeListener = removeListener;
|
|
79
|
-
|
|
80
65
|
/**
|
|
81
66
|
*
|
|
82
67
|
* @type {CacheElement<Key,Value>|null}
|
|
@@ -93,7 +78,7 @@ export class Cache {
|
|
|
93
78
|
|
|
94
79
|
/**
|
|
95
80
|
*
|
|
96
|
-
* @type {HashMap<Key, CacheElement<Key,Value
|
|
81
|
+
* @type {HashMap<Key, CacheElement<Key,Value>>}
|
|
97
82
|
* @private
|
|
98
83
|
*/
|
|
99
84
|
this.data = new HashMap({
|
|
@@ -398,13 +383,32 @@ export class Cache {
|
|
|
398
383
|
this.__removeElement(element);
|
|
399
384
|
|
|
400
385
|
//notify
|
|
401
|
-
this.removeListener(key, element.value);
|
|
402
|
-
|
|
403
386
|
this.onRemoved.send2(key, element.value);
|
|
404
387
|
|
|
405
388
|
return true;
|
|
406
389
|
}
|
|
407
390
|
|
|
391
|
+
/**
|
|
392
|
+
*
|
|
393
|
+
* @param {Key} key
|
|
394
|
+
* @param {function(Key):Value} compute
|
|
395
|
+
* @param {*} [compute_context]
|
|
396
|
+
* @return {Value}
|
|
397
|
+
*/
|
|
398
|
+
getOrCompute(key, compute, compute_context) {
|
|
399
|
+
const existing = this.get(key);
|
|
400
|
+
|
|
401
|
+
if (existing !== null) {
|
|
402
|
+
return existing;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const value = compute.call(compute_context, key);
|
|
406
|
+
|
|
407
|
+
this.set(key, value);
|
|
408
|
+
|
|
409
|
+
return value;
|
|
410
|
+
}
|
|
411
|
+
|
|
408
412
|
/**
|
|
409
413
|
* Remove all elements from the cache
|
|
410
414
|
*/
|
|
@@ -7,53 +7,58 @@
|
|
|
7
7
|
* @param {number} z
|
|
8
8
|
* @param {number} w
|
|
9
9
|
*/
|
|
10
|
-
function array_set_plane_normalized(
|
|
10
|
+
function array_set_plane_normalized(
|
|
11
|
+
destination, destination_offset,
|
|
12
|
+
x, y, z, w
|
|
13
|
+
) {
|
|
11
14
|
// compute vector length
|
|
12
15
|
const length = Math.hypot(x, y, z);
|
|
13
16
|
|
|
14
|
-
const
|
|
17
|
+
const inverse_length = 1.0 / length;
|
|
15
18
|
|
|
16
19
|
// apply normalization
|
|
17
|
-
destination[destination_offset] = x *
|
|
18
|
-
destination[destination_offset + 1] = y *
|
|
19
|
-
destination[destination_offset + 2] = z *
|
|
20
|
-
destination[destination_offset + 3] = w *
|
|
20
|
+
destination[destination_offset] = x * inverse_length;
|
|
21
|
+
destination[destination_offset + 1] = y * inverse_length;
|
|
22
|
+
destination[destination_offset + 2] = z * inverse_length;
|
|
23
|
+
destination[destination_offset + 3] = w * inverse_length;
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
27
|
* Set frustum from projection matrix
|
|
28
|
+
* NOTE: uses Gribb/Hartmann method
|
|
29
|
+
* @see "Fast Extraction of Viewing Frustum Planes from the WorldView-Projection Matrix", 2001 by Gribb & Hartmann
|
|
25
30
|
* @param {number[]|Float32Array} frustum_planes
|
|
26
|
-
* @param {number[]}
|
|
31
|
+
* @param {number[]} m4
|
|
27
32
|
*/
|
|
28
|
-
export function frustum_from_projection_matrix_array(frustum_planes,
|
|
33
|
+
export function frustum_from_projection_matrix_array(frustum_planes, m4) {
|
|
29
34
|
|
|
30
|
-
const me0 =
|
|
31
|
-
const me3 =
|
|
35
|
+
const me0 = m4[0];
|
|
36
|
+
const me3 = m4[3];
|
|
32
37
|
|
|
33
|
-
const me4 =
|
|
34
|
-
const me7 =
|
|
38
|
+
const me4 = m4[4];
|
|
39
|
+
const me7 = m4[7];
|
|
35
40
|
|
|
36
|
-
const me8 =
|
|
37
|
-
const me11 =
|
|
41
|
+
const me8 = m4[8];
|
|
42
|
+
const me11 = m4[11];
|
|
38
43
|
|
|
39
|
-
const me12 =
|
|
40
|
-
const me15 =
|
|
44
|
+
const me12 = m4[12];
|
|
45
|
+
const me15 = m4[15];
|
|
41
46
|
|
|
42
47
|
array_set_plane_normalized(frustum_planes, 0, me3 - me0, me7 - me4, me11 - me8, me15 - me12);
|
|
43
48
|
array_set_plane_normalized(frustum_planes, 4, me3 + me0, me7 + me4, me11 + me8, me15 + me12);
|
|
44
49
|
|
|
45
|
-
const me1 =
|
|
46
|
-
const me5 =
|
|
47
|
-
const me9 =
|
|
48
|
-
const me13 =
|
|
50
|
+
const me1 = m4[1];
|
|
51
|
+
const me5 = m4[5];
|
|
52
|
+
const me9 = m4[9];
|
|
53
|
+
const me13 = m4[13];
|
|
49
54
|
|
|
50
55
|
array_set_plane_normalized(frustum_planes, 8, me3 + me1, me7 + me5, me11 + me9, me15 + me13);
|
|
51
56
|
array_set_plane_normalized(frustum_planes, 12, me3 - me1, me7 - me5, me11 - me9, me15 - me13);
|
|
52
57
|
|
|
53
|
-
const me2 =
|
|
54
|
-
const me6 =
|
|
55
|
-
const me10 =
|
|
56
|
-
const me14 =
|
|
58
|
+
const me2 = m4[2];
|
|
59
|
+
const me6 = m4[6];
|
|
60
|
+
const me10 = m4[10];
|
|
61
|
+
const me14 = m4[14];
|
|
57
62
|
|
|
58
63
|
array_set_plane_normalized(frustum_planes, 16, me3 - me2, me7 - me6, me11 - me10, me15 - me14);
|
|
59
64
|
array_set_plane_normalized(frustum_planes, 20, me3 + me2, me7 + me6, me11 + me10, me15 + me14);
|
package/core/math/max2.js
CHANGED
package/core/math/min2.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isArrayEqualStrict } from "../../../../../core/collection/array/isArrayEqualStrict.js";
|
|
2
|
+
import { is_typed_array_equals } from "../../../../../core/collection/array/typed/is_typed_array_equals.js";
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -17,7 +18,7 @@ export function computeGeometryEquality(a, b) {
|
|
|
17
18
|
return false;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
if (!
|
|
21
|
+
if (!is_typed_array_equals(a_index.array, b_index.array)) {
|
|
21
22
|
return false;
|
|
22
23
|
}
|
|
23
24
|
}
|
|
@@ -46,7 +47,7 @@ export function computeGeometryEquality(a, b) {
|
|
|
46
47
|
const a_attribute = a.attributes[key];
|
|
47
48
|
const b_attribute = b.attributes[key];
|
|
48
49
|
|
|
49
|
-
if (!
|
|
50
|
+
if (!is_typed_array_equals(a_attribute.array, b_attribute.array)) {
|
|
50
51
|
return false;
|
|
51
52
|
}
|
|
52
53
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { computeBufferAttributeHash } from "./computeBufferAttributeHash.js";
|
|
2
|
+
import { computeStringHash } from "../../../../../core/primitives/strings/computeStringHash.js";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
*
|
|
@@ -6,7 +7,14 @@ import { computeBufferAttributeHash } from "./computeBufferAttributeHash.js";
|
|
|
6
7
|
* @returns {number}
|
|
7
8
|
*/
|
|
8
9
|
export function computeGeometryHash(geometry) {
|
|
9
|
-
let hash =
|
|
10
|
+
let hash = 0;
|
|
11
|
+
const attributes = geometry.attributes;
|
|
12
|
+
|
|
13
|
+
for (const attributesKey in attributes) {
|
|
14
|
+
hash = hash * 31 + computeStringHash(attributesKey);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
hash ^= computeBufferAttributeHash(geometry.getIndex());
|
|
10
18
|
|
|
11
19
|
const position_attribute = geometry.getAttribute('position');
|
|
12
20
|
|
|
@@ -1319,11 +1319,16 @@ export class EntityComponentDataset {
|
|
|
1319
1319
|
|
|
1320
1320
|
const numObservers = observersStore.length;
|
|
1321
1321
|
|
|
1322
|
-
|
|
1322
|
+
if (numObservers === 0) {
|
|
1323
|
+
// no observers
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
let i = 0;
|
|
1323
1328
|
|
|
1324
1329
|
const args = [];
|
|
1325
1330
|
|
|
1326
|
-
for (
|
|
1331
|
+
for (; i < numObservers; i++) {
|
|
1327
1332
|
const observer = observersStore[i];
|
|
1328
1333
|
|
|
1329
1334
|
const match = matchComponentMask(this.componentOccupancy, entityIndex, this.componentTypeCount, observer.componentMask);
|
|
@@ -2,6 +2,8 @@ import { BitSet } from "../../../core/binary/BitSet.js";
|
|
|
2
2
|
import { InstancedMeshGroup } from "../../graphics/geometry/instancing/InstancedMeshGroup.js";
|
|
3
3
|
import { queryBinaryNode_FrustumIntersections_Data } from "../../../core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js";
|
|
4
4
|
import Quaternion from "../../../core/geom/Quaternion.js";
|
|
5
|
+
import { compose_matrix4_array } from "../../graphics/util/composeMatrix4.js";
|
|
6
|
+
import Vector3 from "../../../core/geom/Vector3.js";
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
*
|
|
@@ -153,13 +155,21 @@ export class ViewState {
|
|
|
153
155
|
|
|
154
156
|
tempQuaternion.decodeFromUint32(encodedRotation);
|
|
155
157
|
|
|
158
|
+
scratch_v3_0.set(positionX, positionY, positionZ);
|
|
159
|
+
scratch_v3_1.set(scaleX, scaleY, scaleZ);
|
|
160
|
+
|
|
161
|
+
// compose transform
|
|
162
|
+
compose_matrix4_array(scratch_transform, scratch_v3_0, tempQuaternion, scratch_v3_1);
|
|
163
|
+
|
|
156
164
|
//apply instance transforms
|
|
157
|
-
instances.
|
|
158
|
-
instances.
|
|
159
|
-
instances.setScaleAt(i, scaleX, scaleY, scaleZ);
|
|
165
|
+
instances.setTransformAt(i, scratch_transform);
|
|
166
|
+
instances.requestAttributeUpdate();
|
|
160
167
|
}
|
|
161
168
|
}
|
|
162
169
|
}
|
|
163
170
|
|
|
164
171
|
const tempQuaternion = new Quaternion();
|
|
172
|
+
const scratch_v3_0 = new Vector3();
|
|
173
|
+
const scratch_v3_1 = new Vector3();
|
|
165
174
|
const rowData = [];
|
|
175
|
+
const scratch_transform = new Float32Array(16);
|