0

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')

1 Answer 1

0

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

Answer

// 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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.