Mesh does not follow bones

i have a human model created by makehuman addon in blender. i export as glb then import using gltfloader. model has shapekeys that deform the body mesh. i was able to get the skeleton to align with the deformed mesh here (Fitting skeleton to mesh after using shape keys? - #2 by electricmachine).

however, that didnt fix my original problem. i have two skinned mesh objects (body and eyes) that share the same skeleton. eye mesh does not follow the bones influencing it (DEF-eyeR and DEF-eyeL) even though bones are moving themselves.

I have confirmed that these bones influence the eye mesh using skinIndex and skinWeight attributes; and that the bones actually move by tracking their positions. I cant really figure out what’s causing this.

the model:
mhtestupdate.glb (2.3 MB)

i was able to go around the problem by setting the geometry to origin in blender, then setting bind mode to “detached” and moving the mesh manually.

eyeMesh.bindMode = "detached";
eyeMesh.position.copy(eyeBone.position);

but i still dont understand why bones move without the mesh, so i’m leaving this unsolved.

when i rotate the bone manually inside the animate function, the corresponding part of the mesh does rotate with it. bu t logging its position (again inside the animate function) returns 0, 0, 0. both the mesh and the bone are parented to the same object (rigify armature), so they must be in the same space.

i understand morph targets doesnt change position of an object but the bone does move. i will be very happy if someone give me a general direction. i am absolutely stuk with this, i dont know where to look.

this is what i use to move the bones in the skeleton after calculating their reference positions. removing skeleton.calculateInverses allows other meshes like the eyes to move with the skeleton, but then bones are all over the place.

    skeleton.bones.forEach((bone, i) => {

      const localVec = new THREE.Vector3();
      const parentBone = bone.parent;

      const parentMatrixWorld = parentBone.matrixWorld.clone().invert();
      localVec.copy(jointPos[i].headPosition).applyMatrix4(parentMatrixWorld);

      bone.position.copy(localVec);
      bone.updateMatrixWorld();
    });

    skeleton.calculateInverses();
    skeleton.update();

maybe because hierarchy.

if im not wrong, it will better if we using GetWorldPosition,

hierarchy looks like this in blender and imported correctly in three js. I have tried unparenting the meshes from the rig but it doesnt change anthing.

assuming you meant getting world position of the eye mesh, i’ve tried that and it still shows 0,0,0.

i guess it has to with how bone inverses are calculated, because whenever the skeleton position is updated the meshes position is reset to resting pose. im trying to calculate the inverse of each bone individually instead of the whole skeleton, lets see what happens.

still not work?

import * as THREE from 'three';
import { System } from 'three/addons/libs/ecsy.module.js';
import { Draggable } from '../components/DraggableComponent.js';
import { Object3D } from '../components/Object3DComponent.js';
import { SceneComponent } from '../components/sceneComponent.js';

export class DraggableSystem extends System {
    init() {
        this.textMesh = null;
    }
    execute() {
        this.queries.draggable.results.forEach(entity => {
            const draggable = entity.getMutableComponent(Draggable);
            const object = entity.getComponent(Object3D).object;
            const scene = entity.getComponent(SceneComponent).scene;

            if (draggable.originalParent == null) {
                draggable.originalParent = object.parent;
            }

            if (draggable.originalPosition == null) {
                const globalPosition = new THREE.Vector3();
                object.getWorldPosition(globalPosition);
                draggable.originalPosition = globalPosition.clone();
            }
            if (draggable.originalQuaternion == null) {
                draggable.originalQuaternion = object.quaternion.clone();
            }

            switch (draggable.state) {
                case 'to-be-attached':
                    draggable.attachedPointer.children[0].attach(object);
                    draggable.state = 'attached';
                    break;
                case 'to-be-detached':
                    draggable.originalParent.attach(object);
                    object.position.copy(draggable.originalPosition);
                    object.quaternion.copy(draggable.originalQuaternion);
                    object.updateMatrixWorld();
                    draggable.state = 'detached';
                    break;
                default: 
                /*
                    if (draggable.attachedPointer && !draggable.attachedPointer.isPinched()) {
                        
                        if (this.textMesh) scene.remove(this.textMesh);  // Hapus teks lama jika ada
                        this.textMesh = new CreateText({
                            text: object.name,
                            fontSize: 0.03,
                            position: { x: 0, y: 1, z: -2 },
                            color: 0xffffff,
                            textAlign: 'center'
                        });
                        this.textMesh.position.copy(draggable.attachedPointer.position)
                            .add(draggable.attachedPointer.getDirection(new THREE.Vector3()).multiplyScalar(0.5));
                        scene.add(this.textMesh);
                    } else if (this.textMesh) {
                        scene.remove(this.textMesh);  // Hapus teks jika pointer tidak lagi diarahkan
                        this.textMesh = null;
                    } 
                */

                    object.scale.set( 1, 1, 1 );
            }
        });
    }
}

DraggableSystem.queries = {
    draggable: { components: [Draggable] }
};

look, ive object something like this.

–parent
—object

so, i copy the world position of object and i thought its okay.
maybe idk . are you using ecsy method? i thought it will be better. sorry if im wrong

well i can move the object manually, i thought once i moved the bones every object influenced by those bones would move too. but thats not how it works apparently.