Merge remote-tracking branch 'origin/v2-ui' into v2
This commit is contained in:
commit
ccc7a1d954
|
@ -1,112 +1,19 @@
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import * as THREE from "three";
|
import * as THREE from 'three';
|
||||||
import { useEventsStore } from "../../../../../store/simulation/useEventsStore";
|
import { useEventsStore } from '../../../../../store/simulation/useEventsStore';
|
||||||
import useModuleStore from "../../../../../store/useModuleStore";
|
import useModuleStore from '../../../../../store/useModuleStore';
|
||||||
import { TransformControls, useGLTF } from "@react-three/drei";
|
import { TransformControls } from '@react-three/drei';
|
||||||
import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
|
import { detectModifierKeys } from '../../../../../utils/shortcutkeys/detectModifierKeys';
|
||||||
import {
|
import { useSelectedEventSphere, useSelectedEventData } from '../../../../../store/simulation/useSimulationStore';
|
||||||
useSelectedEventSphere,
|
|
||||||
useSelectedEventData,
|
|
||||||
} from "../../../../../store/simulation/useSimulationStore";
|
|
||||||
import PickDropPoints from "../../../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 "../../../ui/arm/useDraggableGLTF";
|
|
||||||
import { useArmBotStore } from "../../../../../store/simulation/useArmBotStore";
|
|
||||||
import { useThree } from "@react-three/fiber";
|
|
||||||
|
|
||||||
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() {
|
function PointsCreator() {
|
||||||
const { events, updatePoint, getPointByUuid, getEventByModelUuid } =
|
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore();
|
||||||
useEventsStore();
|
const { activeModule } = useModuleStore();
|
||||||
const { armBots, updateArmBot, addArmBot, removeArmBot } = useArmBotStore()
|
const transformRef = useRef<any>(null);
|
||||||
|
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null);
|
||||||
const armUiPick = useGLTF(armPick) as any;
|
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
|
||||||
const armUiDrop = useGLTF(armDrop) as any;
|
const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere } = useSelectedEventSphere();
|
||||||
|
const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData();
|
||||||
const updatePointToState = (obj: THREE.Object3D) => {
|
|
||||||
const { modelUuid, pointUuid, actionType, actionUuid } = obj.userData;
|
|
||||||
|
|
||||||
const newPosition = new THREE.Vector3();
|
|
||||||
obj.getWorldPosition(newPosition);
|
|
||||||
const worldPositionArray = newPosition.toArray();
|
|
||||||
|
|
||||||
const armBot = armBots.find((a) => a.modelUuid === modelUuid);
|
|
||||||
if (!armBot) return;
|
|
||||||
|
|
||||||
const updatedActions = armBot.point.actions.map((action: any) => {
|
|
||||||
if (action.actionUuid === actionUuid) {
|
|
||||||
const updatedProcess = { ...action.process };
|
|
||||||
|
|
||||||
if (actionType === "pick") {
|
|
||||||
updatedProcess.startPoint = getLocalPosition(modelUuid, worldPositionArray);
|
|
||||||
}
|
|
||||||
if (actionType === "drop") {
|
|
||||||
updatedProcess.endPoint = getLocalPosition(modelUuid, worldPositionArray);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...action,
|
|
||||||
process: updatedProcess,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return action;
|
|
||||||
});
|
|
||||||
|
|
||||||
updateArmBot(modelUuid, {
|
|
||||||
point: {
|
|
||||||
...armBot.point,
|
|
||||||
actions: updatedActions,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const { handlePointerDown } = useDraggableGLTF(updatePointToState);
|
|
||||||
const { scene } = useThree();
|
|
||||||
const { activeModule } = useModuleStore();
|
|
||||||
const transformRef = useRef<any>(null);
|
|
||||||
const groupRef = 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(() => {
|
useEffect(() => {
|
||||||
if (selectedEventSphere) {
|
if (selectedEventSphere) {
|
||||||
|
@ -139,149 +46,127 @@ function PointsCreator() {
|
||||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||||
}, [selectedEventSphere]);
|
}, [selectedEventSphere]);
|
||||||
|
|
||||||
const [selectedPoint, setSelectedPoint] = useState<THREE.Mesh | null>(null);
|
const updatePointToState = (selectedEventSphere: THREE.Mesh) => {
|
||||||
|
let point = JSON.parse(JSON.stringify(getPointByUuid(selectedEventSphere.userData.modelUuid, selectedEventSphere.userData.pointUuid)));
|
||||||
const getDefaultPositions = (modelUuid: string) => {
|
if (point) {
|
||||||
const modelData = getModelByUuid(modelUuid);
|
point.position = [selectedEventSphere.position.x, selectedEventSphere.position.y, selectedEventSphere.position.z];
|
||||||
if (modelData) {
|
updatePoint(selectedEventSphere.userData.modelUuid, selectedEventSphere.userData.pointUuid, point)
|
||||||
|
}
|
||||||
const baseX = modelData.position?.[0] || 0;
|
|
||||||
const baseY = 2.6;
|
|
||||||
const baseZ = modelData.position?.[2] || 0;
|
|
||||||
return {
|
|
||||||
pick: [baseX, baseY, baseZ + 0.4],
|
|
||||||
drop: [baseX, baseY, baseZ - 1.2],
|
|
||||||
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) => {
|
return (
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
function getLocalPosition(parentUuid: string, worldPosArray: [number, number, number] | null): [number, number, number] | null {
|
|
||||||
if (worldPosArray) {
|
|
||||||
const worldPos = new THREE.Vector3(...worldPosArray);
|
|
||||||
const localPos = worldPos.clone();
|
|
||||||
|
|
||||||
const parentObject = scene.getObjectByProperty('uuid', parentUuid);
|
|
||||||
if (parentObject) {
|
|
||||||
parentObject.worldToLocal(localPos);
|
|
||||||
|
|
||||||
return [localPos.x, localPos.y, localPos.z];
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
|
|
||||||
}, [armBots]);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{activeModule === "simulation" && (
|
|
||||||
<>
|
<>
|
||||||
<group name="EventPointsGroup">
|
{activeModule === 'simulation' &&
|
||||||
{armBots.map((event, i) => {
|
<>
|
||||||
if (event.type === "roboticArm") {
|
<group name='EventPointsGroup' >
|
||||||
const defaultPositions = getDefaultPositions(event.modelUuid);
|
{events.map((event, i) => {
|
||||||
const isSelected =
|
if (event.type === 'transfer') {
|
||||||
selectedPoint?.userData?.modelUuid === event.modelUuid;
|
return (
|
||||||
return (
|
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||||
<group
|
{event.points.map((point, j) => (
|
||||||
key={i}
|
<mesh
|
||||||
position={new THREE.Vector3(...event.position)}
|
name='Event-Sphere'
|
||||||
rotation={new THREE.Euler(...event.rotation)}
|
uuid={point.uuid}
|
||||||
>
|
ref={(el) => (sphereRefs.current[point.uuid] = el!)}
|
||||||
<mesh
|
onClick={(e) => {
|
||||||
name='Event-Sphere'
|
e.stopPropagation();
|
||||||
uuid={event.point.uuid}
|
setSelectedEventSphere(sphereRefs.current[point.uuid]);
|
||||||
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
|
}}
|
||||||
onClick={(e) => {
|
onPointerMissed={() => {
|
||||||
e.stopPropagation();
|
clearSelectedEventSphere();
|
||||||
setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
|
setTransformMode(null);
|
||||||
setSelectedPoint(e.object as THREE.Mesh);
|
}}
|
||||||
}}
|
key={`${i}-${j}`}
|
||||||
onPointerMissed={() => {
|
position={new THREE.Vector3(...point.position)}
|
||||||
clearSelectedEventSphere();
|
userData={{ modelUuid: event.modelUuid, pointUuid: point.uuid }}
|
||||||
setTransformMode(null);
|
>
|
||||||
}}
|
<sphereGeometry args={[0.1, 16, 16]} />
|
||||||
position={new THREE.Vector3(...event.point.position)}
|
<meshStandardMaterial color="orange" />
|
||||||
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
</mesh>
|
||||||
>
|
))}
|
||||||
<sphereGeometry args={[0.1, 16, 16]} />
|
</group>
|
||||||
<meshStandardMaterial
|
);
|
||||||
color={isSelected ? "yellow" : "green"}
|
} else if (event.type === 'vehicle') {
|
||||||
/>
|
return (
|
||||||
</mesh>
|
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||||
{event.point.actions.map((action) => {
|
<mesh
|
||||||
if (action.actionType === "pickAndPlace") {
|
name='Event-Sphere'
|
||||||
|
uuid={event.point.uuid}
|
||||||
const pickPosition =
|
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
|
||||||
action.process.startPoint || defaultPositions.pick;
|
onClick={(e) => {
|
||||||
const dropPosition =
|
e.stopPropagation();
|
||||||
action.process.endPoint || defaultPositions.drop;
|
setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
|
||||||
|
}}
|
||||||
return (
|
onPointerMissed={() => {
|
||||||
<React.Fragment key={action.actionUuid}>
|
clearSelectedEventSphere();
|
||||||
{/* Pick Point */}
|
setTransformMode(null);
|
||||||
<PickDropPoints
|
}}
|
||||||
position={pickPosition}
|
position={new THREE.Vector3(...event.point.position)}
|
||||||
modelUuid={event.modelUuid}
|
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||||
pointUuid={event.point.uuid}
|
>
|
||||||
actionType="pick"
|
<sphereGeometry args={[0.1, 16, 16]} />
|
||||||
actionUuid={action.actionUuid}
|
<meshStandardMaterial color="blue" />
|
||||||
gltfScene={armUiPick.scene}
|
</mesh>
|
||||||
selectedPoint={selectedPoint}
|
</group>
|
||||||
handlePointerDown={handlePointerDown}
|
);
|
||||||
isSelected={isSelected}
|
} else if (event.type === 'roboticArm') {
|
||||||
/>
|
return (
|
||||||
|
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||||
{/* Drop Point */}
|
<mesh
|
||||||
<PickDropPoints
|
name='Event-Sphere'
|
||||||
position={dropPosition}
|
uuid={event.point.uuid}
|
||||||
modelUuid={event.modelUuid}
|
ref={(el) => (sphereRefs.current[event.point.uuid] = el!)}
|
||||||
pointUuid={event.point.uuid}
|
onClick={(e) => {
|
||||||
actionType="drop"
|
e.stopPropagation();
|
||||||
actionUuid={action.actionUuid}
|
setSelectedEventSphere(sphereRefs.current[event.point.uuid]);
|
||||||
gltfScene={armUiDrop.scene}
|
}}
|
||||||
selectedPoint={selectedPoint}
|
onPointerMissed={() => {
|
||||||
handlePointerDown={handlePointerDown}
|
clearSelectedEventSphere();
|
||||||
isSelected={isSelected}
|
setTransformMode(null);
|
||||||
/>
|
}}
|
||||||
</React.Fragment>
|
position={new THREE.Vector3(...event.point.position)}
|
||||||
);
|
userData={{ modelUuid: event.modelUuid, pointUuid: event.point.uuid }}
|
||||||
}
|
>
|
||||||
return null;
|
<sphereGeometry args={[0.1, 16, 16]} />
|
||||||
})}
|
<meshStandardMaterial color="green" />
|
||||||
</group>
|
</mesh>
|
||||||
);
|
</group>
|
||||||
} else {
|
);
|
||||||
return null;
|
} else if (event.type === 'machine') {
|
||||||
}
|
return (
|
||||||
})}
|
<group key={i} position={new THREE.Vector3(...event.position)}>
|
||||||
</group>
|
<mesh
|
||||||
|
name='Event-Sphere'
|
||||||
|
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) }} />
|
||||||
|
}
|
||||||
|
</>
|
||||||
|
}
|
||||||
</>
|
</>
|
||||||
)}
|
);
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PointsCreator;
|
export default PointsCreator;
|
||||||
|
|
Loading…
Reference in New Issue