116 lines
4.5 KiB
TypeScript
116 lines
4.5 KiB
TypeScript
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
import * as THREE from 'three';
|
|
import { NavMeshQuery } from '@recast-navigation/core';
|
|
import { useNavMesh } from '../../../../../store/builder/store';
|
|
import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore';
|
|
import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler';
|
|
import { useSceneContext } from '../../../../scene/sceneContext';
|
|
import { useProductContext } from '../../../products/productContext';
|
|
|
|
import HumanAnimator from './animator/humanAnimator';
|
|
|
|
function HumanInstance({ human }: { human: HumanStatus }) {
|
|
const { navMesh } = useNavMesh();
|
|
const { isPlaying } = usePlayButtonStore();
|
|
const { materialStore, armBotStore, conveyorStore, vehicleStore, humanStore, storageUnitStore, productStore } = useSceneContext();
|
|
const { removeMaterial, setEndTime } = materialStore();
|
|
const { getStorageUnitById } = storageUnitStore();
|
|
const { getArmBotById } = armBotStore();
|
|
const { getConveyorById } = conveyorStore();
|
|
const { getVehicleById } = vehicleStore();
|
|
const { triggerPointActions } = useTriggerHandler();
|
|
const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = productStore();
|
|
const { selectedProductStore } = useProductContext();
|
|
const { selectedProduct } = selectedProductStore();
|
|
const { humans, setHumanActive, setHumanState, setHumanPicking, clearCurrentMaterials, setHumanLoad, decrementHumanLoad, removeLastMaterial, getLastMaterial, incrementIdleTime, incrementActiveTime, resetTime } = humanStore();
|
|
|
|
const [currentPhase, setCurrentPhase] = useState<string>('init');
|
|
const [path, setPath] = useState<[number, number, number][]>([]);
|
|
const pauseTimeRef = useRef<number | null>(null);
|
|
const idleTimeRef = useRef<number>(0);
|
|
const activeTimeRef = useRef<number>(0);
|
|
const isPausedRef = useRef<boolean>(false);
|
|
const isSpeedRef = useRef<number>(0);
|
|
let startTime: number;
|
|
let fixedInterval: number;
|
|
const { speed } = useAnimationPlaySpeed();
|
|
const { isPaused } = usePauseButtonStore();
|
|
const previousTimeRef = useRef<number | null>(null);
|
|
const animationFrameIdRef = useRef<number | null>(null);
|
|
|
|
useEffect(() => {
|
|
isPausedRef.current = isPaused;
|
|
}, [isPaused]);
|
|
|
|
useEffect(() => {
|
|
isSpeedRef.current = speed;
|
|
}, [speed]);
|
|
|
|
const computePath = useCallback(
|
|
(start: any, end: any) => {
|
|
try {
|
|
const navMeshQuery = new NavMeshQuery(navMesh);
|
|
const { path: segmentPath } = navMeshQuery.computePath(start, end);
|
|
if (
|
|
segmentPath.length > 0 &&
|
|
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(end.x) &&
|
|
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(end.z)
|
|
) {
|
|
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
|
} else {
|
|
console.log("There is no path here...Choose valid path")
|
|
const { path: segmentPaths } = navMeshQuery.computePath(start, start);
|
|
return segmentPaths.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
|
}
|
|
} catch {
|
|
console.error("Failed to compute path");
|
|
return [];
|
|
}
|
|
},
|
|
[navMesh]
|
|
);
|
|
|
|
function humanStatus(modelId: string, status: string) {
|
|
// console.log(`${modelId} , ${status}`);
|
|
}
|
|
|
|
function reset() {
|
|
setCurrentPhase('init');
|
|
setHumanActive(human.modelUuid, false);
|
|
setHumanPicking(human.modelUuid, false);
|
|
setHumanState(human.modelUuid, 'idle');
|
|
setHumanLoad(human.modelUuid, 0);
|
|
setPath([]);
|
|
startTime = 0;
|
|
isPausedRef.current = false;
|
|
pauseTimeRef.current = 0;
|
|
resetTime(human.modelUuid)
|
|
activeTimeRef.current = 0
|
|
idleTimeRef.current = 0
|
|
previousTimeRef.current = null
|
|
if (animationFrameIdRef.current !== null) {
|
|
cancelAnimationFrame(animationFrameIdRef.current)
|
|
animationFrameIdRef.current = null
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (isPlaying) {
|
|
|
|
}
|
|
else {
|
|
reset()
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [human, currentPhase, path, isPlaying]);
|
|
|
|
return (
|
|
<>
|
|
|
|
<HumanAnimator />
|
|
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default HumanInstance |