From c9cc8d3534f9a41c11a028f4f282c5e0c46e92f9 Mon Sep 17 00:00:00 2001 From: Jerald-Golden-B Date: Mon, 4 Aug 2025 12:00:48 +0530 Subject: [PATCH] feat: Enhance material handling and storage unit interactions; refactor MaterialAnimator and useRetrieveHandler for improved state management --- .../actionHandler/useRetrieveHandler.ts | 6 +- .../instances/animator/roboticArmAnimator.tsx | 73 ++++++++++- .../instances/animator/MaterialAnimator.tsx | 121 ++++++++++-------- .../instances/storageUnitInstances.tsx | 1 - .../simulation/storageUnit/storageUnit.tsx | 1 - app/src/store/simulation/useMaterialStore.ts | 29 +++++ 6 files changed, 168 insertions(+), 63 deletions(-) diff --git a/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts b/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts index 0373fd0..a92ad09 100644 --- a/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts +++ b/app/src/modules/simulation/actions/storageUnit/actionHandler/useRetrieveHandler.ts @@ -60,9 +60,9 @@ export function useRetrieveHandler() { actionUuid: action.actionUuid }, current: { - modelUuid: action.triggers[0]?.triggeredAsset.triggeredModel.modelUuid, - pointUuid: action.triggers[0]?.triggeredAsset.triggeredPoint.pointUuid, - actionUuid: action.triggers[0]?.triggeredAsset.triggeredAction.actionUuid + modelUuid: modelUuid, + pointUuid: pointUuid, + actionUuid: action.actionUuid }, }; diff --git a/app/src/modules/simulation/roboticArm/instances/animator/roboticArmAnimator.tsx b/app/src/modules/simulation/roboticArm/instances/animator/roboticArmAnimator.tsx index 1f81c2d..755e3ba 100644 --- a/app/src/modules/simulation/roboticArm/instances/animator/roboticArmAnimator.tsx +++ b/app/src/modules/simulation/roboticArm/instances/animator/roboticArmAnimator.tsx @@ -33,8 +33,8 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone const [customCurvePoints, setCustomCurvePoints] = useState(null); const { armBotStore, productStore, materialStore } = useSceneContext(); const { getArmBotById } = armBotStore(); - const { getMaterialById } = materialStore(); - const { getEventByModelUuid } = productStore(); + const { getMaterialById, getMaterialPosition } = materialStore(); + const { getEventByModelUuid, getActionByUuid, getPointByUuid } = productStore(); const { selectedProductStore } = useProductContext(); const { selectedProduct } = selectedProductStore(); const { scene } = useThree(); @@ -167,13 +167,18 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone let start = currentPath[0]; let end = currentPath[currentPath.length - 1]; + const bone = ikSolver.mesh.skeleton.bones.find((b: any) => b.name === targetBone); const armbotStatus = getArmBotById(armBot.modelUuid); const currentMaterial = armbotStatus?.currentAction?.materialId; - if (armbotStatus && currentMaterial && (currentPhase === 'rest-to-start' || currentPhase === 'start-to-end')) { + const currentAction = getActionByUuid(selectedProduct.productUuid, armbotStatus?.currentAction?.actionUuid || ''); + + if (armbotStatus && currentMaterial && currentAction && (currentPhase === 'rest-to-start' || currentPhase === 'start-to-end' || currentPhase === 'end-to-rest')) { const materialData = getMaterialById(currentMaterial); if (materialData) { const prevModel = getEventByModelUuid(selectedProduct.productUuid, materialData.current.modelUuid); + const nextModel = getEventByModelUuid(selectedProduct.productUuid, currentAction?.triggers[0]?.triggeredAsset?.triggeredModel?.modelUuid || ''); + const nextPoint = getPointByUuid(selectedProduct.productUuid, currentAction?.triggers[0]?.triggeredAsset?.triggeredModel?.modelUuid || '', currentAction?.triggers[0]?.triggeredAsset?.triggeredPoint?.pointUuid || ''); if (prevModel && prevModel.type === 'transfer') { const material = scene.getObjectByProperty("uuid", currentMaterial); @@ -194,7 +199,69 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone start = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z]; } } + } else if (prevModel && prevModel.type === 'storageUnit') { + const position = getMaterialPosition(currentMaterial); + const armbotModel = scene.getObjectByProperty("uuid", armBot.modelUuid); + + if (armbotModel) { + const armbotWorldPos = new THREE.Vector3(); + + let materialWorldPos = new THREE.Vector3(); + + if (position) { + materialWorldPos.copy(position); + } else { + materialWorldPos.copy(bone.getWorldPosition(armbotWorldPos)); + } + + const materialLocalPos = materialWorldPos.clone(); + armbotModel.worldToLocal(materialLocalPos); + + if (currentPhase === 'rest-to-start') { + end = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z]; + } else if (currentPhase === 'start-to-end') { + start = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z]; + } else if (currentPhase === 'end-to-rest') { + start = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z]; + } + } } + + if (nextModel && nextPoint && nextModel.type === 'transfer') { + const conveyorModel = scene.getObjectByProperty("uuid", nextModel.modelUuid); + const armbotModel = scene.getObjectByProperty("uuid", armBot.modelUuid); + if (conveyorModel && armbotModel) { + const localPoint = new THREE.Vector3( + nextPoint.position[0], + nextPoint.position[1], + nextPoint.position[2] + ); + + const worldPoint = conveyorModel.localToWorld(localPoint); + + armbotModel.worldToLocal(worldPoint); + + if (currentPhase === 'start-to-end') { + end = [worldPoint.x, worldPoint.y + 0.35, worldPoint.z]; + } + } + } + } + + } + + if (currentPhase === 'end-to-rest') { + console.log('currentPhase: ', currentPhase); + const armbotModel = scene.getObjectByProperty("uuid", armBot.modelUuid); + const armbotWorldPos = new THREE.Vector3(); + + if (armbotModel) { + let materialWorldPos = new THREE.Vector3(); + materialWorldPos.copy(bone.getWorldPosition(armbotWorldPos)); + + const materialLocalPos = materialWorldPos.clone(); + armbotModel.worldToLocal(materialLocalPos); + start = [materialLocalPos.x, materialLocalPos.y + 0.35, materialLocalPos.z]; } } diff --git a/app/src/modules/simulation/storageUnit/instances/animator/MaterialAnimator.tsx b/app/src/modules/simulation/storageUnit/instances/animator/MaterialAnimator.tsx index 2a95262..60d3733 100644 --- a/app/src/modules/simulation/storageUnit/instances/animator/MaterialAnimator.tsx +++ b/app/src/modules/simulation/storageUnit/instances/animator/MaterialAnimator.tsx @@ -1,72 +1,83 @@ -import { useRef, useMemo } from "react"; -import { MaterialModel } from "../../../materials/instances/material/materialModel"; +import { useEffect, useMemo } from "react"; import { Object3D, Box3, Vector3 } from "three"; import { useThree } from "@react-three/fiber"; import { useLoadingProgress } from "../../../../../store/builder/store"; +import { MaterialModel } from "../../../materials/instances/material/materialModel"; +import { useSceneContext } from "../../../../scene/sceneContext"; const MaterialAnimator = ({ - storage, + storage, }: Readonly<{ storage: StorageUnitStatus }>) => { - const meshRef = useRef(null!); - const { scene } = useThree(); - const padding = 0.1; - const { loadingProgress } = useLoadingProgress(); + const { scene } = useThree(); + const padding = 0.1; + const { loadingProgress } = useLoadingProgress(); + const { materialStore } = useSceneContext(); + const { materialPositions, setMaterialPositions } = materialStore(); - const storageModel = useMemo(() => { - return scene.getObjectByProperty("uuid", storage.modelUuid) as Object3D; - }, [scene, storage.modelUuid, loadingProgress]); + const storageModel = useMemo(() => { + return scene.getObjectByProperty("uuid", storage.modelUuid) as Object3D; + }, [scene, storage.modelUuid, loadingProgress]); - const materialPositions = useMemo(() => { - if (!storageModel || storage.currentMaterials.length === 0) return []; + useEffect(() => { + if (!storageModel || storage.currentMaterials.length === 0) { + setMaterialPositions([]); + return; + } - const box = new Box3().setFromObject(storageModel); - const size = new Vector3(); - box.getSize(size); + const box = new Box3().setFromObject(storageModel); + const size = new Vector3(); + box.getSize(size); - const matCount = storage.currentMaterials.length; + const materialWidth = 0.45; + const materialDepth = 0.45; + const materialHeight = 0.3; + const cols = Math.floor(size.x / materialWidth); + const rows = Math.floor(size.z / materialDepth); + const itemsPerLayer = cols * rows; - // Assumed size each material needs in world units - const materialWidth = 0.45; - const materialDepth = 0.45; - const materialHeight = 0.3; + const origin = new Vector3( + box.min.x + materialWidth / 2, + box.max.y + padding, + box.min.z + materialDepth / 2 + ); - const cols = Math.floor(size.x / materialWidth); - const rows = Math.floor(size.z / materialDepth); - const itemsPerLayer = cols * rows; + const newMaterials = storage.currentMaterials.map((mat, i) => { + const layer = Math.floor(i / itemsPerLayer); + const layerIndex = i % itemsPerLayer; + const row = Math.floor(layerIndex / cols); + const col = layerIndex % cols; - const origin = new Vector3( - box.min.x + materialWidth / 2, - box.max.y + padding, // slightly above the surface - box.min.z + materialDepth / 2 + const position = new Vector3( + origin.x + col * materialWidth, + origin.y + layer * (materialHeight + padding), + origin.z + row * materialDepth + ); + + return { + materialId: mat.materialId, + position, + }; + }); + + setMaterialPositions(newMaterials); + }, [storageModel, storage.currentMaterials, setMaterialPositions]); + + return ( + + {materialPositions.map(({ materialId, position }) => { + const mat = storage.currentMaterials.find((m) => m.materialId === materialId); + return ( + + ); + })} + ); - - return Array.from({ length: matCount }, (_, i) => { - const layer = Math.floor(i / itemsPerLayer); - const layerIndex = i % itemsPerLayer; - const row = Math.floor(layerIndex / cols); - const col = layerIndex % cols; - - return new Vector3( - origin.x + col * materialWidth, - origin.y + layer * (materialHeight + padding), - origin.z + row * materialDepth - ); - }); - }, [storageModel, storage.currentMaterials]); - - return ( - - {storage.currentMaterials.map((mat, index) => ( - - ))} - - ); }; export default MaterialAnimator; diff --git a/app/src/modules/simulation/storageUnit/instances/storageUnitInstances.tsx b/app/src/modules/simulation/storageUnit/instances/storageUnitInstances.tsx index d9faf29..cebc4f9 100644 --- a/app/src/modules/simulation/storageUnit/instances/storageUnitInstances.tsx +++ b/app/src/modules/simulation/storageUnit/instances/storageUnitInstances.tsx @@ -7,7 +7,6 @@ import { useViewSceneStore } from "../../../../store/builder/store"; function StorageUnitInstances() { const { storageUnitStore } = useSceneContext(); const { storageUnits } = storageUnitStore(); - // console.log('storageUnits: ', storageUnits); const { viewSceneLabels } = useViewSceneStore(); return ( diff --git a/app/src/modules/simulation/storageUnit/storageUnit.tsx b/app/src/modules/simulation/storageUnit/storageUnit.tsx index eee0875..8d7f1b1 100644 --- a/app/src/modules/simulation/storageUnit/storageUnit.tsx +++ b/app/src/modules/simulation/storageUnit/storageUnit.tsx @@ -1,4 +1,3 @@ -import React from 'react' import StorageUnitInstances from './instances/storageUnitInstances' function StorageUnit() { diff --git a/app/src/store/simulation/useMaterialStore.ts b/app/src/store/simulation/useMaterialStore.ts index 98a0928..777bad0 100644 --- a/app/src/store/simulation/useMaterialStore.ts +++ b/app/src/store/simulation/useMaterialStore.ts @@ -1,15 +1,26 @@ +import * as THREE from 'three'; import { create } from 'zustand'; import { immer } from 'zustand/middleware/immer'; + +interface MaterialPosition { + materialId: string; + position: THREE.Vector3; +} + type MaterialsStore = { materials: MaterialsSchema; materialHistory: MaterialHistorySchema; + materialPositions: MaterialPosition[]; addMaterial: (material: MaterialSchema) => MaterialSchema | undefined; removeMaterial: (materialId: string) => MaterialSchema | undefined; clearMaterials: () => void; updateMaterial: (materialId: string, updates: Partial) => MaterialSchema | undefined; + setMaterialPositions: (materialPosition: MaterialPosition[]) => void; + getMaterialPosition: (materialId: string) => THREE.Vector3 | undefined; + setPreviousLocation: ( materialId: string, location: { @@ -61,6 +72,7 @@ export const createMaterialStore = () => { immer((set, get) => ({ materials: [], materialHistory: [], + materialPositions: [], addMaterial: (material) => { let updatedMaterial: MaterialSchema | undefined; @@ -262,6 +274,23 @@ export const createMaterialStore = () => { return updatedMaterial; }, + setMaterialPositions: (materials) => { + set((state) => { + state.materialPositions = materials; + }); + }, + + getMaterialPosition: (materialid) => { + let position: THREE.Vector3 | undefined; + set((state) => { + const material = state.materialPositions.find(m => m.materialId === materialid); + if (material) { + position = material.position; + } + }); + return position; + }, + getMaterialById: (materialId) => { return get().materials.find(m => m.materialId === materialId); },