@woosh/meep-engine 2.65.0 → 2.67.0

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 (60) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/build/meep.cjs +51290 -54244
  3. package/build/meep.min.js +1 -1
  4. package/build/meep.module.js +51290 -54244
  5. package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +4 -10
  6. package/editor/process/symbolic/makeGridPositionSymbolDisplay.js +7 -7
  7. package/editor/tools/SelectionTool.js +6 -95
  8. package/package.json +1 -1
  9. package/src/core/bvh2/binary/2/BinaryUint32BVH.js +118 -113
  10. package/src/core/bvh2/binary/2/BinaryUint32BVH.spec.js +54 -0
  11. package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.js +98 -0
  12. package/src/core/bvh2/bvh3/BVH.d.ts +1 -1
  13. package/src/core/bvh2/bvh3/BvhClient.d.ts +11 -0
  14. package/src/core/bvh2/bvh3/BvhClient.js +19 -0
  15. package/src/core/collection/array/array_copy.js +6 -0
  16. package/src/core/geom/3d/aabb/aabb3_array_combine.js +17 -8
  17. package/src/core/geom/3d/aabb/aabb3_array_intersects_ray.js +5 -2
  18. package/src/core/geom/3d/aabb/aabb3_array_set.js +25 -0
  19. package/src/core/geom/3d/aabb/aabb3_compute_half_surface_area.js +3 -0
  20. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +8 -1
  21. package/src/engine/EngineHarness.js +23 -25
  22. package/src/engine/ecs/renderable/RenderSystem.js +44 -32
  23. package/src/engine/ecs/renderable/Renderable.d.ts +2 -2
  24. package/src/engine/ecs/renderable/Renderable.js +12 -11
  25. package/src/engine/ecs/terrain/ecs/Terrain.js +83 -87
  26. package/src/engine/ecs/terrain/ecs/TerrainSystem.js +106 -57
  27. package/src/engine/ecs/terrain/ecs/makeTerrainWorkerProxy.js +5 -2
  28. package/src/engine/ecs/terrain/tiles/TerrainTile.js +122 -67
  29. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +162 -146
  30. package/src/engine/ecs/terrain/tiles/TileBuildWorker.js +16 -5
  31. package/src/engine/graphics/GraphicsEngine.js +16 -25
  32. package/src/engine/graphics/camera/testClippingPlaneComputation.js +8 -11
  33. package/src/engine/graphics/debug/VisualSymbolLine.js +1 -0
  34. package/src/engine/graphics/ecs/camera/CameraSystem.js +9 -9
  35. package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.js +3 -23
  36. package/src/engine/graphics/ecs/compileAllMaterials.js +5 -12
  37. package/src/engine/graphics/ecs/light/LightSystem.js +12 -48
  38. package/src/engine/graphics/ecs/mesh/MeshSystem.js +9 -31
  39. package/src/engine/graphics/ecs/mesh/updateNodeByTransformAndBBB.js +3 -43
  40. package/src/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +22 -24
  41. package/src/engine/graphics/ecs/mesh-v2/sample/prototype_sg_raycast.js +21 -23
  42. package/src/engine/graphics/ecs/trail2d/Trail2D.js +105 -106
  43. package/src/engine/graphics/ecs/trail2d/Trail2DSystem.js +60 -61
  44. package/src/engine/graphics/ecs/trail2d/makeGradientTrail.js +3 -3
  45. package/src/engine/graphics/ecs/water/WATER_SIZE.js +1 -0
  46. package/src/engine/graphics/ecs/water/Water.js +84 -42
  47. package/src/engine/graphics/ecs/water/WaterSystem.js +53 -105
  48. package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +13 -7
  49. package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_indexed_geometry.js +58 -0
  50. package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.js +32 -62
  51. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1 -1
  52. package/src/engine/graphics/particles/particular/engine/renderers/billboard/prototypeBillboardRenderer.js +8 -11
  53. package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +21 -19
  54. package/src/engine/graphics/render/layers/RenderLayer.d.ts +4 -3
  55. package/src/engine/graphics/render/layers/RenderLayer.js +34 -108
  56. package/src/engine/graphics/render/make_bvh_visibility_builder.js +64 -0
  57. package/src/engine/graphics/three/expand_aabb_by_transformed_three_object.js +4 -4
  58. package/src/engine/graphics/trail/x/RibbonX.js +26 -5
  59. package/src/core/bvh2/binary/tiny/TinyBVH.js +0 -221
  60. package/src/engine/graphics/ecs/camera/CameraClippingPlaneComputer.js +0 -138
