@woosh/meep-engine 2.65.0 → 2.66.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.
- package/build/bundle-worker-terrain.js +1 -1
- package/build/meep.cjs +52474 -53800
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +52474 -53800
- package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +4 -10
- package/editor/process/symbolic/makeGridPositionSymbolDisplay.js +7 -7
- package/editor/tools/SelectionTool.js +6 -95
- package/package.json +1 -1
- package/src/core/bvh2/binary/2/BinaryUint32BVH.js +118 -113
- package/src/core/bvh2/binary/2/BinaryUint32BVH.spec.js +54 -0
- package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.js +98 -0
- package/src/core/bvh2/bvh3/BVH.d.ts +1 -1
- package/src/core/bvh2/bvh3/BvhClient.d.ts +11 -0
- package/src/core/bvh2/bvh3/BvhClient.js +19 -0
- package/src/core/collection/array/array_copy.js +6 -0
- package/src/core/geom/3d/aabb/aabb3_array_combine.js +17 -8
- package/src/core/geom/3d/aabb/aabb3_array_intersects_ray.js +5 -2
- package/src/core/geom/3d/aabb/aabb3_array_set.js +25 -0
- package/src/core/geom/3d/aabb/aabb3_compute_half_surface_area.js +3 -0
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +8 -1
- package/src/engine/EngineHarness.js +23 -25
- package/src/engine/ecs/renderable/RenderSystem.js +44 -32
- package/src/engine/ecs/renderable/Renderable.d.ts +2 -2
- package/src/engine/ecs/renderable/Renderable.js +12 -11
- package/src/engine/ecs/terrain/ecs/Terrain.js +83 -87
- package/src/engine/ecs/terrain/ecs/TerrainSystem.js +106 -57
- package/src/engine/ecs/terrain/ecs/makeTerrainWorkerProxy.js +5 -2
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +122 -67
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +162 -146
- package/src/engine/ecs/terrain/tiles/TileBuildWorker.js +16 -5
- package/src/engine/graphics/camera/testClippingPlaneComputation.js +3 -6
- package/src/engine/graphics/debug/VisualSymbolLine.js +1 -0
- package/src/engine/graphics/ecs/camera/CameraSystem.js +9 -9
- package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.js +3 -23
- package/src/engine/graphics/ecs/light/LightSystem.js +12 -48
- package/src/engine/graphics/ecs/mesh/MeshSystem.js +9 -31
- package/src/engine/graphics/ecs/mesh/updateNodeByTransformAndBBB.js +3 -43
- package/src/engine/graphics/ecs/trail2d/Trail2D.js +105 -106
- package/src/engine/graphics/ecs/trail2d/Trail2DSystem.js +60 -61
- package/src/engine/graphics/ecs/trail2d/makeGradientTrail.js +3 -3
- package/src/engine/graphics/ecs/water/WATER_SIZE.js +1 -0
- package/src/engine/graphics/ecs/water/Water.js +84 -42
- package/src/engine/graphics/ecs/water/WaterSystem.js +53 -105
- package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +13 -7
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_indexed_geometry.js +58 -0
- package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.js +32 -62
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1 -1
- package/src/engine/graphics/particles/particular/engine/renderers/billboard/prototypeBillboardRenderer.js +8 -11
- package/src/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +21 -19
- package/src/engine/graphics/render/layers/RenderLayer.d.ts +8 -2
- package/src/engine/graphics/render/layers/RenderLayer.js +7 -65
- package/src/engine/graphics/render/make_bvh_visibility_builder.js +64 -0
- package/src/engine/graphics/three/expand_aabb_by_transformed_three_object.js +4 -4
- package/src/engine/graphics/trail/x/RibbonX.js +26 -5
- package/src/core/bvh2/binary/tiny/TinyBVH.js +0 -221
- package/src/engine/graphics/ecs/camera/CameraClippingPlaneComputer.js +0 -138
|
@@ -1,27 +1,27 @@
|
|
|
1
|
+
import { BVH_BINARY_NODE_SIZE, BVH_LEAF_NODE_SIZE } from "../../../../../core/bvh2/binary/2/BinaryUint32BVH.js";
|
|
2
|
+
import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../../../core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
|
|
1
3
|
import {
|
|
2
4
|
aabb3_compute_distance_above_plane_max
|
|
3
5
|
} from "../../../../../core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.js";
|
|
4
6
|
import { point_light_inside_volume } from "./point_light_inside_volume.js";
|
|
5
|
-
import { BVH_BINARY_NODE_SIZE, BVH_LEAF_NODE_SIZE } from "../../../../../core/bvh2/binary/2/BinaryUint32BVH.js";
|
|
6
|
-
import { SCRATCH_UINT32_TRAVERSAL_STACK } from "../../../../../core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js";
|
|
7
7
|
|
|
8
8
|
const stack = SCRATCH_UINT32_TRAVERSAL_STACK;
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
*
|
|
12
|
-
* @param {
|
|
12
|
+
* @param {Float32Array} data
|
|
13
13
|
* @param {number} address
|
|
14
14
|
* @param {ArrayLike<number>|number[]} planes
|
|
15
15
|
* @return {boolean}
|
|
16
16
|
*/
|
|
17
|
-
function frustum_check(
|
|
18
|
-
const n_x0 =
|
|
19
|
-
const n_y0 =
|
|
20
|
-
const n_z0 =
|
|
17
|
+
function frustum_check(data, address, planes) {
|
|
18
|
+
const n_x0 = data[address];
|
|
19
|
+
const n_y0 = data[address + 1];
|
|
20
|
+
const n_z0 = data[address + 2];
|
|
21
21
|
|
|
22
|
-
const n_x1 =
|
|
23
|
-
const n_y1 =
|
|
24
|
-
const n_z1 =
|
|
22
|
+
const n_x1 = data[address + 3];
|
|
23
|
+
const n_y1 = data[address + 4];
|
|
24
|
+
const n_z1 = data[address + 5];
|
|
25
25
|
|
|
26
26
|
for (let plane_address = 0; plane_address < 24; plane_address += 4) {
|
|
27
27
|
|
|
@@ -54,7 +54,7 @@ function frustum_check(data_view, address, planes) {
|
|
|
54
54
|
* Most of the data is in flat continuous array for cache coherence
|
|
55
55
|
* @param {number[]} destination
|
|
56
56
|
* @param {number} destination_offset
|
|
57
|
-
* @param {BinaryUint32BVH}
|
|
57
|
+
* @param {BinaryUint32BVH} bvh
|
|
58
58
|
* @param {number[]|Uint8ClampedArray} source_data
|
|
59
59
|
* @param {number[]|Float32Array|Float64Array} planes
|
|
60
60
|
* @param {number[]|Float32Array|Float64Array} points
|
|
@@ -63,13 +63,13 @@ function frustum_check(data_view, address, planes) {
|
|
|
63
63
|
export function query_bvh_frustum_from_texture(
|
|
64
64
|
destination,
|
|
65
65
|
destination_offset,
|
|
66
|
-
|
|
66
|
+
bvh,
|
|
67
67
|
source_data,
|
|
68
68
|
planes, points
|
|
69
69
|
) {
|
|
70
70
|
let result = 0;
|
|
71
71
|
|
|
72
|
-
const binary_node_count =
|
|
72
|
+
const binary_node_count = bvh.getBinaryNodeCount();
|
|
73
73
|
|
|
74
74
|
if (binary_node_count <= 0) {
|
|
75
75
|
// this should not happen
|
|
@@ -88,8 +88,10 @@ export function query_bvh_frustum_from_texture(
|
|
|
88
88
|
*/
|
|
89
89
|
stack[stack_top] = 0;
|
|
90
90
|
|
|
91
|
-
const last_valid_index = binary_node_count +
|
|
92
|
-
|
|
91
|
+
const last_valid_index = binary_node_count + bvh.getLeafNodeCount();
|
|
92
|
+
|
|
93
|
+
const float32 = bvh.float32;
|
|
94
|
+
const uint32 = bvh.uint32;
|
|
93
95
|
|
|
94
96
|
do {
|
|
95
97
|
stack.pointer--;
|
|
@@ -101,7 +103,7 @@ export function query_bvh_frustum_from_texture(
|
|
|
101
103
|
// is intermediate node
|
|
102
104
|
const node_address = node_index * BVH_BINARY_NODE_SIZE;
|
|
103
105
|
|
|
104
|
-
if (!frustum_check(
|
|
106
|
+
if (!frustum_check(float32, node_address, planes)) {
|
|
105
107
|
continue;
|
|
106
108
|
}
|
|
107
109
|
|
|
@@ -124,7 +126,7 @@ export function query_bvh_frustum_from_texture(
|
|
|
124
126
|
|
|
125
127
|
const node_address = leaf_index * BVH_LEAF_NODE_SIZE + binary_node_count * BVH_BINARY_NODE_SIZE;
|
|
126
128
|
|
|
127
|
-
const light_descriptor =
|
|
129
|
+
const light_descriptor = uint32[node_address + 6];
|
|
128
130
|
|
|
129
131
|
const light_type = light_descriptor & 3;
|
|
130
132
|
|
|
@@ -148,7 +150,7 @@ export function query_bvh_frustum_from_texture(
|
|
|
148
150
|
} else if (light_type === 3) {
|
|
149
151
|
// decal
|
|
150
152
|
|
|
151
|
-
if (!frustum_check(
|
|
153
|
+
if (!frustum_check(float32, node_address, planes)) {
|
|
152
154
|
continue;
|
|
153
155
|
}
|
|
154
156
|
|
|
@@ -162,7 +164,7 @@ export function query_bvh_frustum_from_texture(
|
|
|
162
164
|
result++;
|
|
163
165
|
}
|
|
164
166
|
|
|
165
|
-
}while (stack.pointer > stack_top)
|
|
167
|
+
} while (stack.pointer > stack_top)
|
|
166
168
|
|
|
167
169
|
return result;
|
|
168
170
|
}
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import {BinaryNode} from "../../../../core/bvh2/BinaryNode";
|
|
2
|
-
import {RenderLayerState} from "./RenderLayerState";
|
|
3
1
|
import {Object3D} from "three";
|
|
2
|
+
import {BinaryNode} from "../../../../core/bvh2/BinaryNode";
|
|
4
3
|
import {IncrementalDeltaSet} from "../visibility/IncrementalDeltaSet";
|
|
4
|
+
import {RenderLayerState} from "./RenderLayerState";
|
|
5
5
|
|
|
6
6
|
export class RenderLayer {
|
|
7
|
+
/**
|
|
8
|
+
* @deprecated
|
|
9
|
+
*/
|
|
7
10
|
bvh: BinaryNode
|
|
8
11
|
name: string
|
|
9
12
|
state: RenderLayerState
|
|
10
13
|
|
|
11
14
|
managed: boolean
|
|
12
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated
|
|
18
|
+
*/
|
|
13
19
|
extractRenderable(leafData: any): Object3D
|
|
14
20
|
|
|
15
21
|
/**
|
|
@@ -4,18 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
import { BinaryNode } from '../../../../core/bvh2/BinaryNode.js';
|
|
7
|
-
import { RenderPassType } from "../RenderPassType.js";
|
|
8
|
-
import { IncrementalDeltaSet } from "../visibility/IncrementalDeltaSet.js";
|
|
9
7
|
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
8
|
import { compare_three_objects } from "../../three/compare_three_objects.js";
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
} from "../../../../core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js";
|
|
9
|
+
import { IncrementalDeltaSet } from "../visibility/IncrementalDeltaSet.js";
|
|
10
|
+
import { RenderLayerState } from "./RenderLayerState.js";
|
|
19
11
|
|
|
20
12
|
|
|
21
13
|
/**
|
|
@@ -27,7 +19,7 @@ const scratch_array = [];
|
|
|
27
19
|
export class RenderLayer {
|
|
28
20
|
constructor() {
|
|
29
21
|
/**
|
|
30
|
-
*
|
|
22
|
+
* @deprecated
|
|
31
23
|
* @type {BinaryNode}
|
|
32
24
|
*/
|
|
33
25
|
this.bvh = new BinaryNode();
|
|
@@ -65,12 +57,6 @@ export class RenderLayer {
|
|
|
65
57
|
* @type {IncrementalDeltaSet<THREE.Object3D>}
|
|
66
58
|
*/
|
|
67
59
|
this.visibleSet = new IncrementalDeltaSet(compare_three_objects);
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
*
|
|
71
|
-
* @type {RenderPassType|number}
|
|
72
|
-
*/
|
|
73
|
-
this.renderPass = RenderPassType.Opaque;
|
|
74
60
|
}
|
|
75
61
|
|
|
76
62
|
/**
|
|
@@ -92,6 +78,7 @@ export class RenderLayer {
|
|
|
92
78
|
/**
|
|
93
79
|
* Compute near and far clipping planes for a camera given a frustum.
|
|
94
80
|
* Note: near plane is frustum.planes[4], far plane is frustum.planes[5]
|
|
81
|
+
* @deprecated
|
|
95
82
|
* @param {Frustum} frustum
|
|
96
83
|
* @param {number} near
|
|
97
84
|
* @param {number} far
|
|
@@ -99,62 +86,17 @@ export class RenderLayer {
|
|
|
99
86
|
* @param [thisArg]
|
|
100
87
|
*/
|
|
101
88
|
computeNearFarClippingPlanes(frustum, near, far, callback, thisArg) {
|
|
102
|
-
|
|
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
|
-
|
|
89
|
+
throw new Error('deprecated');
|
|
117
90
|
}
|
|
118
91
|
|
|
119
92
|
/**
|
|
120
|
-
|
|
93
|
+
@deprecated
|
|
121
94
|
* @param {THREE.Object3D[]} destination
|
|
122
95
|
* @param {number} destination_offset
|
|
123
96
|
* @param {CameraView} view
|
|
124
97
|
* @returns {number} Number of records added to destination
|
|
125
98
|
*/
|
|
126
99
|
buildVisibleSet(destination, destination_offset, view) {
|
|
127
|
-
|
|
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;
|
|
100
|
+
throw new Error('deprecated');
|
|
157
101
|
}
|
|
158
102
|
}
|
|
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
|
-
|
|
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
|
-
}
|