@woosh/meep-engine 2.34.35 → 2.34.39

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.
Files changed (49) hide show
  1. package/core/binary/BitSet.js +5 -0
  2. package/core/bvh2/BinaryNode.js +873 -1017
  3. package/core/bvh2/LeafNode.js +82 -75
  4. package/core/bvh2/Node.js +112 -114
  5. package/core/bvh2/aabb3/AABB3.js +46 -1
  6. package/core/bvh2/aabb3/AABB3.spec.js +27 -1
  7. package/core/bvh2/aabb3/aabb3_from_v3_array.js +34 -0
  8. package/core/bvh2/aabb3/aabb3_from_v3_array_transformed.js +39 -0
  9. package/core/bvh2/aabb3/aabb3_intersects_frustum_degree.js +46 -0
  10. package/core/bvh2/traversal/ThreeFrustumsIntersectionBVHVisitor.js +16 -35
  11. package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +52 -0
  12. package/core/geom/3d/aabb/aabb3_computeDistanceAbovePlane.js +1 -1
  13. package/core/geom/3d/aabb/aabb3_matrix4_project.js +3 -4
  14. package/core/geom/3d/aabb/aabb3_matrix4_project.spec.js +13 -0
  15. package/core/geom/3d/triangle/computeTriangleRayIntersection.js +1 -2
  16. package/core/geom/Quaternion.d.ts +2 -0
  17. package/core/geom/Vector3.js +22 -11
  18. package/engine/ecs/attachment/TransformAttachmentBinding.js +0 -1
  19. package/engine/ecs/foliage/FoliageVisibilitySetBuilder.js +1 -31
  20. package/engine/ecs/foliage/InstancedFoliage.js +85 -152
  21. package/engine/ecs/foliage/ViewState.js +165 -0
  22. package/engine/ecs/foliage/ecs/Foliage2System.js +82 -19
  23. package/engine/ecs/foliage/ecs/InstancedMeshComponent.js +30 -0
  24. package/engine/ecs/foliage/ecs/InstancedMeshLayer.js +16 -0
  25. package/engine/ecs/foliage/ecs/InstancedMeshUtils.js +2 -2
  26. package/engine/ecs/parent/EntityNode.js +31 -49
  27. package/engine/ecs/transform-attachment/TransformAttachment.js +88 -0
  28. package/engine/ecs/transform-attachment/TransformAttachmentSystem.js +59 -0
  29. package/engine/graphics/GraphicsEngine.js +23 -2
  30. package/engine/graphics/ecs/camera/Camera.js +33 -16
  31. package/engine/graphics/ecs/camera/unprojectPoint.js +14 -0
  32. package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +22 -17
  33. package/engine/graphics/ecs/mesh/updateNodeByTransformAndBBB.js +21 -21
  34. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +9 -1
  35. package/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +4 -1
  36. package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +32 -8
  37. package/engine/graphics/ecs/water2/shader/AlexWaterShader.js +7 -1
  38. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +18 -12
  39. package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +1 -34
  40. package/engine/graphics/micron/build/fill_patch_geometry_data.js +12 -0
  41. package/engine/graphics/micron/format/MicronGeometry.js +21 -0
  42. package/engine/graphics/micron/format/MicronGeometryPatch.js +0 -7
  43. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -3
  44. package/engine/graphics/micron/prototypeVirtualGeometry.js +69 -1
  45. package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +5 -1
  46. package/engine/graphics/render/layers/RenderLayer.js +22 -85
  47. package/engine/graphics/render/visibility/VisibilityComputer.js +23 -103
  48. package/package.json +1 -1
  49. package/samples/terrain/editor.js +0 -1
