import { useRef, useEffect } from "react"; import { useFrame } from "@react-three/fiber"; import { Stage, useGLTF } from "@react-three/drei"; import { AnimationMixer, AnimationAction, Object3D } from "three"; import * as THREE from "three"; interface GltfLoaderProps { glbdata?: boolean; fromServer?: string; setAnimations?: (animations?: string[]) => void; selectedAnimation?: string; setSelectedAnimation?: (animation: string) => void; } const GltfLoader: React.FC = ({ glbdata, fromServer, setAnimations, selectedAnimation, }) => { const { scene, animations } = useGLTF(fromServer ?? "") as { scene: Object3D; animations: THREE.AnimationClip[]; }; const mixer = useRef( scene ? new AnimationMixer(scene) : null ); const actions = useRef>({}); useEffect(() => { if (animations.length > 0 && mixer.current && setAnimations) { const animationNames = animations.map((animation) => animation.name); setAnimations(animationNames); animations.forEach((animation) => { const action = mixer.current!.clipAction(animation); actions.current[animation.name] = action; }); } else { setAnimations && setAnimations([]); } }, [animations, setAnimations]); useEffect(() => { if (actions.current && selectedAnimation) { const action = actions.current[selectedAnimation]; if (action) { action.reset().fadeIn(0.5).play(); return () => { action.fadeOut(0.5); }; } } }, [selectedAnimation]); useFrame((_, delta) => { if (mixer.current) { mixer.current.update(delta); } }); return ( ); }; export default GltfLoader;