feat: Enhance material handling and storage unit interactions; refactor MaterialAnimator and useRetrieveHandler for improved state management
This commit is contained in:
@@ -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
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react'
|
||||
import StorageUnitInstances from './instances/storageUnitInstances'
|
||||
|
||||
function StorageUnit() {
|
||||
|
||||
Reference in New Issue
Block a user