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.
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.
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