Merge remote-tracking branch 'origin/main-dev' into main-demo
This commit is contained in:
@@ -410,7 +410,7 @@ function Model({ asset }: { readonly asset: Asset }) {
|
|||||||
mixerRef.current.removeEventListener('finished', handleAnimationComplete);
|
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(() => {
|
useEffect(() => {
|
||||||
const canvasElement = gl.domElement;
|
const canvasElement = gl.domElement;
|
||||||
|
|||||||
@@ -85,13 +85,45 @@ export function useWallClassification(walls: Walls) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const allCoords = mergedLineStrings.flatMap(ls => ls.geometry.coordinates);
|
const validLineStrings = mergedLineStrings.map(ls => {
|
||||||
const uniqueCoords = Array.from(new Set(allCoords.map(coord => coord.join(','))));
|
const coords = ls.geometry.coordinates.map(coord => coord.join(','));
|
||||||
if (uniqueCoords.length < 4) return [];
|
|
||||||
|
|
||||||
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<string>([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[][] = [];
|
const rooms: Point[][] = [];
|
||||||
|
|
||||||
|
|||||||
@@ -5,12 +5,14 @@ import { useSceneContext } from "../../../../scene/sceneContext";
|
|||||||
import { useProductContext } from "../../../products/productContext";
|
import { useProductContext } from "../../../products/productContext";
|
||||||
|
|
||||||
export function useRetrieveHandler() {
|
export function useRetrieveHandler() {
|
||||||
const { materialStore, armBotStore, vehicleStore, storageUnitStore, productStore } = useSceneContext();
|
const { materialStore, armBotStore, vehicleStore, storageUnitStore, productStore, humanStore, assetStore } = useSceneContext();
|
||||||
const { selectedProductStore } = useProductContext();
|
const { selectedProductStore } = useProductContext();
|
||||||
const { addMaterial } = materialStore();
|
const { addMaterial } = materialStore();
|
||||||
const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid, getActionByUuid } = productStore();
|
const { getModelUuidByActionUuid, getPointUuidByActionUuid, getEventByModelUuid, getActionByUuid } = productStore();
|
||||||
const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = storageUnitStore();
|
const { getStorageUnitById, getLastMaterial, updateCurrentLoad, removeLastMaterial } = storageUnitStore();
|
||||||
const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = vehicleStore();
|
const { getVehicleById, incrementVehicleLoad, addCurrentMaterial } = vehicleStore();
|
||||||
|
const { getHumanById, incrementHumanLoad, addCurrentMaterial: addCurrentMaterialToHuman } = humanStore();
|
||||||
|
const { getAssetById, setCurrentAnimation } = assetStore();
|
||||||
const { selectedProduct } = selectedProductStore();
|
const { selectedProduct } = selectedProductStore();
|
||||||
const { getArmBotById, addCurrentAction } = armBotStore();
|
const { getArmBotById, addCurrentAction } = armBotStore();
|
||||||
const { isPlaying } = usePlayButtonStore();
|
const { isPlaying } = usePlayButtonStore();
|
||||||
@@ -269,7 +271,7 @@ export function useRetrieveHandler() {
|
|||||||
|
|
||||||
if (material) {
|
if (material) {
|
||||||
removeLastMaterial(storageUnit.modelUuid);
|
removeLastMaterial(storageUnit.modelUuid);
|
||||||
updateCurrentLoad(storageUnit.modelUuid, -1)
|
updateCurrentLoad(storageUnit.modelUuid, -1);
|
||||||
incrementVehicleLoad(vehicle.modelUuid, 1);
|
incrementVehicleLoad(vehicle.modelUuid, 1);
|
||||||
addCurrentMaterial(vehicle.modelUuid, material.materialType, material.materialId);
|
addCurrentMaterial(vehicle.modelUuid, material.materialType, material.materialId);
|
||||||
retrieveLogStatus(material.materialName, `is picked by ${vehicle.modelName}`);
|
retrieveLogStatus(material.materialName, `is picked by ${vehicle.modelName}`);
|
||||||
@@ -293,6 +295,39 @@ export function useRetrieveHandler() {
|
|||||||
retrievalTimeRef.current.delete(actionUuid);
|
retrievalTimeRef.current.delete(actionUuid);
|
||||||
retrievalTimeRef.current.delete(`${actionUuid}_last`);
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -183,45 +183,45 @@ function VehicleAnimator({ path, handleCallBack, currentPhase, agvUuid, agvDetai
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{selectedPath === "auto" && <group>
|
{selectedPath === "auto" &&
|
||||||
{currentPath.map((pos, i) => {
|
<group>
|
||||||
if (i < currentPath.length - 1) {
|
{currentPath.map((pos, i) => {
|
||||||
return (
|
if (i < currentPath.length - 1) {
|
||||||
<DraggableLineSegment
|
return (
|
||||||
key={i}
|
<DraggableLineSegment
|
||||||
index={i}
|
key={i}
|
||||||
start={new THREE.Vector3(...currentPath[i])}
|
index={i}
|
||||||
end={new THREE.Vector3(...currentPath[i + 1])}
|
start={new THREE.Vector3(...currentPath[i])}
|
||||||
updatePoints={(i0, p0, i1, p1) => {
|
end={new THREE.Vector3(...currentPath[i + 1])}
|
||||||
const updated = [...currentPath];
|
updatePoints={(i0, p0, i1, p1) => {
|
||||||
updated[i0] = p0.toArray() as [number, number, number];
|
const updated = [...currentPath];
|
||||||
updated[i1] = p1.toArray() as [number, number, number];
|
updated[i0] = p0.toArray() as [number, number, number];
|
||||||
setCurrentPath(updated);
|
updated[i1] = p1.toArray() as [number, number, number];
|
||||||
}}
|
setCurrentPath(updated);
|
||||||
isAnyDragging={isAnyDragging}
|
}}
|
||||||
setIsAnyDragging={setIsAnyDragging}
|
isAnyDragging={isAnyDragging}
|
||||||
/>
|
setIsAnyDragging={setIsAnyDragging}
|
||||||
);
|
/>
|
||||||
}
|
);
|
||||||
return null;
|
}
|
||||||
})}
|
return null;
|
||||||
{currentPath.length > 0 && (
|
})}
|
||||||
<group onPointerMissed={() => { if (controls) (controls as any).enabled = true; }}>
|
{currentPath.length > 0 && (
|
||||||
{currentPath.map((pos, i) =>
|
<group onPointerMissed={() => { if (controls) (controls as any).enabled = true; }}>
|
||||||
(
|
{currentPath.map((pos, i) =>
|
||||||
<DraggableSphere
|
(
|
||||||
key={i}
|
<DraggableSphere
|
||||||
index={i}
|
key={i}
|
||||||
position={new THREE.Vector3(...pos)}
|
index={i}
|
||||||
onMove={updatePoint}
|
position={new THREE.Vector3(...pos)}
|
||||||
isAnyDragging={isAnyDragging}
|
onMove={updatePoint}
|
||||||
setIsAnyDragging={setIsAnyDragging}
|
isAnyDragging={isAnyDragging}
|
||||||
/>)
|
setIsAnyDragging={setIsAnyDragging}
|
||||||
)}
|
/>)
|
||||||
</group >
|
)}
|
||||||
)
|
</group >
|
||||||
}
|
)}
|
||||||
</group >
|
</group >
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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].x) == Math.round(end.x) &&
|
||||||
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(end.z)
|
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]) || [];
|
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||||
} else {
|
} else {
|
||||||
console.log("There is no path here...Choose valid path")
|
|
||||||
const { path: segmentPaths } = navMeshQuery.computePath(start, start);
|
const { path: segmentPaths } = navMeshQuery.computePath(start, start);
|
||||||
return segmentPaths.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
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");
|
console.error("Failed to compute path");
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
}, [navMesh]);
|
||||||
[navMesh]
|
|
||||||
);
|
|
||||||
|
|
||||||
function vehicleStatus(modelId: string, status: string) {
|
function vehicleStatus(modelId: string, status: string) {
|
||||||
// console.log(`${modelId} , ${status}`);
|
// console.log(`${modelId} , ${status}`);
|
||||||
|
|||||||
@@ -76,12 +76,42 @@ export default function PolygonGenerator({
|
|||||||
turf.lineString(line.map((p: any) => p?.position))
|
turf.lineString(line.map((p: any) => p?.position))
|
||||||
);
|
);
|
||||||
|
|
||||||
const validLineFeatures = lineFeatures.filter((line) => {
|
const validLineFeatures = lineFeatures.map(ls => {
|
||||||
const coords = line.geometry.coordinates;
|
const coords = ls.geometry.coordinates.map(coord => coord.join(','));
|
||||||
return coords.length >= 2;
|
|
||||||
});
|
|
||||||
|
|
||||||
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<string>([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);
|
renderWallGeometry(wallPoints);
|
||||||
|
|
||||||
|
|||||||
@@ -730,6 +730,6 @@ export const useSelectedComment = create<any>((set: any) => ({
|
|||||||
setCommentPositionState: (x: any) => set({ commentPositionState: x }),
|
setCommentPositionState: (x: any) => set({ commentPositionState: x }),
|
||||||
}));
|
}));
|
||||||
export const useSelectedPath = create<any>((set: any) => ({
|
export const useSelectedPath = create<any>((set: any) => ({
|
||||||
selectedPath: "",
|
selectedPath: "auto",
|
||||||
setSelectedPath: (x: any) => set({ selectedPath: x }),
|
setSelectedPath: (x: any) => set({ selectedPath: x }),
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user