added available paths
This commit is contained in:
@@ -172,6 +172,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
const updatePoint = (index: number, pos: THREE.Vector3) => {
|
||||
|
||||
@@ -29,19 +29,20 @@ export const getPathsByPointId = (pointId: any, paths: PathData) => {
|
||||
export const setPathPosition = (
|
||||
pointUuid: string,
|
||||
position: [number, number, number],
|
||||
setPaths: React.Dispatch<React.SetStateAction<PathData>>
|
||||
setPaths: React.Dispatch<React.SetStateAction<PathData>>,
|
||||
paths: PathData
|
||||
) => {
|
||||
setPaths((prevPaths) =>
|
||||
prevPaths.map((path: any) => {
|
||||
if (path?.pathPoints.some((p: any) => p.pointId === pointUuid)) {
|
||||
return {
|
||||
...path,
|
||||
pathPoints: path.pathPoints.map((p: any) =>
|
||||
p.pointId === pointUuid ? { ...p, position } : p
|
||||
) as [PointData, PointData], // 👈 force back to tuple
|
||||
};
|
||||
}
|
||||
return path;
|
||||
})
|
||||
);
|
||||
const newPaths = paths.map((path: any) => {
|
||||
if (path?.pathPoints.some((p: any) => p.pointId === pointUuid)) {
|
||||
return {
|
||||
...path,
|
||||
pathPoints: path.pathPoints.map((p: any) =>
|
||||
p.pointId === pointUuid ? { ...p, position } : p
|
||||
) as [PointData, PointData], // 👈 force back to tuple
|
||||
};
|
||||
}
|
||||
return path;
|
||||
});
|
||||
|
||||
setPaths(newPaths);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import { useCallback, useEffect, useMemo } from "react";
|
||||
import { useCreatedPaths } from "../../../../../store/builder/store";
|
||||
|
||||
export const usePathManager = (pathId?: string, vehicleId?: string | null) => {
|
||||
const { paths, allPaths, setAllPaths } = useCreatedPaths();
|
||||
console.log("allPaths: ", allPaths);
|
||||
|
||||
useEffect(() => {
|
||||
if (!paths || paths.length === 0) return;
|
||||
|
||||
const newPaths = paths.map((val: any) => ({
|
||||
pathId: val.pathId,
|
||||
isAvailable: true,
|
||||
vehicleId: null,
|
||||
}));
|
||||
|
||||
const merged = [...allPaths];
|
||||
newPaths.forEach((p: any) => {
|
||||
if (!merged.find((m) => m.pathId === p.pathId)) {
|
||||
merged.push(p);
|
||||
}
|
||||
});
|
||||
|
||||
if (merged.length !== allPaths.length) {
|
||||
setAllPaths(merged);
|
||||
}
|
||||
}, [paths, allPaths, setAllPaths]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!pathId || !vehicleId) return;
|
||||
|
||||
const updated = allPaths.map((p: any) =>
|
||||
p.pathId === pathId ? { ...p, vehicleId, isAvailable: false } : p
|
||||
);
|
||||
|
||||
const hasChanged = JSON.stringify(updated) !== JSON.stringify(allPaths);
|
||||
if (hasChanged) {
|
||||
setAllPaths(updated);
|
||||
}
|
||||
}, [pathId, vehicleId, allPaths, setAllPaths]);
|
||||
|
||||
return useMemo(() => {
|
||||
if (!pathId) return undefined;
|
||||
return allPaths.find((p: any) => p.pathId === pathId);
|
||||
}, [pathId, allPaths]);
|
||||
};
|
||||
@@ -8,10 +8,9 @@ import React, {
|
||||
useState,
|
||||
} from "react";
|
||||
import { LineCurve3, MathUtils, Plane, Vector3 } from "three";
|
||||
import { Vector3Array } from "../../../../types/world/worldTypes";
|
||||
import {
|
||||
useActiveSubTool,
|
||||
useActiveTool,
|
||||
useCreatedPaths,
|
||||
useToolMode,
|
||||
} from "../../../../store/builder/store";
|
||||
import PointHandler from "./pointHandler";
|
||||
@@ -36,15 +35,19 @@ interface PathDataInterface {
|
||||
type PathData = PathDataInterface[];
|
||||
|
||||
export default function PathCreator() {
|
||||
const [paths, setPaths] = useState<PathData>([]);
|
||||
// const [paths, setPaths] = useState<PathData>([]);
|
||||
// const [paths, setPaths] = useState<PathData>(() => {
|
||||
// const stored = localStorage.getItem("paths");
|
||||
// return stored ? JSON.parse(stored) : [];
|
||||
// });
|
||||
const { paths, setPaths } = useCreatedPaths();
|
||||
const { activeTool } = useActiveTool();
|
||||
const { toolMode } = useToolMode();
|
||||
|
||||
const [draftPoints, setDraftPoints] = useState<PointData[]>([]);
|
||||
const [mousePos, setMousePos] = useState<[number, number, number] | null>(
|
||||
null
|
||||
);
|
||||
const { toolMode } = useToolMode();
|
||||
|
||||
const plane = useMemo(() => new Plane(new Vector3(0, 1, 0), 0), []);
|
||||
const { scene, raycaster, gl } = useThree();
|
||||
const [snappedPosition, setSnappedPosition] = useState<
|
||||
[number, number, number] | null
|
||||
>(null);
|
||||
@@ -54,21 +57,33 @@ export default function PathCreator() {
|
||||
null
|
||||
);
|
||||
const [hoveredPoint, setHoveredPoint] = useState<PointData | null>(null);
|
||||
|
||||
const { activeSubTool } = useActiveSubTool();
|
||||
const { activeTool } = useActiveTool();
|
||||
const [pathPointsList, setPathPointsList] = useState<PointData[]>([]);
|
||||
const [selectedPointIndices, setSelectedPointIndices] = useState<number[]>(
|
||||
[]
|
||||
);
|
||||
const plane = useMemo(() => new Plane(new Vector3(0, 1, 0), 0), []);
|
||||
|
||||
const { scene, raycaster, gl } = useThree();
|
||||
|
||||
const POINT_SNAP_THRESHOLD = 0.5;
|
||||
const CAN_POINT_SNAP = true;
|
||||
|
||||
useEffect(() => {}, [paths]);
|
||||
|
||||
const getAllOtherPathPoints = useCallback((): PointData[] => {
|
||||
if (draftPoints.length === 0) return [];
|
||||
return (
|
||||
paths?.flatMap((path) =>
|
||||
path.pathPoints.filter((pt) => pt.pointId !== draftPoints[0].pointId)
|
||||
paths?.flatMap((path: any) =>
|
||||
path.pathPoints.filter(
|
||||
(pt: PointData) => pt.pointId !== draftPoints[0].pointId
|
||||
)
|
||||
) ?? []
|
||||
);
|
||||
}, [paths, draftPoints]);
|
||||
useEffect(() => {
|
||||
const stored = localStorage.getItem("paths");
|
||||
setPaths(stored ? JSON.parse(stored) : []);
|
||||
}, []);
|
||||
|
||||
const snapPathPoint = useCallback(
|
||||
(position: [number, number, number]) => {
|
||||
@@ -134,13 +149,11 @@ export default function PathCreator() {
|
||||
});
|
||||
|
||||
useEffect(() => {}, [paths]);
|
||||
|
||||
const getPathPointById = (uuid: any) => {
|
||||
for (const path of paths) {
|
||||
const point = path.pathPoints.find((p) => p.pointId === uuid);
|
||||
console.log(
|
||||
"point: ",
|
||||
path.pathPoints.map((val) => val)
|
||||
);
|
||||
const point = path.pathPoints.find((p: PointData) => p.pointId === uuid);
|
||||
|
||||
if (point) return point;
|
||||
}
|
||||
return undefined;
|
||||
@@ -170,7 +183,9 @@ export default function PathCreator() {
|
||||
paths
|
||||
);
|
||||
if (clickedPath) {
|
||||
const hitPath = paths.find((p) => p.pathId === clickedPath.pathId);
|
||||
const hitPath = paths.find(
|
||||
(p: PathDataInterface) => p.pathId === clickedPath.pathId
|
||||
);
|
||||
|
||||
if (!hitPath) return;
|
||||
|
||||
@@ -197,7 +212,13 @@ export default function PathCreator() {
|
||||
t = Math.max(0, Math.min(1, t));
|
||||
|
||||
const closestPoint = new Vector3().lerpVectors(point1Vec, point2Vec, t);
|
||||
setPaths((prev) => prev.filter((p) => p.pathId !== clickedPath.pathId));
|
||||
const filteredPath = paths.filter(
|
||||
(p: PathDataInterface) => p.pathId !== clickedPath.pathId
|
||||
);
|
||||
setPaths(filteredPath);
|
||||
// setPaths((prev: PathData) =>
|
||||
// prev.filter((p) => p.pathId !== clickedPath.pathId)
|
||||
// );
|
||||
|
||||
const point1: PointData = {
|
||||
pointId: clickedPath?.pathPoints[0].pointId,
|
||||
@@ -222,7 +243,8 @@ export default function PathCreator() {
|
||||
pathPoints: [point2, splitPoint],
|
||||
};
|
||||
setDraftPoints([splitPoint]);
|
||||
setPaths((prev) => [...prev, path1, path2]);
|
||||
|
||||
setPaths([...paths, path1, path2]);
|
||||
} else {
|
||||
const newPath: PathDataInterface = {
|
||||
pathId: MathUtils.generateUUID(),
|
||||
@@ -237,7 +259,8 @@ export default function PathCreator() {
|
||||
pathPoints: [point2, splitPoint],
|
||||
};
|
||||
|
||||
setPaths((prev) => [...prev, newPath, firstPath, secondPath]);
|
||||
setPaths([...paths, newPath, firstPath, secondPath]);
|
||||
|
||||
setDraftPoints([splitPoint]);
|
||||
}
|
||||
|
||||
@@ -287,8 +310,7 @@ export default function PathCreator() {
|
||||
pathId: MathUtils.generateUUID(),
|
||||
pathPoints: [draftPoints[0], newPoint],
|
||||
};
|
||||
|
||||
setPaths((prev) => [...prev, newPath]);
|
||||
setPaths([...paths, newPath]);
|
||||
setDraftPoints([newPoint]);
|
||||
}
|
||||
};
|
||||
@@ -322,7 +344,8 @@ export default function PathCreator() {
|
||||
const allPoints = useMemo(() => {
|
||||
const points: PointData[] = [];
|
||||
const seen = new Set<string>();
|
||||
paths.forEach((path) => {
|
||||
console.log("paths: ", paths);
|
||||
paths?.forEach((path: PathDataInterface) => {
|
||||
path.pathPoints.forEach((p) => {
|
||||
if (!seen.has(p.pointId)) {
|
||||
seen.add(p.pointId);
|
||||
@@ -334,8 +357,10 @@ export default function PathCreator() {
|
||||
}, [paths]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("allPoints: ", allPoints);
|
||||
console.log("paths ", paths);
|
||||
localStorage.setItem("paths", JSON.stringify(paths));
|
||||
}, [paths]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Draft points (red) */}
|
||||
@@ -358,6 +383,8 @@ export default function PathCreator() {
|
||||
setHoveredPoint={setHoveredPoint}
|
||||
hoveredLine={hoveredLine}
|
||||
hoveredPoint={hoveredPoint}
|
||||
selected={selectedPointIndices}
|
||||
setSelected={setSelectedPointIndices}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -372,7 +399,7 @@ export default function PathCreator() {
|
||||
)}
|
||||
|
||||
{/* Permanent paths */}
|
||||
{paths.map((path) => (
|
||||
{paths.map((path: PathDataInterface) => (
|
||||
<PathHandler
|
||||
key={path.pathId}
|
||||
selectedPath={path}
|
||||
|
||||
@@ -55,14 +55,17 @@ export default function PathHandler({
|
||||
const [start, end] = points.map((p) => new Vector3(...p.position));
|
||||
return new LineCurve3(start, end);
|
||||
}, [points]);
|
||||
|
||||
const removePath = (pathId: string) => {
|
||||
setPaths((prevPaths) => prevPaths.filter((p) => p.pathId !== pathId));
|
||||
};
|
||||
|
||||
const handlePathClick = (pointId: string) => {
|
||||
if (toolMode === "3D-Delete") {
|
||||
removePath(pointId);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragStart = (points: [PointData, PointData]) => {
|
||||
if (activeTool !== "cursor") return;
|
||||
const intersectionPoint = new Vector3();
|
||||
@@ -77,6 +80,7 @@ export default function PathHandler({
|
||||
setInitialPositions({ paths: pathSet });
|
||||
}
|
||||
};
|
||||
|
||||
// const handleDrag = (points: [PointData, PointData]) => {
|
||||
// if (isHovered && dragOffset) {
|
||||
// const intersectionPoint = new Vector3();
|
||||
@@ -106,7 +110,7 @@ export default function PathHandler({
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
const handleDrag = (points: [PointData, PointData]) => {
|
||||
if (isHovered && dragOffset) {
|
||||
const intersectionPoint = new Vector3();
|
||||
@@ -135,13 +139,14 @@ export default function PathHandler({
|
||||
];
|
||||
|
||||
// ✅ Move both points separately (won’t overwrite other updates)
|
||||
setPathPosition(points[0].pointId, newStart, setPaths);
|
||||
setPathPosition(points[1].pointId, newEnd, setPaths);
|
||||
setPathPosition(points[0].pointId, newStart, setPaths, paths);
|
||||
setPathPosition(points[1].pointId, newEnd, setPaths, paths);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleDragEnd = (points: [PointData, PointData]) => {};
|
||||
|
||||
return (
|
||||
<>
|
||||
<DragControls
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
import { DragControls } from "@react-three/drei";
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useActiveTool, useToolMode } from "../../../../store/builder/store";
|
||||
import { Plane, Vector3 } from "three";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { DragControls, Line } from "@react-three/drei";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import {
|
||||
useActiveTool,
|
||||
useCreatedPaths,
|
||||
useToolMode,
|
||||
} from "../../../../store/builder/store";
|
||||
import { CubicBezierCurve3, Plane, Quaternion, Vector3 } from "three";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { handleCanvasCursors } from "../../../../utils/mouseUtils/handleCanvasCursors";
|
||||
import { getPathsByPointId, setPathPosition } from "./function/getPaths";
|
||||
import { aStar } from "../structuredPath/functions/aStar";
|
||||
import {
|
||||
useAnimationPlaySpeed,
|
||||
usePlayButtonStore,
|
||||
} from "../../../../store/usePlayButtonStore";
|
||||
import { useSceneContext } from "../../../scene/sceneContext";
|
||||
import { usePathManager } from "./function/usePathManager";
|
||||
type PointData = {
|
||||
pointId: string;
|
||||
position: [number, number, number];
|
||||
@@ -31,6 +47,8 @@ type PointHandlerProps = {
|
||||
hoveredLine: PathDataInterface | null;
|
||||
pointIndex: any;
|
||||
points: PointData[];
|
||||
selected: number[];
|
||||
setSelected: React.Dispatch<React.SetStateAction<number[]>>;
|
||||
};
|
||||
function dist(a: PointData, b: PointData): number {
|
||||
return Math.sqrt(
|
||||
@@ -39,6 +57,13 @@ function dist(a: PointData, b: PointData): number {
|
||||
(a.position[2] - b.position[2]) ** 2
|
||||
);
|
||||
}
|
||||
type SegmentPoint = {
|
||||
position: Vector3;
|
||||
originalPoint?: PointData;
|
||||
pathId?: string;
|
||||
startId?: string;
|
||||
endId?: string;
|
||||
};
|
||||
|
||||
/** --- A* Algorithm --- */
|
||||
type AStarResult = {
|
||||
@@ -153,16 +178,31 @@ function nodePathToEdges(
|
||||
|
||||
return edges;
|
||||
}
|
||||
type VehicleDetails = {
|
||||
vehicleId: string;
|
||||
vehiclePosition: [number, number, number];
|
||||
};
|
||||
type Manager = {
|
||||
pathId: string;
|
||||
vehicleId: string;
|
||||
};
|
||||
export default function PointHandler({
|
||||
point,
|
||||
setPaths,
|
||||
paths,
|
||||
// setPaths,
|
||||
// paths,
|
||||
setHoveredPoint,
|
||||
hoveredLine,
|
||||
hoveredPoint,
|
||||
pointIndex,
|
||||
points,
|
||||
setSelected,
|
||||
selected,
|
||||
}: PointHandlerProps) {
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const [multiPaths, setMultiPaths] = useState<
|
||||
{ id: number; path: PathData }[]
|
||||
>([]);
|
||||
const pathIdRef = useRef(1); // To ensure unique incremental IDs
|
||||
const { toolMode } = useToolMode();
|
||||
const { activeTool } = useActiveTool();
|
||||
const { scene, raycaster } = useThree();
|
||||
@@ -172,29 +212,82 @@ export default function PointHandler({
|
||||
const [initialPositions, setInitialPositions] = useState<{
|
||||
paths?: any;
|
||||
}>({});
|
||||
const [selectedPoints, setSelectedPoints] = useState<PointData[]>([]);
|
||||
const [shortestEdges, setShortestEdges] = useState<PathData>([]);
|
||||
const [shortestPaths, setShortestPaths] = useState<PathData>([]);
|
||||
const POINT_SNAP_THRESHOLD = 0.5; // Distance threshold for snapping in meters
|
||||
const [selectedPointIndices, setSelectedPointIndices] = useState<number[]>(
|
||||
[]
|
||||
);
|
||||
const [vehicleUuids, setVehicleUuids] = useState<any>();
|
||||
const CAN_POINT_SNAP = true;
|
||||
const CAN_ANGLE_SNAP = true;
|
||||
const ANGLE_SNAP_DISTANCE_THRESHOLD = 0.5;
|
||||
const [selectedPointIndices, setSelectedPointIndices] = useState<number[]>(
|
||||
[]
|
||||
);
|
||||
const [shortestEdges, setShortestEdges] = useState<PathData>([]);
|
||||
const { speed } = useAnimationPlaySpeed();
|
||||
const { assetStore } = useSceneContext();
|
||||
const { assets } = assetStore();
|
||||
const vehicleMovementState = useRef<any>({});
|
||||
const [activeVehicleIndex, setActiveVehicleIndex] = useState(0);
|
||||
const [vehicleData, setVehicleData] = useState<VehicleDetails[]>([]);
|
||||
const { paths, setPaths } = useCreatedPaths();
|
||||
const [managerData, setManagerData] = useState<Manager>();
|
||||
// useEffect(() => {
|
||||
// const findVehicle = assets
|
||||
// .filter((val) => val.eventData?.type === "Vehicle")
|
||||
// ?.map((val) => val.modelUuid);
|
||||
|
||||
//
|
||||
// setVehicleUuids(findVehicle);
|
||||
|
||||
// vehicleMovementState.current = {};
|
||||
// findVehicle.forEach((uuid) => {
|
||||
// vehicleMovementState.current[uuid] = { index: 0, progress: 0 };
|
||||
// });
|
||||
// }, [assets]);
|
||||
useEffect(() => {
|
||||
const findVehicle = assets
|
||||
.filter((val) => val.eventData?.type === "Vehicle")
|
||||
?.map((val) => val.modelUuid);
|
||||
const findVehicleDatas = assets
|
||||
.filter((val) => val.eventData?.type === "Vehicle")
|
||||
?.map((val) => val);
|
||||
findVehicleDatas.forEach((val) => {
|
||||
const vehicledId = val.modelUuid;
|
||||
const vehiclePosition: [number, number, number] = val.position;
|
||||
|
||||
setVehicleData((prev) => [
|
||||
...prev,
|
||||
{ vehicleId: vehicledId, vehiclePosition },
|
||||
]);
|
||||
});
|
||||
|
||||
setVehicleUuids(findVehicle);
|
||||
setActiveVehicleIndex(0); // Reset to first vehicle
|
||||
|
||||
vehicleMovementState.current = {};
|
||||
findVehicle.forEach((uuid) => {
|
||||
vehicleMovementState.current[uuid] = {
|
||||
index: 0,
|
||||
progress: 0,
|
||||
hasStarted: false,
|
||||
};
|
||||
});
|
||||
}, [assets]);
|
||||
|
||||
const removePathByPoint = (pointId: string): PathDataInterface[] => {
|
||||
const removedPaths: PathDataInterface[] = [];
|
||||
|
||||
setPaths((prevPaths) =>
|
||||
prevPaths.filter((path) => {
|
||||
const hasPoint = path.pathPoints.some((p) => p.pointId === pointId);
|
||||
if (hasPoint) {
|
||||
removedPaths.push(JSON.parse(JSON.stringify(path))); // keep a copy
|
||||
return false; // remove this path
|
||||
}
|
||||
return true; // keep this path
|
||||
})
|
||||
);
|
||||
const newPaths = paths.filter((path: PathDataInterface) => {
|
||||
const hasPoint = path.pathPoints.some(
|
||||
(p: PointData) => p.pointId === pointId
|
||||
);
|
||||
if (hasPoint) {
|
||||
removedPaths.push(JSON.parse(JSON.stringify(path))); // keep a copy
|
||||
return false; // remove this path
|
||||
}
|
||||
return true; // keep this path
|
||||
});
|
||||
|
||||
setPaths(newPaths);
|
||||
|
||||
return removedPaths;
|
||||
};
|
||||
@@ -288,8 +381,8 @@ export default function PointHandler({
|
||||
|
||||
const getAllOtherPathPoints = useCallback((): PointData[] => {
|
||||
return (
|
||||
paths?.flatMap((path) =>
|
||||
path.pathPoints.filter((pt) => pt.pointId !== point.pointId)
|
||||
paths?.flatMap((path: PathDataInterface) =>
|
||||
path.pathPoints.filter((pt: PointData) => pt.pointId !== point.pointId)
|
||||
) ?? []
|
||||
);
|
||||
}, [paths]);
|
||||
@@ -317,43 +410,7 @@ export default function PointHandler({
|
||||
},
|
||||
[getAllOtherPathPoints]
|
||||
);
|
||||
let isHandlingShiftClick = false;
|
||||
|
||||
// const handlePointClick = (e: any, point: PointData) => {
|
||||
// if (toolMode === "3D-Delete") {
|
||||
// removePathByPoint(point.pointId);
|
||||
// }
|
||||
// if (e.shiftKey) {
|
||||
// setSelectedPointIndices((prev) => {
|
||||
// if (prev.length === 0) return [pointIndex];
|
||||
// if (prev.length === 1) {
|
||||
// // defer shortest path calculation
|
||||
// setTimeout(() => {
|
||||
// console.log("points: ", points);
|
||||
// const p1 = points[prev[0]];
|
||||
// console.log(' p1: ', p1);
|
||||
// const p2 = points[pointIndex];
|
||||
// console.log('p2: ', p2);
|
||||
// const result = aStarShortestPath(
|
||||
// p1.pointId,
|
||||
// p2.pointId,
|
||||
// points,
|
||||
// paths
|
||||
// );
|
||||
// if (result) {
|
||||
// const edges = nodePathToEdges(result.pointIds, points, paths);
|
||||
// console.log("edges: ", edges);
|
||||
// setShortestEdges(edges);
|
||||
// } else {
|
||||
// setShortestEdges([]);
|
||||
// }
|
||||
// }, 0);
|
||||
// return [prev[0], pointIndex];
|
||||
// }
|
||||
// return [pointIndex];
|
||||
// });
|
||||
// }
|
||||
// };
|
||||
const handlePointClick = (e: any, point: PointData) => {
|
||||
e.stopPropagation();
|
||||
if (toolMode === "3D-Delete") {
|
||||
@@ -362,53 +419,82 @@ export default function PointHandler({
|
||||
}
|
||||
|
||||
if (e.shiftKey) {
|
||||
if (isHandlingShiftClick) return; // prevent double-handling
|
||||
isHandlingShiftClick = true;
|
||||
|
||||
setTimeout(() => {
|
||||
isHandlingShiftClick = false;
|
||||
}, 100); // reset the flag after a short delay
|
||||
|
||||
setSelectedPointIndices((prev) => {
|
||||
// console.log("Clicked point index:", pointIndex);
|
||||
console.log("Previous selection:", prev);
|
||||
const pointIndex = points.findIndex((p) => p.pointId === point.pointId);
|
||||
if (pointIndex === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSelected((prev) => {
|
||||
if (prev.length === 0) {
|
||||
console.log("first works");
|
||||
return [pointIndex];
|
||||
}
|
||||
// if (prev.length === 1) {
|
||||
// setTimeout(() => {
|
||||
//
|
||||
// const prevPoint = points[prev[0]];
|
||||
//
|
||||
// const newPoint = points[pointIndex];
|
||||
//
|
||||
// const result = aStarShortestPath(
|
||||
// prevPoint.pointId,
|
||||
// newPoint.pointId,
|
||||
// points,
|
||||
// paths
|
||||
// );
|
||||
|
||||
// if (result) {
|
||||
// const edges = nodePathToEdges(result.pointIds, points, paths);
|
||||
//
|
||||
// setShortestPaths(edges);
|
||||
// setShortestEdges(edges);
|
||||
// } else {
|
||||
// setShortestPaths([]);
|
||||
// setShortestEdges([]);
|
||||
// }
|
||||
// if (prevPoint.pointId === newPoint.pointId) {
|
||||
// return prev;
|
||||
// }
|
||||
// }, 0);
|
||||
|
||||
// return [prev[0], pointIndex];
|
||||
// }
|
||||
|
||||
// More than two points — reset
|
||||
if (prev.length === 1) {
|
||||
if (prev[0] === pointIndex) {
|
||||
console.log("Same point selected twice — ignoring");
|
||||
return prev;
|
||||
}
|
||||
setTimeout(() => {
|
||||
const prevPoint = points[prev[0]];
|
||||
const newPoint = points[pointIndex];
|
||||
|
||||
const p1 = points[prev[0]];
|
||||
const p2 = points[pointIndex];
|
||||
if (prevPoint.pointId === newPoint.pointId) return;
|
||||
|
||||
console.log("Point 1:", p1);
|
||||
console.log("Point 2:", p2);
|
||||
|
||||
if (p1 && p2) {
|
||||
const result = aStarShortestPath(
|
||||
p1.pointId,
|
||||
p2.pointId,
|
||||
prevPoint.pointId,
|
||||
newPoint.pointId,
|
||||
points,
|
||||
paths
|
||||
);
|
||||
|
||||
if (result) {
|
||||
const edges = nodePathToEdges(result.pointIds, points, paths);
|
||||
|
||||
// Create a new path object
|
||||
const newPathObj = {
|
||||
id: pathIdRef.current++,
|
||||
path: edges,
|
||||
};
|
||||
setShortestPaths(edges);
|
||||
setShortestEdges(edges);
|
||||
} else {
|
||||
setShortestEdges([]);
|
||||
// Append it to the list of paths
|
||||
setMultiPaths((prevPaths) => [...prevPaths, newPathObj]);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset selection to allow new pair selection
|
||||
}, 0);
|
||||
|
||||
return [prev[0], pointIndex];
|
||||
}
|
||||
|
||||
setShortestPaths([]);
|
||||
return [pointIndex];
|
||||
});
|
||||
}
|
||||
@@ -426,6 +512,7 @@ export default function PointHandler({
|
||||
setInitialPositions({ paths: pathIntersection });
|
||||
}
|
||||
};
|
||||
|
||||
const handleDrag = (point: PointData) => {
|
||||
if (isHovered && dragOffset) {
|
||||
const intersectionPoint = new Vector3();
|
||||
@@ -442,7 +529,7 @@ export default function PointHandler({
|
||||
// ✅ Pass newPosition and pointId
|
||||
const pathSnapped = snapPathAngle(newPosition, point.pointId);
|
||||
const finalSnapped = snapPathPoint(pathSnapped.position);
|
||||
setPathPosition(point.pointId, finalSnapped.position, setPaths);
|
||||
setPathPosition(point.pointId, finalSnapped.position, setPaths, paths);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -454,10 +541,265 @@ export default function PointHandler({
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("selectedPoints: ", selectedPoints);
|
||||
}, [selectedPoints]);
|
||||
const pathSegments = useMemo(() => {
|
||||
if (!shortestPaths || shortestPaths.length === 0) return [];
|
||||
|
||||
const segments: SegmentPoint[] = [];
|
||||
|
||||
shortestPaths.forEach((path) => {
|
||||
const [start, end] = path.pathPoints;
|
||||
|
||||
const startPos = new Vector3(...start.position);
|
||||
const endPos = new Vector3(...end.position);
|
||||
|
||||
segments.push(
|
||||
{ position: startPos, originalPoint: start, startId: start.pointId },
|
||||
{ position: endPos, originalPoint: end, endId: end.pointId }
|
||||
);
|
||||
});
|
||||
|
||||
return segments.filter(
|
||||
(v, i, arr) => i === 0 || !v.position.equals(arr[i - 1].position)
|
||||
);
|
||||
}, [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,
|
||||
endId: string | undefined,
|
||||
shortestPaths: any[]
|
||||
) {
|
||||
for (const path of shortestPaths) {
|
||||
for (let i = 0; i < path.pathPoints.length - 1; i++) {
|
||||
const s = path.pathPoints[i];
|
||||
const e = path.pathPoints[i + 1];
|
||||
|
||||
if (
|
||||
(s.pointId === startId && e.pointId === endId) ||
|
||||
(s.pointId === endId && e.pointId === startId) // handle both directions
|
||||
) {
|
||||
return path.pathId;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; // not found
|
||||
}
|
||||
|
||||
//
|
||||
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;
|
||||
|
||||
// Step 1: Move vehicle to the start of the path
|
||||
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; // start path animation next frame
|
||||
return;
|
||||
}
|
||||
|
||||
// Move toward path start
|
||||
const direction = pathStart.clone().sub(object.position);
|
||||
const distance = direction.length();
|
||||
|
||||
if (distance > step) {
|
||||
direction.normalize();
|
||||
object.position.add(direction.clone().multiplyScalar(step));
|
||||
|
||||
// ROTATE toward direction of movement
|
||||
const forward = new Vector3(0, 0, 1); // <-- adjust this based on your model
|
||||
const targetQuat = new Quaternion().setFromUnitVectors(
|
||||
forward,
|
||||
direction
|
||||
);
|
||||
object.quaternion.slerp(targetQuat, 0.1); // smooth rotation
|
||||
} else {
|
||||
// Snap to start segment when close enough
|
||||
object.position.copy(pathStart);
|
||||
object.quaternion.identity(); // reset orientation or leave as-is
|
||||
vehicleMovementState.current[uuid] = { index: 0, progress: 0 };
|
||||
}
|
||||
|
||||
return; // still approaching start
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// Path complete
|
||||
state.index = 0;
|
||||
state.progress = 0;
|
||||
state.hasStarted = false; // reset for next loop
|
||||
object.position.copy(vehicleStartPos); // go back to start
|
||||
object.quaternion.identity();
|
||||
|
||||
// Move to next vehicle
|
||||
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 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);
|
||||
// });
|
||||
useEffect(() => {}, [multiPaths]);
|
||||
const manager = usePathManager(managerData?.pathId, managerData?.vehicleId);
|
||||
|
||||
useEffect(() => {
|
||||
// if (managerData) {
|
||||
// console.log("manager: ", manager);
|
||||
// }
|
||||
}, [managerData]);
|
||||
return (
|
||||
<>
|
||||
<DragControls
|
||||
@@ -496,6 +838,14 @@ export default function PointHandler({
|
||||
<meshBasicMaterial color="pink" />
|
||||
</mesh>
|
||||
</DragControls>
|
||||
{shortestEdges.map((edge) => (
|
||||
<Line
|
||||
key={`sp-${edge.pathId}`}
|
||||
points={edge.pathPoints.map((p) => p.position)}
|
||||
color="yellow"
|
||||
lineWidth={3}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -446,7 +446,7 @@ type PointData = {
|
||||
|
||||
interface PathDataInterface {
|
||||
pathId: string;
|
||||
pathPoints: [PointData, PointData]; // always two points
|
||||
pathPoints: [PointData, PointData];
|
||||
}
|
||||
|
||||
type PathData = PathDataInterface[];
|
||||
@@ -602,7 +602,7 @@ export default function PointHandlers({
|
||||
const handleARef = useRef<THREE.Mesh>(null);
|
||||
const handleBRef = useRef<THREE.Mesh>(null);
|
||||
const lineRef = useRef<any>(null);
|
||||
const { gl, controls, raycaster } = useThree();
|
||||
const { gl, controls, raycaster } = useThree();
|
||||
|
||||
const [dragging, setDragging] = useState<
|
||||
null | "main" | "handleA" | "handleB"
|
||||
@@ -616,11 +616,13 @@ export default function PointHandlers({
|
||||
|
||||
if (e.shiftKey) {
|
||||
setSelected((prev) => {
|
||||
console.log("prev: ", prev);
|
||||
console.log("pointIndex: ", pointIndex);
|
||||
if (prev.length === 0) return [pointIndex];
|
||||
if (prev.length === 1) {
|
||||
// defer shortest path calculation
|
||||
setTimeout(() => {
|
||||
console.log('points: ', points);
|
||||
console.log("points: ", points);
|
||||
const p1 = points[prev[0]];
|
||||
const p2 = points[pointIndex];
|
||||
const result = aStarShortestPath(
|
||||
@@ -631,7 +633,7 @@ export default function PointHandlers({
|
||||
);
|
||||
if (result) {
|
||||
const edges = nodePathToEdges(result.pointIds, points, paths);
|
||||
console.log('edges: ', edges);
|
||||
console.log("edges: ", edges);
|
||||
setShortestEdges(edges);
|
||||
setShortestPath(edges);
|
||||
} else {
|
||||
@@ -767,6 +769,8 @@ export default function PointHandlers({
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Main point */}
|
||||
|
||||
@@ -33,7 +33,7 @@ function Vehicles() {
|
||||
<PathCreator />
|
||||
{/* <StructuredPath /> */}
|
||||
{/* <PreDefinedPath /> */}
|
||||
{/* <VehicleInstances /> */}
|
||||
<VehicleInstances />
|
||||
{isVehicleSelected && selectedEventSphere && !isPlaying && <VehicleUI />}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4,74 +4,74 @@ import { io } from "socket.io-client";
|
||||
import * as CONSTANTS from "../../types/world/worldConstants";
|
||||
|
||||
export const useSocketStore = create<any>((set: any, get: any) => ({
|
||||
socket: null,
|
||||
initializeSocket: (
|
||||
email?: string,
|
||||
organization?: string,
|
||||
token?: string,
|
||||
refreshToken?: string
|
||||
) => {
|
||||
const existingSocket = get().socket;
|
||||
if (existingSocket) {
|
||||
return;
|
||||
}
|
||||
socket: null,
|
||||
initializeSocket: (
|
||||
email?: string,
|
||||
organization?: string,
|
||||
token?: string,
|
||||
refreshToken?: string
|
||||
) => {
|
||||
const existingSocket = get().socket;
|
||||
if (existingSocket) {
|
||||
return;
|
||||
}
|
||||
|
||||
const socket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
const socket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Builder_v1`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
|
||||
const visualizationSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
const visualizationSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/Visualization_v1`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
|
||||
const dashBoardSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
const projectSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
const threadSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/thread`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
const dashBoardSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/dashboard`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
const projectSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/project`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
const threadSocket = io(
|
||||
`http://${process.env.REACT_APP_SERVER_SOCKET_API_BASE_URL}/thread`,
|
||||
{
|
||||
reconnection: true,
|
||||
auth: { token, refreshToken },
|
||||
}
|
||||
);
|
||||
|
||||
set({
|
||||
socket,
|
||||
visualizationSocket,
|
||||
dashBoardSocket,
|
||||
projectSocket,
|
||||
threadSocket,
|
||||
});
|
||||
},
|
||||
disconnectSocket: () => {
|
||||
set((state: any) => {
|
||||
state.socket?.disconnect();
|
||||
state.visualizationSocket?.disconnect();
|
||||
state.dashBoardSocket?.disconnect();
|
||||
state.projectSocket?.disconnect();
|
||||
state.threadSocket?.disconnect();
|
||||
return { socket: null };
|
||||
});
|
||||
},
|
||||
set({
|
||||
socket,
|
||||
visualizationSocket,
|
||||
dashBoardSocket,
|
||||
projectSocket,
|
||||
threadSocket,
|
||||
});
|
||||
},
|
||||
disconnectSocket: () => {
|
||||
set((state: any) => {
|
||||
state.socket?.disconnect();
|
||||
state.visualizationSocket?.disconnect();
|
||||
state.dashBoardSocket?.disconnect();
|
||||
state.projectSocket?.disconnect();
|
||||
state.threadSocket?.disconnect();
|
||||
return { socket: null };
|
||||
});
|
||||
},
|
||||
}));
|
||||
// export const useSocketStore = create<any>((set: any, get: any) => ({
|
||||
// socket: null,
|
||||
@@ -129,516 +129,543 @@ export const useSocketStore = create<any>((set: any, get: any) => ({
|
||||
// },
|
||||
// }));
|
||||
export const useLoadingProgress = create<{
|
||||
loadingProgress: number;
|
||||
setLoadingProgress: (x: number) => void;
|
||||
loadingProgress: number;
|
||||
setLoadingProgress: (x: number) => void;
|
||||
}>((set) => ({
|
||||
loadingProgress: 1,
|
||||
setLoadingProgress: (x: number) => set({ loadingProgress: x }),
|
||||
loadingProgress: 1,
|
||||
setLoadingProgress: (x: number) => set({ loadingProgress: x }),
|
||||
}));
|
||||
|
||||
export const useOrganization = create<any>((set: any) => ({
|
||||
organization: "",
|
||||
setOrganization: (x: any) => set(() => ({ organization: x })),
|
||||
organization: "",
|
||||
setOrganization: (x: any) => set(() => ({ organization: x })),
|
||||
}));
|
||||
|
||||
export const useToggleView = create<any>((set: any) => ({
|
||||
toggleView: false,
|
||||
setToggleView: (x: any) => set(() => ({ toggleView: x })),
|
||||
toggleView: false,
|
||||
setToggleView: (x: any) => set(() => ({ toggleView: x })),
|
||||
}));
|
||||
|
||||
export const useRoomsState = create<any>((set: any) => ({
|
||||
roomsState: [],
|
||||
setRoomsState: (x: any) => set(() => ({ roomsState: x })),
|
||||
roomsState: [],
|
||||
setRoomsState: (x: any) => set(() => ({ roomsState: x })),
|
||||
}));
|
||||
|
||||
export const useSelectedItem = create<any>((set: any) => ({
|
||||
selectedItem: {
|
||||
name: "",
|
||||
id: "",
|
||||
type: undefined,
|
||||
category: "",
|
||||
subType: "",
|
||||
},
|
||||
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
|
||||
selectedItem: {
|
||||
name: "",
|
||||
id: "",
|
||||
type: undefined,
|
||||
category: "",
|
||||
subType: "",
|
||||
},
|
||||
setSelectedItem: (x: any) => set(() => ({ selectedItem: x })),
|
||||
}));
|
||||
|
||||
export const useNavMesh = create<any>((set: any) => ({
|
||||
navMesh: null,
|
||||
setNavMesh: (x: any) => set({ navMesh: x }),
|
||||
navMesh: null,
|
||||
setNavMesh: (x: any) => set({ navMesh: x }),
|
||||
}));
|
||||
|
||||
type SelectedAssetsState = {
|
||||
selectedAssets: Object3D[];
|
||||
setSelectedAssets: (assets: Object3D[]) => void;
|
||||
selectedAssets: Object3D[];
|
||||
setSelectedAssets: (assets: Object3D[]) => void;
|
||||
};
|
||||
|
||||
export const useSelectedAssets = create<SelectedAssetsState>((set) => ({
|
||||
selectedAssets: [],
|
||||
setSelectedAssets: (assets) => set({ selectedAssets: assets }),
|
||||
selectedAssets: [],
|
||||
setSelectedAssets: (assets) => set({ selectedAssets: assets }),
|
||||
}));
|
||||
|
||||
export const useLayers = create<any>((set: any) => ({
|
||||
Layers: 1,
|
||||
setLayers: (x: any) => set(() => ({ Layers: x })),
|
||||
Layers: 1,
|
||||
setLayers: (x: any) => set(() => ({ Layers: x })),
|
||||
}));
|
||||
|
||||
export const useCamPosition = create<any>((set: any) => ({
|
||||
camPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }),
|
||||
camPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setCamPosition: (newCamPosition: any) => set({ camPosition: newCamPosition }),
|
||||
}));
|
||||
|
||||
export const useMenuVisible = create<any>((set: any) => ({
|
||||
menuVisible: false,
|
||||
setMenuVisible: (x: any) => set(() => ({ menuVisible: x })),
|
||||
menuVisible: false,
|
||||
setMenuVisible: (x: any) => set(() => ({ menuVisible: x })),
|
||||
}));
|
||||
|
||||
export const useToolMode = create<any>((set: any) => ({
|
||||
toolMode: null,
|
||||
setToolMode: (x: any) => set(() => ({ toolMode: x })),
|
||||
toolMode: null,
|
||||
setToolMode: (x: any) => set(() => ({ toolMode: x })),
|
||||
}));
|
||||
|
||||
export const useSelectedWallItem = create<any>((set: any) => ({
|
||||
selectedWallItem: null,
|
||||
setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })),
|
||||
selectedWallItem: null,
|
||||
setSelectedWallItem: (x: any) => set(() => ({ selectedWallItem: x })),
|
||||
}));
|
||||
|
||||
export const useSelectedFloorItem = create<any>((set: any) => ({
|
||||
selectedFloorItem: null,
|
||||
setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })),
|
||||
selectedFloorItem: null,
|
||||
setSelectedFloorItem: (x: any) => set(() => ({ selectedFloorItem: x })),
|
||||
}));
|
||||
|
||||
export const useDeletableFloorItem = create<any>((set: any) => ({
|
||||
deletableFloorItem: null,
|
||||
setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })),
|
||||
deletableFloorItem: null,
|
||||
setDeletableFloorItem: (x: any) => set(() => ({ deletableFloorItem: x })),
|
||||
}));
|
||||
|
||||
export const useSetScale = create<any>((set: any) => ({
|
||||
scale: null,
|
||||
setScale: (x: any) => set(() => ({ scale: x })),
|
||||
scale: null,
|
||||
setScale: (x: any) => set(() => ({ scale: x })),
|
||||
}));
|
||||
|
||||
export const useRoofVisibility = create<any>((set: any) => ({
|
||||
roofVisibility: false,
|
||||
setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })),
|
||||
roofVisibility: false,
|
||||
setRoofVisibility: (x: any) => set(() => ({ roofVisibility: x })),
|
||||
}));
|
||||
|
||||
export const useWallVisibility = create<any>((set: any) => ({
|
||||
wallVisibility: false,
|
||||
setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })),
|
||||
wallVisibility: false,
|
||||
setWallVisibility: (x: any) => set(() => ({ wallVisibility: x })),
|
||||
}));
|
||||
|
||||
export const useShadows = create<any>((set: any) => ({
|
||||
shadows: false,
|
||||
setShadows: (x: any) => set(() => ({ shadows: x })),
|
||||
shadows: false,
|
||||
setShadows: (x: any) => set(() => ({ shadows: x })),
|
||||
}));
|
||||
|
||||
export const useSunPosition = create<any>((set: any) => ({
|
||||
sunPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setSunPosition: (newSuntPosition: any) =>
|
||||
set({ sunPosition: newSuntPosition }),
|
||||
sunPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setSunPosition: (newSuntPosition: any) =>
|
||||
set({ sunPosition: newSuntPosition }),
|
||||
}));
|
||||
|
||||
export const useRemoveLayer = create<any>((set: any) => ({
|
||||
removeLayer: false,
|
||||
setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })),
|
||||
removeLayer: false,
|
||||
setRemoveLayer: (x: any) => set(() => ({ removeLayer: x })),
|
||||
}));
|
||||
|
||||
export const useRemovedLayer = create<any>((set: any) => ({
|
||||
removedLayer: null,
|
||||
setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })),
|
||||
removedLayer: null,
|
||||
setRemovedLayer: (x: any) => set(() => ({ removedLayer: x })),
|
||||
}));
|
||||
|
||||
export const useProjectName = create<any>((set: any) => ({
|
||||
projectName: "Creating Your Project",
|
||||
setProjectName: (x: any) => set({ projectName: x }),
|
||||
projectName: "Creating Your Project",
|
||||
setProjectName: (x: any) => set({ projectName: x }),
|
||||
}));
|
||||
|
||||
export const useActiveLayer = create<any>((set: any) => ({
|
||||
activeLayer: 1,
|
||||
setActiveLayer: (x: any) => set({ activeLayer: x }),
|
||||
activeLayer: 1,
|
||||
setActiveLayer: (x: any) => set({ activeLayer: x }),
|
||||
}));
|
||||
|
||||
export const useResetCamera = create<any>((set: any) => ({
|
||||
resetCamera: false,
|
||||
setResetCamera: (x: any) => set({ resetCamera: x }),
|
||||
resetCamera: false,
|
||||
setResetCamera: (x: any) => set({ resetCamera: x }),
|
||||
}));
|
||||
|
||||
export const useAddAction = create<any>((set: any) => ({
|
||||
addAction: null,
|
||||
setAddAction: (x: any) => set({ addAction: x }),
|
||||
addAction: null,
|
||||
setAddAction: (x: any) => set({ addAction: x }),
|
||||
}));
|
||||
|
||||
export const useActiveTool = create<any>((set: any) => ({
|
||||
activeTool: "cursor",
|
||||
setActiveTool: (x: any) => set({ activeTool: x }),
|
||||
activeTool: "cursor",
|
||||
setActiveTool: (x: any) => set({ activeTool: x }),
|
||||
}));
|
||||
|
||||
export const useActiveSubTool = create<any>((set: any) => ({
|
||||
activeSubTool: "cursor",
|
||||
setActiveSubTool: (x: any) => set({ activeSubTool: x }),
|
||||
activeSubTool: "cursor",
|
||||
setActiveSubTool: (x: any) => set({ activeSubTool: x }),
|
||||
}));
|
||||
|
||||
export const useElevation = create<any>((set: any) => ({
|
||||
elevation: 45,
|
||||
setElevation: (x: any) => set({ elevation: x }),
|
||||
elevation: 45,
|
||||
setElevation: (x: any) => set({ elevation: x }),
|
||||
}));
|
||||
|
||||
export const useAzimuth = create<any>((set: any) => ({
|
||||
azimuth: -160,
|
||||
setAzimuth: (x: any) => set({ azimuth: x }),
|
||||
azimuth: -160,
|
||||
setAzimuth: (x: any) => set({ azimuth: x }),
|
||||
}));
|
||||
|
||||
export const useRenderDistance = create<any>((set: any) => ({
|
||||
renderDistance: 40,
|
||||
setRenderDistance: (x: any) => set({ renderDistance: x }),
|
||||
renderDistance: 40,
|
||||
setRenderDistance: (x: any) => set({ renderDistance: x }),
|
||||
}));
|
||||
|
||||
export const useCamMode = create<any>((set: any) => ({
|
||||
camMode: "ThirdPerson",
|
||||
setCamMode: (x: any) => set({ camMode: x }),
|
||||
camMode: "ThirdPerson",
|
||||
setCamMode: (x: any) => set({ camMode: x }),
|
||||
}));
|
||||
|
||||
export const useUserName = create<any>((set: any) => ({
|
||||
userName: "",
|
||||
setUserName: (x: any) => set({ userName: x }),
|
||||
userName: "",
|
||||
setUserName: (x: any) => set({ userName: x }),
|
||||
}));
|
||||
|
||||
export const useRenameModeStore = create<any>((set: any) => ({
|
||||
isRenameMode: false,
|
||||
setIsRenameMode: (state: boolean) => set({ isRenameMode: state }),
|
||||
isRenameMode: false,
|
||||
setIsRenameMode: (state: boolean) => set({ isRenameMode: state }),
|
||||
}));
|
||||
|
||||
export const useObjectPosition = create<any>((set: any) => ({
|
||||
objectPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectPosition: (newObjectPosition: any) =>
|
||||
set({ objectPosition: newObjectPosition }),
|
||||
objectPosition: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectPosition: (newObjectPosition: any) =>
|
||||
set({ objectPosition: newObjectPosition }),
|
||||
}));
|
||||
|
||||
export const useObjectRotation = create<any>((set: any) => ({
|
||||
objectRotation: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectRotation: (newObjectRotation: any) =>
|
||||
set({ objectRotation: newObjectRotation }),
|
||||
objectRotation: { x: undefined, y: undefined, z: undefined },
|
||||
setObjectRotation: (newObjectRotation: any) =>
|
||||
set({ objectRotation: newObjectRotation }),
|
||||
}));
|
||||
|
||||
export const useDrieTemp = create<any>((set: any) => ({
|
||||
drieTemp: undefined,
|
||||
setDrieTemp: (x: any) => set({ drieTemp: x }),
|
||||
drieTemp: undefined,
|
||||
setDrieTemp: (x: any) => set({ drieTemp: x }),
|
||||
}));
|
||||
|
||||
export const useActiveUsers = create<any>((set: any) => ({
|
||||
activeUsers: [],
|
||||
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
|
||||
set((state: { activeUsers: any[] }) => ({
|
||||
activeUsers:
|
||||
typeof callback === "function" ? callback(state.activeUsers) : callback,
|
||||
})),
|
||||
activeUsers: [],
|
||||
setActiveUsers: (callback: (prev: any[]) => any[] | any[]) =>
|
||||
set((state: { activeUsers: any[] }) => ({
|
||||
activeUsers:
|
||||
typeof callback === "function" ? callback(state.activeUsers) : callback,
|
||||
})),
|
||||
}));
|
||||
|
||||
export const useDrieUIValue = create<any>((set: any) => ({
|
||||
drieUIValue: { touch: null, temperature: null, humidity: null },
|
||||
drieUIValue: { touch: null, temperature: null, humidity: null },
|
||||
|
||||
setDrieUIValue: (x: any) =>
|
||||
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
|
||||
setDrieUIValue: (x: any) =>
|
||||
set((state: any) => ({ drieUIValue: { ...state.drieUIValue, ...x } })),
|
||||
|
||||
setTouch: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, touch: value },
|
||||
})),
|
||||
setTemperature: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, temperature: value },
|
||||
})),
|
||||
setHumidity: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, humidity: value },
|
||||
})),
|
||||
setTouch: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, touch: value },
|
||||
})),
|
||||
setTemperature: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, temperature: value },
|
||||
})),
|
||||
setHumidity: (value: any) =>
|
||||
set((state: any) => ({
|
||||
drieUIValue: { ...state.drieUIValue, humidity: value },
|
||||
})),
|
||||
}));
|
||||
|
||||
export const usezoneTarget = create<any>((set: any) => ({
|
||||
zoneTarget: [],
|
||||
setZoneTarget: (x: any) => set({ zoneTarget: x }),
|
||||
zoneTarget: [],
|
||||
setZoneTarget: (x: any) => set({ zoneTarget: x }),
|
||||
}));
|
||||
|
||||
export const usezonePosition = create<any>((set: any) => ({
|
||||
zonePosition: [],
|
||||
setZonePosition: (x: any) => set({ zonePosition: x }),
|
||||
zonePosition: [],
|
||||
setZonePosition: (x: any) => set({ zonePosition: x }),
|
||||
}));
|
||||
|
||||
interface EditPositionState {
|
||||
Edit: boolean;
|
||||
setEdit: (value: boolean) => void;
|
||||
Edit: boolean;
|
||||
setEdit: (value: boolean) => void;
|
||||
}
|
||||
|
||||
export const useEditPosition = create<EditPositionState>((set) => ({
|
||||
Edit: false,
|
||||
setEdit: (value) => set({ Edit: value }),
|
||||
Edit: false,
|
||||
setEdit: (value) => set({ Edit: value }),
|
||||
}));
|
||||
|
||||
export const useAsset3dWidget = create<any>((set: any) => ({
|
||||
widgetSelect: "",
|
||||
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
|
||||
widgetSelect: "",
|
||||
setWidgetSelect: (x: any) => set({ widgetSelect: x }),
|
||||
}));
|
||||
|
||||
export const useWidgetSubOption = create<any>((set: any) => ({
|
||||
widgetSubOption: "2D",
|
||||
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
|
||||
widgetSubOption: "2D",
|
||||
setWidgetSubOption: (x: any) => set({ widgetSubOption: x }),
|
||||
}));
|
||||
|
||||
export const useLimitDistance = create<any>((set: any) => ({
|
||||
limitDistance: true,
|
||||
setLimitDistance: (x: any) => set({ limitDistance: x }),
|
||||
limitDistance: true,
|
||||
setLimitDistance: (x: any) => set({ limitDistance: x }),
|
||||
}));
|
||||
|
||||
export const useTileDistance = create<any>((set: any) => ({
|
||||
gridValue: {
|
||||
size: CONSTANTS.gridConfig.size,
|
||||
divisions: CONSTANTS.gridConfig.divisions,
|
||||
},
|
||||
planeValue: {
|
||||
height: CONSTANTS.planeConfig.height,
|
||||
width: CONSTANTS.planeConfig.width,
|
||||
},
|
||||
gridValue: {
|
||||
size: CONSTANTS.gridConfig.size,
|
||||
divisions: CONSTANTS.gridConfig.divisions,
|
||||
},
|
||||
planeValue: {
|
||||
height: CONSTANTS.planeConfig.height,
|
||||
width: CONSTANTS.planeConfig.width,
|
||||
},
|
||||
|
||||
setGridValue: (value: any) =>
|
||||
set((state: any) => ({
|
||||
gridValue: { ...state.gridValue, ...value },
|
||||
})),
|
||||
setGridValue: (value: any) =>
|
||||
set((state: any) => ({
|
||||
gridValue: { ...state.gridValue, ...value },
|
||||
})),
|
||||
|
||||
setPlaneValue: (value: any) =>
|
||||
set((state: any) => ({
|
||||
planeValue: { ...state.planeValue, ...value },
|
||||
})),
|
||||
setPlaneValue: (value: any) =>
|
||||
set((state: any) => ({
|
||||
planeValue: { ...state.planeValue, ...value },
|
||||
})),
|
||||
}));
|
||||
|
||||
export const usePlayAgv = create<any>((set, get) => ({
|
||||
PlayAgv: [],
|
||||
setPlayAgv: (updateFn: (prev: any[]) => any[]) =>
|
||||
set({ PlayAgv: updateFn(get().PlayAgv) }),
|
||||
PlayAgv: [],
|
||||
setPlayAgv: (updateFn: (prev: any[]) => any[]) =>
|
||||
set({ PlayAgv: updateFn(get().PlayAgv) }),
|
||||
}));
|
||||
|
||||
// Define the Asset type
|
||||
type Asset = {
|
||||
id: string;
|
||||
name: string;
|
||||
position?: [number, number, number]; // Optional: 3D position
|
||||
rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation
|
||||
id: string;
|
||||
name: string;
|
||||
position?: [number, number, number]; // Optional: 3D position
|
||||
rotation?: { x: number; y: number; z: number }; // Optional: Euler rotation
|
||||
};
|
||||
|
||||
// Zustand store type
|
||||
type ZoneAssetState = {
|
||||
zoneAssetId: Asset | null;
|
||||
setZoneAssetId: (asset: Asset | null) => void;
|
||||
zoneAssetId: Asset | null;
|
||||
setZoneAssetId: (asset: Asset | null) => void;
|
||||
};
|
||||
|
||||
// Zustand store
|
||||
export const useZoneAssetId = create<ZoneAssetState>((set) => ({
|
||||
zoneAssetId: null,
|
||||
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
|
||||
zoneAssetId: null,
|
||||
setZoneAssetId: (asset) => set({ zoneAssetId: asset }),
|
||||
}));
|
||||
|
||||
// version visible hidden
|
||||
interface VersionHistoryState {
|
||||
viewVersionHistory: boolean;
|
||||
setVersionHistoryVisible: (value: boolean) => void;
|
||||
viewVersionHistory: boolean;
|
||||
setVersionHistoryVisible: (value: boolean) => void;
|
||||
}
|
||||
|
||||
const useVersionHistoryVisibleStore = create<VersionHistoryState>((set) => ({
|
||||
viewVersionHistory: false,
|
||||
setVersionHistoryVisible: (value) => set({ viewVersionHistory: value }),
|
||||
viewVersionHistory: false,
|
||||
setVersionHistoryVisible: (value) => set({ viewVersionHistory: value }),
|
||||
}));
|
||||
|
||||
export default useVersionHistoryVisibleStore;
|
||||
|
||||
interface ShortcutStore {
|
||||
showShortcuts: boolean;
|
||||
setShowShortcuts: (value: boolean) => void;
|
||||
toggleShortcuts: () => void;
|
||||
showShortcuts: boolean;
|
||||
setShowShortcuts: (value: boolean) => void;
|
||||
toggleShortcuts: () => void;
|
||||
}
|
||||
|
||||
export const useShortcutStore = create<ShortcutStore>((set) => ({
|
||||
showShortcuts: false,
|
||||
setShowShortcuts: (value) => set({ showShortcuts: value }),
|
||||
toggleShortcuts: () =>
|
||||
set((state) => ({ showShortcuts: !state.showShortcuts })),
|
||||
showShortcuts: false,
|
||||
setShowShortcuts: (value) => set({ showShortcuts: value }),
|
||||
toggleShortcuts: () =>
|
||||
set((state) => ({ showShortcuts: !state.showShortcuts })),
|
||||
}));
|
||||
|
||||
export const useMachineCount = create<any>((set: any) => ({
|
||||
machineCount: 0,
|
||||
setMachineCount: (x: any) => set({ machineCount: x }),
|
||||
machineCount: 0,
|
||||
setMachineCount: (x: any) => set({ machineCount: x }),
|
||||
}));
|
||||
export const useMachineUptime = create<any>((set: any) => ({
|
||||
machineActiveTime: 0,
|
||||
setMachineActiveTime: (x: any) => set({ machineActiveTime: x }),
|
||||
machineActiveTime: 0,
|
||||
setMachineActiveTime: (x: any) => set({ machineActiveTime: x }),
|
||||
}));
|
||||
export const useMachineDowntime = create<any>((set: any) => ({
|
||||
machineIdleTime: 0,
|
||||
setMachineIdleTime: (x: any) => set({ machineIdleTime: x }),
|
||||
machineIdleTime: 0,
|
||||
setMachineIdleTime: (x: any) => set({ machineIdleTime: x }),
|
||||
}));
|
||||
export const useMaterialCycle = create<any>((set: any) => ({
|
||||
materialCycleTime: 0,
|
||||
setMaterialCycleTime: (x: any) => set({ materialCycleTime: x }),
|
||||
materialCycleTime: 0,
|
||||
setMaterialCycleTime: (x: any) => set({ materialCycleTime: x }),
|
||||
}));
|
||||
|
||||
export const useThroughPutData = create<any>((set: any) => ({
|
||||
throughputData: 0,
|
||||
setThroughputData: (x: any) => set({ throughputData: x }),
|
||||
throughputData: 0,
|
||||
setThroughputData: (x: any) => set({ throughputData: x }),
|
||||
}));
|
||||
export const useProductionCapacityData = create<any>((set: any) => ({
|
||||
productionCapacityData: 0,
|
||||
setProductionCapacityData: (x: any) => set({ productionCapacityData: x }),
|
||||
productionCapacityData: 0,
|
||||
setProductionCapacityData: (x: any) => set({ productionCapacityData: x }),
|
||||
}));
|
||||
|
||||
export const useProcessBar = create<any>((set: any) => ({
|
||||
processBar: [],
|
||||
setProcessBar: (x: any) => set({ processBar: x }),
|
||||
processBar: [],
|
||||
setProcessBar: (x: any) => set({ processBar: x }),
|
||||
}));
|
||||
export const useDfxUpload = create<any>((set: any) => ({
|
||||
dfxuploaded: [],
|
||||
dfxWallGenerate: [],
|
||||
objValue: { x: 0, y: 0, z: 0 },
|
||||
setDfxUploaded: (x: any) => set({ dfxuploaded: x }),
|
||||
setDxfWallGenerate: (x: any) => set({ dfxWallGenerate: x }),
|
||||
setObjValue: (x: any) => set({ objValue: x }),
|
||||
dfxuploaded: [],
|
||||
dfxWallGenerate: [],
|
||||
objValue: { x: 0, y: 0, z: 0 },
|
||||
setDfxUploaded: (x: any) => set({ dfxuploaded: x }),
|
||||
setDxfWallGenerate: (x: any) => set({ dfxWallGenerate: x }),
|
||||
setObjValue: (x: any) => set({ objValue: x }),
|
||||
}));
|
||||
|
||||
type InputValuesStore = {
|
||||
inputValues: Record<string, string>;
|
||||
setInputValues: (values: Record<string, string>) => void;
|
||||
updateInputValue: (label: string, value: string) => void; // <- New
|
||||
inputValues: Record<string, string>;
|
||||
setInputValues: (values: Record<string, string>) => void;
|
||||
updateInputValue: (label: string, value: string) => void; // <- New
|
||||
};
|
||||
|
||||
export const useInputValues = create<InputValuesStore>((set) => ({
|
||||
inputValues: {},
|
||||
setInputValues: (values) => set({ inputValues: values }),
|
||||
updateInputValue: (label, value) =>
|
||||
set((state) => ({
|
||||
inputValues: {
|
||||
...state.inputValues,
|
||||
[label]: value,
|
||||
},
|
||||
})),
|
||||
inputValues: {},
|
||||
setInputValues: (values) => set({ inputValues: values }),
|
||||
updateInputValue: (label, value) =>
|
||||
set((state) => ({
|
||||
inputValues: {
|
||||
...state.inputValues,
|
||||
[label]: value,
|
||||
},
|
||||
})),
|
||||
}));
|
||||
|
||||
export interface ROISummaryData {
|
||||
productName: string;
|
||||
roiPercentage: number;
|
||||
paybackPeriod: number;
|
||||
totalCost: number;
|
||||
revenueGenerated: number;
|
||||
netProfit: number;
|
||||
netLoss: number;
|
||||
productName: string;
|
||||
roiPercentage: number;
|
||||
paybackPeriod: number;
|
||||
totalCost: number;
|
||||
revenueGenerated: number;
|
||||
netProfit: number;
|
||||
netLoss: number;
|
||||
}
|
||||
|
||||
interface ROISummaryStore {
|
||||
roiSummary: ROISummaryData;
|
||||
setRoiSummaryData: (values: ROISummaryData) => void;
|
||||
roiSummary: ROISummaryData;
|
||||
setRoiSummaryData: (values: ROISummaryData) => void;
|
||||
}
|
||||
|
||||
export const useROISummaryData = create<ROISummaryStore>((set) => ({
|
||||
roiSummary: {
|
||||
productName: "",
|
||||
roiPercentage: 0,
|
||||
paybackPeriod: 0,
|
||||
totalCost: 0,
|
||||
revenueGenerated: 0,
|
||||
netProfit: 0,
|
||||
netLoss: 0,
|
||||
},
|
||||
setRoiSummaryData: (values) => set({ roiSummary: values }),
|
||||
roiSummary: {
|
||||
productName: "",
|
||||
roiPercentage: 0,
|
||||
paybackPeriod: 0,
|
||||
totalCost: 0,
|
||||
revenueGenerated: 0,
|
||||
netProfit: 0,
|
||||
netLoss: 0,
|
||||
},
|
||||
setRoiSummaryData: (values) => set({ roiSummary: values }),
|
||||
}));
|
||||
|
||||
interface CompareStore {
|
||||
comparePopUp: boolean;
|
||||
setComparePopUp: (value: boolean) => void;
|
||||
toggleComparePopUp: () => void;
|
||||
comparePopUp: boolean;
|
||||
setComparePopUp: (value: boolean) => void;
|
||||
toggleComparePopUp: () => void;
|
||||
}
|
||||
|
||||
export const useCompareStore = create<CompareStore>((set) => ({
|
||||
comparePopUp: false,
|
||||
setComparePopUp: (value) => set({ comparePopUp: value }),
|
||||
toggleComparePopUp: () =>
|
||||
set((state) => ({ comparePopUp: !state.comparePopUp })),
|
||||
comparePopUp: false,
|
||||
setComparePopUp: (value) => set({ comparePopUp: value }),
|
||||
toggleComparePopUp: () =>
|
||||
set((state) => ({ comparePopUp: !state.comparePopUp })),
|
||||
}));
|
||||
|
||||
// Save state store
|
||||
interface SaveVersionStore {
|
||||
isVersionSaved: boolean;
|
||||
setIsVersionSaved: (value: boolean) => void;
|
||||
isVersionSaved: boolean;
|
||||
setIsVersionSaved: (value: boolean) => void;
|
||||
}
|
||||
|
||||
export const useSaveVersion = create<SaveVersionStore>((set) => ({
|
||||
isVersionSaved: false,
|
||||
setIsVersionSaved: (value: boolean) => set({ isVersionSaved: value }),
|
||||
isVersionSaved: false,
|
||||
setIsVersionSaved: (value: boolean) => set({ isVersionSaved: value }),
|
||||
}));
|
||||
|
||||
interface ViewSceneState {
|
||||
viewSceneLabels: boolean;
|
||||
setViewSceneLabels: (value: boolean | ((prev: boolean) => boolean)) => void;
|
||||
viewSceneLabels: boolean;
|
||||
setViewSceneLabels: (value: boolean | ((prev: boolean) => boolean)) => void;
|
||||
}
|
||||
|
||||
export const useViewSceneStore = create<ViewSceneState>((set) => ({
|
||||
viewSceneLabels: getInitialViewSceneLabels(),
|
||||
setViewSceneLabels: (value) => {
|
||||
set((state) => {
|
||||
const newValue =
|
||||
typeof value === "function" ? value(state.viewSceneLabels) : value;
|
||||
viewSceneLabels: getInitialViewSceneLabels(),
|
||||
setViewSceneLabels: (value) => {
|
||||
set((state) => {
|
||||
const newValue =
|
||||
typeof value === "function" ? value(state.viewSceneLabels) : value;
|
||||
|
||||
// Store in localStorage manually
|
||||
localStorage.setItem("viewSceneLabels", JSON.stringify(newValue));
|
||||
// Store in localStorage manually
|
||||
localStorage.setItem("viewSceneLabels", JSON.stringify(newValue));
|
||||
|
||||
return { viewSceneLabels: newValue };
|
||||
});
|
||||
},
|
||||
return { viewSceneLabels: newValue };
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
function getInitialViewSceneLabels(): boolean {
|
||||
if (typeof window === "undefined") return false; // SSR safety
|
||||
const saved = localStorage.getItem("viewSceneLabels");
|
||||
return saved ? JSON.parse(saved) : false;
|
||||
if (typeof window === "undefined") return false; // SSR safety
|
||||
const saved = localStorage.getItem("viewSceneLabels");
|
||||
return saved ? JSON.parse(saved) : false;
|
||||
}
|
||||
export interface CompareProduct {
|
||||
productUuid: string;
|
||||
productName: string;
|
||||
simulationData: {
|
||||
// costPerUnit: number;
|
||||
// workingDaysPerYear: number;
|
||||
// shiftLength: number;
|
||||
// shiftsPerDay: number;
|
||||
roiPercentage: number;
|
||||
// paybackPeriod: number;
|
||||
// totalCost: number;
|
||||
// revenueGenerated: number;
|
||||
netProfit: number;
|
||||
productionCapacity: number;
|
||||
paybackPeriod: number;
|
||||
// netLoss: number;
|
||||
machineIdleTime: number;
|
||||
machineActiveTime: number;
|
||||
throughputData: number;
|
||||
};
|
||||
productUuid: string;
|
||||
productName: string;
|
||||
simulationData: {
|
||||
// costPerUnit: number;
|
||||
// workingDaysPerYear: number;
|
||||
// shiftLength: number;
|
||||
// shiftsPerDay: number;
|
||||
roiPercentage: number;
|
||||
// paybackPeriod: number;
|
||||
// totalCost: number;
|
||||
// revenueGenerated: number;
|
||||
netProfit: number;
|
||||
productionCapacity: number;
|
||||
paybackPeriod: number;
|
||||
// netLoss: number;
|
||||
machineIdleTime: number;
|
||||
machineActiveTime: number;
|
||||
throughputData: number;
|
||||
};
|
||||
}
|
||||
|
||||
export const useCompareProductDataStore = create<{
|
||||
compareProductsData: CompareProduct[];
|
||||
setCompareProductsData: (x: CompareProduct[]) => void;
|
||||
compareProductsData: CompareProduct[];
|
||||
setCompareProductsData: (x: CompareProduct[]) => void;
|
||||
}>((set) => ({
|
||||
compareProductsData: [],
|
||||
setCompareProductsData: (x) => set({ compareProductsData: x }),
|
||||
compareProductsData: [],
|
||||
setCompareProductsData: (x) => set({ compareProductsData: x }),
|
||||
}));
|
||||
|
||||
export const useSelectedComment = create<any>((set: any) => ({
|
||||
selectedComment: null,
|
||||
setSelectedComment: (x: any) => set({ selectedComment: x }),
|
||||
position2Dstate: {},
|
||||
setPosition2Dstate: (x: any) => set({ position2Dstate: x }),
|
||||
commentPositionState: null,
|
||||
setCommentPositionState: (x: any) => set({ commentPositionState: x }),
|
||||
selectedComment: null,
|
||||
setSelectedComment: (x: any) => set({ selectedComment: x }),
|
||||
position2Dstate: {},
|
||||
setPosition2Dstate: (x: any) => set({ position2Dstate: x }),
|
||||
commentPositionState: null,
|
||||
setCommentPositionState: (x: any) => set({ commentPositionState: x }),
|
||||
}));
|
||||
export const useSelectedPath = create<any>((set: any) => ({
|
||||
selectedPath: "auto",
|
||||
setSelectedPath: (x: any) => set({ selectedPath: x }),
|
||||
selectedPath: "auto",
|
||||
setSelectedPath: (x: any) => set({ selectedPath: x }),
|
||||
}));
|
||||
export const useContextActionStore = create<any>((set: any) => ({
|
||||
contextAction: null,
|
||||
setContextAction: (x: any) => set({ contextAction: x }),
|
||||
contextAction: null,
|
||||
setContextAction: (x: any) => set({ contextAction: x }),
|
||||
}));
|
||||
type PointData = {
|
||||
pointId: string;
|
||||
position: [number, number, number];
|
||||
isCurved?: boolean;
|
||||
handleA?: [number, number, number] | null;
|
||||
handleB?: [number, number, number] | null;
|
||||
};
|
||||
|
||||
interface PathDataInterface {
|
||||
pathId: string;
|
||||
isActive?: boolean;
|
||||
isCurved?: boolean;
|
||||
pathPoints: [PointData, PointData];
|
||||
}
|
||||
interface allPaths {
|
||||
paths: string;
|
||||
isAvailable: boolean;
|
||||
vehicleId: string;
|
||||
}
|
||||
|
||||
type PathData = PathDataInterface[];
|
||||
export const useCreatedPaths = create<any>((set: any) => ({
|
||||
paths: [],
|
||||
setPaths: (x: PathData) => set({ paths: x }),
|
||||
allPaths: [],
|
||||
setAllPaths: (x: allPaths) => set({ allPaths: x }),
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user