@pmndrs/viverse 0.2.24 → 0.2.25
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/dist/physics/world.js +28 -9
- package/package.json +1 -1
package/dist/physics/world.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import { Box3, DoubleSide, InstancedMesh, Matrix4, Mesh, Ray, Vector3 } from 'three';
|
|
1
|
+
import { Box3, DoubleSide, InstancedMesh, Matrix4, Mesh, Ray, Vector3, } from 'three';
|
|
2
2
|
import { computeBoundsTree, StaticGeometryGenerator, ExtendedTriangle } from 'three-mesh-bvh';
|
|
3
3
|
const rayHelper = new Ray();
|
|
4
4
|
const farPointHelper = new Vector3();
|
|
5
5
|
const boxHelper = new Box3();
|
|
6
6
|
const triangleHelper = new ExtendedTriangle();
|
|
7
7
|
const matrixHelper = new Matrix4();
|
|
8
|
+
/**
|
|
9
|
+
* Identifies which geometries StaticGeometryGenerator can merge together. Geometries are mergeable when they share
|
|
10
|
+
* the same set of attributes and agree on whether they are indexed, so two geometries with an equal signature are
|
|
11
|
+
* guaranteed not to trigger the "Make sure all geometries have the same number of attributes." error.
|
|
12
|
+
*/
|
|
13
|
+
function geometryAttributeSignature(geometry) {
|
|
14
|
+
const attributeNames = Object.keys(geometry.attributes).sort().join(',');
|
|
15
|
+
return `${geometry.index == null ? 'non-indexed' : 'indexed'}:${attributeNames}`;
|
|
16
|
+
}
|
|
8
17
|
export class BvhPhysicsWorld {
|
|
9
18
|
bodies = [];
|
|
10
19
|
sensors = [];
|
|
@@ -30,35 +39,45 @@ export class BvhPhysicsWorld {
|
|
|
30
39
|
computeBvhEntries(object, isStatic) {
|
|
31
40
|
object.updateWorldMatrix(true, true);
|
|
32
41
|
const result = [];
|
|
33
|
-
|
|
42
|
+
//StaticGeometryGenerator merges all meshes into a single geometry and throws if they don't all expose
|
|
43
|
+
//the same attributes ("Make sure all geometries have the same number of attributes."). Group the meshes by
|
|
44
|
+
//their attribute signature so every merge only ever sees compatible geometries and generate one bvh per group.
|
|
45
|
+
const meshGroups = new Map();
|
|
34
46
|
object.traverse((entry) => {
|
|
35
47
|
if (entry instanceof InstancedMesh) {
|
|
36
48
|
const bvh = computeBoundsTree.apply(entry.geometry);
|
|
37
|
-
result.push(...
|
|
49
|
+
result.push(...Array.from({ length: entry.instanceMatrix.count }, (_, instanceIndex) => ({
|
|
38
50
|
object: entry,
|
|
39
51
|
bvh,
|
|
40
|
-
instanceIndex
|
|
52
|
+
instanceIndex,
|
|
41
53
|
isStatic,
|
|
42
54
|
})));
|
|
43
55
|
return;
|
|
44
56
|
}
|
|
45
57
|
if (entry instanceof Mesh) {
|
|
46
|
-
|
|
58
|
+
const signature = geometryAttributeSignature(entry.geometry);
|
|
59
|
+
let group = meshGroups.get(signature);
|
|
60
|
+
if (group == null) {
|
|
61
|
+
meshGroups.set(signature, (group = []));
|
|
62
|
+
}
|
|
63
|
+
group.push(entry);
|
|
47
64
|
}
|
|
48
65
|
});
|
|
49
|
-
if (
|
|
66
|
+
if (meshGroups.size > 0) {
|
|
50
67
|
const parent = object.parent;
|
|
51
68
|
if (!isStatic) {
|
|
52
69
|
object.parent = null;
|
|
53
70
|
object.updateMatrixWorld(true);
|
|
54
71
|
}
|
|
55
|
-
const
|
|
56
|
-
|
|
72
|
+
for (const meshes of meshGroups.values()) {
|
|
73
|
+
const geometry = new StaticGeometryGenerator(meshes).generate();
|
|
74
|
+
const bvh = computeBoundsTree.apply(geometry);
|
|
75
|
+
result.push({ object, bvh, isStatic });
|
|
76
|
+
}
|
|
57
77
|
if (!isStatic) {
|
|
58
78
|
object.parent = parent;
|
|
59
79
|
object.updateMatrixWorld(true);
|
|
60
80
|
}
|
|
61
|
-
result.push({ object, bvh, isStatic });
|
|
62
81
|
}
|
|
63
82
|
return result;
|
|
64
83
|
}
|