# Physics from Geometry hole objects - Ammo

https://didisoftwares.ddns.net/7/index.html

Has anyone managed to apply physics to a geometry that has a hole?
I know it’s possible with convexhull, but it covers the geometry hole. I’m trying directly with the triangles but the physics is strange, for example the tire stays upright.

console itens: model1, model2, tire
example: physics.bodyJump(model2,new THREE.Vector3(0,10,0));

https://didisoftwares.ddns.net/7/js/physics.js

``````case 'mesh':
let triangleArrays = [];
triangle_mesh = new Ammo.btTriangleMesh();
verticesPos = new Float32Array();
obj.traverse(child => { //multiple geometry
if (child.isMesh && child.geometry) {
verticesPos = Float32Concat(verticesPos,child.geometry.attributes.position.array);
}
});
let computedTriangles = 0;
for (let i = 0; i < verticesPos.length; i += 9) {
let v1 = new Ammo.btVector3(verticesPos[i], verticesPos[i + 1], verticesPos[i + 2]);
let v2 = new Ammo.btVector3(verticesPos[i + 3], verticesPos[i + 4], verticesPos[i + 5]);
let v3 = new Ammo.btVector3(verticesPos[i + 6], verticesPos[i + 7], verticesPos[i + 8]);
Ammo.destroy(v1);
Ammo.destroy(v2);
Ammo.destroy(v3);
computedTriangles++;
if (computedTriangles > 1) {
shape = new Ammo.btConvexTriangleMeshShape(triangle_mesh, true);
triangle_mesh = new Ammo.btTriangleMesh();
computedTriangles = 0;
triangleArrays.push(shape);
}
}
shape = new Ammo.btCompoundShape(true, triangleArrays.length - 1);
let transform = new Ammo.btTransform();
transform.setIdentity();
for (var i = 0; i < triangleArrays.length; i++) {
}
meshmodel = new THREE.BufferGeometry();
meshmodel.setAttribute('position', new THREE.BufferAttribute(verticesPos, 3));
for (let i = 0; i < verticesPos.length; i += 3) {
triangles.push({ x: verticesPos[i], y: verticesPos[i + 1], z: verticesPos[i + 2] });
}

break;
case 'triangle':
meshmodel = new THREE.BufferGeometry();
triangle_mesh = new Ammo.btTriangleMesh();

// Declare vetores para as posições dos vértices
vectA = new Ammo.btVector3(0, 0, 0);
vectB = new Ammo.btVector3(0, 0, 0);
vectC = new Ammo.btVector3(0, 0, 0);

// Recupera as posições dos vértices da geometria do objeto
//verticesPos = obj.geometry.attributes.position.array;
verticesPos = new Float32Array();
obj.traverse(child => { //multiple geometry
if (child.isMesh && child.geometry) {
verticesPos = Float32Concat(verticesPos,child.geometry.attributes.position.array);
}
});
meshmodel.setAttribute('position', new THREE.BufferAttribute(verticesPos, 3));

let normals = new Float32Array();
obj.traverse(child => { //multiple geometry
if (child.isMesh && child.geometry) {
normals = Float32Concat(normals,child.geometry.attributes.normal.array);
}
});
// Recupera as normais das faces, se estiverem disponíveis
//let normals = obj.geometry.attributes.normal.array;

// Adiciona os triângulos ao btTriangleMesh
for (let i = 0; i < verticesPos.length; i += 9) {
// Define os vértices A, B, C para cada triângulo
vectA.setValue(verticesPos[i], verticesPos[i + 1], verticesPos[i + 2]);
vectB.setValue(verticesPos[i + 3], verticesPos[i + 4], verticesPos[i + 5]);
vectC.setValue(verticesPos[i + 6], verticesPos[i + 7], verticesPos[i + 8]);

// Adiciona os triângulos ao btTriangleMesh

// Se as normais estiverem disponíveis, também pode ser útil usá-las para corrigir a orientação
if (normals && normals.length >= i + 9) {
let normalA = new Ammo.btVector3(normals[i], normals[i + 1], normals[i + 2]);
let normalB = new Ammo.btVector3(normals[i + 3], normals[i + 4], normals[i + 5]);
let normalC = new Ammo.btVector3(normals[i + 6], normals[i + 7], normals[i + 8]);
Ammo.destroy(normalA);
Ammo.destroy(normalB);
Ammo.destroy(normalC);
}
}

// Limpa os recursos Ammo
Ammo.destroy(vectA);
Ammo.destroy(vectB);
Ammo.destroy(vectC);
// Cria o shape apropriado para o btTriangleMesh (btBvhTriangleMeshShape ou btConvexTriangleMeshShape)
//shape = new Ammo.btBvhTriangleMeshShape(triangle_mesh, false); // Utilize btBvhTriangleMeshShape ou btConvexTriangleMeshShape conforme necessário
shape = new Ammo.btConvexTriangleMeshShape(triangle_mesh, true); // Outra opção caso seja necessário um shape convexo

// Define a margem do shape, se necessário
shape.setMargin(this.conf.margim);

break;
``````

Do you initialize the inertia tensor? The inertia tensor controls how/what axis the object tends to rotate around, based on the distribution of its mass.
The math to compute for non platonic solids is gnarly, but you can often just fake up 3 number values until it “feels” right.

from chatgpt, “ammo.js inertia tensor setup for a roughly cylindrical/wheel kind of thing”:

``````// Assume mass, radius, and height are already defined
var mass = 1; // Replace with actual mass
var height = 2; // Replace with actual height

// Calculate inertia tensor components
var I_x = (1 / 12) * mass * (3 * radius * radius + height * height);
var I_y = (1 / 2) * mass * radius * radius;
var I_z = I_x;

var inertia = new Ammo.btVector3(I_x, I_y, I_z);
cylinderShape.calculateLocalInertia(mass, inertia);

// Create the rigid body
var transform = new Ammo.btTransform();
transform.setIdentity();
var position = new Ammo.btVector3(0, 0, 0); // Replace with actual position
transform.setOrigin(position);
var motionState = new Ammo.btDefaultMotionState(transform);
var rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, cylinderShape, inertia);
var body = new Ammo.btRigidBody(rbInfo);

// Add the body to the dynamics world

``````
1 Like

There is a relatively recent update including “closed rings” kind of shapes (aka: dynamic concave shapes) `btGImpactMeshShape`

Here is the githack link directly using the demo source in the “examples”
https://rawcdn.githack.com/kripken/ammo.js/1ed8b58c7058a5f697f2642ceef8ee20fdd55e10/examples/webgl_demo_gimpact_chain/index.html

The readme of ammo.js was not updated to show this demo.

1 Like

The new version is very good, however this model still uses the convexhull that joins all the points of an object to create the physics, this covers holes that the object has

you were right the error was the center of mass of the object, when imported the object.scene may not be in the center of mass.
i used this conversion before physics apply.

1 Like

This is a solution for too, use this for impact objects, but need be called for only 1 object per time:
https://didisoftwares.ddns.net/7/index.html

physics.createObj(child,‘geometry’,‘obj’,null,1);