@@ -3,75 +3,45 @@
3
3
  */
4
4
 
5
5
 
6
- import { BinaryNode } from '../../../../core/bvh2/BinaryNode.js';
7
- import { RenderPassType } from "../RenderPassType.js";
8
- import { IncrementalDeltaSet } from "../visibility/IncrementalDeltaSet.js";
9
6
  import { passThrough } from "../../../../core/function/Functions.js";
10
- import { traverseBinaryNodeUsingVisitor } from "../../../../core/bvh2/traversal/traverseBinaryNodeUsingVisitor.js";
11
- import {
12
- ThreeClippingPlaneComputingBVHVisitor
13
- } from "../../../../core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js";
14
- import { RenderLayerState } from "./RenderLayerState.js";
15
7
  import { compare_three_objects } from "../../three/compare_three_objects.js";
16
- import {
17
- queryBinaryNode_FrustumIntersections_Data
18
- } from "../../../../core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js";
19
-
20
-
21
- /**
22
- *
23
- * @type {*[]}
24
- */
25
- const scratch_array = [];
8
+ import { IncrementalDeltaSet } from "../visibility/IncrementalDeltaSet.js";
9
+ import { RenderLayerState } from "./RenderLayerState.js";
26
10
 
27
11
  export class RenderLayer {
28
- constructor() {
29
- /**
30
- *
31
- * @type {BinaryNode}
32
- */
33
- this.bvh = new BinaryNode();
34
- this.bvh.setNegativelyInfiniteBounds();
35
-
36
- /**
37
- *
38
- * @type {RenderLayerState}
39
- */
40
- this.state = new RenderLayerState();
41
12
 
42
- /**
43
- *
44
- * @type {String|null}
45
- */
46
- this.name = null;
13
+ /**
14
+ *
15
+ * @type {RenderLayerState}
16
+ */
17
+ state = new RenderLayerState();
47
18
 
48
- /**
49
- * Layer is managed externally, visibility will not be updated in the rendering engine
50
- * @deprecated
51
- * @type {boolean}
52
- */
53
- this.managed = false;
19
+ /**
20
+ *
21
+ * @type {String|null}
22
+ */
23
+ name = null;
54
24
 
55
- /**
56
- *
57
- * @type {function(*): Object3D}
58
- */
59
- this.extractRenderable = passThrough;
25
+ /**
26
+ * Layer is managed externally, visibility will not be updated in the rendering engine
27
+ * @deprecated
28
+ * @type {boolean}
29
+ */
30
+ managed = false;
60
31
 
61
- /**
62
- * @deprecated use CameraView's visible set instead
63
- * Contains visible elements across all views, if element is in at least one view - it will be here
64
- * @deprecated
65
- * @type {IncrementalDeltaSet<THREE.Object3D>}
66
- */
67
- this.visibleSet = new IncrementalDeltaSet(compare_three_objects);
32
+ /**
33
+ *
34
+ * @type {function(*): Object3D}
35
+ */
36
+ extractRenderable = passThrough;
68
37
 
69
- /**
70
- *
71
- * @type {RenderPassType|number}
72
- */
73
- this.renderPass = RenderPassType.Opaque;
74
- }
38
+ /**
39
+ * @deprecated use CameraView's visible set instead
40
+ * Contains visible elements across all views, if element is in at least one view - it will be here
41
+ * @deprecated
42
+ * @type {IncrementalDeltaSet<THREE.Object3D>}
43
+ */
44
+ visibleSet = new IncrementalDeltaSet(compare_three_objects);
75
45
 
76
46
  /**
77
47
  * @deprecated
@@ -92,6 +62,7 @@ export class RenderLayer {
92
62
  /**
93
63
  * Compute near and far clipping planes for a camera given a frustum.
94
64
  * Note: near plane is frustum.planes[4], far plane is frustum.planes[5]
65
+ * @deprecated
95
66
  * @param {Frustum} frustum
96
67
  * @param {number} near
97
68
  * @param {number} far
@@ -99,62 +70,17 @@ export class RenderLayer {
99
70
  * @param [thisArg]
100
71
  */
101
72
  computeNearFarClippingPlanes(frustum, near, far, callback, thisArg) {
102
- const tree = this.bvh;
103
-
104
- bvh_visitor_ClippingPlanes.setFrustum(frustum);
105
- bvh_visitor_ClippingPlanes.near = near;
106
- bvh_visitor_ClippingPlanes.far = far;
107
-
108
- if (!tree.isEmpty()) {
109
-
110
- // only do the actual traversal if the tree is not empty
111
- traverseBinaryNodeUsingVisitor(tree, bvh_visitor_ClippingPlanes);
112
-
113
- }
114
-
115
- callback.call(thisArg, bvh_visitor_ClippingPlanes.near, bvh_visitor_ClippingPlanes.far);
116
-
73
+ throw new Error('deprecated');
117
74
  }
118
75
 
119
76
  /**
120
- *
77
+ * @deprecated
121
78
  * @param {THREE.Object3D[]} destination
122
79
  * @param {number} destination_offset
123
80
  * @param {CameraView} view
124
81
  * @returns {number} Number of records added to destination
125
82
  */
126
83
  buildVisibleSet(destination, destination_offset, view) {
127
- const frustum = view.frustum;
128
-
129
- const reader = this.extractRenderable;
130
-
131
- if (typeof reader !== "function") {
132
- // no reader method
133
- return 0;
134
- }
135
-
136
- const intersection_count = queryBinaryNode_FrustumIntersections_Data(scratch_array, 0, this.bvh, frustum);
137
-
138
- let additions = 0;
139
- let i = 0;
140
-
141
- for (; i < intersection_count; i++) {
142
- const datum = scratch_array[i];
143
-
144
- const object3D = reader(datum);
145
-
146
- if (!object3D) {
147
- // null or undefined
148
- continue;
149
- }
150
-
151
- destination[additions + destination_offset] = object3D;
152
-
153
- additions++;
154
- }
155
-
156
- return additions;
84
+ throw new Error('deprecated');
157
85
  }
158
86
  }