@@ -6,13 +6,11 @@ export class ThreeFrustumsIntersectionBVHVisitor extends BVHVisitor {
6
6
  super();
7
7
 
8
8
  /**
9
- * Collection of THREE.js Frustums
9
+ * [plane_x, plane_y, plane_z, constant] collection, defining a frustum
10
10
  * @private
11
- * @type {Frustum[]}
11
+ * @type {ArrayLike<number>|number[]}
12
12
  */
13
- this.frustums = [];
14
-
15
- this.frustumCount = 0;
13
+ this.frustum = [];
16
14
 
17
15
  /**
18
16
  *
@@ -23,49 +21,32 @@ export class ThreeFrustumsIntersectionBVHVisitor extends BVHVisitor {
23
21
 
24
22
  /**
25
23
  *
26
- * @param {Frustum[]} frustums
24
+ * @param {ArrayLike<number>|number[]|Float32Array} frustum
27
25
  */
28
- setFrustums(frustums) {
29
- this.frustums = frustums;
30
- this.frustumCount = frustums.length;
26
+ setFrustum(frustum) {
27
+ this.frustum = frustum;
31
28
  }
32
29
 
33
30
  visitLeaf(node) {
34
31
 
35
- const n = this.frustumCount;
36
-
37
- for (let i = 0; i < n; i++) {
32
+ const degree = node.intersectFrustumDegree_array(this.frustum);
38
33
 
39
- const degree = node.intersectFrustumDegree(this.frustums[i]);
40
-
41
- if (degree !== 0) {
42
- this.collector.visitLeaf(node);
43
- return;
44
- }
34
+ if (degree !== 0) {
35
+ // at least partially visible
36
+ this.collector.visitLeaf(node);
45
37
  }
46
-
47
38
  }
48
39
 
49
40
  visitBinary(node) {
50
- let flag = false;
51
-
52
- const n = this.frustumCount;
53
-
54
- for (let i = 0; i < n; i++) {
55
-
56
- const degree = node.intersectFrustumDegree(this.frustums[i]);
57
41
 
58
- if (degree === 2) {
59
- //completely inside
60
- traverseBinaryNodeUsingVisitor(node, this.collector);
61
- return false;
62
- } else if (degree === 1) {
63
- //partially inside, continue traversal
64
- flag = true;
65
- }
42
+ const degree = node.intersectFrustumDegree_array(this.frustum);
66
43
 
44
+ if (degree === 2) {
45
+ //completely inside, do fast traversal
46
+ traverseBinaryNodeUsingVisitor(node, this.collector);
47
+ return false;
67
48
  }
68
49
 
69
- return flag;
50
+ return degree === 1;
70
51
  }
71
52
  }
@@ -0,0 +1,52 @@
1
+ /**
2
+ *
3
+ * @type {(BinaryNode|LeafNode)[]}
4
+ */
5
+ const stack = [];
6
+
7
+
8
+ /**
9
+ * @template T
10
+ * @param {T[]} destination
11
+ * @param {number} destinationOffset
12
+ * @param {BinaryNode<T>} root
13
+ * @param {ArrayLike<number>|number[]|Float32Array} frustum
14
+ * @returns {number} Number of results
15
+ */
16
+ export function queryBinaryNode_FrustumIntersections_Data(destination, destinationOffset, root, frustum) {
17
+ let n;
18
+ let i = 0;
19
+ let stackPointer = 1;
20
+
21
+ stack[0] = root;
22
+
23
+ while (stackPointer > 0) {
24
+ stackPointer--;
25
+
26
+ n = stack[stackPointer];
27
+
28
+ if (!n.intersectFrustum_array(frustum)) {
29
+ continue;
30
+ }
31
+
32
+ if (n.isBinaryNode) {
33
+
34
+ if (n.right !== null) {
35
+ stack[stackPointer++] = n.right;
36
+ }
37
+
38
+ if (n.left !== null) {
39
+ stack[stackPointer++] = n.left;
40
+ }
41
+
42
+ } else {
43
+
44
+ destination[destinationOffset + i] = n.object;
45
+
46
+ i++;
47
+ }
48
+
49
+ }
50
+
51
+ return i;
52
+ }
@@ -23,5 +23,5 @@ export function aabb3_computeDistanceAbovePlane(
23
23
  const pz = plane_normal_z > 0 ? _z1 : _z0;
24
24
 
25
25
  // dot(v4,v4) inlined for speed
26
- return (plane_normal_x * px + plane_normal_y * py + plane_normal_z * pz) + plane_constant;
26
+ return plane_constant + plane_normal_x * px + plane_normal_y * py + plane_normal_z * pz;
27
27
  }
@@ -1,8 +1,7 @@
1
-
2
1
  /**
3
2
  * NOTE: Based on Transforming Axis-Aligned Bounding Boxes by Jim Arvo from "Graphics Gems", Academic Press, 1990
4
- * @param {number[]} result
5
- * @param {number[]} aabb
3
+ * @param {ArrayLike<number>|number[]|Float32Array} result
4
+ * @param {ArrayLike<number>|number[]|Float32Array} aabb
6
5
  * @param {number[]} matrix 4x4 matrix
7
6
  */
8
7
  export function aabb3_matrix4_project(result, aabb, matrix) {
@@ -15,7 +14,7 @@ export function aabb3_matrix4_project(result, aabb, matrix) {
15
14
  for (let i = 0; i < 3; i++) {
16
15
  for (let j = 0; j < 3; j++) {
17
16
 
18
- const m_a = i * 4 + j;
17
+ const m_a = i + j * 4;
19
18
  const m_v = matrix[m_a];
20
19
 
21
20
  const a = m_v * aabb[j];
@@ -1,4 +1,7 @@
1
1
  import { aabb3_matrix4_project } from "./aabb3_matrix4_project.js";
2
+ import { compose_matrix4_array } from "../../../../engine/graphics/util/composeMatrix4.js";
3
+ import Vector3 from "../../Vector3.js";
4
+ import Quaternion from "../../Quaternion.js";
2
5
 
3
6
  test('identity', () => {
4
7
  const r = [];
@@ -39,3 +42,13 @@ test('scale case', () => {
39
42
 
40
43
  expect(r).toEqual([-5, 4, -27, -1, 14, -9]);
41
44
  });
45
+
46
+ test('translation + scale case', () => {
47
+ const m4 = [];
48
+ compose_matrix4_array(m4, new Vector3(-1, 2, -3), Quaternion.identity, new Vector3(7, -11, 13));
49
+
50
+ const r = [];
51
+ aabb3_matrix4_project(r, [1, 2, 3, 5, 7, 9], m4);
52
+
53
+ expect(r).toEqual([6, -75, 36, 34, -20, 114]);
54
+ });
@@ -95,9 +95,8 @@ export function computeTriangleRayIntersection(
95
95
  // Line intersects triangle, check if ray does.
96
96
  const QdN = -sign * v3_dot(diff_x, diff_y, diff_z, normal_x, normal_y, normal_z);
97
97
 
98
- // t < 0, no intersection
99
98
  if (QdN < 0) {
100
-
99
+ // t < 0, no intersection
101
100
  return false;
102
101
 
103
102
  }
@@ -22,4 +22,6 @@ export default class Quaternion {
22
22
  threeSetRotationMatrix(result: Matrix4): void
23
23
 
24
24
  setFromRotationMatrix(m: Matrix4): void
25
+
26
+ decodeFromUint32(uint: number): void
25
27
  }
@@ -523,21 +523,25 @@ class Vector3 {
523
523
  /**
524
524
  *
525
525
  * @param {THREE.Matrix4} matrix4
526
- * @returns {Vector3}
527
526
  */
528
527
  applyMatrix4_three(matrix4) {
528
+ this.applyMatrix4(matrix4.elements);
529
+ }
529
530
 
531
+ /**
532
+ *
533
+ * @param {ArrayList<number>|number[]|Float32Array} m4
534
+ */
535
+ applyMatrix4(m4) {
530
536
  const x = this.x;
531
537
  const y = this.y;
532
538
  const z = this.z;
533
539
 
534
- const e = matrix4.elements;
535
-
536
- const _x = e[0] * x + e[4] * y + e[8] * z + e[12];
537
- const _y = e[1] * x + e[5] * y + e[9] * z + e[13];
538
- const _z = e[2] * x + e[6] * y + e[10] * z + e[14];
540
+ const _x = m4[0] * x + m4[4] * y + m4[8] * z + m4[12];
541
+ const _y = m4[1] * x + m4[5] * y + m4[9] * z + m4[13];
542
+ const _z = m4[2] * x + m4[6] * y + m4[10] * z + m4[14];
539
543
 
540
- return this.set(_x, _y, _z);
544
+ this.set(_x, _y, _z);
541
545
  }
542
546
 
543
547
  /**
@@ -589,11 +593,18 @@ class Vector3 {
589
593
  * @param {THREE.Matrix4} matrix4
590
594
  */
591
595
  threejs_setFromMatrixPosition(matrix4) {
592
- const e = matrix4.elements;
596
+ this.setFromMatrixPosition(matrix4.elements);
597
+ }
598
+
599
+ /**
600
+ *
601
+ * @param {ArrayLike<number>|number[]|Float32Array} matrix4 4x4 transform matrix
602
+ */
603
+ setFromMatrixPosition(matrix4) {
593
604
 
594
- const _x = e[12];
595
- const _y = e[13];
596
- const _z = e[14];
605
+ const _x = matrix4[12];
606
+ const _y = matrix4[13];
607
+ const _z = matrix4[14];
597
608
 
598
609
  this.set(_x, _y, _z);
599
610
  }
@@ -8,7 +8,6 @@ const scratch_m4_2 = new Float32Array(16);
8
8
  export class TransformAttachmentBinding extends AttachmentBinding {
9
9
  constructor() {
10
10
  super();
11
-
12
11
  }
13
12
 
14
13
  /**
@@ -5,28 +5,13 @@ export class FoliageVisibilitySetBuilder extends BVHVisitor {
5
5
  constructor() {
6
6
  super();
7
7
 
8
- /**
9
- * Visibility filters
10
- * @type {(function(LeafNode):boolean)[]}
11
- */
12
- this.filters = [];
13
-
14
8
  /**
15
9
  *
16
10
  * @type {BitSet}
17
11
  */
18
12
  this.visibleSet = new BitSet();
19
13
  //prevent re-allocation
20
- this.visibleSet.__shrinkFactor = 0;
21
- }
22
-
23
- /**
24
- *
25
- * @param {(function(LeafNode):boolean)[]} filters
26
- */
27
- setFilters(filters) {
28
- this.filters = filters;
29
- this.filterCount = filters.length;
14
+ this.visibleSet.preventShrink();
30
15
  }
31
16
 
32
17
  initialize() {
@@ -34,21 +19,6 @@ export class FoliageVisibilitySetBuilder extends BVHVisitor {
34
19
  }
35
20
 
36
21
  visitLeaf(node) {
37
-
38
- const n = this.filterCount;
39
-
40
- const filters = this.filters;
41
-
42
- for (let i = 0; i < n; i++) {
43
- const visibilityFilter = filters[i];
44
-
45
- if (!visibilityFilter(node)) {
46
- //not visible
47
- return;
48
- }
49
-
50
- }
51
-
52
22
  const index = node.object;
53
23
 
54
24
  //TODO check screen space size to decide if element should be seen or not
@@ -1,23 +1,19 @@
1
1
  import { BinaryNode } from "../../../core/bvh2/BinaryNode.js";
2
2
  import { RowFirstTable } from "../../../core/collection/table/RowFirstTable.js";
3
- import { InstancedMeshGroup } from "../../graphics/geometry/instancing/InstancedMeshGroup.js";
4
- import Vector3 from "../../../core/geom/Vector3.js";
5
3
  import { LeafNode } from "../../../core/bvh2/LeafNode.js";
6
4
  import Vector4 from "../../../core/geom/Vector4.js";
7
5
 
8
6
  import { BufferGeometry } from 'three';
9
7
  import { DataType } from "../../../core/collection/table/DataType.js";
10
8
  import { RowFirstTableSpec } from "../../../core/collection/table/RowFirstTableSpec.js";
11
- import Quaternion from "../../../core/geom/Quaternion.js";
12
- import { ThreeFrustumsIntersectionBVHVisitor } from "../../../core/bvh2/traversal/ThreeFrustumsIntersectionBVHVisitor.js";
13
- import { FoliageVisibilitySetBuilder } from "./FoliageVisibilitySetBuilder.js";
14
- import { traverseBinaryNodeUsingVisitor } from "../../../core/bvh2/traversal/traverseBinaryNodeUsingVisitor.js";
15
9
  import { serializeBinaryNodeToBinaryBuffer } from "../../../core/bvh2/serialization/serializeBinaryNodeToBinaryBuffer.js";
16
10
  import { deserializeBinaryNodeFromBinaryBuffer } from "../../../core/bvh2/serialization/deserializeBinaryNodeFromBinaryBuffer.js";
17
11
  import { computeGeometryBoundingSphereMiniball } from "../../graphics/geometry/buffered/computeGeometryBoundingSphereMiniball.js";
18
12
  import { serializeRowFirstTable } from "../../../core/collection/table/serializeRowFirstTable.js";
19
13
  import { deserializeRowFirstTable } from "../../../core/collection/table/deserializeRowFirstTable.js";
20
- import { assert } from "../../../core/assert.js";
14
+ import { compose_matrix4_array } from "../../graphics/util/composeMatrix4.js";
15
+ import { aabb3_from_v3_array_transformed } from "../../../core/bvh2/aabb3/aabb3_from_v3_array_transformed.js";
16
+ import { ViewState } from "./ViewState.js";
21
17
 
22
18
  /**
23
19
  * @readonly
@@ -57,15 +53,16 @@ export class InstancedFoliage {
57
53
 
58
54
  /**
59
55
  *
60
- * @type {InstancedMeshGroup}
56
+ * @type {THREE.BufferGeometry|null}
61
57
  */
62
- this.instances = new InstancedMeshGroup();
58
+ this.geometry = null;
63
59
 
64
60
  /**
65
61
  *
66
- * @type {THREE.BufferGeometry|null}
62
+ * @type {THREE.Material|null}
63
+ * @private
67
64
  */
68
- this.geometry = null;
65
+ this.__material = null;
69
66
 
70
67
  /**
71
68
  *
@@ -73,32 +70,39 @@ export class InstancedFoliage {
73
70
  */
74
71
  this.instanceBoundingSphere = new Vector4(0, 0, 0, 0);
75
72
 
76
-
77
73
  /**
78
74
  *
79
- * @type {ThreeFrustumsIntersectionBVHVisitor}
75
+ * @type {Map<CameraView, ViewState>}
76
+ * @private
80
77
  */
81
- this.bvhVisibilityVisitor = new ThreeFrustumsIntersectionBVHVisitor();
78
+ this.__views = new Map();
82
79
 
83
- /**
84
- *
85
- * @type {FoliageVisibilitySetBuilder}
86
- */
87
- this.visibilitySetBuilder = new FoliageVisibilitySetBuilder();
88
- this.bvhVisibilityVisitor.collector = this.visibilitySetBuilder;
80
+ this.__cast_shadow = true;
81
+ this.__receive_shadow = true;
82
+ }
89
83
 
90
- /**
91
- *
92
- * @type {*[]}
93
- * @private
94
- */
95
- this.__garbage = [];
96
- /**
97
- *
98
- * @type {number}
99
- * @private
100
- */
101
- this.__garbagePointer = 0;
84
+ set castShadow(v) {
85
+ this.__cast_shadow = v;
86
+
87
+ for (const [view, state] of this.__views) {
88
+ state.instances.mesh.castShadow = v;
89
+ }
90
+ }
91
+
92
+ get castShadow() {
93
+ return this.__cast_shadow;
94
+ }
95
+
96
+ set receiveShadow(v) {
97
+ this.__receive_shadow = v;
98
+
99
+ for (const [view, state] of this.__views) {
100
+ state.instances.mesh.receiveShadow = v;
101
+ }
102
+ }
103
+
104
+ get receiveShadow() {
105
+ return this.__receive_shadow;
102
106
  }
103
107
 
104
108
  /**
@@ -136,7 +140,11 @@ export class InstancedFoliage {
136
140
  }
137
141
 
138
142
  dispose() {
139
- this.instances.dispose();
143
+ for (const [view, state] of this.__views) {
144
+ state.dispose();
145
+ }
146
+
147
+ this.__views.clear();
140
148
  }
141
149
 
142
150
  initialize() {
@@ -168,7 +176,7 @@ export class InstancedFoliage {
168
176
  );
169
177
 
170
178
  //compute bounding box for this instance
171
- this.expandBoundingBoxForInstance(position, rotation, scale, leaf);
179
+ this.computeInstanceBoundsTight(position, rotation, scale, leaf);
172
180
 
173
181
  //insert bounding box into the spatial index
174
182
  this.bvh.insertNode(leaf);
@@ -210,42 +218,15 @@ export class InstancedFoliage {
210
218
  * @param {Quaternion} rotation
211
219
  * @param {Vector3} scale
212
220
  */
213
- expandBoundingBoxForInstance(position, rotation, scale, result) {
221
+ computeInstanceBoundsTight(position, rotation, scale, result) {
214
222
 
215
223
  const vertexData = this.geometry.attributes.position.array;
216
224
 
217
- const rXYZ = new Vector3(rotation.x, rotation.y, rotation.z);
218
-
219
- const v = new Vector3(0, 0, 0);
220
-
221
- const c0 = new Vector3(0, 0, 0);
222
- const c1 = new Vector3(0, 0, 0);
223
- const c2 = new Vector3(0, 0, 0);
224
-
225
- for (let i = 0, l = vertexData.length; i < l; i += 3) {
226
- const x = vertexData[i];
227
- const y = vertexData[i + 1];
228
- const z = vertexData[i + 2];
229
-
230
- v.set(x, y, z);
231
-
232
- //transform point
233
-
234
- //apply scale
235
- v.multiply(scale);
225
+ const transform = new Float32Array(16);
236
226
 
237
- //apply rotation
238
- c1.copy(v).multiplyScalar(rotation.w);
239
- c0.copy(rXYZ).cross(v).add(c1);
240
- c2.copy(rXYZ).cross(c0).multiplyScalar(2);
227
+ compose_matrix4_array(transform, position, rotation, scale);
241
228
 
242
- v.add(c2);
243
-
244
- //apply translation
245
- v.add(position);
246
-
247
- result._expandToFitPoint(v.x, v.y, v.z);
248
- }
229
+ aabb3_from_v3_array_transformed(result, vertexData, vertexData.length, transform);
249
230
  }
250
231
 
251
232
  computeInstanceBoundingSphere() {
@@ -277,9 +258,12 @@ export class InstancedFoliage {
277
258
 
278
259
 
279
260
  this.geometry = bufferGeometry;
261
+ this.__material = material;
280
262
 
281
- this.instances.setMaterial(material);
282
- this.instances.setGeometry(bufferGeometry);
263
+ for (const [view, state] of this.__views) {
264
+ state.instances.setMaterial(material);
265
+ state.instances.setGeometry(bufferGeometry);
266
+ }
283
267
 
284
268
  this.computeInstanceBoundingSphere();
285
269
 
@@ -318,108 +302,60 @@ export class InstancedFoliage {
318
302
 
319
303
  /**
320
304
  *
321
- * @param index
322
- * @param {int} ref
305
+ * @param {CameraView} view
323
306
  */
324
- __updateVisibility(index, ref) {
325
- assert.isNonNegativeInteger(ref, 'ref');
326
-
327
- /**
328
- *
329
- * @type {FoliageVisibilitySetBuilder}
330
- */
331
- const builder = this.visibilitySetBuilder;
307
+ add_view(view) {
332
308
 
333
- /**
334
- *
335
- * @type {BitSet}
336
- */
337
- const visibleElementSet = builder.visibleSet;
338
-
339
- if (!visibleElementSet.get(ref)) {
340
- //no longer visible
341
- this.__garbage[this.__garbagePointer++] = ref;
342
- } else {
343
- //visible, and is already in the group, update the set
344
- visibleElementSet.set(ref, false);
309
+ if (this.__views.has(view)) {
310
+ throw new Error('View already registered');
345
311
  }
346
- }
347
-
348
- __removeGarbage() {
349
312
 
350
- const garbagePointer = this.__garbagePointer;
351
- const instances = this.instances;
313
+ const state = new ViewState();
352
314
 
315
+ state.__view = view;
353
316
 
354
- const garbage = this.__garbage;
355
-
356
- for (let i = 0; i < garbagePointer; i++) {
357
- const ref = garbage[i];
358
- instances.remove(ref);
317
+ if (this.geometry !== null) {
318
+ state.instances.setGeometry(this.geometry);
319
+ }
320
+ if (this.__material !== null) {
321
+ state.instances.setMaterial(this.__material);
359
322
  }
360
323
 
324
+ state.instances.mesh.castShadow = this.castShadow;
325
+ state.instances.mesh.receiveShadow = this.receiveShadow;
326
+
327
+ this.__views.set(view, state);
361
328
  }
362
329
 
363
330
  /**
364
331
  *
365
- * @param {Frustum[]} frustums
366
- * @param {function[]} [visibilityFilters]
332
+ * @param {CameraView} view
367
333
  */
368
- update(frustums, visibilityFilters = []) {
369
- const instances = this.instances;
370
-
371
- this.bvhVisibilityVisitor.setFrustums(frustums);
334
+ remove_view(view) {
335
+ const state = this.__views.get(view);
372
336
 
373
- const visibilitySetBuilder = this.visibilitySetBuilder;
374
- visibilitySetBuilder.setFilters(visibilityFilters);
375
- visibilitySetBuilder.initialize();
376
-
377
- const visibleElementSet = visibilitySetBuilder.visibleSet;
378
-
379
- //build visible set
380
- traverseBinaryNodeUsingVisitor(this.bvh, this.bvhVisibilityVisitor);
381
-
382
- visibilitySetBuilder.finalize();
383
-
384
- // console.log(`Visible: `, elementsToAdd.size);
385
-
386
- //reset garbage pointer
387
- this.__garbagePointer = 0;
388
-
389
- //remove those that are no longer visible
390
- instances.traverseReferences(this.__updateVisibility, this);
391
-
392
- //cull instances that are no longer visible
393
- this.__removeGarbage();
394
-
395
-
396
- const data = this.data;
397
-
398
- //process entities that have become newly visible
399
- for (let index = visibleElementSet.nextSetBit(0); index !== -1; index = visibleElementSet.nextSetBit(index + 1)) {
400
- //read transform data for instance
401
- data.getRow(index, rowData);
402
-
403
- const positionX = rowData[0];
404
- const positionY = rowData[1];
405
- const positionZ = rowData[2];
337
+ if (state === undefined) {
338
+ return false;
339
+ }
406
340
 
407
- const encodedRotation = rowData[3];
341
+ state.dispose();
408
342
 
343
+ this.__views.delete(view);
409
344
 
410
- const scaleX = rowData[4];
411
- const scaleY = rowData[5];
412
- const scaleZ = rowData[6];
345
+ return true;
346
+ }
413
347
 
414
- const i = instances.add(index);
348
+ /**
349
+ *
350
+ * @param {CameraView} view
351
+ * @return {ViewState}
352
+ */
353
+ update(view) {
354
+ const state = this.__views.get(view);
415
355
 
416
- tempQuaternion.decodeFromUint32(encodedRotation);
356
+ state.update(this.bvh, this.data);
417
357
 
418
- //apply instance transforms
419
- instances.setPositionAt(i, positionX, positionY, positionZ);
420
- instances.setRotationAt(i, tempQuaternion.x, tempQuaternion.y, tempQuaternion.z, tempQuaternion.w);
421
- instances.setScaleAt(i, scaleX, scaleY, scaleZ);
422
- }
358
+ return state;
423
359
  }
424
360
  }
425
361
 
@@ -442,6 +378,3 @@ function serializeLeafValueUintVar(buffer, value) {
442
378
  }
443
379
 
444
380
 
445
- const tempQuaternion = new Quaternion();
446
- const rowData = [];
447
-