@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.
- package/core/binary/BitSet.js +5 -0
- package/core/bvh2/BinaryNode.js +873 -1017
- package/core/bvh2/LeafNode.js +82 -75
- package/core/bvh2/Node.js +112 -114
- package/core/bvh2/aabb3/AABB3.js +46 -1
- package/core/bvh2/aabb3/AABB3.spec.js +27 -1
- package/core/bvh2/aabb3/aabb3_from_v3_array.js +34 -0
- package/core/bvh2/aabb3/aabb3_from_v3_array_transformed.js +39 -0
- package/core/bvh2/aabb3/aabb3_intersects_frustum_degree.js +46 -0
- package/core/bvh2/traversal/ThreeFrustumsIntersectionBVHVisitor.js +16 -35
- package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +52 -0
- package/core/geom/3d/aabb/aabb3_computeDistanceAbovePlane.js +1 -1
- package/core/geom/3d/aabb/aabb3_matrix4_project.js +3 -4
- package/core/geom/3d/aabb/aabb3_matrix4_project.spec.js +13 -0
- package/core/geom/3d/triangle/computeTriangleRayIntersection.js +1 -2
- package/core/geom/Quaternion.d.ts +2 -0
- package/core/geom/Vector3.js +22 -11
- package/engine/ecs/attachment/TransformAttachmentBinding.js +0 -1
- package/engine/ecs/foliage/FoliageVisibilitySetBuilder.js +1 -31
- package/engine/ecs/foliage/InstancedFoliage.js +85 -152
- package/engine/ecs/foliage/ViewState.js +165 -0
- package/engine/ecs/foliage/ecs/Foliage2System.js +82 -19
- package/engine/ecs/foliage/ecs/InstancedMeshComponent.js +30 -0
- package/engine/ecs/foliage/ecs/InstancedMeshLayer.js +16 -0
- package/engine/ecs/foliage/ecs/InstancedMeshUtils.js +2 -2
- package/engine/ecs/parent/EntityNode.js +31 -49
- package/engine/ecs/transform-attachment/TransformAttachment.js +88 -0
- package/engine/ecs/transform-attachment/TransformAttachmentSystem.js +59 -0
- package/engine/graphics/GraphicsEngine.js +23 -2
- package/engine/graphics/ecs/camera/Camera.js +33 -16
- package/engine/graphics/ecs/camera/unprojectPoint.js +14 -0
- package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +22 -17
- package/engine/graphics/ecs/mesh/updateNodeByTransformAndBBB.js +21 -21
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +9 -1
- package/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +4 -1
- package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +32 -8
- package/engine/graphics/ecs/water2/shader/AlexWaterShader.js +7 -1
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +18 -12
- package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +1 -34
- package/engine/graphics/micron/build/fill_patch_geometry_data.js +12 -0
- package/engine/graphics/micron/format/MicronGeometry.js +21 -0
- package/engine/graphics/micron/format/MicronGeometryPatch.js +0 -7
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -3
- package/engine/graphics/micron/prototypeVirtualGeometry.js +69 -1
- package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +5 -1
- package/engine/graphics/render/layers/RenderLayer.js +22 -85
- package/engine/graphics/render/visibility/VisibilityComputer.js +23 -103
- package/package.json +1 -1
- package/samples/terrain/editor.js +0 -1
|
@@ -6,13 +6,11 @@ export class ThreeFrustumsIntersectionBVHVisitor extends BVHVisitor {
|
|
|
6
6
|
super();
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* [plane_x, plane_y, plane_z, constant] collection, defining a frustum
|
|
10
10
|
* @private
|
|
11
|
-
* @type {
|
|
11
|
+
* @type {ArrayLike<number>|number[]}
|
|
12
12
|
*/
|
|
13
|
-
this.
|
|
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 {
|
|
24
|
+
* @param {ArrayLike<number>|number[]|Float32Array} frustum
|
|
27
25
|
*/
|
|
28
|
-
|
|
29
|
-
this.
|
|
30
|
-
this.frustumCount = frustums.length;
|
|
26
|
+
setFrustum(frustum) {
|
|
27
|
+
this.frustum = frustum;
|
|
31
28
|
}
|
|
32
29
|
|
|
33
30
|
visitLeaf(node) {
|
|
34
31
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
for (let i = 0; i < n; i++) {
|
|
32
|
+
const degree = node.intersectFrustumDegree_array(this.frustum);
|
|
38
33
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
}
|
package/core/geom/Vector3.js
CHANGED
|
@@ -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
|
|
535
|
-
|
|
536
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
595
|
-
const _y =
|
|
596
|
-
const _z =
|
|
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
|
}
|
|
@@ -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.
|
|
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 {
|
|
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 {
|
|
56
|
+
* @type {THREE.BufferGeometry|null}
|
|
61
57
|
*/
|
|
62
|
-
this.
|
|
58
|
+
this.geometry = null;
|
|
63
59
|
|
|
64
60
|
/**
|
|
65
61
|
*
|
|
66
|
-
* @type {THREE.
|
|
62
|
+
* @type {THREE.Material|null}
|
|
63
|
+
* @private
|
|
67
64
|
*/
|
|
68
|
-
this.
|
|
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 {
|
|
75
|
+
* @type {Map<CameraView, ViewState>}
|
|
76
|
+
* @private
|
|
80
77
|
*/
|
|
81
|
-
this.
|
|
78
|
+
this.__views = new Map();
|
|
82
79
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
221
|
+
computeInstanceBoundsTight(position, rotation, scale, result) {
|
|
214
222
|
|
|
215
223
|
const vertexData = this.geometry.attributes.position.array;
|
|
216
224
|
|
|
217
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
282
|
-
|
|
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
|
|
322
|
-
* @param {int} ref
|
|
305
|
+
* @param {CameraView} view
|
|
323
306
|
*/
|
|
324
|
-
|
|
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
|
|
351
|
-
const instances = this.instances;
|
|
313
|
+
const state = new ViewState();
|
|
352
314
|
|
|
315
|
+
state.__view = view;
|
|
353
316
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
instances.
|
|
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 {
|
|
366
|
-
* @param {function[]} [visibilityFilters]
|
|
332
|
+
* @param {CameraView} view
|
|
367
333
|
*/
|
|
368
|
-
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
this.bvhVisibilityVisitor.setFrustums(frustums);
|
|
334
|
+
remove_view(view) {
|
|
335
|
+
const state = this.__views.get(view);
|
|
372
336
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
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
|
-
|
|
341
|
+
state.dispose();
|
|
408
342
|
|
|
343
|
+
this.__views.delete(view);
|
|
409
344
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
const scaleZ = rowData[6];
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
413
347
|
|
|
414
|
-
|
|
348
|
+
/**
|
|
349
|
+
*
|
|
350
|
+
* @param {CameraView} view
|
|
351
|
+
* @return {ViewState}
|
|
352
|
+
*/
|
|
353
|
+
update(view) {
|
|
354
|
+
const state = this.__views.get(view);
|
|
415
355
|
|
|
416
|
-
|
|
356
|
+
state.update(this.bvh, this.data);
|
|
417
357
|
|
|
418
|
-
|
|
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
|
-
|