feat: Enhance material handling and storage unit interactions; refactor MaterialAnimator and useRetrieveHandler for improved state management

This commit is contained in:
2025-08-04 12:00:48 +05:30
parent 0da9e8997c
commit c9cc8d3534
6 changed files with 168 additions and 63 deletions

View File

@@ -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
},
};

View File

@@ -33,8 +33,8 @@ function RoboticArmAnimator({ HandleCallback, restPosition, ikSolver, targetBone
const [customCurvePoints, setCustomCurvePoints] = useState<THREE.Vector3[] | null>(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];
}
}

View File

@@ -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<any>(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 (
<group position={[0, -padding, 0]}>
{materialPositions.map(({ materialId, position }) => {
const mat = storage.currentMaterials.find((m) => m.materialId === materialId);
return (
<MaterialModel
key={materialId}
materialId={materialId}
matRef={null}
materialType={mat?.materialType ?? "Default material"}
position={position}
/>
);
})}
</group>
);
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 (
<group {...{ position: [0, -padding, 0] }}>
{storage.currentMaterials.map((mat, index) => (
<MaterialModel
key={`${index}-${mat.materialId}`}
materialId={mat.materialId}
matRef={meshRef}
materialType={mat.materialType ?? "Default material"}
position={materialPositions[index]}
/>
))}
</group>
);
};
export default MaterialAnimator;

View File

@@ -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 (

View File

@@ -1,4 +1,3 @@
import React from 'react'
import StorageUnitInstances from './instances/storageUnitInstances'
function StorageUnit() {