90 lines
3.3 KiB
TypeScript
90 lines
3.3 KiB
TypeScript
import { useEffect, useRef } from "react";
|
|
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from "../../../../../store/ui/usePlayButtonStore";
|
|
import { useSceneContext } from "../../../../scene/sceneContext";
|
|
|
|
import MaterialAnimator from "../animator/materialAnimator";
|
|
import ManufacturerInstance from "./actions/manufacturerInstance";
|
|
import WorkerInstance from "./actions/workerInstance";
|
|
import OperatorInstance from "./actions/operatorInstance";
|
|
|
|
function HumanInstance({ human }: { readonly human: HumanStatus }) {
|
|
const { isPlaying } = usePlayButtonStore();
|
|
const { humanStore, productStore } = useSceneContext();
|
|
const { getActionByUuid, selectedProduct } = productStore();
|
|
const { incrementIdleTime, incrementActiveTime } = humanStore();
|
|
|
|
const idleTimeRef = useRef<number>(0);
|
|
const activeTimeRef = useRef<number>(0);
|
|
const isPausedRef = useRef<boolean>(false);
|
|
const isSpeedRef = useRef<number>(0);
|
|
const { speed } = useAnimationPlaySpeed();
|
|
const { isPaused } = usePauseButtonStore();
|
|
const previousTimeRef = useRef<number | null>(null);
|
|
const animationFrameIdRef = useRef<number | null>(null);
|
|
const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || "");
|
|
|
|
useEffect(() => {
|
|
isPausedRef.current = isPaused;
|
|
}, [isPaused]);
|
|
|
|
useEffect(() => {
|
|
isSpeedRef.current = speed;
|
|
}, [speed]);
|
|
|
|
function animate(currentTime: number) {
|
|
if (previousTimeRef.current === null) {
|
|
previousTimeRef.current = currentTime;
|
|
}
|
|
|
|
const deltaTime = (currentTime - previousTimeRef.current) / 1000;
|
|
previousTimeRef.current = currentTime;
|
|
|
|
if (human.isActive) {
|
|
if (!isPausedRef.current) {
|
|
activeTimeRef.current += deltaTime * isSpeedRef.current;
|
|
}
|
|
} else {
|
|
if (!isPausedRef.current) {
|
|
idleTimeRef.current += deltaTime * isSpeedRef.current;
|
|
}
|
|
}
|
|
animationFrameIdRef.current = requestAnimationFrame(animate);
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (!isPlaying) return;
|
|
if (!human.isActive) {
|
|
const roundedActiveTime = Math.round(activeTimeRef.current);
|
|
incrementActiveTime(human.modelUuid, roundedActiveTime);
|
|
activeTimeRef.current = 0;
|
|
} else {
|
|
const roundedIdleTime = Math.round(idleTimeRef.current);
|
|
incrementIdleTime(human.modelUuid, roundedIdleTime);
|
|
idleTimeRef.current = 0;
|
|
}
|
|
|
|
if (animationFrameIdRef.current === null) {
|
|
animationFrameIdRef.current = requestAnimationFrame(animate);
|
|
}
|
|
|
|
return () => {
|
|
if (animationFrameIdRef.current !== null) {
|
|
cancelAnimationFrame(animationFrameIdRef.current);
|
|
animationFrameIdRef.current = null;
|
|
}
|
|
};
|
|
}, [human, isPlaying]);
|
|
|
|
return (
|
|
<>
|
|
{action && action.actionType === "worker" && <WorkerInstance human={human} />}
|
|
{action && action.actionType === "manufacturer" && <ManufacturerInstance human={human} />}
|
|
{action && action.actionType === "operator" && <OperatorInstance human={human} />}
|
|
|
|
<MaterialAnimator human={human} />
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default HumanInstance;
|