import React, { useCallback, useEffect, useRef, useState } from 'react'; 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 { useVehicleStore } from '../../../../../store/simulation/useVehicleStore'; import MaterialAnimator from '../animator/materialAnimator'; function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { const { navMesh } = useNavMesh(); const vehicleRef: any = useRef(); const { isPlaying } = usePlayButtonStore(); const { vehicles, setVehicleActive, setVehicleState, incrementVehicleLoad, setMaterialType, setVehicleLoad } = useVehicleStore(); const [currentPhase, setCurrentPhase] = useState('stationed'); const [path, setPath] = useState<[number, number, number][]>([]); let isIncrememtable = useRef(true); const computePath = useCallback( (start: any, end: any) => { try { const navMeshQuery = new NavMeshQuery(navMesh); const { path: segmentPath } = navMeshQuery.computePath(start, end); return ( segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [] ); } catch { return []; } }, [navMesh] ); function vehicleStatus(modelId: string, status: string) { // console.log(`${modelId} , ${status}`); } // Function to reset everything function reset() { setCurrentPhase('stationed'); setVehicleActive(agvDetail.modelUuid, false); setVehicleState(agvDetail.modelUuid, 'idle'); setVehicleLoad(agvDetail.modelUuid, 0); setPath([]); } const increment = () => { if (isIncrememtable.current) { incrementVehicleLoad(agvDetail.modelUuid, 10); setMaterialType(agvDetail.modelUuid, 'Material 1') isIncrememtable.current = false; } } useEffect(() => { if (isPlaying) { if (!agvDetail.point.action.unLoadPoint || !agvDetail.point.action.pickUpPoint) return; if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'stationed') { const toPickupPath = computePath( new THREE.Vector3(agvDetail?.position[0], agvDetail?.position[1], agvDetail?.position[2]), agvDetail?.point?.action?.pickUpPoint?.position ); setPath(toPickupPath); setCurrentPhase('stationed-pickup'); setVehicleState(agvDetail.modelUuid, 'running'); setVehicleActive(agvDetail.modelUuid, true); vehicleStatus(agvDetail.modelUuid, 'Started from station, heading to pickup'); return; } else if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'picking') { // setTimeout(() => { // increment(); // }, 5000); if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity && agvDetail.materialType) { if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) { const toDrop = computePath( agvDetail.point.action.pickUpPoint.position, agvDetail.point.action.unLoadPoint.position ); setPath(toDrop); setCurrentPhase('pickup-drop'); setVehicleState(agvDetail.modelUuid, 'running'); setVehicleActive(agvDetail.modelUuid, true); vehicleStatus(agvDetail.modelUuid, 'Started from pickup point, heading to drop point'); } } } else if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'dropping' && agvDetail.currentLoad === 0) { if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) { const dropToPickup = computePath( agvDetail.point.action.unLoadPoint.position, agvDetail.point.action.pickUpPoint.position ); setPath(dropToPickup); setCurrentPhase('drop-pickup'); setVehicleState(agvDetail.modelUuid, 'running'); setVehicleActive(agvDetail.modelUuid, true); vehicleStatus(agvDetail.modelUuid, 'Started from dropping point, heading to pickup point'); isIncrememtable.current = true; } } } else { reset() } }, [vehicles, currentPhase, path, isPlaying]); function handleCallBack() { if (currentPhase === 'stationed-pickup') { setCurrentPhase('picking'); setVehicleState(agvDetail.modelUuid, 'idle'); setVehicleActive(agvDetail.modelUuid, false); vehicleStatus(agvDetail.modelUuid, 'Reached pickup point, waiting for material'); setPath([]); } else if (currentPhase === 'pickup-drop') { setCurrentPhase('dropping'); setVehicleState(agvDetail.modelUuid, 'idle'); setVehicleActive(agvDetail.modelUuid, false); vehicleStatus(agvDetail.modelUuid, 'Reached drop point'); setPath([]); } else if (currentPhase === 'drop-pickup') { setCurrentPhase('picking'); setVehicleState(agvDetail.modelUuid, 'idle'); setVehicleActive(agvDetail.modelUuid, false); setPath([]); setMaterialType(agvDetail.modelUuid, null) vehicleStatus(agvDetail.modelUuid, 'Reached pickup point again, cycle complete'); } } return ( <> ); } export default VehicleInstance;