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
// Clean up function to fade out the animation when component unmounts
return () => {
// Fade out the animation
currentAction.fadeOut(0.5);
};
Above is the updated return function. There is no need to modify the skeleton's pose in the code