Need help for physic with rapier

Hi everyone,

I am an absolute beginner in threejs and coding in general, (sorry for my english I speak french >but I am belgian!) I am struggling with a cylinder collider applier on a glb (asterisk shape >*), the problem is that the 3D object seems to have a conflict with the physics body and the collider, I am using a debugmesh to try to understand but even though the debug mesh is perfectly aligned with the 3D model the asterisk still sinks into the ground, it falls correctly to the ground bounces correctly then when it is done bouncing instead of staying flat on the ground it slowly leans to one side and sinks into the ground, and I have absolutely no idea why… Can any of you help me find out why it is reacting like this?

I think there is an inconsistency between the physical body (collider) and the real object but I don’t understand what, GPT claude copilot and deepseek didn’t find it either I’m a bit desperate I’ve been looking for the solution for three days… Any suggestion is welcome! Thanks to those who will read me.

TitiPopo

Here is the code for physic :

createDynamicBody(position, size, options = {}) {
    // Log pour debug initial
    console.log("Création corps dynamique:", { position, size, options });

    // Créer le RigidBodyDesc avec rotation si spécifiée
    const bodyDesc = RAPIER.RigidBodyDesc.dynamic()
        .setTranslation(position.x, position.y, position.z);

    if (options.rotation) {
        bodyDesc.setRotation(options.rotation); // Appliquer la rotation au corps
    }

    const rigidBody = this.world.createRigidBody(bodyDesc);

    // Créer le collider avec les bonnes propriétés
    let colliderDesc;
    if (options.type === 'cylinder') {
        colliderDesc = RAPIER.ColliderDesc.cylinder(
            size.radius, // Rayon du cylindre
            size.height / 2 // Hauteur du cylindre (divisée par 2)
        )
            .setRestitution(0.3)
            .setFriction(1.0) // Augmenter la friction
            .setDensity(10.0); // Augmenter la densité pour plus de stabilité
    }

    this.world.createCollider(colliderDesc, rigidBody);

    // Ajuster l'inertie pour favoriser une rotation plate
    rigidBody.setAngularDamping(3.0); // Fort amortissement angulaire

    // Log position et rotation initiales
    console.log("RigidBody initial state:", {
        position: rigidBody.translation(),
        rotation: rigidBody.rotation()
    });

    return rigidBody;
}

And the mesh:

        const loader = new GLTFLoader();// Chargement du modèle Asterisk
        loader.load(
            './models/asterisk.glb',
            (gltf) => {
                asteriskMesh = gltf.scene;
                asteriskMesh.scale.set(ASTERISK_SCALE, ASTERISK_SCALE, ASTERISK_SCALE * 2);
                const startPos = { x: 10, y: 15, z: -15 };
                asteriskMesh.position.set(startPos.x, startPos.y, startPos.z);
                sceneManager.getScene().add(asteriskMesh);
                asteriskMesh.rotateZ(Math.PI / 4); // Rotation pour l'orientation

                const physicsScale = ASTERISK_SCALE;
                const colliderRadius = physicsScale * 0.4; // Rayon du cylindre
                const colliderHeight = physicsScale * 0.1; // Hauteur du cylindre
                const startRotation = new THREE.Euler(Math.PI / 2, 0, Math.PI / 4);
                const startQuaternion = new THREE.Quaternion().setFromEuler(startRotation);

                asteriskMesh.quaternion.copy(startQuaternion);
                asteriskBody = physicsManager.createDynamicBody(
                    startPos,
                    {
                        radius: colliderRadius,    // Utiliser le mĂŞme rayon que le debug
                        height: colliderHeight
                    },
                    { 
                        type: 'cylinder',
                        rotation: startQuaternion
                    }
                );

                // Debug visuel ajusté (doit correspondre exactement à la physique)
                const debugGeometry = new THREE.CylinderGeometry(
                    colliderRadius,    // MĂŞme rayon que la physique
                    colliderRadius,    // MĂŞme rayon que la physique
                    colliderHeight   // MĂŞme hauteur que la physique
                    
                );
                const debugMaterial = new THREE.MeshBasicMaterial({
                    color: 0xff0000,
                    wireframe: true,
                    opacity: 0.5,
                    transparent: true
                });
                const debugMesh = new THREE.Mesh(debugGeometry, debugMaterial);
                debugMesh.rotation.x = Math.PI / 2;  // Aligner le debug avec la physique
                asteriskMesh.add(debugMesh);
            }
        );

    }    

Thank you

You can see the result here : no-title

I suspect your debug mesh does not acurately represent the matrix of your cylinder physics body.

Here is an un-abstracted inline code version of a rapier cylinder with matching debug mesh.

1 Like

Hi, That’s what I thought too but I couldn’t make the two match, thank you very much for your link I will analyze all that, have a good day