diff --git a/app/src/modules/simulation/human/instances/animator/manufacturerAnimator.tsx b/app/src/modules/simulation/human/instances/animator/manufacturerAnimator.tsx index e1be18b..904cec3 100644 --- a/app/src/modules/simulation/human/instances/animator/manufacturerAnimator.tsx +++ b/app/src/modules/simulation/human/instances/animator/manufacturerAnimator.tsx @@ -25,7 +25,6 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly(false); const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || ""); const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.manufacturePoint?.rotation || [0, 0, 0]); - const [restingRotation, setRestingRotation] = useState(true); const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]); const { scene } = useThree(); @@ -48,7 +47,6 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly= totalDistance) { - if (restingRotation && objectRotation) { + if (objectRotation) { const targetEuler = new THREE.Euler(0, objectRotation[1], 0); const baseQuaternion = new THREE.Quaternion().setFromEuler(targetEuler); const y180 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI); const targetQuaternion = baseQuaternion.multiply(y180); - const angle = object.quaternion.angleTo(targetQuaternion); - if (angle < 0.01) { + + const step = rotationSpeed * delta * speed * human.speed; + object.quaternion.slerp(targetQuaternion, Math.min(1, step / angle)); + + if (object.quaternion.angleTo(targetQuaternion) < 0.001) { object.quaternion.copy(targetQuaternion); - setRestingRotation(false); + setCurrentAnimation(human.modelUuid, "idle", true, true, true); + progressRef.current = 0; + setCurrentPath([]); + handleCallBack(); } else { const step = rotationSpeed * delta * speed * human.speed; object.quaternion.rotateTowards(targetQuaternion, step); @@ -138,13 +142,6 @@ function ManufacturerAnimator({ path, handleCallBack, human, reset }: Readonly= totalDistance) { - setRestingRotation(true); - progressRef.current = 0; - setCurrentPath([]); - handleCallBack(); - } }); return ( diff --git a/app/src/modules/simulation/human/instances/animator/operatorAnimator.tsx b/app/src/modules/simulation/human/instances/animator/operatorAnimator.tsx index db3752f..e2a7ab3 100644 --- a/app/src/modules/simulation/human/instances/animator/operatorAnimator.tsx +++ b/app/src/modules/simulation/human/instances/animator/operatorAnimator.tsx @@ -26,13 +26,13 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly(false); const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || ""); const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.pickUpPoint?.rotation || [0, 0, 0]); - const [restingRotation, setRestingRotation] = useState(true); const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]); const { scene } = useThree(); useEffect(() => { if (!human.currentAction?.actionUuid) return; const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || ""); + completedRef.current = true; if (human.currentPhase === "init-loadPoint" && path.length > 0) { setCurrentPath(path); setObjectRotation((action as HumanAction).pickUpPoint?.rotation ?? null); @@ -43,7 +43,7 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly { completedRef.current = false; @@ -57,7 +57,6 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly= totalDistance) { - if (restingRotation && objectRotation) { + if (objectRotation) { const targetEuler = new THREE.Euler(0, objectRotation[1], 0); const baseQuaternion = new THREE.Quaternion().setFromEuler(targetEuler); const y180 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI); const targetQuaternion = baseQuaternion.multiply(y180); - const angle = object.quaternion.angleTo(targetQuaternion); - if (angle < 0.01) { + + const step = rotationSpeed * delta * speed * human.speed; + object.quaternion.slerp(targetQuaternion, Math.min(1, step / angle)); + + if (object.quaternion.angleTo(targetQuaternion) < 0.001) { object.quaternion.copy(targetQuaternion); - setRestingRotation(false); + setCurrentAnimation(human.modelUuid, "idle", true, true, true); + progressRef.current = 0; + movingForward.current = !movingForward.current; + completedRef.current = true; + setCurrentPath([]); + handleCallBack(); } else { const step = rotationSpeed * delta * speed * human.speed; object.quaternion.rotateTowards(targetQuaternion, step); @@ -147,14 +154,6 @@ function OperatorAnimator({ path, handleCallBack, human, reset }: Readonly= totalDistance) { - setRestingRotation(true); - progressRef.current = 0; - movingForward.current = !movingForward.current; - setCurrentPath([]); - handleCallBack(); - } }); return ( diff --git a/app/src/modules/simulation/human/instances/animator/workerAnimator.tsx b/app/src/modules/simulation/human/instances/animator/workerAnimator.tsx index efdd836..6692440 100644 --- a/app/src/modules/simulation/human/instances/animator/workerAnimator.tsx +++ b/app/src/modules/simulation/human/instances/animator/workerAnimator.tsx @@ -27,7 +27,6 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc const completedRef = useRef(false); const action = getActionByUuid(selectedProduct.productUuid, human?.currentAction?.actionUuid || ""); const [objectRotation, setObjectRotation] = useState<[number, number, number] | null>((action as HumanAction)?.pickUpPoint?.rotation || [0, 0, 0]); - const [restingRotation, setRestingRotation] = useState(true); const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]); const { scene } = useThree(); @@ -58,7 +57,6 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc movingForward.current = true; progressRef.current = 0; setReset(false); - setRestingRotation(true); const object = scene.getObjectByProperty("uuid", human.modelUuid); const humanData = getHumanById(human.modelUuid); if (object && humanData) { @@ -118,7 +116,7 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc const isAligned = angle < 0.01; if (isAligned) { - progressRef.current += delta * (speed * human.speed); + progressRef.current = Math.min(progressRef.current + delta * (speed * human.speed), totalDistance); const t = (progressRef.current - accumulatedDistance) / segmentDistance; const position = start.clone().lerp(end, t); object.position.copy(position); @@ -137,16 +135,26 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc } if (progressRef.current >= totalDistance) { - if (restingRotation && objectRotation) { + if (objectRotation) { const targetEuler = new THREE.Euler(0, objectRotation[1], 0); const baseQuaternion = new THREE.Quaternion().setFromEuler(targetEuler); const y180 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI); const targetQuaternion = baseQuaternion.multiply(y180); - const angle = object.quaternion.angleTo(targetQuaternion); - if (angle < 0.01) { + + const step = rotationSpeed * delta * speed * human.speed; + object.quaternion.slerp(targetQuaternion, Math.min(1, step / angle)); + + if (object.quaternion.angleTo(targetQuaternion) < 0.001) { object.quaternion.copy(targetQuaternion); - setRestingRotation(false); + setCurrentAnimation(human.modelUuid, human.currentMaterials.length > 0 ? "idle_with_box" : "idle", true, true, true); + progressRef.current = 0; + movingForward.current = !movingForward.current; + setCurrentPath([]); + handleCallBack(); + if (human.currentPhase === "pickup-drop") { + requestAnimationFrame(startUnloadingProcess); + } } else { const step = rotationSpeed * delta * speed * human.speed; object.quaternion.rotateTowards(targetQuaternion, step); @@ -158,7 +166,6 @@ function WorkerAnimator({ path, handleCallBack, human, reset, startUnloadingProc } if (progressRef.current >= totalDistance) { - setRestingRotation(true); progressRef.current = 0; movingForward.current = !movingForward.current; setCurrentPath([]); diff --git a/app/src/modules/simulation/human/instances/instance/actions/manufacturerInstance.tsx b/app/src/modules/simulation/human/instances/instance/actions/manufacturerInstance.tsx index 2223e45..dd3f702 100644 --- a/app/src/modules/simulation/human/instances/instance/actions/manufacturerInstance.tsx +++ b/app/src/modules/simulation/human/instances/instance/actions/manufacturerInstance.tsx @@ -49,7 +49,11 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) { let startPoint = new THREE.Vector3(start[0], start[1], start[2]); let endPoint = new THREE.Vector3(end[0], end[1], end[2]); const { path: segmentPath } = navMeshQuery.computePath(startPoint, endPoint); - if (segmentPath.length > 0 && Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)) { + if ( + segmentPath.length > 0 && + Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && + Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.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"); @@ -126,7 +130,14 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) { processAnimationIdRef.current = requestAnimationFrame(trackManufactureProcess); } } - } else if (human.isActive && human.state === "running" && human.currentMaterials.length > 0 && humanAsset && humanAsset.animationState?.current === "working_standing" && humanAsset.animationState?.isCompleted) { + } else if ( + human.isActive && + human.state === "running" && + human.currentMaterials.length > 0 && + humanAsset && + humanAsset.animationState?.current === "working_standing" && + humanAsset.animationState?.isCompleted + ) { if ((action as HumanAction).manufacturePoint && human.currentPhase === "manufacturing") { setHumanState(human.modelUuid, "idle"); setCurrentPhase(human.modelUuid, "waiting"); @@ -141,8 +152,6 @@ function ManufacturerInstance({ human }: { readonly human: HumanStatus }) { } } } - } else { - reset(); } }, [human, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]); diff --git a/app/src/modules/simulation/human/instances/instance/actions/operatorInstance.tsx b/app/src/modules/simulation/human/instances/instance/actions/operatorInstance.tsx index 3d5e04a..6154637 100644 --- a/app/src/modules/simulation/human/instances/instance/actions/operatorInstance.tsx +++ b/app/src/modules/simulation/human/instances/instance/actions/operatorInstance.tsx @@ -29,13 +29,13 @@ function OperatorInstance({ human }: { readonly human: HumanStatus }) { const animationFrameIdRef = useRef(null); const humanAsset = getAssetById(human.modelUuid); - useEffect(() => { - isPausedRef.current = isPaused; - }, [isPaused]); + // useEffect(() => { + // isPausedRef.current = isPaused; + // }, [isPaused]); - useEffect(() => { - isSpeedRef.current = speed; - }, [speed]); + // useEffect(() => { + // isSpeedRef.current = speed; + // }, [speed]); const computePath = useCallback( (start: [number, number, number], end: [number, number, number]) => { @@ -44,7 +44,11 @@ function OperatorInstance({ human }: { readonly human: HumanStatus }) { let startPoint = new THREE.Vector3(start[0], start[1], start[2]); let endPoint = new THREE.Vector3(end[0], end[1], end[2]); const { path: segmentPath } = navMeshQuery.computePath(startPoint, endPoint); - if (segmentPath.length > 0 && Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)) { + if ( + segmentPath.length > 0 && + Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && + Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.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"); @@ -119,8 +123,6 @@ function OperatorInstance({ human }: { readonly human: HumanStatus }) { setCurrentAnimation(human.modelUuid, "working_standing", true, false, false); }, 1); } - } else { - reset(); } }, [human, human.currentAction, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]); diff --git a/app/src/modules/simulation/human/instances/instance/actions/workerInstance.tsx b/app/src/modules/simulation/human/instances/instance/actions/workerInstance.tsx index 211de3d..6711c07 100644 --- a/app/src/modules/simulation/human/instances/instance/actions/workerInstance.tsx +++ b/app/src/modules/simulation/human/instances/instance/actions/workerInstance.tsx @@ -23,7 +23,19 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) { const { triggerPointActions } = useTriggerHandler(); const { setCurrentAnimation, resetAnimation, getAssetById } = assetStore(); const { getActionByUuid, getEventByModelUuid, getTriggerByUuid, selectedProduct } = productStore(); - const { setHumanActive, setHumanState, clearCurrentMaterials, setHumanLoad, setHumanScheduled, decrementHumanLoad, removeLastMaterial, incrementIdleTime, incrementActiveTime, resetTime, setCurrentPhase } = humanStore(); + const { + setHumanActive, + setHumanState, + clearCurrentMaterials, + setHumanLoad, + setHumanScheduled, + decrementHumanLoad, + removeLastMaterial, + incrementIdleTime, + incrementActiveTime, + resetTime, + setCurrentPhase, + } = humanStore(); const [path, setPath] = useState<[number, number, number][]>([]); const pauseTimeRef = useRef(null); @@ -52,7 +64,11 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) { let startPoint = new THREE.Vector3(start[0], start[1], start[2]); let endPoint = new THREE.Vector3(end[0], end[1], end[2]); const { path: segmentPath } = navMeshQuery.computePath(startPoint, endPoint); - if (segmentPath.length > 0 && Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.z)) { + if ( + segmentPath.length > 0 && + Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(endPoint.x) && + Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(endPoint.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"); @@ -115,7 +131,14 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) { humanStatus(human.modelUuid, "Started from init, heading to pickup"); return; } else if (!human.isActive && human.state === "idle" && human.currentPhase === "picking") { - if (humanAsset && human.currentLoad === action.loadCapacity && human.currentMaterials.length > 0 && human.currentLoad > 0 && humanAsset.animationState?.current === "pickup" && humanAsset.animationState?.isCompleted) { + if ( + humanAsset && + human.currentLoad === action.loadCapacity && + human.currentMaterials.length > 0 && + human.currentLoad > 0 && + humanAsset.animationState?.current === "pickup" && + humanAsset.animationState?.isCompleted + ) { if (action.pickUpPoint && action.dropPoint) { const toDrop = computePath(action.pickUpPoint.position || [0, 0, 0], action.dropPoint.position || [0, 0, 0]); setPath(toDrop); @@ -168,8 +191,6 @@ function WorkerInstance({ human }: { readonly human: HumanStatus }) { } } } - } else { - reset(); } }, [human, human.currentAction, human.currentPhase, path, isPlaying, humanAsset?.animationState?.isCompleted]);