diff --git a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx index fc5303e..db484d7 100644 --- a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx +++ b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx @@ -9,12 +9,13 @@ import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore interface VehicleAnimatorProps { path: [number, number, number][]; handleCallBack: () => void; + reset: () => void; currentPhase: string; agvUuid: number; agvDetail: any; } -function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetail }: VehicleAnimatorProps) { +function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetail, reset }: VehicleAnimatorProps) { const { decrementVehicleLoad, vehicles } = useVehicleStore(); const { isPaused } = usePauseButtonStore(); const { speed } = useAnimationPlaySpeed(); @@ -44,8 +45,118 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai setProgress(0); completedRef.current = false; }, [currentPath]); + // useEffect(() => { + // console.log('isReset: ', isReset); + // if (isReset) { + // reset(); + // setCurrentPath([]); + // setProgress(0); + // completedRef.current = false; + // decrementVehicleLoad(agvDetail.modelUuid, 0) + // } + // }, [isReset]) + + // useFrame((_, delta) => { + // const object = scene.getObjectByProperty('uuid', agvUuid); + // if (!object || currentPath.length < 2) return; + // if (isPaused) return; + + // let totalDistance = 0; + // const distances = []; + + // for (let i = 0; i < currentPath.length - 1; i++) { + // const start = new THREE.Vector3(...currentPath[i]); + // const end = new THREE.Vector3(...currentPath[i + 1]); + // const segmentDistance = start.distanceTo(end); + // distances.push(segmentDistance); + // totalDistance += segmentDistance; + // } + + // let coveredDistance = progressRef.current; + // let accumulatedDistance = 0; + // let index = 0; + + // while ( + // index < distances.length && + // coveredDistance > accumulatedDistance + distances[index] + // ) { + // accumulatedDistance += distances[index]; + // index++; + // } + + // if (index < distances.length) { + // const start = new THREE.Vector3(...currentPath[index]); + // const end = new THREE.Vector3(...currentPath[index + 1]); + // const segmentDistance = distances[index]; + + // const currentDirection = new THREE.Vector3().subVectors(end, start).normalize(); + // const targetAngle = Math.atan2(currentDirection.x, currentDirection.z); + // const rotationSpeed = 2.0; + // const currentAngle = object.rotation.y; + + // let angleDifference = targetAngle - currentAngle; + // if (angleDifference > Math.PI) angleDifference -= 2 * Math.PI; + // if (angleDifference < -Math.PI) angleDifference += 2 * Math.PI; + + // const maxRotationStep = rotationSpeed * delta; + // object.rotation.y += Math.sign(angleDifference) * Math.min(Math.abs(angleDifference), maxRotationStep); + + // const isAligned = Math.abs(angleDifference) < 0.01; + + // if (isAligned) { + // progressRef.current += delta * (speed * agvDetail.speed); + // coveredDistance = progressRef.current; + + // const t = (coveredDistance - accumulatedDistance) / segmentDistance; + // const position = start.clone().lerp(end, t); + // object.position.copy(position); + // } + // } + + // if (progressRef.current >= totalDistance) { + // if (restRotation) { + // const targetQuaternion = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, 0, 0)); + // object.quaternion.slerp(targetQuaternion, delta * 2); + // const angleDiff = object.quaternion.angleTo(targetQuaternion); + // if (angleDiff < 0.01) { + // let objectRotation = agvDetail.point.rotation + // object.rotation.set(objectRotation[0], objectRotation[1], objectRotation[2]); + // setRestingRotation(false); + // } + // return; + // } + // } + + // if (progressRef.current >= totalDistance) { + // setRestingRotation(true); + // progressRef.current = 0; + // movingForward.current = !movingForward.current; + // setCurrentPath([]); + // handleCallBack(); + // if (currentPhase === 'pickup-drop') { + // requestAnimationFrame(firstFrame); + // } + // } + // }); + useEffect(() => { + console.log('isReset: ', isReset); + if (isReset) { + reset(); + setCurrentPath([]); + setProgress(0); + progressRef.current = 0; + completedRef.current = false; + movingForward.current = true; + setRestingRotation(false); + decrementVehicleLoad(agvDetail.modelUuid, 0); + console.log('agvDetail: ', vehicles); + } + }, [isReset]); useFrame((_, delta) => { + // If reset is active, don't run anything in frame + if (isReset) return; + const object = scene.getObjectByProperty('uuid', agvUuid); if (!object || currentPath.length < 2) return; if (isPaused) return; @@ -65,10 +176,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai let accumulatedDistance = 0; let index = 0; - while ( - index < distances.length && - coveredDistance > accumulatedDistance + distances[index] - ) { + while (index < distances.length && coveredDistance > accumulatedDistance + distances[index]) { accumulatedDistance += distances[index]; index++; } @@ -80,15 +188,16 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai const currentDirection = new THREE.Vector3().subVectors(end, start).normalize(); const targetAngle = Math.atan2(currentDirection.x, currentDirection.z); - const rotationSpeed = 2.0; const currentAngle = object.rotation.y; let angleDifference = targetAngle - currentAngle; if (angleDifference > Math.PI) angleDifference -= 2 * Math.PI; if (angleDifference < -Math.PI) angleDifference += 2 * Math.PI; + const rotationSpeed = 2.0; const maxRotationStep = rotationSpeed * delta; - object.rotation.y += Math.sign(angleDifference) * Math.min(Math.abs(angleDifference), maxRotationStep); + const rotationStep = Math.sign(angleDifference) * Math.min(Math.abs(angleDifference), maxRotationStep); + object.rotation.y += rotationStep; const isAligned = Math.abs(angleDifference) < 0.01; @@ -108,22 +217,19 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai object.quaternion.slerp(targetQuaternion, delta * 2); const angleDiff = object.quaternion.angleTo(targetQuaternion); if (angleDiff < 0.01) { - let objectRotation = agvDetail.point.rotation + const objectRotation = agvDetail.point.rotation; object.rotation.set(objectRotation[0], objectRotation[1], objectRotation[2]); setRestingRotation(false); } - return; - } - } - - if (progressRef.current >= totalDistance) { - setRestingRotation(true); - progressRef.current = 0; - movingForward.current = !movingForward.current; - setCurrentPath([]); - handleCallBack(); - if (currentPhase === 'pickup-drop') { - requestAnimationFrame(firstFrame); + } else { + setRestingRotation(true); + progressRef.current = 0; + movingForward.current = !movingForward.current; + setCurrentPath([]); + handleCallBack(); + if (currentPhase === 'pickup-drop') { + requestAnimationFrame(firstFrame); + } } } }); @@ -137,8 +243,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai } function step(droppedMaterial: number) { - const elapsedTime = performance.now() - startTime; - + const elapsedTime = (performance.now() - startTime) * speed; if (elapsedTime >= fixedInterval) { let droppedMat = droppedMaterial - 1; decrementVehicleLoad(agvDetail.modelUuid, 1); diff --git a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx index d0691f9..44a8ad8 100644 --- a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx +++ b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx @@ -3,12 +3,13 @@ import VehicleAnimator from '../animator/vehicleAnimator'; import * as THREE from 'three'; import { NavMeshQuery } from '@recast-navigation/core'; import { useNavMesh } from '../../../../../store/store'; -import { usePlayButtonStore } from '../../../../../store/usePlayButtonStore'; +import { usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore'; import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore'; function VehicleInstance({ agvDetail }: any) { const { navMesh } = useNavMesh(); - const { isPlaying } = usePlayButtonStore(); + const { isPlaying, setIsPlaying } = usePlayButtonStore(); + const { isReset } = useResetButtonStore(); const { vehicles, setVehicleActive, setVehicleState, incrementVehicleLoad } = useVehicleStore(); const [currentPhase, setCurrentPhase] = useState('stationed'); const [path, setPath] = useState<[number, number, number][]>([]); @@ -31,6 +32,13 @@ function VehicleInstance({ agvDetail }: any) { function vehicleStatus(modelid: string, status: string) { // console.log(`AGV ${modelid}: ${status}`); } + function reset() { + console.log("runs"); + setVehicleActive(agvDetail.modelUuid, false); + setVehicleState(agvDetail.modelUuid, 'idle'); + setPath([]); + setCurrentPhase('stationed') + } useEffect(() => { if (isPlaying) { @@ -50,7 +58,7 @@ function VehicleInstance({ agvDetail }: any) { agvDetail.state === 'idle' && currentPhase === 'picking' ) { - + setTimeout(() => { incrementVehicleLoad(agvDetail.modelUuid, 2); }, 5000); @@ -83,7 +91,7 @@ function VehicleInstance({ agvDetail }: any) { vehicleStatus(agvDetail.modelUuid, 'Started from dropping point, heading to pickup point'); } } - }, [vehicles, currentPhase, path, isPlaying]); + }, [vehicles, currentPhase, path, isPlaying, isReset]); function handleCallBack() { if (currentPhase === 'stationed-pickup') { @@ -115,6 +123,7 @@ function VehicleInstance({ agvDetail }: any) { currentPhase={currentPhase} agvUuid={agvDetail?.modelUuid} agvDetail={agvDetail} + reset={reset} /> );