Hi I am working on a 3d avatar model to replicate sign language poses. I have created two separate actions in blender for my avatar hampalmd & hamshouldertop. In blender it is possible to create keyframes for certain joints instead of the full body. So by blending both actions I am able to create my sign in blender. However in React-three-fiber where I have uploaded my model I encountered the problem where my model resets to the rest position when transitioning to new animation. How do I save the endstate / pose of the 3d model as the beginning state for the next animation?Example
import React, { useEffect, useRef } from "react";
import { useGLTF, useAnimations } from "@react-three/drei";
import { useCharacterAnimations } from "../contexts/CharacterAnimations";
import * as THREE from "three";
const Man = (props) => {
const group = useRef();
const { nodes, materials, animations } = useGLTF("./models/man.glb");
const { setAnimations, animationIndex } = useCharacterAnimations();
const { actions, names } = useAnimations(animations, group);
console.log(names);
useEffect(() => {
setAnimations(names);
}, [names]);
useEffect(() => {
const currentAction = actions[names[animationIndex]];
// Reset, fade in, and play the animation
currentAction.reset().fadeIn(0.5).play();
// Ensure animation plays once
currentAction.setLoop(THREE.LoopOnce, 1);
// Pause the animation at the end of the last frame
currentAction.clampWhenFinished = true;
// Clean up function to fade out the animation when component unmounts
return () => {
currentAction.fadeOut(0.5);
};
}, [animationIndex]);
return (
<group ref={group} {...props} dispose={null}>
<group name="Scene">
<group name="Armature001" rotation={[1.829, 0, 0]}>
<primitive object={nodes.root} />
<skinnedMesh
name="rp_manuel_animated_001_dancing_geo"
geometry={nodes.rp_manuel_animated_001_dancing_geo.geometry}
material={materials["rp_manuel_animated_001_mat.005"]}
skeleton={nodes.rp_manuel_animated_001_dancing_geo.skeleton}
castShadow
/>
</group>
</group>
</group>
);
};
export default Man;
useGLTF.preload("./models/man.glb");
I tried setting the new rest pose of the 3d model after animation ends but encounter an error
// Clean up function to fade out the animation when component unmounts
return () => {
// Fade out the animation
currentAction.fadeOut(0.5);
// Apply the skeleton's pose to the skinned mesh
group.current.skeleton.applySkeleton(group.current);
};
But i encountered the error
TypeError: Cannot read properties of null (reading 'skeleton')
I have solved the problem, it was a simple fix. When exporting the model to selected format (fbx, glb ...) you have to uncheck the "Reset pose bones" under the "Armature" tab
Above is the updated return function. There is no need to modify the skeleton's pose in the code