Ammo js/enable3d js: Physics body not updating with changes in bone rotation of mesh?

original post: https://github.com/enable3d/enable3d/discussions/196


I have a rigged mesh loaded via:

    var hand
    const loader = new THREE.GLTFLoader().load('./hand.glb', function (gltf) {
        const Object3D = gltf.scene.children[0]

        hand = {
            Object3D: Object3D,
            skinned_mesh: Object3D.children[1],
            skeleton: Object3D.children[1].skeleton,
            position: Object3D.position,
            rotation: Object3D.rotation,
            quaternion: Object3D.quaternion,
        }

        const bones = hand.skeleton.bones;
        hand.forearm = bones[0];
        hand.wrist = bones[1];
        hand.palm = bones[2];
        hand.thumb = bones.slice(3, 7);
        hand.index = bones.slice(7, 11);
        hand.middle = bones.slice(11, 15);
        hand.ring = bones.slice(15, 19);
        hand.pinky = bones.slice(19, 23);

        hand.Object3D.traverse(child => {
            if (child.isMesh) {
                child.castShadow = child.receiveShadow = false
                child.material.metalness = 0
                child.material.roughness = 1
            }
        })
 
        scene.add(hand.Object3D)
        scene.add(new THREE.SkeletonHelper(hand.Object3D))
        physics.add.existing(hand.Object3D, { shape: 'convex', collisionFlags: 2 })
    })

it loads as expected into the scene:

1

However, when I try to rotate an individual bone on the mesh, the mesh and bones rotate as expected, but the physics body does not remain in sync:

hand.palm.rotation.y += Math.PI / 2

2

Is there a way to achieve this?

The documentation says for Kinematic bodies, you need to set needUpdate to true when changing rotation or position. I tried setting that after any rotations or transformations via hand.Object3D.body.needUpdate = true and this does not seem to fix it either.

I also tried adding Object3D to an new ExtendedObject3D() as in the headless GLTF example to see if this would make a difference via

Object3D = new ExtendedObject3D() Object3D.add(gltf.scene.children[0])

This does not work and also did not seem necessary anyways because once hand.Object3D is added to physics, it appears it is automatically converted to an ExtendedObject3D.

I’m not sure what else to try besides removing the physics body and then trying to re-add it frame by frame after any transformations? However, this seems horribly inefficient, there must be an already defined approach for doing this that I’m missing.


If you see in the original discussion, one of the maintainers of enable3d (which uses Ammo js as the backbone of the library) implies this is more of an Ammo js issue than a three js or enable3d js issue. He is also looking for a way to make this work.

Does anyone have any ideas on how to make this work as expected?

There are 2 solutions to this problem.

  1. Adding a softBody to the mesh and use the bones to deform the softBody.
  2. Adding primitive kinematic bodies to each bone.

Both examples will soon be available on enable3d.io.