Merging instanced geometries to create collider

I’ve looked into this question but didn’t find a solution.

My case: I want to create a collider using three-mesh-bvh. To do this, I need to catch all geometries in the scenes, clone them, and merge them using mergeBufferGeometries. If var geometries is an array containing all geometries, then what I can do is:

 const mergedGeometry = BufferGeometryUtils.mergeBufferGeometries(
    geometries,
    false
  );
  mergedGeometry.boundsTree = new MeshBVH(mergedGeometry, {
    lazyGeneration: true,
  });

My problem: I don’t know how to clone my InstancedMesh instances and push them to the geometries array.

Why I want to do this: I want to render the visible scene with the better performances, hence the InstancedMesh (I can have thousands of times the same geometries in my scenes), but I want a collider, hence the merging.

How would you proceed, or what do you think I should do to get to my result? Not using InstancedMesh does work, but I’d like to use it if I could.

Not seen cases of three-mesh-bvh with instances but I’m guessing you may need to create your box3 bvh tree on the original geometry being sent to the mesh instancer and see if you can reference this first in each instance, what it looks like currently is that you are trying to calculate a bvh tree from the instanced mesh’s entire bounding volume instead of each instance

EDIT: this example demonstrates using instance meshes and a box3 calculation for each indexed geometry, applying the matrix of each indexed geometry to the corralative box3

1 Like

My problem : I don’t know how to clone my InstancedMesh instances and push them to the geometries array.

Sounds like you want to generate all instances into a single mesh. With the mergeBufferGeometries function this means providing a separate individual mesh for each instance where the geometry is already transformed into the right location.

To do this you can create a clone of the instance geometry for each instance, apply the instance matrix using BufferGeometry.applyMatrix4. You can get each instance matrix using InstanceMesh.getMatrixAt.

There are more optimal, memory-efficient ways to generate this geometry but that would add more complexity to the solution.

1 Like

Many thanks for your answer! This does work, even though I end up regenerating meshes for the merge. I suppose that I do get a performance enhancement nevertheless, as the regenerated-for-the-merging meshes are never visible.

As you got from my question, I make my way in terms of high-level abstractions without knowing much about what’s behind. I’m however curious of the more complex/efficient solution there. Do you mind elaborating (it could help more proficient users that have problems similar to mine)? Or maybe you would rather wait for contributors to build helpers so as to provide an easier access for everyone?

As you got from my question, I make my way in terms of high-level abstractions without knowing much about what’s behind. I’m however curious of the more complex/efficient solution there. Do you mind elaborating

The better solution here would involve generating the mesh without making so many duplicate geometries in order to merge. Instead of making duplicates of the geometry you could transform vertices of the triangle while writing them to a new buffer which would save on memory. This is how StaticGeometryGenerator works for merging multiple geometries into one in three-mesh-bvh - though instanced meshes do not work out of the box there.

The best solution is to build something like a BVH or oct tree out of the instances so they can continue to share the same geometry. The instance geometry can then retain its own triangle BVH.

1 Like

just to give you another perspective,

you should not have to do that. a rigid body normally doesn’t need this, you can have multiple colliders describing a ridig body. usually you only have to do it for instancing.

i have an examples, too. it uses both physics and instancing. in order to get the hat to instance it merges its geometries (using three-bvh-csg made by garrett above, same as mergeBufferGeometries(geoms, true) i guess) and then feeds it to rapier. but it also uses multi body rigid bodies: https://twitter.com/0xca0a/status/1557707678847311873

1 Like

you should not have to do that. a rigid body normally doesn’t need this, you can have multiple colliders describing a ridig body. usually you only have to do it for instancing.

To be clear a physics engine usually uses a top level or scene level spatial acceleration structure like a BVH or Oct Tree as I’ve mentioned above.

1 Like

Many thanks for your replies! I think I got the gist of what you meant, I’ll work on it and might come back with additional questions :slight_smile: