feat: Refactor PointsCreator component for improved readability and maintainability

This commit is contained in:
Vishnu 2025-04-29 10:30:28 +05:30
parent 2f65ee6a71
commit dd853a66d4
1 changed files with 228 additions and 164 deletions

View File

@ -1,173 +1,237 @@
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 } from '@react-three/drei'; import { TransformControls } from "@react-three/drei";
import { detectModifierKeys } from '../../../../../utils/shortcutkeys/detectModifierKeys'; import { detectModifierKeys } from "../../../../../utils/shortcutkeys/detectModifierKeys";
import { useSelectedEventSphere, useSelectedEventData } from '../../../../../store/simulation/useSimulationStore'; import {
useSelectedEventSphere,
useSelectedEventData,
} from "../../../../../store/simulation/useSimulationStore";
function PointsCreator() { function PointsCreator() {
const { events, updatePoint, getPointByUuid, getEventByModelUuid } = useEventsStore(); const { events, updatePoint, getPointByUuid, getEventByModelUuid } =
const { activeModule } = useModuleStore(); useEventsStore();
const transformRef = useRef<any>(null); const { activeModule } = useModuleStore();
const [transformMode, setTransformMode] = useState<"translate" | "rotate" | null>(null); const transformRef = useRef<any>(null);
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({}); const [transformMode, setTransformMode] = useState<
const { selectedEventSphere, setSelectedEventSphere, clearSelectedEventSphere } = useSelectedEventSphere(); "translate" | "rotate" | null
const { setSelectedEventData, clearSelectedEventData } = useSelectedEventData(); >(null);
const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({});
const {
selectedEventSphere,
setSelectedEventSphere,
clearSelectedEventSphere,
} = useSelectedEventSphere();
const { setSelectedEventData, clearSelectedEventData } =
useSelectedEventData();
useEffect(() => { useEffect(() => {
if (selectedEventSphere) { if (selectedEventSphere) {
const eventData = getEventByModelUuid(selectedEventSphere.userData.modelUuid); const eventData = getEventByModelUuid(
if (eventData) { selectedEventSphere.userData.modelUuid
setSelectedEventData( );
eventData, if (eventData) {
selectedEventSphere.userData.pointUuid setSelectedEventData(eventData, selectedEventSphere.userData.pointUuid);
); } else {
} else { clearSelectedEventData();
clearSelectedEventData(); }
} } else {
} else { clearSelectedEventData();
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 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)
}
} }
}, [selectedEventSphere]);
return ( useEffect(() => {
<> const handleKeyDown = (e: KeyboardEvent) => {
{activeModule === 'simulation' && const keyCombination = detectModifierKeys(e);
<> if (!selectedEventSphere) return;
<group name='EventPointsGroup' > if (keyCombination === "G") {
{events.map((event, i) => { setTransformMode((prev) => (prev === "translate" ? null : "translate"));
if (event.type === 'transfer') { }
return ( if (keyCombination === "R") {
<group key={i} position={new THREE.Vector3(...event.position)}> setTransformMode((prev) => (prev === "rotate" ? null : "rotate"));
{event.points.map((point, j) => ( }
<mesh };
name='Event-Sphere'
uuid={point.uuid} window.addEventListener("keydown", handleKeyDown);
ref={(el) => (sphereRefs.current[point.uuid] = el!)} return () => window.removeEventListener("keydown", handleKeyDown);
onClick={(e) => { }, [selectedEventSphere]);
e.stopPropagation();
setSelectedEventSphere(sphereRefs.current[point.uuid]); const updatePointToState = (selectedEventSphere: THREE.Mesh) => {
}} let point = JSON.parse(
onPointerMissed={() => { JSON.stringify(
clearSelectedEventSphere(); getPointByUuid(
setTransformMode(null); selectedEventSphere.userData.modelUuid,
}} selectedEventSphere.userData.pointUuid
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
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="blue" />
</mesh>
</group>
);
} else if (event.type === 'roboticArm') {
return (
<group key={i} position={new THREE.Vector3(...event.position)}>
<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="green" />
</mesh>
</group>
);
} else if (event.type === 'machine') {
return (
<group key={i} position={new THREE.Vector3(...event.position)}>
<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) }} />
}
</>
}
</>
); );
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
name="Event-Sphere"
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
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="blue" />
</mesh>
</group>
);
} else if (event.type === "machine") {
return (
<group
key={i}
position={new THREE.Vector3(...event.position)}
>
<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 if (event.type === "roboticArm") {
return (
<group
key={i}
position={new THREE.Vector3(...event.position)}
>
<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="green" />
</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;