From b44111a62057d65b9c2a4f567dd9755a47fb173f Mon Sep 17 00:00:00 2001 From: Poovizhi Date: Mon, 1 Sep 2025 11:24:18 +0530 Subject: [PATCH] solved a bug based on generating point based on zustand --- .../instances/animator/vehicleAnimator2.tsx | 436 ++++++++++++++++++ .../instances/instance/vehicleInstance2.tsx | 26 +- .../pathCreator/function/usePathManager.ts | 13 +- .../vehicle/pathCreator/pathCreator.tsx | 37 +- .../vehicle/pathCreator/pathHandler.tsx | 5 +- .../vehicle/pathCreator/pointHandler.tsx | 329 ------------- app/src/store/builder/store.ts | 104 ++--- 7 files changed, 545 insertions(+), 405 deletions(-) create mode 100644 app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator2.tsx diff --git a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator2.tsx b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator2.tsx new file mode 100644 index 0000000..3747451 --- /dev/null +++ b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator2.tsx @@ -0,0 +1,436 @@ +import { useFrame, useThree } from "@react-three/fiber"; +import React, { useEffect, useRef, useState } from "react"; +import { Quaternion, Vector3 } from "three"; +import { + useAnimationPlaySpeed, + usePlayButtonStore, +} from "../../../../../store/usePlayButtonStore"; +import { usePathManager } from "../../pathCreator/function/usePathManager"; + +interface VehicleAnimatorProps { + vehiclesData: VehicleStructure[]; +} +type ManagerData = { + pathId: string; + vehicleId: string; +}; +export default function VehicleAnimator2({ + vehiclesData, +}: VehicleAnimatorProps) { + const [managerData, setManagerData] = useState(); + const { scene } = useThree(); + const { speed } = useAnimationPlaySpeed(); + const { isPlaying } = usePlayButtonStore(); + const vehicleMovementState = useRef< + Record< + string, + { + index: number; + progress: number; + hasStarted: boolean; + pathIndex: number; + pointIndex: number; + } + > + >({}); + const managerRef = useRef(); + // const manager = usePathManager(managerData?.pathId, managerData?.vehicleId); + + // useFrame((_, delta) => { + // if (!isPlaying) return; + + // vehiclesData.forEach((vehicle) => { + // const { vehicleId, route } = vehicle; + + // if ( + // !route || + // route.length === 0 || + // !route[0].pathPoints || + // route[0].pathPoints.length < 2 + // ) { + // return; + // } + + // const mesh = scene.getObjectByProperty("uuid", vehicleId); // or getObjectByName + // if (!mesh) return; + // const currentPath = route[0]; + // const pathPoints = currentPath.pathPoints; + // const currentPathId = currentPath.pathId; + + // // ✅ Call your function here + // setManagerData({ pathId: currentPathId, vehicleId: vehicleId }); + // const pathStart = new Vector3(...pathPoints[0].position); + // const uuid = vehicleId; + + // // Initialize movement state + // if (!vehicleMovementState.current[uuid]) { + // vehicleMovementState.current[uuid] = { + // index: 0, + // progress: 0, + // hasStarted: false, + // }; + // } + + // const state = vehicleMovementState.current[uuid]; + + // // ✳️ Step 1: Move to start point first + // if (!state.hasStarted) { + // const distanceToStart = mesh.position.distanceTo(pathStart); + // const step = speed * delta; + + // if (distanceToStart <= step) { + // mesh.position.copy(pathStart); + // mesh.quaternion.identity(); + // state.hasStarted = true; + // return; + // } + + // const direction = pathStart.clone().sub(mesh.position); + // const distance = direction.length(); + + // if (distance > step) { + // direction.normalize(); + // mesh.position.add(direction.clone().multiplyScalar(step)); + + // const forward = new Vector3(0, 0, 1); + // const targetQuat = new Quaternion().setFromUnitVectors( + // forward, + // direction + // ); + // mesh.quaternion.slerp(targetQuat, 0.1); + // } else { + // mesh.position.copy(pathStart); + // mesh.quaternion.identity(); + // state.hasStarted = true; + // state.index = 0; + // state.progress = 0; + // } + + // return; + // } + + // // ✳️ Step 2: Move along the route + // const currentPoint = new Vector3(...pathPoints[state.index].position); + // const nextPoint = new Vector3(...pathPoints[state.index + 1].position); + + // const segmentVector = new Vector3().subVectors(nextPoint, currentPoint); + // const segmentLength = segmentVector.length(); + // const direction = segmentVector.clone().normalize(); + + // const moveDistance = speed * delta; + // state.progress += moveDistance / segmentLength; + + // if (state.progress >= 1) { + // state.index++; + // state.progress = 0; + + // if (state.index >= pathPoints.length - 1) { + // // Stop at the end + // state.index = pathPoints.length - 2; + // state.progress = 1; + // } + // } + + // // Interpolate position + // const newPos = new Vector3().lerpVectors( + // currentPoint, + // nextPoint, + // state.progress + // ); + // mesh.position.copy(newPos); + + // // Smooth rotation + // const forward = new Vector3(0, 0, 1); + // const targetQuat = new Quaternion().setFromUnitVectors( + // forward, + // direction + // ); + // mesh.quaternion.slerp(targetQuat, 0.1); + // }); + // }); + // ✅ Shared waypoint reservation system + const reservedWaypoints = new Set(); + + function tryReserveWaypoint(vehicleId: string, waypointId: string) { + if (reservedWaypoints.has(waypointId)) return false; // already reserved + reservedWaypoints.add(waypointId); + return true; + } + + function releaseWaypoint(waypointId: string) { + reservedWaypoints.delete(waypointId); + } + + useFrame((_, delta) => { + if (!isPlaying) return; + + vehiclesData.forEach((vehicle) => { + const { vehicleId, route } = vehicle; + if (!route || route.length === 0) return; + + const mesh = scene.getObjectByProperty("uuid", vehicleId); + if (!mesh) return; + + const uuid = vehicleId; + + // ✅ Initialize state + if (!vehicleMovementState.current[uuid]) { + vehicleMovementState.current[uuid] = { + index: 0, + pointIndex: 0, + pathIndex: 0, + progress: 0, + hasStarted: false, + }; + } + + const state = vehicleMovementState.current[uuid]; + let currentPath = route[state.pathIndex]; + if ( + !currentPath || + !currentPath.pathPoints || + currentPath.pathPoints.length < 2 + ) + return; + + let pathPoints = currentPath.pathPoints; + const pathStart = new Vector3(...pathPoints[0].position); + + // Step 1: move mesh to start + if (!state.hasStarted) { + const distanceToStart = mesh.position.distanceTo(pathStart); + const step = speed * delta; + + if (distanceToStart <= step) { + mesh.position.copy(pathStart); + mesh.quaternion.identity(); + state.hasStarted = true; + return; + } + + const direction = pathStart.clone().sub(mesh.position).normalize(); + mesh.position.add(direction.clone().multiplyScalar(step)); + + const forward = new Vector3(0, 0, 1); + const targetQuat = new Quaternion().setFromUnitVectors( + forward, + direction + ); + mesh.quaternion.slerp(targetQuat, 0.1); + + return; + } + + // ✅ Conflict Resolution: Check reservation before moving + const nextWaypointId = `${currentPath.pathId}-${state.pointIndex + 1}`; + if (!tryReserveWaypoint(uuid, nextWaypointId)) { + // ⏸ Wait here until waypoint becomes free + return; + } + + // Step 2: Move along current path + const currentPoint = new Vector3( + ...pathPoints[state.pointIndex].position + ); + const nextPoint = new Vector3( + ...pathPoints[state.pointIndex + 1].position + ); + + const segmentVector = new Vector3().subVectors(nextPoint, currentPoint); + const segmentLength = segmentVector.length(); + const direction = segmentVector.clone().normalize(); + + const moveDistance = speed * delta; + state.progress += moveDistance / segmentLength; + + if (state.progress >= 1) { + // ✅ Release waypoint once passed + releaseWaypoint(nextWaypointId); + + state.pointIndex++; + state.progress = 0; + + // ✅ reached end of current path → switch to next path + if (state.pointIndex >= pathPoints.length - 1) { + state.pathIndex++; + state.pointIndex = 0; + state.progress = 0; + + // 🔥 refresh path data after advancing + if (state.pathIndex < route.length) { + currentPath = route[state.pathIndex]; + pathPoints = currentPath.pathPoints; + } else { + // ✅ Finished ALL paths → stop + state.pathIndex = route.length - 1; + const lastPath = route[state.pathIndex]; + const lastPts = lastPath.pathPoints; + state.pointIndex = lastPts.length - 2; + state.progress = 1; + } + } + } + + // Interpolate position + const newPos = new Vector3().lerpVectors( + new Vector3(...pathPoints[state.pointIndex].position), + new Vector3(...pathPoints[state.pointIndex + 1].position), + state.progress + ); + mesh.position.copy(newPos); + + // Smooth rotation + const forward = new Vector3(0, 0, 1); + const targetQuat = new Quaternion().setFromUnitVectors( + forward, + direction + ); + mesh.quaternion.slerp(targetQuat, 0.1); + }); + }); + + // useFrame((_, delta) => { + // if (!isPlaying) return; + + // vehiclesData.forEach((vehicle) => { + // console.log("vehiclesData: ", vehiclesData); + // const { vehicleId, route } = vehicle; + // if (!route || route.length === 0) return; + + // const mesh = scene.getObjectByProperty("uuid", vehicleId); + // if (!mesh) return; + + // const uuid = vehicleId; + + // // ✅ Initialize state + // if (!vehicleMovementState.current[uuid]) { + // vehicleMovementState.current[uuid] = { + // index: 0, + // pointIndex: 0, + // pathIndex: 0, + // progress: 0, + // hasStarted: false, + // }; + // } + + // const state = vehicleMovementState.current[uuid]; + // let currentPath = route[state.pathIndex]; + // if ( + // !currentPath || + // !currentPath.pathPoints || + // currentPath.pathPoints.length < 2 + // ) + // return; + + // let pathPoints = currentPath.pathPoints; + // const pathStart = new Vector3(...pathPoints[0].position); + + // // Step 1: move mesh to start + // if (!state.hasStarted) { + // const distanceToStart = mesh.position.distanceTo(pathStart); + // const step = speed * delta; + + // if (distanceToStart <= step) { + // mesh.position.copy(pathStart); + // mesh.quaternion.identity(); + // state.hasStarted = true; + // return; + // } + + // const direction = pathStart.clone().sub(mesh.position).normalize(); + // mesh.position.add(direction.clone().multiplyScalar(step)); + + // const forward = new Vector3(0, 0, 1); + // const targetQuat = new Quaternion().setFromUnitVectors( + // forward, + // direction + // ); + // mesh.quaternion.slerp(targetQuat, 0.1); + + // return; + // } + // // managerRef.current = { pathId: currentPath.pathId, vehicleId: uuid }; + // // // ✅ only setState when pathId actually changes + // // if (managerData?.pathId !== currentPath.pathId) { + // // setManagerData({ pathId: currentPath.pathId, vehicleId: uuid }); + // // } + // if ( + // !managerRef.current || + // managerRef.current.pathId !== currentPath.pathId || + // managerRef.current.vehicleId !== uuid + // ) { + // managerRef.current = { pathId: currentPath.pathId, vehicleId: uuid }; + // } + // // Step 2: Move along current path + // const currentPoint = new Vector3( + // ...pathPoints[state.pointIndex].position + // ); + // const nextPoint = new Vector3( + // ...pathPoints[state.pointIndex + 1].position + // ); + + // const segmentVector = new Vector3().subVectors(nextPoint, currentPoint); + // const segmentLength = segmentVector.length(); + // const direction = segmentVector.clone().normalize(); + + // console.log("speed: ", speed); + // const moveDistance = speed * delta; + // state.progress += moveDistance / segmentLength; + + // if (state.progress >= 1) { + // state.pointIndex++; + // state.progress = 0; + + // // ✅ reached end of current path → switch to next path + // if (state.pointIndex >= pathPoints.length - 1) { + // state.pathIndex++; + // state.pointIndex = 0; + // state.progress = 0; + + // // 🔥 refresh path data after advancing + // if (state.pathIndex < route.length) { + // currentPath = route[state.pathIndex]; + // pathPoints = currentPath.pathPoints; + // } else { + // // ✅ Finished ALL paths → stop + // state.pathIndex = route.length - 1; + // const lastPath = route[state.pathIndex]; + // const lastPts = lastPath.pathPoints; + // state.pointIndex = lastPts.length - 2; + // state.progress = 1; + // } + // } + // } + + // // Interpolate position + // const newPos = new Vector3().lerpVectors( + // new Vector3(...pathPoints[state.pointIndex].position), + // new Vector3(...pathPoints[state.pointIndex + 1].position), + // state.progress + // ); + // mesh.position.copy(newPos); + + // // Smooth rotation + // const forward = new Vector3(0, 0, 1); + // const targetQuat = new Quaternion().setFromUnitVectors( + // forward, + // direction + // ); + // mesh.quaternion.slerp(targetQuat, 0.1); + // }); + // }); + + // const manager = usePathManager( + // managerRef.current?.pathId, + // managerRef.current?.vehicleId + // ); + + // useEffect(() => { + // console.log("managerRef.current: ", managerRef.current); + // if (managerRef.current) { + // console.log("Path manager updated:", manager); + // } + // }, [manager, managerRef.current]); + + return null; +} diff --git a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance2.tsx b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance2.tsx index 26d29c8..b64a246 100644 --- a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance2.tsx +++ b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance2.tsx @@ -5,6 +5,7 @@ import { Vector3 } from "three"; import { useSceneContext } from "../../../../scene/sceneContext"; import { useProductContext } from "../../../products/productContext"; import { useSelectedEventSphere } from "../../../../../store/simulation/useSimulationStore"; +import VehicleAnimator2 from "../animator/vehicleAnimator2"; function dist(a: PointData, b: PointData): number { return Math.sqrt( (a.position[0] - b.position[0]) ** 2 + @@ -156,7 +157,7 @@ export default function VehicleInstance2({ const allPoints = useMemo(() => { const points: PointData[] = []; const seen = new Set(); - paths?.forEach((path: PathDataInterface) => { + useCreatedPaths.getState().paths?.forEach((path: PathDataInterface) => { path.pathPoints.forEach((p) => { if (!seen.has(p.pointId)) { seen.add(p.pointId); @@ -214,13 +215,28 @@ export default function VehicleInstance2({ setTimeout(() => { const modelUuid = selectedEventSphere?.userData?.modelUuid; + // const index = vehiclesData.findIndex( + // (v) => v.vehicleId === modelUuid + // ); + + // if (index !== -1) { + // const updatedVehicles = [...vehiclesData]; + // updatedVehicles[index] = { + // ...updatedVehicles[index], + // startPoint: prevPoint.position, + // endPoint: newPoint.position, + // route: edges, + // }; + // + // setVehiclesData(updatedVehicles); + // } + // }, 0); const index = vehiclesDataRef.current.findIndex( (v) => v.vehicleId === modelUuid ); console.log( "vehiclesDataRef.current: ", - vehiclesDataRef.current, - modelUuid + vehiclesDataRef.current ); if (index !== -1) { @@ -252,7 +268,7 @@ export default function VehicleInstance2({ return () => { canvasElement.removeEventListener("contextmenu", handleContextMenu); }; - }, [raycaster, setVehiclesData, vehiclesData]); + }, [raycaster, setVehiclesData, vehiclesData, selectedEventSphere]); - return null; + return ; } diff --git a/app/src/modules/simulation/vehicle/pathCreator/function/usePathManager.ts b/app/src/modules/simulation/vehicle/pathCreator/function/usePathManager.ts index c35db5f..c8b8554 100644 --- a/app/src/modules/simulation/vehicle/pathCreator/function/usePathManager.ts +++ b/app/src/modules/simulation/vehicle/pathCreator/function/usePathManager.ts @@ -1,10 +1,10 @@ -import { useCallback, useEffect, useMemo } from "react"; +import { useEffect, useMemo } from "react"; import { useCreatedPaths } from "../../../../../store/builder/store"; -export const usePathManager = (pathId?: string, vehicleId?: string | null) => { +export const usePathManager = (pathId?: string, vehicleId?: string) => { const { paths, allPaths, setAllPaths } = useCreatedPaths(); - + // Initialize all paths into allPaths store useEffect(() => { if (!paths || paths.length === 0) return; @@ -26,6 +26,7 @@ export const usePathManager = (pathId?: string, vehicleId?: string | null) => { } }, [paths, allPaths, setAllPaths]); + // Assign vehicle to a path useEffect(() => { if (!pathId || !vehicleId) return; @@ -39,8 +40,10 @@ export const usePathManager = (pathId?: string, vehicleId?: string | null) => { } }, [pathId, vehicleId, allPaths, setAllPaths]); + // ✅ return true if path exists & isAvailable, else false return useMemo(() => { - if (!pathId) return undefined; - return allPaths.find((p: any) => p.pathId === pathId); + if (!pathId) return false; + const path = allPaths.find((p: any) => p.pathId === pathId); + return path ? path.isAvailable : false; }, [pathId, allPaths]); }; diff --git a/app/src/modules/simulation/vehicle/pathCreator/pathCreator.tsx b/app/src/modules/simulation/vehicle/pathCreator/pathCreator.tsx index fc60b9c..44c4d82 100644 --- a/app/src/modules/simulation/vehicle/pathCreator/pathCreator.tsx +++ b/app/src/modules/simulation/vehicle/pathCreator/pathCreator.tsx @@ -209,13 +209,19 @@ export default function PathCreator() { t = Math.max(0, Math.min(1, t)); const closestPoint = new Vector3().lerpVectors(point1Vec, point2Vec, t); - const filteredPath = paths.filter( - (p: PathDataInterface) => p.pathId !== clickedPath.pathId - ); - setPaths(filteredPath); - // setPaths((prev: PathData) => - // prev.filter((p) => p.pathId !== clickedPath.pathId) + // const filteredPath = paths.filter( + // (p: PathDataInterface) => + // String(p.pathId).trim() !== String(clickedPath.pathId).trim() // ); + // setPaths(filteredPath); + const filteredPath = useCreatedPaths + .getState() + .paths.filter( + (p: PathDataInterface) => + String(p.pathId).trim() !== String(clickedPath.pathId).trim() + ); + + setPaths(filteredPath); const point1: PointData = { pointId: clickedPath?.pathPoints[0].pointId, @@ -240,8 +246,14 @@ export default function PathCreator() { pathPoints: [point2, splitPoint], }; setDraftPoints([splitPoint]); + // Instead of relying on "paths" from the component: + setPaths([ + ...useCreatedPaths.getState().paths, // 👈 always current from store + path1, + path2, + ]); - setPaths([...paths, path1, path2]); + // setPaths([...paths, path1, path2]); } else { const newPath: PathDataInterface = { pathId: MathUtils.generateUUID(), @@ -256,7 +268,12 @@ export default function PathCreator() { pathPoints: [point2, splitPoint], }; - setPaths([...paths, newPath, firstPath, secondPath]); + setPaths([ + ...useCreatedPaths.getState().paths, + newPath, + firstPath, + secondPath, + ]); setDraftPoints([splitPoint]); } @@ -307,7 +324,7 @@ export default function PathCreator() { pathId: MathUtils.generateUUID(), pathPoints: [draftPoints[0], newPoint], }; - setPaths([...paths, newPath]); + setPaths([...useCreatedPaths.getState().paths, newPath]); setDraftPoints([newPoint]); } }; @@ -352,10 +369,10 @@ export default function PathCreator() { }); return points; }, [paths]); - useEffect(() => { localStorage.setItem("paths", JSON.stringify(paths)); + console.log("paths: ", paths); }, [paths]); return ( diff --git a/app/src/modules/simulation/vehicle/pathCreator/pathHandler.tsx b/app/src/modules/simulation/vehicle/pathCreator/pathHandler.tsx index 9a3b888..57adb22 100644 --- a/app/src/modules/simulation/vehicle/pathCreator/pathHandler.tsx +++ b/app/src/modules/simulation/vehicle/pathCreator/pathHandler.tsx @@ -138,10 +138,7 @@ export default function PathHandler({ end.z + delta.z, ]; - // ✅ Move both points separately (won’t overwrite other updates) - setPathPosition(points[0].pointId, newStart, setPaths, paths); - setPathPosition(points[1].pointId, newEnd, setPaths, paths); - } + } } }; diff --git a/app/src/modules/simulation/vehicle/pathCreator/pointHandler.tsx b/app/src/modules/simulation/vehicle/pathCreator/pointHandler.tsx index da6e4fb..967b5fb 100644 --- a/app/src/modules/simulation/vehicle/pathCreator/pointHandler.tsx +++ b/app/src/modules/simulation/vehicle/pathCreator/pointHandler.tsx @@ -646,52 +646,6 @@ export default function PointHandler({ ); }, [shortestPaths]); - // useFrame((_, delta) => { - // if (!isPlaying || pathSegments.length < 2) return; - - // vehicleUuids.forEach((uuid: any) => { - // const object = scene.getObjectByProperty("uuid", uuid); - // if (!object) return; - - // const state = vehicleMovementState.current[uuid]; - // if (!state) return; - - // const startSeg = pathSegments[state.index]; - // const endSeg = pathSegments[state.index + 1]; - // if (!startSeg || !endSeg) return; - - // const segmentDistance = startSeg.position.distanceTo(endSeg.position); - // state.progress += (speed * delta) / segmentDistance; - - // while (state.progress >= 1) { - // state.progress -= 1; - // state.index++; - // if (state.index >= pathSegments.length - 1) { - // state.index = 0; - // state.progress = 0; - // object.position.copy(pathSegments[0].position); - // object.quaternion.identity(); // reset rotation - // } - // } - - // const newPos = startSeg.position - // .clone() - // .lerp(endSeg.position, state.progress); - // object.position.copy(newPos); - - // const forward = new Vector3(0, 0, 1); - // const targetDir = endSeg.position - // .clone() - // .sub(startSeg.position) - // .normalize(); - // const targetQuat = new Quaternion().setFromUnitVectors( - // forward, - // targetDir - // ); - - // object.quaternion.slerp(targetQuat, 0.1); - // }); - // }); function getPathIdByPoints( startId: string | undefined, @@ -713,263 +667,7 @@ export default function PointHandler({ } return null; // not found } - //works - useFrame((_, delta) => { - if (!isPlaying || pathSegments.length < 2 || vehicleData.length === 0) - return; - const vehicle = vehicleData[activeVehicleIndex]; - if (!vehicle) return; - - const uuid = vehicle.vehicleId; - const vehicleStartPos = new Vector3(...vehicle.vehiclePosition); - - const object = scene.getObjectByProperty("uuid", uuid); - if (!object) return; - - const state = vehicleMovementState.current[uuid]; - if (!state) return; - - const pathStart = pathSegments[0].position; - - if (!state.hasStarted) { - const distanceToStart = object.position.distanceTo(pathStart); - const step = speed * delta; - - if (distanceToStart <= step) { - object.position.copy(pathStart); - object.quaternion.identity(); - state.hasStarted = true; - return; - } - - const direction = pathStart.clone().sub(object.position); - const distance = direction.length(); - - if (distance > step) { - direction.normalize(); - object.position.add(direction.clone().multiplyScalar(step)); - - const forward = new Vector3(0, 0, 1); - const targetQuat = new Quaternion().setFromUnitVectors( - forward, - direction - ); - object.quaternion.slerp(targetQuat, 0.1); - } else { - object.position.copy(pathStart); - object.quaternion.identity(); - vehicleMovementState.current[uuid] = { index: 0, progress: 0 }; - } - - return; - } - - // Step 2: Follow the path - const startSeg = pathSegments[state.index]; - const endSeg = pathSegments[state.index + 1]; - if (!startSeg || !endSeg) return; - const currentPathId = getPathIdByPoints( - startSeg.startId || startSeg.endId, - endSeg.endId || endSeg.startId, - shortestPaths - ); - setManagerData({ pathId: currentPathId, vehicleId: uuid }); - - const segmentDistance = startSeg.position.distanceTo(endSeg.position); - state.progress += (speed * delta) / segmentDistance; - - while (state.progress >= 1) { - state.progress -= 1; - state.index++; - - if (state.index >= pathSegments.length - 1) { - state.index = 0; - state.progress = 0; - state.hasStarted = false; - object.position.copy(vehicleStartPos); - object.quaternion.identity(); - - setActiveVehicleIndex((prevIndex) => - prevIndex + 1 >= vehicleData.length ? 0 : prevIndex + 1 - ); - - return; - } - } - - const newPos = startSeg.position - .clone() - .lerp(endSeg.position, state.progress); - object.position.copy(newPos); - - const forward = new Vector3(0, 0, 1); - const targetDir = endSeg.position - .clone() - .sub(startSeg.position) - .normalize(); - const targetQuat = new Quaternion().setFromUnitVectors(forward, targetDir); - object.quaternion.slerp(targetQuat, 0.1); - }); - - // useFrame((_, delta) => { - // if (!isPlaying || pathSegments.length < 2 || vehicleData.length === 0) - // return; - - // const vehicleStartPos = new Vector3(...agvDetail.position); - - // const object = scene.getObjectByProperty("uuid", agvDetail.modelUuid); - // if (!object) return; - - // const state = vehicleMovementState.current[agvDetail.modelUuid]; - // if (!state) return; - - // const moveSpeed = speed * delta; - - // const pathStart = pathSegments[0].position; - - // // ➤ Step 1: Move the object to the starting point of the path - // if (!state.hasStarted) { - // const distanceToStart = object.position.distanceTo(pathStart); - - // if (distanceToStart <= moveSpeed) { - // object.position.copy(pathStart); - // object.quaternion.identity(); - // state.hasStarted = true; - // state.index = 0; - // state.progress = 0; - // return; - // } - - // const direction = pathStart.clone().sub(object.position).normalize(); - // object.position.add(direction.clone().multiplyScalar(moveSpeed)); - - // const forward = new Vector3(0, 0, 1); - // const targetQuat = new Quaternion().setFromUnitVectors( - // forward, - // direction - // ); - // object.quaternion.slerp(targetQuat, 0.1); - - // return; - // } - - // // ➤ Step 2: Traverse path segments - // const startSeg = pathSegments[state.index]; - // const endSeg = pathSegments[state.index + 1]; - // if (!startSeg || !endSeg) return; - - // const currentPathId = getPathIdByPoints( - // startSeg.startId || startSeg.endId, - // endSeg.endId || endSeg.startId, - // shortestPaths - // ); - - // setManagerData({ pathId: currentPathId, vehicleId: agvDetail.modelUuid }); - - // const segmentDistance = startSeg.position.distanceTo(endSeg.position); - // state.progress += moveSpeed / segmentDistance; - - // // ➤ Step 3: If we've finished this segment, move to the next - // while (state.progress >= 1) { - // state.progress -= 1; - // state.index++; - - // if (state.index >= pathSegments.length - 1) { - // // Path completed - // state.index = 0; - // state.progress = 0; - // state.hasStarted = false; - - // object.position.copy(vehicleStartPos); - // object.quaternion.identity(); - - // setActiveVehicleIndex((prevIndex) => - // prevIndex + 1 >= vehicleData.length ? 0 : prevIndex + 1 - // ); - - // return; - // } - // } - - // // ➤ Step 4: Interpolate position and rotate - // const newPos = startSeg.position - // .clone() - // .lerp(endSeg.position, state.progress); - // object.position.copy(newPos); - - // const direction = endSeg.position - // .clone() - // .sub(startSeg.position) - // .normalize(); - // const forward = new Vector3(0, 0, 1); - // const targetQuat = new Quaternion().setFromUnitVectors(forward, direction); - // object.quaternion.slerp(targetQuat, 0.1); - // }); - - // useFrame((_, delta) => { - // if (!isPlaying || pathSegments.length < 2 || vehicleData.length === 0) - // return; - // const vehicle = vehicleData[activeVehicleIndex]; - // if (!vehicle) return; - - // const uuid = vehicle.vehicleId; - // const vehiclePosition = vehicle.vehiclePosition; - - // const object = scene.getObjectByProperty("uuid", uuid); - // if (!object) return; - - // const state = vehicleMovementState.current[uuid]; - // if (!state) return; - - // const startSeg = pathSegments[state.index]; - // const endSeg = pathSegments[state.index + 1]; - // if (!startSeg || !endSeg) return; - - // const segmentDistance = startSeg.position.distanceTo(endSeg.position); - // state.progress += (speed * delta) / segmentDistance; - - // while (state.progress >= 1) { - // state.progress -= 1; - // state.index++; - - // // If finished path - // if (state.index >= pathSegments.length - 1) { - // state.index = 0; - // state.progress = 0; - // object.position.copy(pathSegments[0].position); - // object.quaternion.identity(); - - // // Move to next vehicle - // setActiveVehicleIndex((prevIndex) => - // prevIndex + 1 >= vehicleUuids.length ? 0 : prevIndex + 1 - // ); - // return; // Stop updating this frame - // } - // } - - // const newPos = startSeg.position - // .clone() - // .lerp(endSeg.position, state.progress); - // object.position.copy(newPos); - - // const forward = new Vector3(0, 0, 1); - // const targetDir = endSeg.position - // .clone() - // .sub(startSeg.position) - // .normalize(); - // const targetQuat = new Quaternion().setFromUnitVectors(forward, targetDir); - - // object.quaternion.slerp(targetQuat, 0.1); - // }); - - const manager = usePathManager(managerData?.pathId, managerData?.vehicleId); - - useEffect(() => { - // if (managerData) { - // - // } - }, [managerData]); return ( <> ); } - -// const setPathPosition = useCallback( -// ( -// pointUuid: string, -// position: [number, number, number], -// setPaths: React.Dispatch> -// ) => { -// setPaths((prevPaths) => -// prevPaths.map((path) => { -// if (path.pathPoints.some((p) => p.pointId === pointUuid)) { -// return { -// ...path, -// pathPoints: path.pathPoints.map((p) => -// p.pointId === pointUuid ? { ...p, position } : p -// ) as [PointData, PointData], // 👈 force back to tuple -// }; -// } -// return path; -// }) -// ); -// }, -// [setPaths] -// ); - -// const getPathsByPointId = (pointId: any) => { -// return paths.filter((a) => a.pathPoints.some((p) => p.pointId === pointId)); -// }; diff --git a/app/src/store/builder/store.ts b/app/src/store/builder/store.ts index 973a65d..2bdaeac 100644 --- a/app/src/store/builder/store.ts +++ b/app/src/store/builder/store.ts @@ -665,58 +665,58 @@ interface allPaths { type PathData = PathDataInterface[]; export const useCreatedPaths = create((set: any) => ({ paths: [ - { - pathId: "276724c5-05a3-4b5e-a127-a60b3533ccce", - pathPoints: [ - { - pointId: "19c3f429-f214-4f87-8906-7eaaedd925da", - position: [2.33155763270131, 0, -20.538859668988927], - }, - { - pointId: "ea73c7c8-0e26-4aae-9ed8-2349ff2d6718", - position: [17.13371069714903, 0, -22.156135485080462], - }, - ], - }, - { - pathId: "2736b20b-a433-443c-a5c9-5ba4348ac682", - pathPoints: [ - { - pointId: "ea73c7c8-0e26-4aae-9ed8-2349ff2d6718", - position: [17.13371069714903, 0, -22.156135485080462], - }, - { - pointId: "2212bb52-c63c-4289-8b50-5ffd229d13e5", - position: [16.29236816120279, 0, -10.819973445497789], - }, - ], - }, - { - pathId: "3144a2df-7aad-483d-bbc7-de7f7b5b3bfc", - pathPoints: [ - { - pointId: "2212bb52-c63c-4289-8b50-5ffd229d13e5", - position: [16.29236816120279, 0, -10.819973445497789], - }, - { - pointId: "adfd05a7-4e16-403f-81d0-ce99f2e34f5f", - position: [4.677047323894161, 0, -8.279486846767094], - }, - ], - }, - { - pathId: "e0a1b5da-27c2-44a0-81db-759b5a5eb416", - pathPoints: [ - { - pointId: "adfd05a7-4e16-403f-81d0-ce99f2e34f5f", - position: [4.677047323894161, 0, -8.279486846767094], - }, - { - pointId: "19c3f429-f214-4f87-8906-7eaaedd925da", - position: [2.33155763270131, 0, -20.538859668988927], - }, - ], - }, + // { + // pathId: "276724c5-05a3-4b5e-a127-a60b3533ccce", + // pathPoints: [ + // { + // pointId: "19c3f429-f214-4f87-8906-7eaaedd925da", + // position: [2.33155763270131, 0, -20.538859668988927], + // }, + // { + // pointId: "ea73c7c8-0e26-4aae-9ed8-2349ff2d6718", + // position: [17.13371069714903, 0, -22.156135485080462], + // }, + // ], + // }, + // { + // pathId: "2736b20b-a433-443c-a5c9-5ba4348ac682", + // pathPoints: [ + // { + // pointId: "ea73c7c8-0e26-4aae-9ed8-2349ff2d6718", + // position: [17.13371069714903, 0, -22.156135485080462], + // }, + // { + // pointId: "2212bb52-c63c-4289-8b50-5ffd229d13e5", + // position: [16.29236816120279, 0, -10.819973445497789], + // }, + // ], + // }, + // { + // pathId: "3144a2df-7aad-483d-bbc7-de7f7b5b3bfc", + // pathPoints: [ + // { + // pointId: "2212bb52-c63c-4289-8b50-5ffd229d13e5", + // position: [16.29236816120279, 0, -10.819973445497789], + // }, + // { + // pointId: "adfd05a7-4e16-403f-81d0-ce99f2e34f5f", + // position: [4.677047323894161, 0, -8.279486846767094], + // }, + // ], + // }, + // { + // pathId: "e0a1b5da-27c2-44a0-81db-759b5a5eb416", + // pathPoints: [ + // { + // pointId: "adfd05a7-4e16-403f-81d0-ce99f2e34f5f", + // position: [4.677047323894161, 0, -8.279486846767094], + // }, + // { + // pointId: "19c3f429-f214-4f87-8906-7eaaedd925da", + // position: [2.33155763270131, 0, -20.538859668988927], + // }, + // ], + // }, ], setPaths: (x: PathData) => set({ paths: x }), allPaths: [],