I’ve implemented the 3d model to perform animation, but I want to extract the joint information of this model so that only these joints can perform that animation. ‘model.glb’ is a file that combines animation with a 3d model. Under the current code, I just get the T-pose, but not the actual positions in every given time. How can I solve this problem?
_setupAnimations(gltf) {
const model = gltf.scene;
const mixer = new THREE.AnimationMixer(model);
const gltfAnimations = gltf.animations;
const domControls = document.querySelector("#controls");
const animationsMap = {};
gltfAnimations.forEach(animationClip => {
const name = animationClip.name;
const domButton = document.createElement("div");
domButton.classList.add("button");
domButton.innerText = name;
domControls.appendChild(domButton);
domButton.addEventListener("click", () => {
const animationName = domButton.innerHTML;
this.changeAnimation(animationName);
});
const animationAction = mixer.clipAction(animationClip);
animationsMap[name] = animationAction;
});
this._mixer = mixer;
this._animationsMap = animationsMap;
this._currentAnimationAction = this._animationsMap["HipHopDancing"];
this._currentAnimationAction.play();
}
_setupModel() {
new GLTFLoader().load("./data/model.glb", (gltf) => {
const model = gltf.scene;
this._scene.add(model);
this._setupAnimations(gltf);
const boneList = this._getBoneList(model);
this.visualizeBones(boneList);
});
}
_getBoneList(object) {
const boneList = [];
object.traverse((node) => {
if (node.isBone) {
boneList.push(node);
}
});
return boneList;
}
visualizeBones(bones) {
const boneGeometry = new THREE.SphereGeometry(1.5, 16, 16);
const boneMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.5 });
bones.forEach((bone) => {
const boneMesh = new THREE.Mesh(boneGeometry.clone(), boneMaterial.clone());
boneMesh.position.copy(bone.getWorldPosition(new THREE.Vector3()));
this._scene.add(boneMesh);
});
}
_setupCamera() {
const camera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
100,
1000
);
camera.position.set(0, 0, 300);
this._camera = camera;
}
_setupLight() {
const color = 0xffffff;
const intensity = 5;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(0, 0, 1);
this._scene.add(light);
}
update(time) {
time *= 0.0005; // second unit
if (this._mixer) {
const deltaTime = time - this._previousTime;
this._mixer.update(deltaTime);
}
this._previousTime = time;
}
updateBonesPosition() {
if (this._mixer) {
const skeleton = this._model.children[0].skeleton;
const boneMeshes = this._scene.children.filter((child) => child.isBoneMesh);
for (let i = 0; i < skeleton.bones.length; i++) {
const bone = skeleton.bones[i];
const boneMesh = boneMeshes[i];
if (bone && boneMesh) {
const worldPosition = new THREE.Vector3();
bone.getWorldPosition(worldPosition);
boneMesh.position.copy(worldPosition);
}
}
}
}
render(time) {
this._renderer.render(this._scene, this._camera);
this.update(time);
// this.updateBonesPosition();
requestAnimationFrame(this.render.bind(this));
}
and below is part of the constructor part.
this._setupCamera();
this._setupLight();
this._setupModel();
this._setupControls();
// ...
requestAnimationFrame(this.render.bind(this));
please help me…