159
-
160
- const bvh_visitor_ClippingPlanes = new ThreeClippingPlaneComputingBVHVisitor();
@@ -0,0 +1,64 @@
1
+ import { assert } from "../../../core/assert.js";
2
+ import {
3
+ bvh_query_user_data_overlaps_frustum
4
+ } from "../../../core/bvh2/bvh3/query/bvh_query_user_data_overlaps_frustum.js";
5
+
6
+ /**
7
+ * Assumes that BVH stored entity IDs
8
+ * @param {EntityManager} em
9
+ * @param {BVH} bvh
10
+ * @param {function(Object3D[],number,number,EntityComponentDataset)} extract
11
+ * @param {*} [extract_context]
12
+ * @returns {(function(Object3D[], number, CameraView): number)|*}
13
+ */
14
+ export function make_bvh_visibility_builder(em, bvh, extract, extract_context) {
15
+ assert.defined(em, 'em');
16
+ assert.defined(bvh, 'bvh');
17
+ assert.isFunction(extract, 'extract');
18
+
19
+ const scratch_array = [];
20
+
21
+ /**
22
+ *
23
+ * @param {THREE.Object3D[]} destination
24
+ * @param {number} destination_offset
25
+ * @param {CameraView} view
26
+ * @returns {number} Number of records added to destination
27
+ */
28
+ function compute(destination, destination_offset, view) {
29
+
30
+ if (em === null) {
31
+ return 0;
32
+ }
33
+
34
+ const dataset = em.dataset;
35
+
36
+ if (dataset === null) {
37
+ return 0;
38
+ }
39
+
40
+ const matches = bvh_query_user_data_overlaps_frustum(
41
+ scratch_array, 0,
42
+ bvh, view.frustum
43
+ );
44
+
45
+ let additions = 0;
46
+
47
+ for (let i = 0; i < matches; i++) {
48
+ const entity = scratch_array[i];
49
+
50
+ const offset = destination_offset + additions;
51
+
52
+ const elements_from_entity = extract.call(extract_context, destination, offset, entity, dataset);
53
+
54
+ assert.isNonNegativeInteger(elements_from_entity, 'additions');
55
+
56
+ additions += elements_from_entity;
57
+ }
58
+
59
+ return additions;
60
+ }
61
+
62
+ return compute;
63
+
64
+ }
@@ -1,8 +1,8 @@
1
- import { ensureGeometryBoundingBox } from "../util/ensureGeometryBoundingBox.js";
2
- import { aabb3_matrix4_project } from "../../../core/geom/3d/aabb/aabb3_matrix4_project.js";
3
1
  import { aabb3_array_combine } from "../../../core/geom/3d/aabb/aabb3_array_combine.js";
