diff --git a/app/src/modules/builder/asset/models/model/model.tsx b/app/src/modules/builder/asset/models/model/model.tsx index a600a4e..6819cb4 100644 --- a/app/src/modules/builder/asset/models/model/model.tsx +++ b/app/src/modules/builder/asset/models/model/model.tsx @@ -410,7 +410,7 @@ function Model({ asset }: { readonly asset: Asset }) { mixerRef.current.removeEventListener('finished', handleAnimationComplete); } }; - }, [asset.animationState?.current, asset.animationState?.isPlaying, isPaused, activeModule]); + }, [asset.animationState?.current, asset.animationState?.isCompleted, asset.animationState?.isPlaying, isPaused, activeModule]); useEffect(() => { const canvasElement = gl.domElement; diff --git a/app/src/modules/builder/wall/Instances/instance/helpers/useWallClassification.ts b/app/src/modules/builder/wall/Instances/instance/helpers/useWallClassification.ts index bc910b5..8ba211a 100644 --- a/app/src/modules/builder/wall/Instances/instance/helpers/useWallClassification.ts +++ b/app/src/modules/builder/wall/Instances/instance/helpers/useWallClassification.ts @@ -85,13 +85,45 @@ export function useWallClassification(walls: Walls) { })); } - const allCoords = mergedLineStrings.flatMap(ls => ls.geometry.coordinates); - const uniqueCoords = Array.from(new Set(allCoords.map(coord => coord.join(',')))); - if (uniqueCoords.length < 4) return []; + const validLineStrings = mergedLineStrings.map(ls => { + const coords = ls.geometry.coordinates.map(coord => coord.join(',')); - const lineStrings = turf.featureCollection(mergedLineStrings); + if (coords.length < 2) return null; - const polygons = turf.polygonize(lineStrings); + const start = coords[0]; + const end = coords[coords.length - 1]; + const middle = coords.slice(1, -1); + + const seen = new Set([start, end]); + const filteredMiddle: string[] = []; + + for (const point of middle) { + if (!seen.has(point)) { + seen.add(point); + filteredMiddle.push(point); + } + } + + const newCoords = [start, ...filteredMiddle, end]; + + if (newCoords.length >= 4) { + const resultCoords = newCoords.map(str => str.split(',').map(Number)); + return { + ...ls, + geometry: { + ...ls.geometry, + coordinates: resultCoords, + }, + }; + } + + return null; + }).filter(Boolean); + + if (validLineStrings.length === 0) return []; + + const lineStrings = turf.featureCollection(validLineStrings as any); + const polygons = turf.polygonize(lineStrings as any); const rooms: Point[][] = []; diff --git a/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts b/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts index c4b4245..416f67e 100644 --- a/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts +++ b/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts @@ -5,12 +5,14 @@ import { useSceneContext } from "../../../../scene/sceneContext"; import { useProductContext } from "../../../products/productContext"; export function useRetrieveHandler() { - const { materialStore, armBotStore, vehicleStore, storageUnitStore, productStore } = useSceneContext(); + const { materialStore, armBotStore, vehicleStore, storageUnitStore, productStore, humanStore, assetStore } = useSceneContext(); const { selectedProductStore } = useProductContext(); const { addMaterial } = materialStore(); const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid, getActionByUuid } = productStore(); const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = storageUnitStore(); const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = vehicleStore(); + const { getHumanById, incrementHumanLoad, addCurrentMaterial: addCurrentMaterialToHuman } = humanStore(); + const { getAssetById, setCurrentAnimation } = assetStore(); const { selectedProduct } = selectedProductStore(); const { getArmBotById, addCurrentAction } = armBotStore(); const { isPlaying } = usePlayButtonStore(); @@ -269,7 +271,7 @@ export function useRetrieveHandler() { if (material) { removeLastMaterial(storageUnit.modelUuid); - updateCurrentLoad(storageUnit.modelUuid, -1) + updateCurrentLoad(storageUnit.modelUuid, -1); incrementVehicleLoad(vehicle.modelUuid, 1); addCurrentMaterial(vehicle.modelUuid, material.materialType, material.materialId); retrieveLogStatus(material.materialName, `is picked by ${vehicle.modelName}`); @@ -293,6 +295,39 @@ export function useRetrieveHandler() { retrievalTimeRef.current.delete(actionUuid); retrievalTimeRef.current.delete(`${actionUuid}_last`); } + } else if (triggeredModel.type === 'human') { + const human = getHumanById(triggeredModel.modelUuid); + const humanAsset = getAssetById(triggeredModel.modelUuid); + + if (human && !human.isScheduled && human.state === 'idle' && human.currentLoad < human.point.action.loadCapacity) { + if (humanAsset && humanAsset.animationState?.current === 'idle') { + setCurrentAnimation(human.modelUuid, 'pickup', true, false, false); + } else if (humanAsset && humanAsset.animationState?.current === 'pickup' && humanAsset.animationState.isCompleted) { + const lastMaterial = getLastMaterial(storageUnit.modelUuid); + if (lastMaterial) { + if (human.currentLoad < human.point.action.loadCapacity) { + const material = createNewMaterial( + lastMaterial.materialId, + lastMaterial.materialType, + storageUnit.point.action + ); + if (material) { + removeLastMaterial(storageUnit.modelUuid); + updateCurrentLoad(storageUnit.modelUuid, -1); + incrementHumanLoad(human.modelUuid, 1); + addCurrentMaterialToHuman(human.modelUuid, material.materialType, material.materialId); + retrieveLogStatus(material.materialName, `is picked by ${human.modelName}`); + } + if (human.currentLoad + 1 < human.point.action.loadCapacity) { + setCurrentAnimation(human.modelUuid, 'idle_with_box', true, false, false); + setTimeout(() => { + setCurrentAnimation(human.modelUuid, 'pickup', true, false, false); + }, 0) + } + } + } + } + } } }); diff --git a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx index 7699c9c..9d79de3 100644 --- a/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx +++ b/app/src/modules/simulation/vehicle/instances/animator/vehicleAnimator.tsx @@ -183,45 +183,45 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai return ( <> - {selectedPath === "auto" && - {currentPath.map((pos, i) => { - if (i < currentPath.length - 1) { - return ( - { - const updated = [...currentPath]; - updated[i0] = p0.toArray() as [number, number, number]; - updated[i1] = p1.toArray() as [number, number, number]; - setCurrentPath(updated); - }} - isAnyDragging={isAnyDragging} - setIsAnyDragging={setIsAnyDragging} - /> - ); - } - return null; - })} - {currentPath.length > 0 && ( - { if (controls) (controls as any).enabled = true; }}> - {currentPath.map((pos, i) => - ( - ) - )} - - ) - } - + {selectedPath === "auto" && + + {currentPath.map((pos, i) => { + if (i < currentPath.length - 1) { + return ( + { + const updated = [...currentPath]; + updated[i0] = p0.toArray() as [number, number, number]; + updated[i1] = p1.toArray() as [number, number, number]; + setCurrentPath(updated); + }} + isAnyDragging={isAnyDragging} + setIsAnyDragging={setIsAnyDragging} + /> + ); + } + return null; + })} + {currentPath.length > 0 && ( + { if (controls) (controls as any).enabled = true; }}> + {currentPath.map((pos, i) => + ( + ) + )} + + )} + } ); diff --git a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx index 3e910a7..443ffa3 100644 --- a/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx +++ b/app/src/modules/simulation/vehicle/instances/instance/vehicleInstance.tsx @@ -58,10 +58,8 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(end.x) && Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(end.z) ) { - console.log('segmentPath: ', segmentPath); return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || []; } else { - console.log("There is no path here...Choose valid path") const { path: segmentPaths } = navMeshQuery.computePath(start, start); return segmentPaths.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || []; } @@ -70,9 +68,7 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>) console.error("Failed to compute path"); return []; } - }, - [navMesh] - ); + }, [navMesh]); function vehicleStatus(modelId: string, status: string) { // console.log(`${modelId} , ${status}`); diff --git a/app/src/modules/simulation/vehicle/navMesh/polygonGenerator.tsx b/app/src/modules/simulation/vehicle/navMesh/polygonGenerator.tsx index f22cef4..9ce9ea9 100644 --- a/app/src/modules/simulation/vehicle/navMesh/polygonGenerator.tsx +++ b/app/src/modules/simulation/vehicle/navMesh/polygonGenerator.tsx @@ -76,12 +76,42 @@ export default function PolygonGenerator({ turf.lineString(line.map((p: any) => p?.position)) ); - const validLineFeatures = lineFeatures.filter((line) => { - const coords = line.geometry.coordinates; - return coords.length >= 2; - }); + const validLineFeatures = lineFeatures.map(ls => { + const coords = ls.geometry.coordinates.map(coord => coord.join(',')); - const polygons = turf.polygonize(turf.featureCollection(validLineFeatures)); + if (coords.length < 2) return null; + + const start = coords[0]; + const end = coords[coords.length - 1]; + const middle = coords.slice(1, -1); + + const seen = new Set([start, end]); + const filteredMiddle: string[] = []; + + for (const point of middle) { + if (!seen.has(point)) { + seen.add(point); + filteredMiddle.push(point); + } + } + + const newCoords = [start, ...filteredMiddle, end]; + + if (newCoords.length >= 4) { + const resultCoords = newCoords.map(str => str.split(',').map(Number)); + return { + ...ls, + geometry: { + ...ls.geometry, + coordinates: resultCoords, + }, + }; + } + + return null; + }).filter(Boolean); + + const polygons = turf.polygonize(turf.featureCollection(validLineFeatures as any) as any); renderWallGeometry(wallPoints); diff --git a/app/src/store/builder/store.ts b/app/src/store/builder/store.ts index 529e42f..e62449b 100644 --- a/app/src/store/builder/store.ts +++ b/app/src/store/builder/store.ts @@ -730,6 +730,6 @@ export const useSelectedComment = create((set: any) => ({ setCommentPositionState: (x: any) => set({ commentPositionState: x }), })); export const useSelectedPath = create((set: any) => ({ - selectedPath: "", + selectedPath: "auto", setSelectedPath: (x: any) => set({ selectedPath: x }), }));