added arm ui

This commit is contained in:
Nalvazhuthi
2025-04-28 12:26:31 +05:30
parent c5d4679068
commit 3ebadf3c10
14 changed files with 1413 additions and 489 deletions

View File

@@ -1,169 +1,337 @@
import React, { useEffect, useRef, useState } from 'react';
import * as THREE from 'three';
import { useEventsStore } from '../../../../../store/simulation/useEventsStore';
import useModuleStore from '../../../../../store/useModuleStore';
import { TransformControls } from '@react-three/drei';
import { detectModifierKeys } from '../../../../../utils/shortcutkeys/detectModifierKeys';
import { useSelectedEventSphere, useSelectedEventData } from '../../../../../store/simulation/useSimulationStore';
import React, { useEffect, useRef, useState } from "react";
import * as THREE from "three";
import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
import useModuleStore from "../../../../../store/useModuleStore";
import { TransformControls, useGLTF } from "@react-three/drei";
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
import {
useSelectedEventSphere,
useSelectedEventData,
} from "../../../../../store/simulation/useSimulationStore";
import PickDropPoints from "../../../../../components/ui/arm/PickDropPoints";
import armPick from "../../../../../assets/gltf-glb/arm_ui_pick.glb";
import armDrop from "../../../../../assets/gltf-glb/arm_ui_drop.glb";
import useDraggableGLTF from "../../../../../components/ui/arm/useDraggableGLTF";
interface Process {
startPoint: number[] | null;
endPoint: number[] | null;
}
interface Action {
actionUuid: string;
actionName: string;
actionType: string;
process: Process;
triggers: any[];
}
interface Point {
uuid: string;
position: number[];
rotation: number[];
actions: Action[];
}
interface RoboticArmEvent {
modelUuid: string;
modelName: string;
position: number[];
rotation: number[];
state: string;
type: string;
speed: number;
point: Point;
}
function PointsCreator() {
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
const { activeModule } = useModuleStore();
const transformRef = useRef<any>(null);
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere } = useSelectedEventSphere();
const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData();
const { events, updatePoint, getPointByUuid, getEventByModelUuid } =
useEventsStore();
useEffect(() => {
if (selectedEventSphere) {
const eventData = getEventByModelUuid(selectedEventSphere.userData.modelUuid);
if (eventData) {
setSelectedEventData(
eventData,
selectedEventSphere.userData.pointUuid
);
} else {
clearSelectedEventData();
const [armBotStatusSample, setArmBotStatusSample] = useState<
RoboticArmEvent[]
>([
{
modelUuid: "b3556818-9e46-48b0-a869-a75c92857125",
modelName: "robotic_arm",
position: [0, 0, 0],
rotation: [0, 0, 0],
state: "idle",
type: "roboticArm",
speed: 1.5,
point: {
uuid: "point-123",
position: [0, 1.5, 0],
rotation: [0, 0, 0],
actions: [
{
actionUuid: "action-001",
actionName: "Pick Component",
actionType: "pickAndPlace",
process: {
startPoint: null,
endPoint: null,
},
triggers: [],
},
{
actionUuid: "action-002",
actionName: "Pick Component",
actionType: "pickAndPlace",
process: {
startPoint: null,
endPoint: null,
},
triggers: [],
},
],
},
},
{
modelUuid: "16a394c7-0808-4bdf-a5d3-e5ca141ffb9f",
modelName: "arm without rig (1)",
position: [0, 0, 0],
rotation: [0, 0, 0],
state: "idle",
type: "roboticArm",
speed: 1.5,
point: {
uuid: "point-123",
position: [0, 1.5, 0],
rotation: [0, 0, 0],
actions: [
{
actionUuid: "action-001",
actionName: "Pick Component",
actionType: "pickAndPlace",
process: {
startPoint: null,
endPoint: null,
},
triggers: [],
},
],
},
},
]);
const armUiPick = useGLTF(armPick) as any;
const armUiDrop = useGLTF(armDrop) as any;
const updatePointToState = (obj: THREE.Object3D) => {
const { modelUuid, pointUuid, actionType, actionUuid } = obj.userData;
const newPosition = obj.position.toArray();
setArmBotStatusSample((prev) =>
prev.map((event) => {
if (event.modelUuid === modelUuid) {
const updatedActions = event.point.actions.map((action) => {
if (action.actionUuid === actionUuid) {
const updatedProcess = { ...action.process };
if (actionType === "pick") {
updatedProcess.startPoint = newPosition;
} else if (actionType === "drop") {
updatedProcess.endPoint = newPosition;
}
return {
...action,
process: updatedProcess,
};
}
} else {
clearSelectedEventData();
return action;
});
return {
...event,
point: {
...event.point,
actions: updatedActions,
},
};
}
}, [selectedEventSphere]);
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
const keyCombination = detectModifierKeys(e);
if (!selectedEventSphere) return;
if (keyCombination === "G") {
setTransformMode((prev) => (prev === "translate" ? null : "translate"));
}
if (keyCombination === "R") {
setTransformMode((prev) => (prev === "rotate" ? null : "rotate"));
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [selectedEventSphere]);
const updatePointToState = (selectedEventSphere: THREE.Mesh) => {
let point = JSON.parse(JSON.stringify(getPointByUuid(selectedEventSphere.userData.modelUuid, selectedEventSphere.userData.pointUuid)));
if (point) {
point.position = [selectedEventSphere.position.x, selectedEventSphere.position.y, selectedEventSphere.position.z];
updatePoint(selectedEventSphere.userData.modelUuid, selectedEventSphere.userData.pointUuid, point)
}
}
return (
<>
{activeModule === 'simulation' &&
<>
<group name='EventPointsGroup' >
{events.map((event, i) => {
if (event.type === 'transfer') {
return (
<group key={i} position={new THREE.Vector3(...event.position)}>
{event.points.map((point, j) => (
<mesh
uuid={point.uuid}
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
onClick={(e) => {
e.stopPropagation();
setSelectedEventSphere(sphereRefs.current[point.uuid]);
}}
onPointerMissed={() => {
clearSelectedEventSphere();
setTransformMode(null);
}}
key={`${i}-${j}`}
position={new THREE.Vector3(...point.position)}
userData={{ modelUuid: event.modelUuid, pointUuid: point.uuid }}
>
<sphereGeometry args={[0.1, 16, 16]} />
<meshStandardMaterial color="orange" />
</mesh>
))}
</group>
);
} else if (event.type === 'vehicle') {
return (
<group key={i} position={new THREE.Vector3(...event.position)}>
<mesh
uuid={event.point.uuid}
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
onClick={(e) => {
e.stopPropagation();
setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
}}
onPointerMissed={() => {
clearSelectedEventSphere();
setTransformMode(null);
}}
position={new THREE.Vector3(...event.point.position)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
>
<sphereGeometry args={[0.1, 16, 16]} />
<meshStandardMaterial color="blue" />
</mesh>
</group>
);
} else if (event.type === 'roboticArm') {
return (
<group key={i} position={new THREE.Vector3(...event.position)}>
<mesh
uuid={event.point.uuid}
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
onClick={(e) => {
e.stopPropagation();
setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
}}
onPointerMissed={() => {
clearSelectedEventSphere();
setTransformMode(null);
}}
position={new THREE.Vector3(...event.point.position)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
>
<sphereGeometry args={[0.1, 16, 16]} />
<meshStandardMaterial color="green" />
</mesh>
</group>
);
} else if (event.type === 'machine') {
return (
<group key={i} position={new THREE.Vector3(...event.position)}>
<mesh
uuid={event.point.uuid}
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
onClick={(e) => {
e.stopPropagation();
setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
}}
onPointerMissed={() => {
clearSelectedEventSphere();
setTransformMode(null);
}}
position={new THREE.Vector3(...event.point.position)}
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
>
<sphereGeometry args={[0.1, 16, 16]} />
<meshStandardMaterial color="purple" />
</mesh>
</group>
);
} else {
return null;
}
})}
</group>
{(selectedEventSphere && transformMode) &&
<TransformControls ref={transformRef} object={selectedEventSphere} mode={transformMode} onMouseUp={(e) => { updatePointToState(selectedEventSphere) }} />
}
</>
}
</>
return event;
})
);
};
const { handlePointerDown } = useDraggableGLTF(updatePointToState);
const { activeModule } = useModuleStore();
const transformRef = useRef<any>(null);
const [transformMode, setTransformMode] = useState<
"translate" | "rotate" | null
>(null);
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
const {
selectedEventSphere,
setSelectedEventSphere,
clearSelectedEventSphere,
} = useSelectedEventSphere();
const { setSelectedEventData, clearSelectedEventData } =
useSelectedEventData();
useEffect(() => {
if (selectedEventSphere) {
const eventData = getEventByModelUuid(
selectedEventSphere.userData.modelUuid
);
if (eventData) {
setSelectedEventData(eventData, selectedEventSphere.userData.pointUuid);
} else {
clearSelectedEventData();
}
} else {
clearSelectedEventData();
}
}, [selectedEventSphere]);
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
const keyCombination = detectModifierKeys(e);
if (!selectedEventSphere) return;
if (keyCombination === "G") {
setTransformMode((prev) => (prev === "translate" ? null : "translate"));
}
if (keyCombination === "R") {
setTransformMode((prev) => (prev === "rotate" ? null : "rotate"));
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [selectedEventSphere]);
const [selectedPoint, setSelectedPoint] = useState<THREE.Mesh | null>(null);
const getDefaultPositions = (modelUuid: string) => {
const modelData = getModelByUuid(modelUuid);
if (modelData) {
const baseX = modelData.position?.[0] || 0;
const baseY = modelData.position?.[1] + 2.8 || 1.5;
const baseZ = modelData.position?.[2] || 0;
return {
pick: [baseX, baseY, baseZ - 2.5],
drop: [baseX, baseY, baseZ - 0.5],
default: [baseX, baseY, baseZ - 1.5],
};
}
return {
pick: [0.5, 1.5, 0],
drop: [-0.5, 1.5, 0],
default: [0, 1.5, 0],
};
};
const getModelByUuid = (modelUuid: string) => {
try {
const modelsJson = localStorage.getItem("FloorItems");
if (modelsJson) {
const models = JSON.parse(modelsJson);
return models.find((m: any) => m.modeluuid === modelUuid);
}
const storeModels = (useModuleStore.getState() as any).models || [];
return storeModels.find((m: any) => m.modelUuid === modelUuid);
} catch (error) {}
return null;
};
useEffect(() => {
console.log("armBotStatusSample: ", armBotStatusSample);
}, [armBotStatusSample]);
return (
<>
{activeModule === "simulation" && (
<>
<group name="EventPointsGroup">
{armBotStatusSample.map((event, i) => {
if (event.type === "roboticArm") {
const defaultPositions = getDefaultPositions(event.modelUuid);
const isSelected =
selectedPoint?.userData?.modelUuid === event.modelUuid;
return (
<group
key={i}
position={new THREE.Vector3(...event.position)}
>
<mesh
uuid={event.point.uuid}
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
onClick={(e) => {
e.stopPropagation();
setSelectedEventSphere(
sphereRefs.current[event.point.uuid]
);
setSelectedPoint(e.object as THREE.Mesh);
}}
onPointerMissed={() => {
clearSelectedEventSphere();
setTransformMode(null);
}}
position={new THREE.Vector3(...defaultPositions.default)}
userData={{
modelUuid: event.modelUuid,
pointUuid: event.point.uuid,
}}
>
<sphereGeometry args={[0.1, 16, 16]} />
<meshStandardMaterial
color={isSelected ? "yellow" : "green"}
/>
</mesh>
{event.point.actions.map((action) => {
if (action.actionType === "pickAndPlace") {
const pickPosition =
action.process.startPoint || defaultPositions.pick;
const dropPosition =
action.process.endPoint || defaultPositions.drop;
return (
<React.Fragment key={action.actionUuid}>
{/* Pick Point */}
<PickDropPoints
position={pickPosition}
modelUuid={event.modelUuid}
pointUuid={event.point.uuid}
actionType="pick"
actionUuid={action.actionUuid}
gltfScene={armUiPick.scene}
selectedPoint={selectedPoint}
handlePointerDown={handlePointerDown}
isSelected={isSelected}
/>
{/* Drop Point */}
<PickDropPoints
position={dropPosition}
modelUuid={event.modelUuid}
pointUuid={event.point.uuid}
actionType="drop"
actionUuid={action.actionUuid}
gltfScene={armUiDrop.scene}
selectedPoint={selectedPoint}
handlePointerDown={handlePointerDown}
isSelected={isSelected}
/>
</React.Fragment>
);
}
return null;
})}
</group>
);
} else {
return null;
}
})}
</group>
</>
)}
</>
);
}
export default PointsCreator;