new human event mangaer
This commit is contained in:
@@ -265,6 +265,7 @@ function AssetsGroup({ plane }: { readonly plane: RefMesh }) {
|
||||
actionName: "Action 1",
|
||||
actionType: "worker",
|
||||
loadCount: 1,
|
||||
assemblyCount: 1,
|
||||
loadCapacity: 1,
|
||||
processTime: 10,
|
||||
triggers: []
|
||||
|
||||
@@ -384,6 +384,7 @@ async function handleModelLoad(
|
||||
actionName: "Action 1",
|
||||
actionType: "worker",
|
||||
loadCount: 1,
|
||||
assemblyCount: 1,
|
||||
loadCapacity: 1,
|
||||
processTime: 10,
|
||||
triggers: []
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import { useEffect, useRef, useCallback, useState } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import { useSceneContext } from '../../../../../scene/sceneContext';
|
||||
import useModuleStore from '../../../../../../store/useModuleStore';
|
||||
import { usePauseButtonStore, useAnimationPlaySpeed } from '../../../../../../store/usePlayButtonStore';
|
||||
|
||||
interface ModelAnimatorProps {
|
||||
asset: Asset;
|
||||
gltfScene: THREE.Object3D;
|
||||
}
|
||||
|
||||
export function ModelAnimator({
|
||||
asset,
|
||||
gltfScene,
|
||||
}: ModelAnimatorProps) {
|
||||
const mixerRef = useRef<THREE.AnimationMixer>();
|
||||
const actions = useRef<{ [name: string]: THREE.AnimationAction }>({});
|
||||
const [previousAnimation, setPreviousAnimation] = useState<string | null>(null);
|
||||
|
||||
const blendFactor = useRef(0);
|
||||
const blendDuration = 0.5;
|
||||
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
const { isPaused } = usePauseButtonStore();
|
||||
const { assetStore } = useSceneContext();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { setAnimations, setAnimationComplete } = assetStore();
|
||||
|
||||
const handleAnimationComplete = useCallback(() => {
|
||||
if (asset.animationState) {
|
||||
setAnimationComplete(asset.modelUuid, true);
|
||||
}
|
||||
}, [asset.animationState]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!gltfScene || !gltfScene.animations || gltfScene.animations.length === 0) return;
|
||||
|
||||
mixerRef.current = new THREE.AnimationMixer(gltfScene);
|
||||
|
||||
gltfScene.animations.forEach((clip: THREE.AnimationClip) => {
|
||||
const action = mixerRef.current!.clipAction(clip);
|
||||
actions.current[clip.name] = action;
|
||||
});
|
||||
|
||||
const animationNames = gltfScene.animations.map(clip => clip.name);
|
||||
setAnimations(asset.modelUuid, animationNames);
|
||||
|
||||
return () => {
|
||||
mixerRef.current?.stopAllAction();
|
||||
mixerRef.current = undefined;
|
||||
};
|
||||
}, [gltfScene]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!asset.animationState || !mixerRef.current) return;
|
||||
|
||||
const { current, loopAnimation, isPlaying } = asset.animationState;
|
||||
const currentAction = actions.current[current];
|
||||
const previousAction = previousAnimation ? actions.current[previousAnimation] : null;
|
||||
|
||||
if (isPlaying && currentAction && !isPaused) {
|
||||
blendFactor.current = 0;
|
||||
|
||||
currentAction.reset();
|
||||
currentAction.setLoop(loopAnimation ? THREE.LoopRepeat : THREE.LoopOnce, loopAnimation ? Infinity : 1);
|
||||
currentAction.clampWhenFinished = true;
|
||||
|
||||
if (previousAction && previousAction !== currentAction) {
|
||||
previousAction.crossFadeTo(currentAction, blendDuration, false);
|
||||
}
|
||||
|
||||
currentAction.play();
|
||||
mixerRef.current.addEventListener('finished', handleAnimationComplete);
|
||||
setPreviousAnimation(current);
|
||||
} else {
|
||||
Object.values(actions.current).forEach((action) => action.stop());
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (mixerRef.current) {
|
||||
mixerRef.current.removeEventListener('finished', handleAnimationComplete);
|
||||
}
|
||||
};
|
||||
}, [asset.animationState?.current, asset.animationState?.isCompleted, asset.animationState?.isPlaying, isPaused, activeModule]);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
if (mixerRef.current) {
|
||||
mixerRef.current.update(delta * (activeModule === 'simulation' ? speed : 1));
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user