diff --git a/app/src/modules/builder/builder.tsx b/app/src/modules/builder/builder.tsx index c0a3267..fdf17bc 100644 --- a/app/src/modules/builder/builder.tsx +++ b/app/src/modules/builder/builder.tsx @@ -18,19 +18,19 @@ import Window from "../../assets/gltf-glb/window.glb"; ////////// Zustand State Imports ////////// import { - useToggleView, - useDeletePointOrLine, - useMovePoint, - useActiveLayer, - useWallVisibility, - useRoofVisibility, - useShadows, - useUpdateScene, - useWalls, - useToolMode, - useRefTextUpdate, - useRenderDistance, - useLimitDistance, + useToggleView, + useDeletePointOrLine, + useMovePoint, + useActiveLayer, + useWallVisibility, + useRoofVisibility, + useShadows, + useUpdateScene, + useWalls, + useToolMode, + useRefTextUpdate, + useRenderDistance, + useLimitDistance, } from "../../store/store"; ////////// 3D Function Imports ////////// @@ -54,296 +54,295 @@ import MeasurementTool from "../scene/tools/measurementTool"; import NavMesh from "../simulation/vehicle/navMesh/navMesh"; export default function Builder() { - const state = useThree(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements. - const csg = useRef(); // Reference for CSG object, used for 3D modeling. - const CSGGroup = useRef() as Types.RefMesh; // Reference to a group of CSG objects. - const scene = useRef() as Types.RefScene; // Reference to the scene. - const camera = useRef() as Types.RefCamera; // Reference to the camera object. - const controls = useRef(); // Reference to the controls object. - const raycaster = useRef() as Types.RefRaycaster; // Reference for raycaster used for detecting objects being pointed at in the scene. - const dragPointControls = useRef() as Types.RefDragControl; // Reference for drag point controls, an array for drag control. + const state = useThree(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements. + const csg = useRef(); // Reference for CSG object, used for 3D modeling. + const CSGGroup = useRef() as Types.RefMesh; // Reference to a group of CSG objects. + const scene = useRef() as Types.RefScene; // Reference to the scene. + const camera = useRef() as Types.RefCamera; // Reference to the camera object. + const controls = useRef(); // Reference to the controls object. + const raycaster = useRef() as Types.RefRaycaster; // Reference for raycaster used for detecting objects being pointed at in the scene. + const dragPointControls = useRef() as Types.RefDragControl; // Reference for drag point controls, an array for drag control. - // Assigning the scene and camera from the Three.js state to the references. + // Assigning the scene and camera from the Three.js state to the references. - scene.current = state.scene; - camera.current = state.camera; - controls.current = state.controls; - raycaster.current = state.raycaster; + scene.current = state.scene; + camera.current = state.camera; + controls.current = state.controls; + raycaster.current = state.raycaster; - const plane = useRef(null); // Reference for a plane object for raycaster reference. - const grid = useRef() as any; // Reference for a grid object for raycaster reference. - const snappedPoint = useRef() as Types.RefVector3; // Reference for storing a snapped point at the (end = isSnapped) and (start = ispreSnapped) of the line. - const isSnapped = useRef(false) as Types.RefBoolean; // Boolean reference to indicate if an object is snapped at the (end). - const anglesnappedPoint = useRef() as Types.RefVector3; // Reference for storing an angle-snapped point when the line is in 90 degree etc... - const isAngleSnapped = useRef(false) as Types.RefBoolean; // Boolean to indicate if angle snapping is active. - const isSnappedUUID = useRef() as Types.RefString; // UUID reference to identify the snapped point. - const ispreSnapped = useRef(false) as Types.RefBoolean; // Boolean reference to indicate if an object is snapped at the (start). - const tempLoader = useRef() as Types.RefMesh; // Reference for a temporary loader for the floor items. - const isTempLoader = useRef() as Types.RefBoolean; // Reference to check if a temporary loader is active. - const Tube = useRef() as Types.RefTubeGeometry; // Reference for tubes used for reference line creation and updation. - const line = useRef([]) as Types.RefLine; // Reference for line which stores the current line that is being drawn. - const lines = useRef([]) as Types.RefLines; // Reference for lines which stores all the lines that are ever drawn. - const onlyFloorline = useRef([]); // Reference for floor lines which does not have walls or roof and have only floor used to store the current line that is being drawn. - const onlyFloorlines = useRef([]); // Reference for all the floor lines that are ever drawn. - const ReferenceLineMesh = useRef() as Types.RefMesh; // Reference for storing the mesh of the reference line for moving it during draw. - const LineCreated = useRef(false) as Types.RefBoolean; // Boolean to track whether the reference line is created or not. - const referencePole = useRef() as Types.RefMesh; // Reference for a pole that is used as the reference for the user to show where it is placed. - const itemsGroup = useRef() as Types.RefGroup; // Reference to the THREE.Group that has the floor items (Gltf). - const floorGroup = useRef() as Types.RefGroup; // Reference to the THREE.Group that has the roofs and the floors. - const AttachedObject = useRef() as Types.RefMesh; // Reference for an object that is attached using dbl click for transform controls rotation. - const floorPlanGroup = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the lines group and the points group. - const floorPlanGroupLine = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the lines that are drawn. - const floorPlanGroupPoint = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the points that are created. - const floorGroupAisle = useRef() as Types.RefGroup; - const zoneGroup = useRef() as Types.RefGroup; - const currentLayerPoint = useRef([]) as Types.RefMeshArray; // Reference for points that re in the current layer used to update the points in drag controls. - const hoveredDeletablePoint = useRef() as Types.RefMesh; // Reference for the currently hovered point that can be deleted. - const hoveredDeletableLine = useRef() as Types.RefMesh; // Reference for the currently hovered line that can be deleted. - const hoveredDeletableFloorItem = useRef() as Types.RefMesh; // Reference for the currently hovered floor item that can be deleted. - const hoveredDeletableWallItem = useRef() as Types.RefMesh; // Reference for the currently hovered wall item that can be deleted. - const hoveredDeletablePillar = useRef() as Types.RefMesh; // Reference for the currently hovered pillar that can be deleted. - const currentWallItem = useRef() as Types.RefMesh; // Reference for the currently selected wall item that can be scaled, dragged etc... + const plane = useRef(null); // Reference for a plane object for raycaster reference. + const grid = useRef() as any; // Reference for a grid object for raycaster reference. + const snappedPoint = useRef() as Types.RefVector3; // Reference for storing a snapped point at the (end = isSnapped) and (start = ispreSnapped) of the line. + const isSnapped = useRef(false) as Types.RefBoolean; // Boolean reference to indicate if an object is snapped at the (end). + const anglesnappedPoint = useRef() as Types.RefVector3; // Reference for storing an angle-snapped point when the line is in 90 degree etc... + const isAngleSnapped = useRef(false) as Types.RefBoolean; // Boolean to indicate if angle snapping is active. + const isSnappedUUID = useRef() as Types.RefString; // UUID reference to identify the snapped point. + const ispreSnapped = useRef(false) as Types.RefBoolean; // Boolean reference to indicate if an object is snapped at the (start). + const tempLoader = useRef() as Types.RefMesh; // Reference for a temporary loader for the floor items. + const isTempLoader = useRef() as Types.RefBoolean; // Reference to check if a temporary loader is active. + const Tube = useRef() as Types.RefTubeGeometry; // Reference for tubes used for reference line creation and updation. + const line = useRef([]) as Types.RefLine; // Reference for line which stores the current line that is being drawn. + const lines = useRef([]) as Types.RefLines; // Reference for lines which stores all the lines that are ever drawn. + const onlyFloorline = useRef([]); // Reference for floor lines which does not have walls or roof and have only floor used to store the current line that is being drawn. + const onlyFloorlines = useRef([]); // Reference for all the floor lines that are ever drawn. + const ReferenceLineMesh = useRef() as Types.RefMesh; // Reference for storing the mesh of the reference line for moving it during draw. + const LineCreated = useRef(false) as Types.RefBoolean; // Boolean to track whether the reference line is created or not. + const referencePole = useRef() as Types.RefMesh; // Reference for a pole that is used as the reference for the user to show where it is placed. + const itemsGroup = useRef() as Types.RefGroup; // Reference to the THREE.Group that has the floor items (Gltf). + const floorGroup = useRef() as Types.RefGroup; // Reference to the THREE.Group that has the roofs and the floors. + const AttachedObject = useRef() as Types.RefMesh; // Reference for an object that is attached using dbl click for transform controls rotation. + const floorPlanGroup = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the lines group and the points group. + const floorPlanGroupLine = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the lines that are drawn. + const floorPlanGroupPoint = useRef() as Types.RefGroup; // Reference for a THREE.Group that has the points that are created. + const floorGroupAisle = useRef() as Types.RefGroup; + const zoneGroup = useRef() as Types.RefGroup; + const currentLayerPoint = useRef([]) as Types.RefMeshArray; // Reference for points that re in the current layer used to update the points in drag controls. + const hoveredDeletablePoint = useRef() as Types.RefMesh; // Reference for the currently hovered point that can be deleted. + const hoveredDeletableLine = useRef() as Types.RefMesh; // Reference for the currently hovered line that can be deleted. + const hoveredDeletableFloorItem = useRef() as Types.RefMesh; // Reference for the currently hovered floor item that can be deleted. + const hoveredDeletableWallItem = useRef() as Types.RefMesh; // Reference for the currently hovered wall item that can be deleted. + const hoveredDeletablePillar = useRef() as Types.RefMesh; // Reference for the currently hovered pillar that can be deleted. + const currentWallItem = useRef() as Types.RefMesh; // Reference for the currently selected wall item that can be scaled, dragged etc... - const cursorPosition = new THREE.Vector3(); // 3D vector for storing the cursor position. + const cursorPosition = new THREE.Vector3(); // 3D vector for storing the cursor position. - const [selectedItemsIndex, setSelectedItemsIndex] = - useState(null); // State for tracking the index of the selected item. - const { activeLayer } = useActiveLayer(); // State that changes based on which layer the user chooses in Layers.jsx. - const { toggleView } = useToggleView(); // State for toggling between 2D and 3D. - const { toolMode, setToolMode } = useToolMode(); - const { setMovePoint } = useMovePoint(); // State that stores a boolean which represents whether the move mode is active or not. - const { setDeletePointOrLine } = useDeletePointOrLine(); - const { setRoofVisibility } = useRoofVisibility(); - const { setWallVisibility } = useWallVisibility(); - const { setShadows } = useShadows(); - const { setRenderDistance } = useRenderDistance(); - const { setLimitDistance } = useLimitDistance(); - const { setUpdateScene } = useUpdateScene(); - const { setWalls } = useWalls(); - const { refTextupdate, setRefTextUpdate } = useRefTextUpdate(); + const [selectedItemsIndex, setSelectedItemsIndex] = useState(null); // State for tracking the index of the selected item. + const { activeLayer } = useActiveLayer(); // State that changes based on which layer the user chooses in Layers.jsx. + const { toggleView } = useToggleView(); // State for toggling between 2D and 3D. + const { toolMode, setToolMode } = useToolMode(); + const { setMovePoint } = useMovePoint(); // State that stores a boolean which represents whether the move mode is active or not. + const { setDeletePointOrLine } = useDeletePointOrLine(); + const { setRoofVisibility } = useRoofVisibility(); + const { setWallVisibility } = useWallVisibility(); + const { setShadows } = useShadows(); + const { setRenderDistance } = useRenderDistance(); + const { setLimitDistance } = useLimitDistance(); + const { setUpdateScene } = useUpdateScene(); + const { setWalls } = useWalls(); + const { refTextupdate, setRefTextUpdate } = useRefTextUpdate(); - // const loader = new GLTFLoader(); - // const dracoLoader = new DRACOLoader(); + // const loader = new GLTFLoader(); + // const dracoLoader = new DRACOLoader(); - // dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/'); - // loader.setDRACOLoader(dracoLoader); + // dracoLoader.setDecoderPath('https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/gltf/'); + // loader.setDRACOLoader(dracoLoader); - ////////// Assest Configuration Values ////////// + ////////// Assest Configuration Values ////////// - const AssetConfigurations: Types.AssetConfigurations = { - arch: { - modelUrl: arch, - scale: [0.75, 0.75, 0.75], - csgscale: [2, 4, 0.5], - csgposition: [0, 2, 0], - positionY: () => 0, - type: "Fixed-Move", - }, - door: { - modelUrl: door, - scale: [0.75, 0.75, 0.75], - csgscale: [2, 4, 0.5], - csgposition: [0, 2, 0], - positionY: () => 0, - type: "Fixed-Move", - }, - window: { - modelUrl: Window, - scale: [0.75, 0.75, 0.75], - csgscale: [5, 3, 0.5], - csgposition: [0, 1.5, 0], - positionY: (intersectionPoint) => intersectionPoint.point.y, - type: "Free-Move", - }, - }; + const AssetConfigurations: Types.AssetConfigurations = { + arch: { + modelUrl: arch, + scale: [0.75, 0.75, 0.75], + csgscale: [2, 4, 0.5], + csgposition: [0, 2, 0], + positionY: () => 0, + type: "Fixed-Move", + }, + door: { + modelUrl: door, + scale: [0.75, 0.75, 0.75], + csgscale: [2, 4, 0.5], + csgposition: [0, 2, 0], + positionY: () => 0, + type: "Fixed-Move", + }, + window: { + modelUrl: Window, + scale: [0.75, 0.75, 0.75], + csgscale: [5, 3, 0.5], + csgposition: [0, 1.5, 0], + positionY: (intersectionPoint) => intersectionPoint.point.y, + type: "Free-Move", + }, + }; - ////////// All Toggle's ////////// + ////////// All Toggle's ////////// - useEffect(() => { - setRefTextUpdate((prevUpdate: number) => prevUpdate - 1); - if (dragPointControls.current) { - dragPointControls.current.enabled = false; - } - if (toggleView) { - Layer2DVisibility( - activeLayer, - floorPlanGroup, - floorPlanGroupLine, - floorPlanGroupPoint, - currentLayerPoint, - dragPointControls - ); - } else { - setToolMode(null); - setDeletePointOrLine(false); - setMovePoint(false); - loadWalls(lines, setWalls); - setUpdateScene(true); - line.current = []; - } - }, [toggleView]); + useEffect(() => { + setRefTextUpdate((prevUpdate: number) => prevUpdate - 1); + if (dragPointControls.current) { + dragPointControls.current.enabled = false; + } + if (toggleView) { + Layer2DVisibility( + activeLayer, + floorPlanGroup, + floorPlanGroupLine, + floorPlanGroupPoint, + currentLayerPoint, + dragPointControls + ); + } else { + setToolMode(null); + setDeletePointOrLine(false); + setMovePoint(false); + loadWalls(lines, setWalls); + setUpdateScene(true); + line.current = []; + } + }, [toggleView]); - useEffect(() => { - THREE.Cache.clear(); - THREE.Cache.enabled = true; - }, []); + useEffect(() => { + THREE.Cache.clear(); + THREE.Cache.enabled = true; + }, []); - useEffect(() => { - const email = localStorage.getItem("email"); - const organization = email!.split("@")[1].split(".")[0]; + useEffect(() => { + const email = localStorage.getItem("email"); + const organization = email!.split("@")[1].split(".")[0]; - async function fetchVisibility() { - const visibility = await findEnvironment( - organization, - localStorage.getItem("userId")! - ); - if (visibility) { - setRoofVisibility(visibility.roofVisibility); - setWallVisibility(visibility.wallVisibility); - setShadows(visibility.shadowVisibility); - setRenderDistance(visibility.renderDistance); - setLimitDistance(visibility.limitDistance); - } - } - fetchVisibility(); - }, []); + async function fetchVisibility() { + const visibility = await findEnvironment( + organization, + localStorage.getItem("userId")! + ); + if (visibility) { + setRoofVisibility(visibility.roofVisibility); + setWallVisibility(visibility.wallVisibility); + setShadows(visibility.shadowVisibility); + setRenderDistance(visibility.renderDistance); + setLimitDistance(visibility.limitDistance); + } + } + fetchVisibility(); + }, []); - ////////// UseFrame is Here ////////// + ////////// UseFrame is Here ////////// - useFrame(() => { - if (toolMode) { - Draw( - state, - plane, - cursorPosition, - floorPlanGroupPoint, - floorPlanGroupLine, - snappedPoint, - isSnapped, - isSnappedUUID, - line, - lines, - ispreSnapped, - floorPlanGroup, - ReferenceLineMesh, - LineCreated, - setRefTextUpdate, - Tube, - anglesnappedPoint, - isAngleSnapped, - toolMode - ); - } - }); + useFrame(() => { + if (toolMode) { + Draw( + state, + plane, + cursorPosition, + floorPlanGroupPoint, + floorPlanGroupLine, + snappedPoint, + isSnapped, + isSnappedUUID, + line, + lines, + ispreSnapped, + floorPlanGroup, + ReferenceLineMesh, + LineCreated, + setRefTextUpdate, + Tube, + anglesnappedPoint, + isAngleSnapped, + toolMode + ); + } + }); - ////////// Return ////////// + ////////// Return ////////// - return ( - <> - + return ( + <> + - + - + - + - + - + - + - + - + - + - + - - - ); + + + ); } diff --git a/app/src/modules/builder/geomentries/lines/distanceText/distanceText.tsx b/app/src/modules/builder/geomentries/lines/distanceText/distanceText.tsx index 307d51f..b8c0947 100644 --- a/app/src/modules/builder/geomentries/lines/distanceText/distanceText.tsx +++ b/app/src/modules/builder/geomentries/lines/distanceText/distanceText.tsx @@ -2,142 +2,180 @@ import { useEffect, useState } from "react"; import { getLines } from "../../../../../services/factoryBuilder/lines/getLinesApi"; import * as THREE from "three"; import { - useActiveLayer, - useDeletedLines, - useNewLines, - useToggleView, + useActiveLayer, + useDeletedLines, + useNewLines, + useRoomsState, + useToggleView, } from "../../../../../store/store"; import objectLinesToArray from "../lineConvertions/objectLinesToArray"; import { Html } from "@react-three/drei"; import * as Types from "../../../../../types/world/worldTypes"; +import getRoomsFromLines from "../getRoomsFromLines"; const DistanceText = () => { - const [lines, setLines] = useState< - { - distance: string; - position: THREE.Vector3; - userData: Types.Line; - layer: string; - }[] - >([]); - const { activeLayer } = useActiveLayer(); - const { toggleView } = useToggleView(); - const { newLines, setNewLines } = useNewLines(); - const { deletedLines, setDeletedLines } = useDeletedLines(); + const [lines, setLines] = useState< + { + distance: string; + position: THREE.Vector3; + userData: Types.Line; + layer: string; + }[] + >([]); + const { activeLayer } = useActiveLayer(); + const { toggleView } = useToggleView(); + const { newLines, setNewLines } = useNewLines(); + const { deletedLines, setDeletedLines } = useDeletedLines(); + const [linesState, setLinesState] = useState([]); + const { roomsState, setRoomsState } = useRoomsState(); - useEffect(() => { - const email = localStorage.getItem("email"); - if (!email) return; - const organization = email.split("@")[1].split(".")[0]; + useEffect(() => { + if (linesState.length === 0) return; + const getLines = async () => { - getLines(organization).then((data) => { - data = objectLinesToArray(data); + if (lines.length > 2) { + const linesByLayer = linesState.reduce((acc: { [key: number]: any[] }, pair) => { + const layer = pair[0][2]; + if (!acc[layer]) acc[layer] = []; + acc[layer].push(pair); + return acc; + }, {}); - const lines = data - .filter((line: Types.Line) => line[0][2] === activeLayer) - .map((line: Types.Line) => { - const point1 = new THREE.Vector3( - line[0][0].x, - line[0][0].y, - line[0][0].z - ); - const point2 = new THREE.Vector3( - line[1][0].x, - line[1][0].y, - line[1][0].z - ); - const distance = point1.distanceTo(point2); - const midpoint = new THREE.Vector3() - .addVectors(point1, point2) - .divideScalar(2); - return { - distance: distance.toFixed(1), - position: midpoint, - userData: line, - layer: activeLayer, - }; + for (const layer in linesByLayer) { + + const rooms: Types.Rooms = await getRoomsFromLines({ current: linesByLayer[layer] }); + + } + } + } + getLines(); + }, [linesState]) + + useEffect(() => { + const email = localStorage.getItem("email"); + if (!email) return; + const organization = email.split("@")[1].split(".")[0]; + + getLines(organization).then((data) => { + data = objectLinesToArray(data); + setLinesState(data); + + const lines = data + .filter((line: Types.Line) => line[0][2] === activeLayer) + .map((line: Types.Line) => { + const point1 = new THREE.Vector3( + line[0][0].x, + line[0][0].y, + line[0][0].z + ); + const point2 = new THREE.Vector3( + line[1][0].x, + line[1][0].y, + line[1][0].z + ); + const distance = point1.distanceTo(point2); + const midpoint = new THREE.Vector3() + .addVectors(point1, point2) + .divideScalar(2); + return { + distance: distance.toFixed(1), + position: midpoint, + userData: line, + layer: activeLayer, + }; + }); + setLines(lines); }); - setLines(lines); - }); - }, [activeLayer]); + }, [activeLayer]); - useEffect(() => { - if (newLines.length > 0) { - if (newLines[0][0][2] !== activeLayer) return; - const newLinesData = newLines.map((line: Types.Line) => { - const point1 = new THREE.Vector3( - line[0][0].x, - line[0][0].y, - line[0][0].z - ); - const point2 = new THREE.Vector3( - line[1][0].x, - line[1][0].y, - line[1][0].z - ); - const distance = point1.distanceTo(point2); - const midpoint = new THREE.Vector3() - .addVectors(point1, point2) - .divideScalar(2); + useEffect(() => { + if (newLines.length > 0) { + if (newLines[0][0][2] !== activeLayer) return; + const newLinesData = newLines.map((line: Types.Line) => { + const point1 = new THREE.Vector3( + line[0][0].x, + line[0][0].y, + line[0][0].z + ); + const point2 = new THREE.Vector3( + line[1][0].x, + line[1][0].y, + line[1][0].z + ); + const distance = point1.distanceTo(point2); + const midpoint = new THREE.Vector3() + .addVectors(point1, point2) + .divideScalar(2); - return { - distance: distance.toFixed(1), - position: midpoint, - userData: line, - layer: activeLayer, - }; - }); - setLines((prevLines) => [...prevLines, ...newLinesData]); - setNewLines([]); - } - }, [newLines, activeLayer]); + return { + distance: distance.toFixed(1), + position: midpoint, + userData: line, + layer: activeLayer, + }; + }); + setLines((prevLines) => [...prevLines, ...newLinesData]); + setLinesState((prevLines) => [...prevLines, ...newLines]); + setNewLines([]); + } + }, [newLines, activeLayer]); - useEffect(() => { - if ((deletedLines as Types.Lines).length > 0) { - setLines((prevLines) => - prevLines.filter( - (line) => - !deletedLines.some( - (deletedLine: any) => - deletedLine[0][1] === line.userData[0][1] && - deletedLine[1][1] === line.userData[1][1] - ) - ) - ); - setDeletedLines([]); - } - }, [deletedLines]); + useEffect(() => { + if ((deletedLines as Types.Lines).length > 0) { + setLines((prevLines) => + prevLines.filter( + (line) => + !deletedLines.some( + (deletedLine: any) => + deletedLine[0][1] === line.userData[0][1] && + deletedLine[1][1] === line.userData[1][1] + ) + ) + ); - return ( - <> - {toggleView && ( - - {lines.map((text) => ( - -
- {text.distance} m -
- - ))} -
- )} - - ); + setLinesState(prev => + prev.filter(line => + !(deletedLines as Types.Lines).some( + deleted => + line[0][1] === deleted[0][1] && line[1][1] === deleted[1][1] + ) + ) + ); + + setDeletedLines([]); + } + }, [deletedLines]); + + return ( + <> + {toggleView && ( + + {lines.map((text) => ( + +
+ {text.distance} m +
+ + ))} +
+ )} + + ); }; export default DistanceText; diff --git a/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts b/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts index 90019f0..c77b518 100644 --- a/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts +++ b/app/src/modules/simulation/actions/vehicle/actionHandler/useTravelHandler.ts @@ -25,7 +25,6 @@ export function useTravelHandler() { if (!modelUuid) return; incrementVehicleLoad(modelUuid, 1); - console.log('material: ', material); addCurrentMaterial(modelUuid, material.materialType, material.materialId); travelLogStatus(material.materialId, `is triggering travel from ${modelUuid}`); diff --git a/app/src/modules/simulation/materials/instances/instance/materialInstance.tsx b/app/src/modules/simulation/materials/instances/instance/materialInstance.tsx index a26109c..74bd61f 100644 --- a/app/src/modules/simulation/materials/instances/instance/materialInstance.tsx +++ b/app/src/modules/simulation/materials/instances/instance/materialInstance.tsx @@ -85,37 +85,10 @@ function MaterialInstance({ material }: { material: MaterialSchema }) { const callTrigger = () => { if (!material.next) return; - const fromModel = getEventByModelUuid(selectedProduct.productId, material.next.modelUuid); - if (!fromModel) return; - const fromPoint = getPointByUuid(selectedProduct.productId, fromModel.modelUuid, material.next.pointUuid); - if (!fromPoint) return; - - if (fromModel.type === 'transfer') { - const toModel = getEventByModelUuid(selectedProduct.productId, material.next.modelUuid); - if (!toModel) return; - if (toModel.type === 'transfer') { - const action = getActionByPointUuid(selectedProduct.productId, material.next.pointUuid); - if (action) { - triggerPointActions(action, material.materialId); - } - } else if (toModel?.type === 'vehicle') { - // Transfer to Vehicle - - } else if (toModel?.type === 'machine') { - // Transfer to Machine - - } else if (toModel?.type === 'roboticArm') { - // Transfer to Robotic Arm - - } else if (toModel?.type === 'storageUnit') { - // Transfer to Storage Unit - } - } else if (fromModel.type === 'vehicle') { - } else if (fromModel.type === 'machine') { - } else if (fromModel.type === 'roboticArm') { - } else if (fromModel.type === 'storageUnit') { + const action = getActionByPointUuid(selectedProduct.productId, material.next.pointUuid); + if (action) { + triggerPointActions(action, material.materialId); } - } return ( diff --git a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts index 1679da6..ccd3e00 100644 --- a/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts +++ b/app/src/modules/simulation/triggers/triggerHandler/useTriggerHandler.ts @@ -14,7 +14,7 @@ export function useTriggerHandler() { const { getVehicleById } = useVehicleStore(); const { setCurrentLocation, setNextLocation, getMaterialById, setIsPaused, setIsVisible, setEndTime } = useMaterialStore(); - const handleTrigger = (trigger: TriggerSchema, action: Action, materialId: string) => { + const handleTrigger = (trigger: TriggerSchema, action: Action, materialId?: string) => { const fromEvent = getEventByTriggerUuid(selectedProduct.productId, trigger.triggerUuid); @@ -23,7 +23,7 @@ export function useTriggerHandler() { if (fromEvent?.type === 'transfer') { if (toEvent?.type === 'transfer') { // Transfer to Transfer - if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { + if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { const material = getMaterialById(materialId); if (material) { if (material.next) { @@ -44,7 +44,7 @@ export function useTriggerHandler() { } } else if (toEvent?.type === 'vehicle') { // Transfer to Vehicle - if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { + if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { const material = getMaterialById(materialId); if (material) { @@ -90,7 +90,7 @@ export function useTriggerHandler() { } else if (toEvent?.type === 'roboticArm') { // Transfer to Robotic Arm - if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { + if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { const material = getMaterialById(materialId); if (material) { @@ -136,6 +136,7 @@ export function useTriggerHandler() { } } else if (fromEvent?.type === 'vehicle') { if (toEvent?.type === 'transfer') { + console.log('toEvent: ', toEvent); // Vehicle to Transfer } else if (toEvent?.type === 'vehicle') { @@ -171,7 +172,7 @@ export function useTriggerHandler() { } else if (fromEvent?.type === 'roboticArm') { if (toEvent?.type === 'transfer') { // Robotic Arm to Transfer - if (trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { + if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { const material = getMaterialById(materialId); if (material) { setIsPaused(material.materialId, false); @@ -199,6 +200,41 @@ export function useTriggerHandler() { } else if (toEvent?.type === 'vehicle') { // Robotic Arm to Vehicle + if (materialId && trigger.triggeredAsset && trigger.triggeredAsset.triggeredPoint && trigger.triggeredAsset.triggeredAction) { + const material = getMaterialById(materialId); + if (material) { + const action = getActionByUuid(selectedProduct.productId, trigger.triggeredAsset.triggeredAction.actionUuid); + const vehicle = getVehicleById(trigger.triggeredAsset?.triggeredModel.modelUuid); + + setCurrentLocation(material.materialId, { + modelUuid: trigger.triggeredAsset.triggeredModel.modelUuid, + pointUuid: trigger.triggeredAsset.triggeredPoint.pointUuid, + actionUuid: trigger.triggeredAsset?.triggeredAction?.actionUuid, + }); + + setNextLocation(material.materialId, null); + + if (action) { + + if (vehicle) { + + if (vehicle.isActive === false && vehicle.state === 'idle' && vehicle.currentLoad < vehicle.point.action.loadCapacity) { + + setIsVisible(materialId, false); + + // Handle current action from vehicle + handleAction(action, materialId); + + } else { + + // Event Manager Needed + + } + } + } + + } + } } else if (toEvent?.type === 'machine') { // Robotic Arm to Machine @@ -230,18 +266,18 @@ export function useTriggerHandler() { } } - const handleFinalAction = (action: Action, materialId: string) => { + const handleFinalAction = (action: Action, materialId?: string) => { if (!action) return; const modelUuid = getModelUuidByActionUuid(selectedProduct.productId, action.actionUuid); if (!modelUuid) return; const finalModel = getEventByModelUuid(selectedProduct.productId, modelUuid); if (!finalModel) return; - const material = getMaterialById(materialId); if (finalModel.type === 'transfer') { // Storage Unit to Transfer - + if (!materialId) return; + const material = getMaterialById(materialId); if (material) { const currentTime = performance.now(); @@ -274,7 +310,7 @@ export function useTriggerHandler() { } - const triggerPointActions = useCallback((action: Action, materialId: string) => { + const triggerPointActions = useCallback((action: Action, materialId?: string) => { if (!action) return; if (action.triggers.length > 0) { diff --git a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx index f67e22c..ba16302 100644 --- a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx +++ b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx @@ -4,7 +4,6 @@ import * as THREE from 'three'; import { Line } from '@react-three/drei'; import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore, useResetButtonStore } from '../../../../../store/usePlayButtonStore'; import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore'; -import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore'; interface VehicleAnimatorProps { path: [number, number, number][]; @@ -17,8 +16,7 @@ interface VehicleAnimatorProps { } function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetail, reset, startUnloadingProcess }: VehicleAnimatorProps) { - const { decrementVehicleLoad, getVehicleById, removeLastMaterial } = useVehicleStore(); - const { removeMaterial } = useMaterialStore(); + const { getVehicleById } = useVehicleStore(); const { isPaused } = usePauseButtonStore(); const { isPlaying } = usePlayButtonStore(); const { speed } = useAnimationPlaySpeed(); @@ -27,11 +25,9 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai const movingForward = useRef(true); const completedRef = useRef(false); const [objectRotation, setObjectRotation] = useState<{ x: number; y: number; z: number } | undefined>(agvDetail.point?.action?.pickUpPoint?.rotation || { x: 0, y: 0, z: 0 }) - const [progress, setProgress] = useState(0); const [restRotation, setRestingRotation] = useState(true); const [currentPath, setCurrentPath] = useState<[number, number, number][]>([]); const { scene } = useThree(); - let coveredDistance = progressRef.current; useEffect(() => { if (currentPhase === 'stationed-pickup' && path.length > 0) { @@ -47,7 +43,6 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai }, [currentPhase, path, objectRotation]); useEffect(() => { - setProgress(0); completedRef.current = false; }, [currentPath]); @@ -55,11 +50,9 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai if (isReset || !isPlaying) { reset(); setCurrentPath([]); - setProgress(0); completedRef.current = false; movingForward.current = true; progressRef.current = 0; - coveredDistance = 0; setReset(false); setRestingRotation(true); const object = scene.getObjectByProperty('uuid', agvUuid); @@ -89,7 +82,7 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai totalDistance += segmentDistance; } - while (index < distances.length && coveredDistance > accumulatedDistance + distances[index]) { + while (index < distances.length && progressRef.current > accumulatedDistance + distances[index]) { accumulatedDistance += distances[index]; index++; } @@ -115,14 +108,12 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai if (isAligned) { progressRef.current += delta * (speed * agvDetail.speed); - coveredDistance = progressRef.current; - const t = (coveredDistance - accumulatedDistance) / segmentDistance; + const t = (progressRef.current - accumulatedDistance) / segmentDistance; const position = start.clone().lerp(end, t); object.position.copy(position); } } - if (progressRef.current >= totalDistance) { if (restRotation && objectRotation) { const targetEuler = new THREE.Euler( @@ -152,8 +143,6 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai } }); - - return ( <> {currentPath.length > 0 && ( diff --git a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx index 28ed64b..274f18f 100644 --- a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx +++ b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx @@ -5,13 +5,19 @@ import { NavMeshQuery } from '@recast-navigation/core'; import { useNavMesh } from '../../../../../store/store'; import { useAnimationPlaySpeed, usePauseButtonStore, usePlayButtonStore } from '../../../../../store/usePlayButtonStore'; import { useVehicleStore } from '../../../../../store/simulation/useVehicleStore'; -import MaterialAnimator from '../animator/materialAnimator'; import { useMaterialStore } from '../../../../../store/simulation/useMaterialStore'; +import { useProductStore } from '../../../../../store/simulation/useProductStore'; +import { useSelectedProduct } from '../../../../../store/simulation/useSimulationStore'; +import { useTriggerHandler } from '../../../triggers/triggerHandler/useTriggerHandler'; +import MaterialAnimator from '../animator/materialAnimator'; function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { const { navMesh } = useNavMesh(); const { isPlaying } = usePlayButtonStore(); const { removeMaterial } = useMaterialStore(); + const { triggerPointActions } = useTriggerHandler(); + const { getActionByUuid, getEventByModelUuid, getTriggerByUuid } = useProductStore(); + const { selectedProduct } = useSelectedProduct(); const { vehicles, setVehicleActive, setVehicleState, clearCurrentMaterials, setVehicleLoad, decrementVehicleLoad, removeLastMaterial } = useVehicleStore(); const [currentPhase, setCurrentPhase] = useState('stationed'); const [path, setPath] = useState<[number, number, number][]>([]); @@ -22,7 +28,6 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { const { speed } = useAnimationPlaySpeed(); const { isPaused } = usePauseButtonStore(); - useEffect(() => { isPausedRef.current = isPaused; }, [isPaused]); @@ -44,7 +49,6 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { function vehicleStatus(modelId: string, status: string) { // console.log(`${modelId} , ${status}`); - } // Function to reset everything @@ -75,11 +79,6 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { vehicleStatus(agvDetail.modelUuid, 'Started from station, heading to pickup'); return; } else if (!agvDetail.isActive && agvDetail.state === 'idle' && currentPhase === 'picking') { - - // setTimeout(() => { - // increment(); - // }, 5000); - if (agvDetail.currentLoad === agvDetail.point.action.loadCapacity && agvDetail.currentMaterials.length > 0) { if (agvDetail.point.action.pickUpPoint && agvDetail.point.action.unLoadPoint) { const toDrop = computePath( @@ -135,17 +134,44 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { } function startUnloadingProcess() { - const droppedMaterial = agvDetail.currentLoad; - startTime = performance.now(); - handleMaterialDrop(droppedMaterial); + if (agvDetail.point.action.triggers.length > 0) { + const trigger = getTriggerByUuid(selectedProduct.productId, agvDetail.point.action.triggers[0].triggerUuid); + const model = getEventByModelUuid(selectedProduct.productId, trigger?.triggeredAsset?.triggeredModel?.modelUuid || ''); + + if (trigger && model) { + if (model.type === 'transfer') { + const action = getActionByUuid(selectedProduct.productId, agvDetail.point.action.actionUuid); + if (action) { + triggerPointActions(action); + } + } else if (model.type === 'machine') { + + } else if (model.type === 'roboticArm') { + + } else if (model.type === 'storageUnit') { + + } + } else { + const droppedMaterial = agvDetail.currentLoad; + startTime = performance.now(); + handleMaterialDropByDefault(droppedMaterial); + } + } else { + const droppedMaterial = agvDetail.currentLoad; + startTime = performance.now(); + handleMaterialDropByDefault(droppedMaterial); + } } - function handleMaterialDrop(droppedMaterial: number) { + function handleMaterialDropToConveyor() { } + + + function handleMaterialDropByDefault(droppedMaterial: number) { if (isPausedRef.current) { if (!pauseTimeRef.current) { pauseTimeRef.current = performance.now(); } - requestAnimationFrame(() => handleMaterialDrop(droppedMaterial)); + requestAnimationFrame(() => handleMaterialDropByDefault(droppedMaterial)); return; } @@ -168,16 +194,15 @@ function VehicleInstance({ agvDetail }: { agvDetail: VehicleStatus }) { } if (droppedMat > 0) { startTime = performance.now(); - requestAnimationFrame(() => handleMaterialDrop(droppedMat)); + requestAnimationFrame(() => handleMaterialDropByDefault(droppedMat)); } else { return; } } else { - requestAnimationFrame(() => handleMaterialDrop(droppedMaterial)); + requestAnimationFrame(() => handleMaterialDropByDefault(droppedMaterial)); } } - return ( <> { // console.log('zoneAssetId: ', zoneAssetId); if (!zoneAssetId) return @@ -70,8 +71,6 @@ export default function ZoneAssets() { } }, [zoneAssetId, scene, controls]) - - return ( <> diff --git a/app/src/modules/visualization/zone/zoneCameraTarget.tsx b/app/src/modules/visualization/zone/zoneCameraTarget.tsx index d1587de..c3116ef 100644 --- a/app/src/modules/visualization/zone/zoneCameraTarget.tsx +++ b/app/src/modules/visualization/zone/zoneCameraTarget.tsx @@ -13,8 +13,6 @@ export default function ZoneCentreTarget() { const { zoneTarget, setZoneTarget } = usezoneTarget(); const { Edit, setEdit } = useEditPosition(); - - useEffect(() => { if ( selectedZone.zoneViewPortTarget && diff --git a/app/src/store/store.ts b/app/src/store/store.ts index b16e1ff..68740b7 100644 --- a/app/src/store/store.ts +++ b/app/src/store/store.ts @@ -66,6 +66,11 @@ export const useWalls = create((set: any) => ({ setWalls: (x: any) => set(() => ({ walls: x })), })); +export const useRoomsState = create((set: any) => ({ + roomsState: [], + setRoomsState: (x: any) => set(() => ({ walls: x })), +})); + export const useZones = create((set: any) => ({ zones: [], setZones: (callback: any) =>