Converting babylonjs matrix to ammojs bttransform matrix

I tried to copy the babylonjs matrix in a bullet collide matrix, but things seem reverted. what could be wrong ?

const matrix = mesh.computeWorldMatrix(true);

const mat = matrix.asArray();

const trsf = new this.ammoInjection.btTransform();

trsf.setFromOpenGLMatrix(mat);

const m = this.CollideMesh[mesh.name];

m.setWorldTransform(trsf);

Hey there could you be a little more specific what this means? Or have a playground showing what happens. :slight_smile:

1 Like

Probably an handedness issue, let se how @Cedric does it internally ?

1 Like

I wonder if the reverted behavior is due to Bullet using a right-handed coordinate system (http://www.cs.kent.edu/~ruttan/GameEngines/lectures/Bullet_User_Manual) and Babylon using a left-handed coordinate system?

1 Like

yup, exactly what I mean by

Sorry if it was unclear, and I know we would solve it internally so let s provide the trick we use for consistency :slight_smile:

1 Like

@gbz :smiley: Yes, probably !
At first, I cloned scene meshes from babylonjs to collide scene world.
Then, for efficient, and avoid to send again the whole scene, I am only updating meshes matrix in the collide world .
For debugging purpose I am checking that collide world is right , using debugWorld feature of ammojs / bullet api and displaying vertex of collide world in the scene .

This works perfectly when I send the whole scene (without myself computing matrix) . but not when only updating matrix meshes myself.

1 Like

In Babylon, a quaternion and position is set in a btTransform. Matrix values are not copied directly.

2 Likes

I found a first mistake in my project. In collide world I was storing meshes vertex on which I already applied the matrix, and keeping an identity matrix defined…
So, when updating matrix, it was wrong… however it is not completely solved.

If I rebuild the whole collide physicsworld scene at each render. this works as expected. I enclosed the working code (matrix applied works :slight_smile: )

The problem is when I want only to update collide scene for efficiency . So, I suppose I have problems related to the static rigid body settings in collide world .

const trimesh = new this.ammoInjection.btTriangleMesh();
        const va = new Vector3();
        const vb = new Vector3();
        const vc = new Vector3();
        const matrix = mesh.computeWorldMatrix(true);

        if (indices && vertices) {
            for (let j = 0; j < indices.length; j += 3) {
                const ai = indices[j] * 3;
                const bi = indices[j + 1] * 3;
                const ci = indices[j + 2] * 3;
                this._tmpAmmoVectorA.setValue(vertices[ai], vertices[ai + 1], vertices[ai + 2]);
                this._tmpAmmoVectorB.setValue(vertices[bi], vertices[bi + 1], vertices[bi + 2]);
                this._tmpAmmoVectorC.setValue(vertices[ci], vertices[ci + 1], vertices[ci + 2]);
                trimesh.addTriangle(this._tmpAmmoVectorA, this._tmpAmmoVectorB, this._tmpAmmoVectorC, false);
            }
        }
        const shape = new this.ammoInjection.btConvexTriangleMeshShape(trimesh);
        const m = new this.ammoInjection.btCollisionObject();
        m.setCollisionShape(shape);
        const mat = matrix.asArray();
        this._tmpTransform.setFromOpenGLMatrix(mat);
        m.setWorldTransform(this._tmpTransform);
        this._physicsWorld.addCollisionObject(m, mesh.collisionGroup, mesh.collisionMask);
1 Like

Have you considered using rigidBody instead of collisionObject?

Here’s a helpful guide that shows how to initialize a rigidBody with a position and rotation:

let transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
transform.setRotation( new Ammo.btQuaternion( quat.x, quat.y, quat.z, quat.w ) );
let motionState = new Ammo.btDefaultMotionState( transform );

let colShape = new Ammo.btBoxShape( new Ammo.btVector3( scale.x * 0.5, scale.y * 0.5, scale.z * 0.5 ) );
colShape.setMargin( 0.05 );

let localInertia = new Ammo.btVector3( 0, 0, 0 );
colShape.calculateLocalInertia( mass, localInertia );

let rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, colShape, localInertia );
let body = new Ammo.btRigidBody( rbInfo );

body.setFriction(4);
body.setRollingFriction(10);

physicsWorld.addRigidBody( body );

When you update the collide scene, are you updating the vertices of the rigid body? Or instead just translating and rotating the rigid body? If the latter, maybe you could consider a Kinematic rigid body instead of a Static one. The link above also mentions the difference between Static, Kinematic, and Dynamic rigid bodies

I am updating only matrix .

I setted up KINEMATIC_FLAG only.