4
- import { m4_multiply } from "../../../core/geom/3d/matrix/m4_multiply.js";
5
2
  import { aabb3_from_threejs_geometry } from "../../../core/geom/3d/aabb/aabb3_from_threejs_geometry.js";
3
+ import { aabb3_matrix4_project } from "../../../core/geom/3d/aabb/aabb3_matrix4_project.js";
4
+ import { m4_multiply } from "../../../core/geom/3d/matrix/m4_multiply.js";
5
+ import { ensureGeometryBoundingBox } from "../util/ensureGeometryBoundingBox.js";
6
6
 
7
7
  const scratch_aabb3_array_0 = new Float32Array(6);
8
8
  const scratch_aabb3_array_1 = new Float32Array(6);
@@ -27,7 +27,7 @@ export function expand_aabb_by_transformed_three_object(result, object, transfor
27
27
 
28
28
  aabb3_matrix4_project(scratch_aabb3_array_1, scratch_aabb3_array_0, transform);
29
29
 
30
- aabb3_array_combine(result, result, scratch_aabb3_array_1);
30
+ aabb3_array_combine(result,0, result,0, scratch_aabb3_array_1,0);
31
31
  }
32
32
 
33
33
  const children = object.children;
@@ -5,7 +5,11 @@ import {
5
5
  InterleavedBuffer,
6
6
  InterleavedBufferAttribute
7
7
  } from "three";
8
+ import { assert } from "../../../../core/assert.js";
8
9
  import { RowFirstTable } from "../../../../core/collection/table/RowFirstTable.js";
