RigidBody with imported obj in THREE.js and Ammo.js Collision

I have imported 3d obj and glb files in my THREE.js and Ammo.js project .
For example lets take say i have a tiger obj and a lion obj or glb file.

I need to apply Rigidbody constraint to both of them so when they move towards each other they should collide.

But in my case as I couldn’t predict the shape , How can I achieve this …

How can I apply the Rigidbody function to my loaded obj model.


 var objLoader2 = new THREE.OBJLoader();
 objLoader2.load('../../objfiles/Object.obj', function(object) {
     scene.add(object);
 });

Do someone have the code for that.
Or if someone could help me solve this problem it would be of great help .

2 Likes

noooooooo the link is broken! do you still have a solution?

I’ve deleted my previous post since @Coder’s crosspost at stackoverflow did not receive any answers and thus was deleted.

2 Likes

Hey,Has it been solved,I met too。

If the mesh of the model has parameters attribute like SphereBufferGeometry , BoxBufferGeometry,.then I can traverse to get the length, width and height of the Geometry in the model and create the corresponding ammojs physical model. :sweat_smile: :sweat_smile:

Hey, im using this function ATM. I need to scale up the geometry to get the right shape, so if anyone knows how to improve, let me know. This is for static rigid bodies / kinematic bodies only!

function createTriangleShapeByBufferGeometry(geometry, scalingFactor) {
        var mesh = new Ammo.btTriangleMesh(true, true);
        var vertexPositionArray = geometry.attributes.position.array;
        for (var i = 0; i < geometry.attributes.position.count/3; i++) {
                mesh.addTriangle(
                    new Ammo.btVector3(vertexPositionArray[i*9+0]*scalingFactor, vertexPositionArray[i*9+1]*scalingFactor, vertexPositionArray[i*9+2]*scalingFactor ),
                    new Ammo.btVector3(vertexPositionArray[i*9+3]*scalingFactor, vertexPositionArray[i*9+4]*scalingFactor, vertexPositionArray[i*9+5]*scalingFactor),
                    new Ammo.btVector3(vertexPositionArray[i*9+6]*scalingFactor, vertexPositionArray[i*9+7]*scalingFactor, vertexPositionArray[i*9+8]*scalingFactor),
                    false
                );
        }
        var shape = new Ammo.btBvhTriangleMeshShape(mesh, true, true);
        return shape;
    }

Greetings… did you figure this out? I have been unable to make an Ammo rigid body from a complex mesh for use with collisions… I passed the buffer geometry of a large map to your function but its taking a lot of time… I wonder if theres any way to create a temporary collider for only a small area of a such a large object.

don’t use ammo triangle-based shapes for large maps. There is a dedicated shape for complex heightfields (does not work with digged terrains like caves or bridges)
https://threejs.org/examples/?q=ammo#physics_ammo_terrain

For any triangle-based shapes, the best practice is to create invisible low poly mesh around your models and use it as collision shape. You rarely need 1:1 perfect collisions on large structures.

To answer your last question, ammo already provide automatic BVH optimisation (localised collision check on large shapes), here is another exemple, nearly identical to Attila answer, aside I’m decomposing the geometry into ammo triangles for various experimental / shenanigan purposes

            //new ammo triangles
            let triangle, triangle_mesh = new AmmoLib.btTriangleMesh();

            //declare triangles position vectors
            let vectA = new AmmoLib.btVector3(0, 0, 0);
            let vectB = new AmmoLib.btVector3(0, 0, 0);
            let vectC = new AmmoLib.btVector3(0, 0, 0);

            //retrieve vertices positions from object
            let verticesPos = geometry.getAttribute('position').array;
            let triangles = [];
            for (let i = 0; i < verticesPos.length; i += 3) {
                triangles.push({
                    x: verticesPos[i],
                    y: verticesPos[i + 1],
                    z: verticesPos[i + 2]
                })
            }

            //use triangles data to draw ammo shape
            for (let i = 0; i < triangles.length - 3; i += 3) {

                vectA.setX(triangles[i].x);
                vectA.setY(triangles[i].y);
                vectA.setZ(triangles[i].z);

                vectB.setX(triangles[i + 1].x);
                vectB.setY(triangles[i + 1].y);
                vectB.setZ(triangles[i + 1].z);

                vectC.setX(triangles[i + 2].x);
                vectC.setY(triangles[i + 2].y);
                vectC.setZ(triangles[i + 2].z);

                triangle_mesh.addTriangle(vectA, vectB, vectC, true);
            }
			//Ammo vectors should be destroyed after use to avoid memory leak.
			AmmoLib.destroy(vectA);
            AmmoLib.destroy(vectB);
            AmmoLib.destroy(vectC);

			var shape = new AmmoLib.btBvhTriangleMeshShape(triangle_mesh, true);
			
			//var shape = new Ammo.btConvexTriangleMeshShape( triangle_mesh, true);
			
			shape.setMargin(0);
			
			return shape