@woosh/meep-engine 2.34.33 → 2.34.37
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/assert.js +11 -0
- package/core/binary/BitSet.js +5 -0
- package/core/bvh2/BinaryNode.js +880 -848
- package/core/bvh2/LeafNode.js +80 -82
- package/core/bvh2/Node.d.ts +3 -0
- package/core/bvh2/Node.js +111 -114
- package/core/bvh2/aabb3/AABB3.js +50 -4
- package/core/bvh2/aabb3/AABB3.spec.js +27 -1
- package/core/bvh2/aabb3/AABB3Math.js +1 -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/transform/RotationOptimizer.js +2 -262
- package/core/bvh2/transform/tryRotateSingleNode.js +259 -0
- package/core/bvh2/traversal/ThreeFrustumsIntersectionBVHVisitor.js +16 -35
- package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +52 -0
- package/core/collection/list/List.js +0 -34
- package/core/events/signal/Signal.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/asset/loaders/ArrayBufferLoader.js +7 -0
- package/engine/asset/loaders/image/ImageRGBADataLoader.js +11 -6
- package/engine/ecs/EntityBuilder.js +12 -5
- package/engine/ecs/EntityComponentDataset.js +26 -6
- package/engine/ecs/attachment/AttachmentSystem.js +1 -1
- 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 +190 -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/sockets/AttachmentSockets.js +11 -1
- 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 +2 -19
- 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 +40 -8
- package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +3 -3
- package/engine/graphics/ecs/water2/shader/AlexWaterShader.js +7 -1
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +17 -11
- 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/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/engine/sound/ecs/emitter/SoundEmitterSystem.js +1 -1
- package/package.json +1 -1
- package/samples/terrain/editor.js +0 -1
package/core/bvh2/LeafNode.js
CHANGED
|
@@ -14,98 +14,97 @@ function isLeaf(node) {
|
|
|
14
14
|
return node.isLeafNode;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
17
|
+
export class LeafNode extends Node {
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param {*} object
|
|
21
|
+
* @param {number} x0
|
|
22
|
+
* @param {number} y0
|
|
23
|
+
* @param {number} z0
|
|
24
|
+
* @param {number} x1
|
|
25
|
+
* @param {number} y1
|
|
26
|
+
* @param {number} z1
|
|
27
|
+
* @constructor
|
|
28
|
+
*/
|
|
29
|
+
constructor(object, x0, y0, z0, x1, y1, z1) {
|
|
30
|
+
super();
|
|
31
|
+
|
|
32
|
+
this.object = object;
|
|
33
|
+
this.parentNode = null;
|
|
34
|
+
|
|
35
|
+
this.x0 = x0;
|
|
36
|
+
this.y0 = y0;
|
|
37
|
+
this.z0 = z0;
|
|
38
|
+
this.x1 = x1;
|
|
39
|
+
this.y1 = y1;
|
|
40
|
+
this.z1 = z1;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @type {boolean}
|
|
45
|
+
*/
|
|
46
|
+
this.isLeafNode = true;
|
|
47
|
+
/**
|
|
48
|
+
* Useful shortcut, to avoid having to distinguish between leaf and intermediate nodes
|
|
49
|
+
* @readonly
|
|
50
|
+
* @type {number}
|
|
51
|
+
*/
|
|
52
|
+
this.leafNodeCount = 1;
|
|
53
|
+
}
|
|
40
54
|
|
|
41
|
-
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @param {number} dx
|
|
58
|
+
* @param {number} dy
|
|
59
|
+
* @param {number} dz
|
|
60
|
+
*/
|
|
61
|
+
move(dx, dy, dz) {
|
|
62
|
+
this.x0 += dx;
|
|
63
|
+
this.x1 += dx;
|
|
64
|
+
this.y0 += dy;
|
|
65
|
+
this.y1 += dy;
|
|
66
|
+
this.z0 += dz;
|
|
67
|
+
this.z1 += dz;
|
|
68
|
+
if (this.parentNode !== null) {
|
|
69
|
+
this.parentNode.bubbleRefit();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
42
72
|
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
* @param {number} x0
|
|
76
|
+
* @param {number} y0
|
|
77
|
+
* @param {number} z0
|
|
78
|
+
* @param {number} x1
|
|
79
|
+
* @param {number} y1
|
|
80
|
+
* @param {number} z1
|
|
81
|
+
*/
|
|
82
|
+
resize(x0, y0, z0, x1, y1, z1) {
|
|
83
|
+
this.setBounds(x0, y0, z0, x1, y1, z1);
|
|
84
|
+
|
|
85
|
+
this.bubbleRefit();
|
|
86
|
+
}
|
|
48
87
|
|
|
49
|
-
|
|
50
|
-
* Useful shortcut, to avoid having to distinguish between leaf and intermediate nodes
|
|
51
|
-
* @readonly
|
|
52
|
-
* @type {number}
|
|
53
|
-
*/
|
|
54
|
-
LeafNode.prototype.leafNodeCount = 1;
|
|
88
|
+
bubbleRefit() {
|
|
55
89
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
* @param {number} dy
|
|
60
|
-
* @param {number} dz
|
|
61
|
-
*/
|
|
62
|
-
LeafNode.prototype.move = function (dx, dy, dz) {
|
|
63
|
-
this.x0 += dx;
|
|
64
|
-
this.x1 += dx;
|
|
65
|
-
this.y0 += dy;
|
|
66
|
-
this.y1 += dy;
|
|
67
|
-
this.z0 += dz;
|
|
68
|
-
this.z1 += dz;
|
|
69
|
-
if (this.parentNode !== null) {
|
|
70
|
-
this.parentNode.bubbleRefit();
|
|
90
|
+
if (this.parentNode !== null) {
|
|
91
|
+
this.parentNode.bubbleRefit();
|
|
92
|
+
}
|
|
71
93
|
}
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
*
|
|
76
|
-
* @param {number} x0
|
|
77
|
-
* @param {number} y0
|
|
78
|
-
* @param {number} z0
|
|
79
|
-
* @param {number} x1
|
|
80
|
-
* @param {number} y1
|
|
81
|
-
* @param {number} z1
|
|
82
|
-
*/
|
|
83
|
-
LeafNode.prototype.resize = function (x0, y0, z0, x1, y1, z1) {
|
|
84
|
-
this.setBounds(x0, y0, z0, x1, y1, z1);
|
|
85
94
|
|
|
86
|
-
|
|
87
|
-
|
|
95
|
+
/**
|
|
96
|
+
*
|
|
97
|
+
* @return {LeafNode}
|
|
98
|
+
*/
|
|
99
|
+
clone() {
|
|
100
|
+
const clone = new LeafNode(this.object, this.x0, this.y0, this.z0, this.x1, this.y1, this.z1);
|
|
88
101
|
|
|
89
|
-
|
|
102
|
+
clone.parentNode = this.parentNode;
|
|
90
103
|
|
|
91
|
-
|
|
92
|
-
this.parentNode.bubbleRefit();
|
|
104
|
+
return clone;
|
|
93
105
|
}
|
|
94
106
|
}
|
|
95
107
|
|
|
96
|
-
/**
|
|
97
|
-
*
|
|
98
|
-
* @return {LeafNode}
|
|
99
|
-
*/
|
|
100
|
-
LeafNode.prototype.clone = function () {
|
|
101
|
-
const clone = new LeafNode(this.object, this.x0, this.y0, this.z0, this.x1, this.y1, this.z1);
|
|
102
|
-
|
|
103
|
-
clone.parentNode = this.parentNode;
|
|
104
|
-
|
|
105
|
-
return clone;
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
|
|
109
108
|
/**
|
|
110
109
|
*
|
|
111
110
|
* @param {BinaryBuffer} buffer
|
|
@@ -130,7 +129,6 @@ function deserializeLeafNode(buffer, node, valueDeserializer) {
|
|
|
130
129
|
|
|
131
130
|
export {
|
|
132
131
|
isLeaf,
|
|
133
|
-
LeafNode,
|
|
134
132
|
serializeLeafNode,
|
|
135
133
|
deserializeLeafNode
|
|
136
134
|
};
|
package/core/bvh2/Node.d.ts
CHANGED
package/core/bvh2/Node.js
CHANGED
|
@@ -5,144 +5,142 @@ import computeMortonCode from "../geom/3d/morton/Morton.js";
|
|
|
5
5
|
import { AABB3 } from "./aabb3/AABB3.js";
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
export class Node extends AABB3 {
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @type {BinaryNode|null}
|
|
15
|
+
*/
|
|
16
|
+
this.parentNode = null;
|
|
17
|
+
this._mortonCode = void 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
/**
|
|
14
|
-
*
|
|
15
|
-
* @type {BinaryNode|null}
|
|
21
|
+
* @return {boolean}
|
|
16
22
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
validateAncestorChain() {
|
|
24
|
+
//check containment
|
|
25
|
+
const parent = this.parentNode;
|
|
26
|
+
if (parent === null) {
|
|
27
|
+
//nothing to do
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
22
30
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
//check containment
|
|
28
|
-
const parent = this.parentNode;
|
|
29
|
-
if (parent === null) {
|
|
30
|
-
//nothing to do
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
31
|
+
if (!parent.containsBox(this)) {
|
|
32
|
+
//bounds violated
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
if (parent.left === this || parent.right === this) {
|
|
37
|
+
//all is well
|
|
38
|
+
} else {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
//all is well
|
|
41
|
-
} else {
|
|
42
|
-
return false;
|
|
42
|
+
return true;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @returns {number}
|
|
48
|
+
*/
|
|
49
|
+
computeDepth() {
|
|
50
|
+
let d = 0;
|
|
51
|
+
let node = this.parentNode;
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
* @returns {number}
|
|
51
|
-
*/
|
|
52
|
-
Node.prototype.computeDepth = function () {
|
|
53
|
-
let d = 0;
|
|
54
|
-
let node = this.parentNode;
|
|
53
|
+
while (node !== null) {
|
|
54
|
+
node = node.parentNode;
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
d++;
|
|
57
|
+
}
|
|
58
58
|
|
|
59
|
-
d
|
|
59
|
+
return d;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @returns {Node}
|
|
65
|
+
*/
|
|
66
|
+
computeRoot() {
|
|
67
|
+
let p = this;
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
*/
|
|
69
|
-
Node.prototype.computeRoot = function () {
|
|
70
|
-
let p = this;
|
|
69
|
+
while (p.parentNode !== null) {
|
|
70
|
+
p = p.parentNode;
|
|
71
|
+
}
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
p = p.parentNode;
|
|
73
|
+
return p;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
} else {
|
|
88
|
-
return this._mortonCode;
|
|
76
|
+
getMortonCode() {
|
|
77
|
+
if (this._mortonCode === void 0) {
|
|
78
|
+
const hx = (this.x1 + this.x0) / 2;
|
|
79
|
+
const hy = (this.y1 + this.y0) / 2;
|
|
80
|
+
const hz = (this.z1 + this.z0) / 2;
|
|
81
|
+
const mortonCode = computeMortonCode(hx, hy, hz);
|
|
82
|
+
this._mortonCode = mortonCode;
|
|
83
|
+
return mortonCode;
|
|
84
|
+
} else {
|
|
85
|
+
return this._mortonCode;
|
|
86
|
+
}
|
|
89
87
|
}
|
|
90
|
-
};
|
|
91
88
|
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Expands current node and all ancestors until root to accommodate for given box, terminate if node is already
|
|
91
|
+
* large enough
|
|
92
|
+
* @param {AABB3} box
|
|
93
|
+
*/
|
|
94
|
+
bubbleExpandToFit(box) {
|
|
95
|
+
let node = this;
|
|
96
|
+
while (node.expandToFit(box)) {
|
|
97
|
+
node = node.parentNode;
|
|
98
|
+
if (node === null) {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
|
-
};
|
|
106
103
|
|
|
107
|
-
/**
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
104
|
+
/**
|
|
105
|
+
* @deprecated
|
|
106
|
+
*/
|
|
107
|
+
remove() {
|
|
108
|
+
console.error("This method is deprecated, use 'disconnect' instead.");
|
|
109
|
+
this.disconnect();
|
|
110
|
+
}
|
|
114
111
|
|
|
115
|
-
/**
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Detaches this node from its parent
|
|
114
|
+
*/
|
|
115
|
+
disconnect() {
|
|
116
|
+
const node = this.parentNode;
|
|
120
117
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
118
|
+
if (node === null) {
|
|
119
|
+
//no parent already
|
|
120
|
+
// console.warn(`Node has no parent, nothing to disconnect from`);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
126
123
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
124
|
+
if (this === node.left) {
|
|
125
|
+
node.left = null;
|
|
126
|
+
this.parentNode = null;
|
|
127
|
+
} else if (this === node.right) {
|
|
128
|
+
node.right = null;
|
|
129
|
+
this.parentNode = null;
|
|
130
|
+
} else {
|
|
131
|
+
throw new Error("impostor child");
|
|
132
|
+
}
|
|
136
133
|
|
|
137
|
-
|
|
138
|
-
}
|
|
134
|
+
node.updateLeafNodeCount();
|
|
135
|
+
}
|
|
139
136
|
|
|
140
|
-
/**
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
137
|
+
/**
|
|
138
|
+
* traverses all siblings up to the root
|
|
139
|
+
*/
|
|
140
|
+
traverseSiblingsUp() {
|
|
141
|
+
throw new Error('Not Implemented');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
146
144
|
|
|
147
145
|
function buildPathForNode(n) {
|
|
148
146
|
|
|
@@ -185,7 +183,7 @@ function strinfityPath(path) {
|
|
|
185
183
|
* @param {int} len maximum number of path elements
|
|
186
184
|
* @returns {string}
|
|
187
185
|
*/
|
|
188
|
-
function buildShortStringPath(n, len) {
|
|
186
|
+
export function buildShortStringPath(n, len) {
|
|
189
187
|
const longPath = buildPathForNode(n);
|
|
190
188
|
|
|
191
189
|
if (longPath.length > len) {
|
|
@@ -195,4 +193,3 @@ function buildShortStringPath(n, len) {
|
|
|
195
193
|
}
|
|
196
194
|
}
|
|
197
195
|
|
|
198
|
-
export { Node, buildShortStringPath };
|
package/core/bvh2/aabb3/AABB3.js
CHANGED
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
import { aabb3_computeDistanceAbovePlane } from "../../geom/3d/aabb/aabb3_computeDistanceAbovePlane.js";
|
|
7
7
|
import { computeAABB3PlaneSide } from "../../geom/3d/aabb/computeAABB3PlaneSide.js";
|
|
8
8
|
import computeMortonCode from "../../geom/3d/morton/Morton.js";
|
|
9
|
-
import {
|
|
9
|
+
import { boxSurfaceArea, intersectRay, intersectSegment } from "./AABB3Math.js";
|
|
10
10
|
import { aabb3_build_corners } from "../../geom/3d/aabb/aabb3_build_corners.js";
|
|
11
11
|
import { assert } from "../../assert.js";
|
|
12
|
+
import { aabb3_intersects_frustum_degree } from "./aabb3_intersects_frustum_degree.js";
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -81,7 +82,7 @@ AABB3.prototype.computeMortonCode = function () {
|
|
|
81
82
|
* @returns {number}
|
|
82
83
|
*/
|
|
83
84
|
AABB3.prototype.computeSurfaceArea = function () {
|
|
84
|
-
return
|
|
85
|
+
return boxSurfaceArea(this.x0, this.y0, this.z0, this.x1, this.y1, this.z1);
|
|
85
86
|
};
|
|
86
87
|
|
|
87
88
|
/**
|
|
@@ -296,7 +297,8 @@ AABB3.prototype.costForInclusion = function (other) {
|
|
|
296
297
|
};
|
|
297
298
|
|
|
298
299
|
/**
|
|
299
|
-
*
|
|
300
|
+
* Surface area delta when including a given AABB
|
|
301
|
+
* 0 means that including a given AABB would not cause any change to total surface area
|
|
300
302
|
* @param {number} x0
|
|
301
303
|
* @param {number} y0
|
|
302
304
|
* @param {number} z0
|
|
@@ -834,7 +836,7 @@ AABB3.prototype.intersectFrustumDegree = function (frustum) {
|
|
|
834
836
|
|
|
835
837
|
let i = 0;
|
|
836
838
|
let result = 2;
|
|
837
|
-
for (
|
|
839
|
+
for (; i < 6; i++) {
|
|
838
840
|
|
|
839
841
|
const plane = planes[i];
|
|
840
842
|
|
|
@@ -848,6 +850,16 @@ AABB3.prototype.intersectFrustumDegree = function (frustum) {
|
|
|
848
850
|
}
|
|
849
851
|
return result;
|
|
850
852
|
};
|
|
853
|
+
/**
|
|
854
|
+
*
|
|
855
|
+
* @param {number[]} frustum
|
|
856
|
+
* @returns {number}
|
|
857
|
+
*/
|
|
858
|
+
AABB3.prototype.intersectFrustumDegree_array = function (frustum) {
|
|
859
|
+
return aabb3_intersects_frustum_degree(
|
|
860
|
+
this.x0, this.y0, this.z0, this.x1, this.y1, this.z1, frustum
|
|
861
|
+
);
|
|
862
|
+
};
|
|
851
863
|
|
|
852
864
|
/**
|
|
853
865
|
*
|
|
@@ -866,6 +878,40 @@ AABB3.prototype.intersectFrustum = function intersectFrustum(frustum) {
|
|
|
866
878
|
return true;
|
|
867
879
|
};
|
|
868
880
|
|
|
881
|
+
/**
|
|
882
|
+
*
|
|
883
|
+
* @param {ArrayLike<number>|number[]|Float32Array}frustum
|
|
884
|
+
* @returns {boolean}
|
|
885
|
+
*/
|
|
886
|
+
AABB3.prototype.intersectFrustum_array = function intersectFrustum(frustum) {
|
|
887
|
+
const x0 = this.x0;
|
|
888
|
+
const y0 = this.y0;
|
|
889
|
+
const z0 = this.z0;
|
|
890
|
+
const x1 = this.x1;
|
|
891
|
+
const y1 = this.y1;
|
|
892
|
+
const z1 = this.z1;
|
|
893
|
+
|
|
894
|
+
for (let i = 0; i < 24; i += 4) {
|
|
895
|
+
|
|
896
|
+
const p_nx = frustum[i];
|
|
897
|
+
const p_ny = frustum[i + 1];
|
|
898
|
+
const p_nz = frustum[i + 2];
|
|
899
|
+
const p_c = frustum[i + 3];
|
|
900
|
+
|
|
901
|
+
if (aabb3_computeDistanceAbovePlane(
|
|
902
|
+
p_nx, p_ny, p_nz, p_c,
|
|
903
|
+
x0, y0, z0,
|
|
904
|
+
x1, y1, z1
|
|
905
|
+
) < 0) {
|
|
906
|
+
// below plane, i.e. outside of the frustum
|
|
907
|
+
return false;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
}
|
|
911
|
+
return true;
|
|
912
|
+
};
|
|
913
|
+
|
|
914
|
+
|
|
869
915
|
/**
|
|
870
916
|
*
|
|
871
917
|
* @param {number} v
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { BinaryBuffer } from "../../binary/BinaryBuffer.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AABB3,
|
|
4
|
+
deserializeAABB3,
|
|
5
|
+
deserializeAABB3Quantized16Uint,
|
|
6
|
+
serializeAABB3,
|
|
7
|
+
serializeAABB3Quantized16Uint
|
|
8
|
+
} from "./AABB3.js";
|
|
3
9
|
|
|
4
10
|
|
|
5
11
|
function compareBounds(expected, actual, numDigits = 10) {
|
|
@@ -182,3 +188,23 @@ test('isBelowPlane negative space and orthogonal planes', () => {
|
|
|
182
188
|
expect(a._isBelowPlane(0, 0, -1, -4)).toBeTruthy();
|
|
183
189
|
});
|
|
184
190
|
|
|
191
|
+
test('readFrom/writeTo Array consistency', () => {
|
|
192
|
+
const s = new AABB3(
|
|
193
|
+
1, 2, 3, 4, 5, 6
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
const a = [];
|
|
197
|
+
|
|
198
|
+
s.writeToArray(a, 0);
|
|
199
|
+
|
|
200
|
+
expect(a).toEqual([1, 2, 3, 4, 5, 6]);
|
|
201
|
+
|
|
202
|
+
s.readFromArray(a, 0);
|
|
203
|
+
|
|
204
|
+
expect(s.x0).toEqual(1);
|
|
205
|
+
expect(s.y0).toEqual(2);
|
|
206
|
+
expect(s.z0).toEqual(3);
|
|
207
|
+
expect(s.x1).toEqual(4);
|
|
208
|
+
expect(s.y1).toEqual(5);
|
|
209
|
+
expect(s.z1).toEqual(6);
|
|
210
|
+
});
|
|
@@ -540,7 +540,7 @@ function boxSurfaceArea(x0, y0, z0, x1, y1, z1) {
|
|
|
540
540
|
const dx = x1 - x0;
|
|
541
541
|
const dy = y1 - y0;
|
|
542
542
|
const dz = z1 - z0;
|
|
543
|
-
return (
|
|
543
|
+
return (dy * (dx + dz) + dz * dx) * 2; //2 of each side
|
|
544
544
|
}
|
|
545
545
|
|
|
546
546
|
/**
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { min2 } from "../../math/min2.js";
|
|
2
|
+
import { max2 } from "../../math/max2.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {AABB3} result
|
|
7
|
+
* @param {number[]|ArrayLike<number>} input
|
|
8
|
+
* @param {number} input_length
|
|
9
|
+
*/
|
|
10
|
+
export function aabb3_from_v3_array(result, input, input_length) {
|
|
11
|
+
let x0 = Infinity;
|
|
12
|
+
let y0 = Infinity;
|
|
13
|
+
let z0 = Infinity;
|
|
14
|
+
|
|
15
|
+
let x1 = -Infinity;
|
|
16
|
+
let y1 = -Infinity;
|
|
17
|
+
let z1 = -Infinity;
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i < input_length; i += 3) {
|
|
20
|
+
const x = input[i];
|
|
21
|
+
const y = input[i + 1];
|
|
22
|
+
const z = input[i + 2];
|
|
23
|
+
|
|
24
|
+
x0 = min2(x, x0);
|
|
25
|
+
y0 = min2(y, y0);
|
|
26
|
+
z0 = min2(z, z0);
|
|
27
|
+
|
|
28
|
+
x1 = max2(x, x1);
|
|
29
|
+
y1 = max2(y, y1);
|
|
30
|
+
z1 = max2(z, z1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
result.setBounds(x0, y0, z0, x1, y1, z1);
|
|
34
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { min2 } from "../../math/min2.js";
|
|
2
|
+
import { max2 } from "../../math/max2.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {AABB3} result
|
|
7
|
+
* @param {number[]|ArrayLike<number>} input
|
|
8
|
+
* @param {number} input_length
|
|
9
|
+
* @param {ArrayLike<number>|number[]|Float32Array} e 4x4 transformation matrix
|
|
10
|
+
*/
|
|
11
|
+
export function aabb3_from_v3_array_transformed(result, input, input_length, e) {
|
|
12
|
+
let x0 = Infinity;
|
|
13
|
+
let y0 = Infinity;
|
|
14
|
+
let z0 = Infinity;
|
|
15
|
+
|
|
16
|
+
let x1 = -Infinity;
|
|
17
|
+
let y1 = -Infinity;
|
|
18
|
+
let z1 = -Infinity;
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < input_length; i += 3) {
|
|
21
|
+
const x = input[i];
|
|
22
|
+
const y = input[i + 1];
|
|
23
|
+
const z = input[i + 2];
|
|
24
|
+
|
|
25
|
+
const _x = e[0] * x + e[4] * y + e[8] * z + e[12];
|
|
26
|
+
const _y = e[1] * x + e[5] * y + e[9] * z + e[13];
|
|
27
|
+
const _z = e[2] * x + e[6] * y + e[10] * z + e[14];
|
|
28
|
+
|
|
29
|
+
x0 = min2(_x, x0);
|
|
30
|
+
y0 = min2(_y, y0);
|
|
31
|
+
z0 = min2(_z, z0);
|
|
32
|
+
|
|
33
|
+
x1 = max2(_x, x1);
|
|
34
|
+
y1 = max2(_y, y1);
|
|
35
|
+
z1 = max2(_z, z1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
result.setBounds(x0, y0, z0, x1, y1, z1);
|
|
39
|
+
}
|