@woosh/meep-engine 2.34.36 → 2.34.40
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/bvh2/BinaryNode.js +872 -965
- package/core/bvh2/LeafNode.js +82 -75
- package/core/bvh2/Node.js +112 -114
- package/core/bvh2/aabb3/AABB3.spec.js +27 -1
- package/core/geom/3d/aabb/aabb3_computeDistanceAbovePlane.js +1 -1
- package/core/geom/3d/aabb/aabb3_matrix4_project.js +1 -1
- package/core/geom/3d/aabb/aabb3_matrix4_project.spec.js +13 -0
- package/core/geom/3d/triangle/computeTriangleRayIntersection.js +1 -2
- package/core/geom/Vector3.js +22 -11
- package/engine/ecs/foliage/InstancedFoliage.js +8 -4
- package/engine/ecs/foliage/ViewState.js +5 -30
- package/engine/ecs/foliage/ecs/Foliage2System.js +2 -7
- package/engine/graphics/GraphicsEngine.js +1 -1
- 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 +24 -2
- package/engine/graphics/ecs/water2/shader/AlexWaterShader.js +7 -1
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +1 -1
- package/engine/graphics/micron/format/MicronGeometryPatch.js +0 -7
- package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +5 -1
- package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +3 -1
- package/engine/graphics/render/buffer/simple-fx/ao/SAOShader.js +2 -1
- package/engine/plugin/EnginePluginManager.js +2 -1
- package/package.json +1 -1
package/core/bvh2/LeafNode.js
CHANGED
|
@@ -14,97 +14,105 @@ 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
|
-
|
|
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;
|
|
31
41
|
|
|
42
|
+
}
|
|
32
43
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
* @param {number} dx
|
|
47
|
+
* @param {number} dy
|
|
48
|
+
* @param {number} dz
|
|
49
|
+
*/
|
|
50
|
+
move(dx, dy, dz) {
|
|
51
|
+
this.x0 += dx;
|
|
52
|
+
this.x1 += dx;
|
|
53
|
+
this.y0 += dy;
|
|
54
|
+
this.y1 += dy;
|
|
55
|
+
this.z0 += dz;
|
|
56
|
+
this.z1 += dz;
|
|
57
|
+
if (this.parentNode !== null) {
|
|
58
|
+
this.parentNode.bubbleRefit();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
42
61
|
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param {number} x0
|
|
65
|
+
* @param {number} y0
|
|
66
|
+
* @param {number} z0
|
|
67
|
+
* @param {number} x1
|
|
68
|
+
* @param {number} y1
|
|
69
|
+
* @param {number} z1
|
|
70
|
+
*/
|
|
71
|
+
resize(x0, y0, z0, x1, y1, z1) {
|
|
72
|
+
this.setBounds(x0, y0, z0, x1, y1, z1);
|
|
73
|
+
|
|
74
|
+
this.bubbleRefit();
|
|
75
|
+
}
|
|
48
76
|
|
|
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;
|
|
77
|
+
bubbleRefit() {
|
|
55
78
|
|
|
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();
|
|
79
|
+
if (this.parentNode !== null) {
|
|
80
|
+
this.parentNode.bubbleRefit();
|
|
81
|
+
}
|
|
71
82
|
}
|
|
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
83
|
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @return {LeafNode}
|
|
87
|
+
*/
|
|
88
|
+
clone() {
|
|
89
|
+
const clone = new LeafNode(this.object, this.x0, this.y0, this.z0, this.x1, this.y1, this.z1);
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
clone.parentNode = this.parentNode;
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
this.parentNode.bubbleRefit();
|
|
93
|
+
return clone;
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
96
97
|
/**
|
|
97
98
|
*
|
|
98
|
-
* @
|
|
99
|
+
* @type {boolean}
|
|
99
100
|
*/
|
|
100
|
-
LeafNode.prototype.
|
|
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;
|
|
101
|
+
LeafNode.prototype.isLeafNode = true;
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Leaf node will have height 0, root node will have height equal to maximum depth of the tree
|
|
105
|
+
* @type {number}
|
|
106
|
+
*/
|
|
107
|
+
LeafNode.prototype.height = 0;
|
|
107
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Useful shortcut, to avoid having to distinguish between leaf and intermediate nodes
|
|
111
|
+
* @readonly
|
|
112
|
+
* @deprecated
|
|
113
|
+
* @type {number}
|
|
114
|
+
*/
|
|
115
|
+
LeafNode.prototype.leafNodeCount = 1;
|
|
108
116
|
|
|
109
117
|
/**
|
|
110
118
|
*
|
|
@@ -130,7 +138,6 @@ function deserializeLeafNode(buffer, node, valueDeserializer) {
|
|
|
130
138
|
|
|
131
139
|
export {
|
|
132
140
|
isLeaf,
|
|
133
|
-
LeafNode,
|
|
134
141
|
serializeLeafNode,
|
|
135
142
|
deserializeLeafNode
|
|
136
143
|
};
|
package/core/bvh2/Node.js
CHANGED
|
@@ -5,144 +5,143 @@ 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
|
+
node.updateHeight();
|
|
136
|
+
}
|
|
139
137
|
|
|
140
|
-
/**
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
138
|
+
/**
|
|
139
|
+
* traverses all siblings up to the root
|
|
140
|
+
*/
|
|
141
|
+
traverseSiblingsUp() {
|
|
142
|
+
throw new Error('Not Implemented');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
146
145
|
|
|
147
146
|
function buildPathForNode(n) {
|
|
148
147
|
|
|
@@ -185,7 +184,7 @@ function strinfityPath(path) {
|
|
|
185
184
|
* @param {int} len maximum number of path elements
|
|
186
185
|
* @returns {string}
|
|
187
186
|
*/
|
|
188
|
-
function buildShortStringPath(n, len) {
|
|
187
|
+
export function buildShortStringPath(n, len) {
|
|
189
188
|
const longPath = buildPathForNode(n);
|
|
190
189
|
|
|
191
190
|
if (longPath.length > len) {
|
|
@@ -195,4 +194,3 @@ function buildShortStringPath(n, len) {
|
|
|
195
194
|
}
|
|
196
195
|
}
|
|
197
196
|
|
|
198
|
-
export { Node, buildShortStringPath };
|
|
@@ -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
|
+
});
|
|
@@ -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,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
|
}
|
|
@@ -176,7 +176,7 @@ export class InstancedFoliage {
|
|
|
176
176
|
);
|
|
177
177
|
|
|
178
178
|
//compute bounding box for this instance
|
|
179
|
-
this.
|
|
179
|
+
this.computeInstanceBoundsTight(position, rotation, scale, leaf);
|
|
180
180
|
|
|
181
181
|
//insert bounding box into the spatial index
|
|
182
182
|
this.bvh.insertNode(leaf);
|
|
@@ -218,7 +218,7 @@ export class InstancedFoliage {
|
|
|
218
218
|
* @param {Quaternion} rotation
|
|
219
219
|
* @param {Vector3} scale
|
|
220
220
|
*/
|
|
221
|
-
|
|
221
|
+
computeInstanceBoundsTight(position, rotation, scale, result) {
|
|
222
222
|
|
|
223
223
|
const vertexData = this.geometry.attributes.position.array;
|
|
224
224
|
|
|
@@ -314,8 +314,12 @@ export class InstancedFoliage {
|
|
|
314
314
|
|
|
315
315
|
state.__view = view;
|
|
316
316
|
|
|
317
|
-
|
|
318
|
-
|
|
317
|
+
if (this.geometry !== null) {
|
|
318
|
+
state.instances.setGeometry(this.geometry);
|
|
319
|
+
}
|
|
320
|
+
if (this.__material !== null) {
|
|
321
|
+
state.instances.setMaterial(this.__material);
|
|
322
|
+
}
|
|
319
323
|
|
|
320
324
|
state.instances.mesh.castShadow = this.castShadow;
|
|
321
325
|
state.instances.mesh.receiveShadow = this.receiveShadow;
|