Generate Custom Mesh Collider dynamically + options for Rigid body

How can I specify the mesh to my MeshCollider ?
I already add it to my mesh

by user 224464722878005248

By using addNewComponent, do I need to make another thing to make it works ?

by user 224464722878005248

So, MeshCollider is a component and you need to speicify what Mesh data it will use. (that will be the sharedMesh property)

const colliderObject = new Object3D(); // new object that will host the mesh collider component 
this.gameObject.add(colliderObject); // add it as a children to the main object

const renderer = this.gameObject.getComponent(MeshRenderer); // get the mesh renderer from the main object
const collider = new MeshCollider(); // create a new MeshCollider component

// sanitize input
if(renderer && renderer.sharedMesh) { 
  collider.sharedMesh = renderer?.sharedMesh; // set the mesh of the mesh renderer to the mesh collider
  GameObject.addComponent(colliderObject, collider); // add the MeshCollider component to the new gameobject
}
else {
  console.error(`no mesh can be found on ${this.gameObject.name}`, this.gameObject);
}

It is called SharedMesh to save performance since as the name hints, it will reuse the same instance on multiple colliders as possible, same applies to materials.

Let me know if anything wouldn’t be clear :cactus:

Hmmm okay

by user 224464722878005248

I will try, thanks a lot Kipash

by user 224464722878005248

It came to my attention that this would work if the object is from Unity. But if you load an external model it likely uses Three.js objects directly and there is no MeshRenderer. Let me see, if i can clarify what to do in such case.

Yes, there is no MeshRenderer

by user 224464722878005248

I got error and after a log, the renderer is null

by user 224464722878005248

How could I do ?

by user 224464722878005248

I tried to add a MeshRenderer component bu it’s not sufficient

by user 224464722878005248

var mesh: Mesh | null = null;              
instance.traverse((x: Object3D) => { // iterate through all children
    if(mesh) return; //already found a result
    mesh = x instanceof Mesh ? x : null;
});

if(mesh != null) {
    mesh = mesh as Mesh;

    // create the mesh collider and assign the mesh
    const collider = new MeshCollider();
    collider.sharedMesh = mesh!;
    
    // create a host object to hold possible offsets
    const colliderObject = new Object3D();
    GameObject.addComponent(colliderObject, collider); // add the new collider to the new collider object

    // add the collider object under the mehs to get correct scale, position and rotation
    mesh.add(colliderObject); 

    // add rigidbody to the main object
    const rigidbody = new Rigidbody(); 
    rigidbody.isKinematic = true; // for debuging purposes otherwise it falls endlessly
    instance.addComponent(rigidbody);
}

so, in your case the instance variable is your rightRooth.

The code is naive in the sense that it tries to find the first Mesh object in the hiearchy, you could run in to problems if a tooth visual is comprised of two Meshes.

This is how it looks like in our ExternalContent sample where the green outline is the MeshCollider visualized by ?showcolliders

That’s weird… I got one warning and one error by tooth
Here the coliders generated :

by user 224464722878005248

The warning :

Your model is using scaled mesh colliders which is not optimal for performance LowerTooth_42

The error :

rapier_wasm3d.js:133 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')
    at q (rapier_wasm3d.js:133:28)
    at _.trimesh (rapier_wasm3d.js:3830:22)
    at oI.intoRaw (shape.ts:817:25)
    at MI.createCollider (collider_set.ts:65:35)
    at sI.createCollider (world.ts:342:31)
    at _RapierPhysics.createCollider (engine_physics_rapier.ts:653:32)
    at _RapierPhysics.addMeshCollider (engine_physics_rapier.ts:583:30)
    at MeshCollider.onEnable (Collider.ts:93:42)
    at MeshCollider.__internalEnable (Component.ts:499:14)
    at set enabled [as enabled] (Component.ts:554:18)

Still

by user 224464722878005248

Tooth21.obj

by user 224464722878005248

Example of the tooth that I use

by user 224464722878005248