10
+ import { aabb3_array_set } from "../../../../core/geom/3d/aabb/aabb3_array_set.js";
11
+ import { max2 } from "../../../../core/math/max2.js";
12
+ import { min2 } from "../../../../core/math/min2.js";
9
13
  import {
10
14
  RIBBON_ATTRIBUTE_ADDRESS_ALPHA,
11
15
  RIBBON_ATTRIBUTE_ADDRESS_COLOR,
@@ -16,7 +20,6 @@ import {
16
20
  RIBBON_ATTRIBUTE_ADDRESS_THICKNESS,
17
21
  ribbon_attributes_spec
18
22
  } from "./ribbon_attributes_spec.js";
19
- import { assert } from "../../../../core/assert.js";
20
23
 
21
24
 
22
25
  export class RibbonX {
@@ -438,16 +441,22 @@ export class RibbonX {
438
441
 
439
442
  /**
440
443
  * NOTE: takes trail thickness into account
441
- * @param {AABB3} result
444
+ * @param {AABB3|ArrayLike<number>} result
442
445
  */
443
446
  computeBoundingBox(result) {
444
447
 
445
448
  const n = this.getCount() * 2;
446
449
 
447
- result.setNegativelyInfiniteBounds();
448
-
449
450
  const data = this.__data;
450
451
 
452
+ let _x0 = Infinity;
453
+ let _y0 = Infinity;
454
+ let _z0 = Infinity;
455
+
456
+ let _x1 = -Infinity;
457
+ let _y1 = -Infinity;
458
+ let _z1 = -Infinity;
459
+
451
460
  for (let i = 0; i < n; i += 2) {
452
461
  const thickness = data.readCellValue(i, RIBBON_ATTRIBUTE_ADDRESS_THICKNESS);
453
462
  const half_thickness = thickness / 2;
@@ -456,9 +465,21 @@ export class RibbonX {
456
465
  const y = data.readCellValue(i, RIBBON_ATTRIBUTE_ADDRESS_POSITION + 1);
457
466
  const z = data.readCellValue(i, RIBBON_ATTRIBUTE_ADDRESS_POSITION + 2);
458
467
 
459
- result._expandToFit(x - half_thickness, y - half_thickness, z - half_thickness, x + half_thickness, y + half_thickness, z + half_thickness);
468
+ _x0 = min2(_x0, x - half_thickness);
469
+ _y0 = min2(_y0, y - half_thickness);
470
+ _z0 = min2(_z0, z - half_thickness);
471
+ _x1 = max2(_x1, x + half_thickness);
472
+ _y1 = max2(_y1, y + half_thickness);
473
+ _z1 = max2(_z1, z + half_thickness);
474
+
460
475
  }
461
476
 
477
+ aabb3_array_set(
478
+ result, 0,
479
+ _x0, _y0, _z0,
480
+ _x1, _y1, _z1
481
+ );
482
+
462
483
  }
463
484
 
464
485
 
@@ -1,221 +0,0 @@
1
- import { AABB3 } from "../../aabb3/AABB3.js";
2
-
3
- /**
4
- *
5
- * @param {AABB3} bounds
6
- * @param {number} type
7
- * @param {number} x0
8
- * @param {number} y0
9
- * @param {number} z0
10
- * @param {number} x1
11
- * @param {number} y1
12
- * @param {number} z1
13
- */
14
- function build_common_part(bounds, type, x0, y0, z0, x1, y1, z1) {
15
- const bounds_x0 = bounds.x0;
16
- const bounds_x1 = bounds.x1;
17
-
18
- const bounds_y0 = bounds.y0;
19
- const bounds_y1 = bounds.y1;
20
-
21
- const bounds_z0 = bounds.z0;
22
- const bounds_z1 = bounds.z1;
23
-
24
- const range_x = bounds_x1 - bounds_x0;
25
- const range_y = bounds_y1 - bounds_y0;
26
- const range_z = bounds_z1 - bounds_z0;
27
-
28
- const n_x0 = range_x * (x0 - bounds_x0);
29
- const n_x1 = range_x * (x1 - bounds_x0);
30
-
31
- const n_y0 = range_y * (y0 - bounds_y0);
32
- const n_y1 = range_y * (y1 - bounds_y0);
33
-
34
- const n_z0 = range_z * (z0 - bounds_z0);
35
- const n_z1 = range_z * (z1 - bounds_z0);
36
-
37
- const _x0 = n_x0 * 32;
38
- const _x1 = Math.ceil(n_x1 * 32);
39
-
40
- const _y0 = n_y0 * 32;
41
- const _y1 = Math.ceil(n_y1 * 32);
42
-
43
- const _z0 = n_z0 * 32;
44
- const _z1 = Math.ceil(n_z1 * 32);
45
-
46
- return (type << 30)
47
- | ((_x0 << 25) & 0b00111110000000000000000000000000)
48
- | ((_y0 << 20) & 0b00000001111100000000000000000000)
49
- | ((_z0 << 15) & 0b00000000000011111000000000000000)
50
- | ((_x1 << 10) & 0b00000000000000000111110000000000)
51
- | ((_y1 << 5) & 0b00000000000000000000001111100000)
52
- | ((_z1) & 0b00000000000000000000000000011111)
53
- ;
54
- }
55
-
56
- const scratch_aabb3_0 = new AABB3(0, 0, 0, 0, 0, 0);
57
-
58
- /**
59
- * This is WiP
60
- * TODO implement
61
- * The idea is to have fixed precision of bounds at each level, so the deeper the hierarchy - the more precise the bounds, at the same time take up very little space
62
- * Binary layout:
63
- * * common: 2[type],5[x0],5[y0],5[z0],5[x1],5[y1],5[z1]
64
- * * leaf: common, 16[id]
65
- * * intermediate: common
66
- */
67
- export class TinyBVH {
68
- constructor() {
69
- /**
70
- *
71
- * @type {DataView|null}
72
- */
73
- this.view = null;
74
-
75
- this.leaf_count = 0;
76
- this.leaf_nodes_offset = 0;
77
-
78
- /**
79
- *
80
- * @type {AABB3}
81
- */
82
- this.bounds = new AABB3(0, 0, 0, 0, 0, 0);
83
- }
84
-
85
- initialize(length) {
86
-
87
- this.leaf_count = length;
88
-
89
- const two_log = Math.log2(length);
90
-
91
- const two_leaf_limit = Math.pow(2, Math.ceil(two_log));
92
-
93
- const binary_node_count = two_leaf_limit - 1;
94
-
95
- this.leaf_nodes_offset = binary_node_count * 4;
96
- }
97
-
98
-
99
- /**
100
- *
101
- * @param {number} length
102
- * @param {function} factory
103
- */
104
- initialize(length, factory) {
105
- this.leaf_count = length;
106
-
107
- const two_log = Math.log2(length);
108
-
109
- const two_leaf_limit = Math.pow(2, Math.ceil(two_log));
110
-
111
- const binary_node_count = two_leaf_limit - 1;
112
-
113
- this.leaf_nodes_offset = binary_node_count * 4;
114
-
115
- const view = this.view;
116
-
117
- // initialize bounds
118
- this.bounds.setNegativelyInfiniteBounds();
119
-
120
- // actual full bounds of each node
121
- const proper_leaf_bounds = new Float32Array((length + binary_node_count) * 6);
122
-
123
- const morton_codes = new Uint32Array(length);
124
-
125
- const leaf_index_mapping = new Uint32Array(length);
126
-
127
- // collect leaf data
128
- for (let i = 0; i < length; i++) {
129
- const id = factory(i, scratch_aabb3_0);
130
-
131
- const address = this.leaf_nodes_offset + i * 8;
132
-
133
- // write leaf ID
134
- view.setUint32(address + 4, id);
135
-
136
- const bounds_address_offset = (binary_node_count + i) * 6;
137
-
138
- proper_leaf_bounds[bounds_address_offset] = scratch_aabb3_0.x0;
139
- proper_leaf_bounds[bounds_address_offset + 1] = scratch_aabb3_0.y0;
140
- proper_leaf_bounds[bounds_address_offset + 2] = scratch_aabb3_0.z0;
141
-
142
- proper_leaf_bounds[bounds_address_offset + 3] = scratch_aabb3_0.x1;
143
- proper_leaf_bounds[bounds_address_offset + 4] = scratch_aabb3_0.y1;
144
- proper_leaf_bounds[bounds_address_offset + 5] = scratch_aabb3_0.z1;
145
-
146
- morton_codes[i] = scratch_aabb3_0.computeMortonCode();
147
-
148
- leaf_index_mapping[i] = i;
149
- }
150
-
151
- leaf_index_mapping.sort((a, b) => {
152
- return morton_codes[a] - morton_codes[b];
153
- });
154
-
155
-
156
- let level = Math.floor(Math.log2(binary_node_count));
157
-
158
- let level_node_count = Math.pow(2, level);
159
- let offset = (level_node_count - 1)
160
-
161
- let i;
162
- for (i = 0; i < level_node_count; i++) {
163
- const child_offset = i * 2;
164
-
165
- const child_index_0 = child_offset;
166
- const child_index_1 = child_offset + 1;
167
-
168
- if (child_index_0 < length) {
169
- const leaf_index_0 = leaf_index_mapping[child_index_0];
170
- const address_0 = leaf_index_0 * 8 + this.leaf_nodes_offset;
171
-
172
- view.setUint16(address_0,)
173
- }
174
- }
175
-
176
- for (; level >= 0; level--) {
177
- level_node_count = Math.pow(2, level);
178
- let parent_index = level_node_count - 1;
179
-
180
- for (i = 0; i < level_node_count; i++) {
181
- const child_index_0 = (parent_index << 1) + 1;
182
- const child_index_1 = child_index_0 + 1;
183
-
184
-
185
- }
186
-
187
- parent_index++;
188
- }
189
-
190
- }
191
-
192
- /**
193
- *
194
- * @param {number} index
195
- * @param {number} id
196
- * @param {number} x0
197
- * @param {number} y0
198
- * @param {number} z0
199
- * @param {number} x1
200
- * @param {number} y1
201
- * @param {number} z1
202
- */
203
- setLeaf(index, id, x0, y0, z0, x1, y1, z1) {
204
- const address = this.leaf_nodes_offset + index * 8;
205
-
206
- const view = this.view;
207
-
208
- const part_0 = build_common_part(this.bounds, 0, x0, y0, z0, x1, y1, z1);
209
-
210
- view.setUint32(address, part_0);
211
- view.setUint32(address + 4, id);
212
- }
213
-
214
- /**
215
- *
216
- * @param {DataView} view
217
- */
218
- attach(view) {
219
- this.view = view;
220
- }
221
- }
@@ -1,138 +0,0 @@
1
- import { Frustum as ThreeFrustum } from "three";
2
- import { v3_dot } from "../../../../core/geom/vec3/v3_dot.js";
3
- import { isValueBetweenInclusive } from "../../../../core/math/interval/isValueBetweenInclusive.js";
4
- import { frustum_from_camera } from "./frustum_from_camera.js";
5
- import { is_valid_distance_value } from "./is_valid_distance_value.js";
6
-
7
- const CLIPPING_EPSILON = 0.001;
8
-
9
- const CLIPPING_NEAR_MIN = 0.5;
10
-
11
- const CLIPPING_FAR_DEFAULT = 100;
12
-
13
- export class CameraClippingPlaneComputer {
14
- constructor() {
15
- /**
16
- *
17
- * @type {Camera}
18
- */
19
- this.camera = null;
20
-
21
- /**
22
- *
23
- * @type {RenderLayerManager}
24
- */
25
- this.layers = null;
26
-
27
- /**
28
- * Prevents minor shrinkage of the frustum. This variable controls the threshold at which the shrinkage should occur.
29
- * @example value 0 would result is unconditional shrinkage
30
- * @example value 1 would result in shrinkage occurring never
31
- * @type {number}
32
- */
33
- this.hysteresis = 0.5;
34
-
35
- /**
36
- *
37
- * @type {Frustum}
38
- * @private
39
- */
40
- this.__frustum = new ThreeFrustum();
41
-
42
-
43
- this.near = 0;
44
- this.far = 0;
45
- }
46
-
47
- /**
48
- *
49
- * @param {RenderLayer} layer
50
- * @private
51
- */
52
- __processLayer(layer) {
53
- if (!layer.state.visible) {
54
- return;
55
- }
56
-
57
- layer.computeNearFarClippingPlanes(this.__frustum, this.near, this.far, this.__updateClippingPlanes, this);
58
- }
59
-
60
- /**
61
- *
62
- * @param {number} z0
63
- * @param {number} z1
64
- * @private
65
- */
66
- __updateClippingPlanes(z0, z1) {
67
- if (z0 < this.near && z0 !== Number.NEGATIVE_INFINITY) {
68
- this.near = z0;
69
- }
70
- if (z1 > this.far && z1 !== Number.POSITIVE_INFINITY) {
71
- this.far = z1;
72
- }
73
- }
74
-
75
- compute() {
76
- const camera = this.camera;
77
-
78
- /**
79
- *
80
- * @type {number}
81
- */
82
- const hysteresis = this.hysteresis;
83
-
84
- //quantify hysteresis
85
- const oldNear = camera.near;
86
- const oldFar = camera.far;
87
- const oldClippingPlaneDistance = Math.abs(oldFar - oldNear);
88
-
89
- const shrinkThreshold = hysteresis * oldClippingPlaneDistance;
90
-
91
- frustum_from_camera(camera, this.__frustum);
92
-
93
- // compute plane constant (D) to move "near" plane to intersect camera position
94
- const nearPlane = this.__frustum.planes[5];
95
- const near_plane_normal = nearPlane.normal;
96
- const camera_position = camera.position;
97
-
98
- nearPlane.constant = -v3_dot(
99
- camera_position.x,
100
- camera_position.y,
101
- camera_position.z,
102
- near_plane_normal.x,
103
- near_plane_normal.y,
104
- near_plane_normal.z
105
- );
106
-
107
- this.far = Number.NEGATIVE_INFINITY;
108
- this.near = Number.POSITIVE_INFINITY;
109
-
110
- this.layers.traverse(this.__processLayer, this);
111
-
112
- //offset clipping planes by a small margin to prevent clipping of parallel planar surfaces
113
- this.near -= CLIPPING_EPSILON;
114
- this.far += CLIPPING_EPSILON;
115
-
116
- //clip near
117
- if (!is_valid_distance_value(this.near) || this.near < CLIPPING_NEAR_MIN) {
118
- //use a default
119
- //NOTE: values smaller than 0.001 seem to lead to glitchy rendering where polygons clip through one another
120
- this.near = CLIPPING_NEAR_MIN;
121
- }
122
-
123
- if (!is_valid_distance_value(this.far) || this.far < 0) {
124
- //use a default
125
- this.far = CLIPPING_FAR_DEFAULT;
126
- }
127
-
128
- //hysteresis check
129
- if (isValueBetweenInclusive(this.near - oldNear, 0, shrinkThreshold)) {
130
- this.near = oldNear;
131
- }
132
-
133
- if (isValueBetweenInclusive(oldFar - this.far, 0, shrinkThreshold)) {
134
- this.far = oldFar;
135
- }
136
-
137
- }
138
- }