feat: Enhance InputWithDropDown to support disabled state
fix: Update Model component to manage animation states and transitions more effectively feat: Implement worker action handling in useWorkerHandler for material management feat: Add MaterialAnimator to HumanInstance for dynamic material loading feat: Extend useTriggerHandler to support interactions between humans and various entities feat: Create WorkerAction component for managing load capacity and actions feat: Introduce MaterialAnimator for human instances to visualize material loads refactor: Update asset store to manage animation completion state fix: Ensure proper handling of human materials in useHumanStore
This commit is contained in:
@@ -24,7 +24,7 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
const { subModule } = useSubModuleStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { assetStore, eventStore, productStore } = useSceneContext();
|
||||
const { removeAsset, setAnimations, resetAnimation } = assetStore();
|
||||
const { removeAsset, setAnimations, resetAnimation, setAnimationComplete, setCurrentAnimation: setAnmationAnimation } = assetStore();
|
||||
const { setTop } = useTopData();
|
||||
const { setLeft } = useLeftData();
|
||||
const { getIsEventInProduct } = productStore();
|
||||
@@ -49,10 +49,9 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
const { userId, organization } = getUserData();
|
||||
const mixerRef = useRef<THREE.AnimationMixer>();
|
||||
const actions = useRef<{ [name: string]: THREE.AnimationAction }>({});
|
||||
const [currentAnimation, setCurrentAnimation] = useState<string | null>(null);
|
||||
const [previousAnimation, setPreviousAnimation] = useState<string | null>(null);
|
||||
const [blendFactor, setBlendFactor] = useState(0);
|
||||
const blendDuration = 0.3;
|
||||
const blendFactor = useRef(0);
|
||||
const blendDuration = 0.5;
|
||||
|
||||
useEffect(() => {
|
||||
setDeletableFloorItem(null);
|
||||
@@ -283,63 +282,48 @@ function Model({ asset }: { readonly asset: Asset }) {
|
||||
}
|
||||
|
||||
const handleAnimationComplete = useCallback(() => {
|
||||
console.log(`Animation "${currentAnimation}" completed`);
|
||||
}, [currentAnimation]);
|
||||
if (asset.animationState) {
|
||||
setAnimationComplete(asset.modelUuid, true);
|
||||
}
|
||||
}, [asset.animationState]);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
if (mixerRef.current) {
|
||||
if (blendFactor < 1) {
|
||||
setBlendFactor(prev => Math.min(prev + delta / blendDuration, 1));
|
||||
}
|
||||
|
||||
mixerRef.current.update(delta);
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (asset.animationState && asset.animationState.isPlaying) {
|
||||
if (!mixerRef.current) return;
|
||||
if (!asset.animationState || !mixerRef.current) return;
|
||||
|
||||
if (asset.animationState.current !== currentAnimation) {
|
||||
setPreviousAnimation(currentAnimation);
|
||||
setCurrentAnimation(asset.animationState.current);
|
||||
setBlendFactor(0);
|
||||
const { current, loopAnimation, isPlaying } = asset.animationState;
|
||||
const currentAction = actions.current[current];
|
||||
const previousAction = previousAnimation ? actions.current[previousAnimation] : null;
|
||||
|
||||
if (isPlaying && currentAction) {
|
||||
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);
|
||||
}
|
||||
|
||||
const currentAction = actions.current[asset.animationState.current];
|
||||
const previousAction = previousAnimation ? actions.current[previousAnimation] : null;
|
||||
|
||||
if (currentAction) {
|
||||
const loopMode = asset.animationState.loopAnimation ? THREE.LoopRepeat : THREE.LoopOnce;
|
||||
|
||||
currentAction.reset();
|
||||
currentAction.setLoop(loopMode, loopMode === THREE.LoopRepeat ? Infinity : 1);
|
||||
|
||||
currentAction.play();
|
||||
|
||||
mixerRef.current.addEventListener('finished', handleAnimationComplete);
|
||||
|
||||
if (previousAction && blendFactor < 1) {
|
||||
previousAction.crossFadeTo(currentAction, blendDuration, true);
|
||||
}
|
||||
}
|
||||
|
||||
Object.entries(actions.current).forEach(([name, action]) => {
|
||||
if ((asset.animationState && name !== asset.animationState.current) && name !== previousAnimation) {
|
||||
action.stop();
|
||||
}
|
||||
});
|
||||
currentAction.play();
|
||||
mixerRef.current.addEventListener('finished', handleAnimationComplete);
|
||||
setPreviousAnimation(current);
|
||||
} else {
|
||||
Object.values(actions.current).forEach((action) => action.stop());
|
||||
setCurrentAnimation(null);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (mixerRef.current) {
|
||||
mixerRef.current.removeEventListener('finished', handleAnimationComplete);
|
||||
}
|
||||
}
|
||||
}, [asset.animationState, currentAnimation, previousAnimation, handleAnimationComplete]);
|
||||
};
|
||||
}, [asset.animationState?.current, asset.animationState?.isPlaying]);
|
||||
|
||||
return (
|
||||
<group
|
||||
|
||||
Reference in New Issue
Block a user