@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.
@@ -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
- let hasNonInstancedMeshes = false;
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(...new Array(entry.instanceMatrix.count).fill(undefined).map((_, i) => ({
49
+ result.push(...Array.from({ length: entry.instanceMatrix.count }, (_, instanceIndex) => ({
38
50
  object: entry,
39
51
  bvh,
40
- instanceIndex: i,
52
+ instanceIndex,
41
53
  isStatic,
42
54
  })));
43
55
  return;
44
56
  }
45
57
  if (entry instanceof Mesh) {
46
- hasNonInstancedMeshes = true;
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 (hasNonInstancedMeshes) {
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 geometry = new StaticGeometryGenerator(object).generate();
56
- const bvh = computeBoundsTree.apply(geometry);
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
  }
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "peerDependencies": {
22
22
  "three": "*"
23
23
  },
24
- "version": "0.2.24",
24
+ "version": "0.2.25",
25
25
  "type": "module",
26
26
  "dependencies": {
27
27
  "@pixiv/three-vrm": "^3.4.2",