import * as THREE from 'three'; import { useRef, useState, useEffect } from 'react'; import { Sphere, TransformControls } from '@react-three/drei'; import { useIsConnecting, useRenderDistance, useSelectedActionSphere, useSelectedPath, useSimulationPaths } from '../../../store/store'; import { useFrame, useThree } from '@react-three/fiber'; import { useSubModuleStore } from '../../../store/useModuleStore'; import { point } from '@turf/helpers'; interface ConveyorEventsSchema { modeluuid: string; modelName: string; type: 'Conveyor'; points: { uuid: string; position: [number, number, number]; rotation: [number, number, number]; actions: { uuid: string; name: string; type: string; material: string; delay: number | string; spawnInterval: number | string; isUsed: boolean }[] | []; triggers: { uuid: string; name: string; type: string; isUsed: boolean }[] | []; connections: { source: { pathUUID: string; pointUUID: string }; targets: { pathUUID: string; pointUUID: string }[] }; }[]; assetPosition: [number, number, number]; assetRotation: [number, number, number]; speed: number; } function PathCreation({ pathsGroupRef }: { pathsGroupRef: React.MutableRefObject }) { const { renderDistance } = useRenderDistance(); const { setSubModule } = useSubModuleStore(); const { setSelectedActionSphere, selectedActionSphere } = useSelectedActionSphere(); const { setSelectedPath } = useSelectedPath(); const { simulationPaths, setSimulationPaths } = useSimulationPaths(); const { isConnecting } = useIsConnecting(); const { camera } = useThree(); const groupRefs = useRef<{ [key: string]: THREE.Group }>({}); const sphereRefs = useRef<{ [key: string]: THREE.Mesh }>({}); const transformRef = useRef(null); const [transformMode, setTransformMode] = useState<'translate' | 'rotate' | null>(null); useEffect(() => { setTransformMode(null); const handleKeyDown = (e: KeyboardEvent) => { if (!selectedActionSphere) return; if (e.key === 'g') { setTransformMode(prev => prev === 'translate' ? null : 'translate'); } if (e.key === 'r') { setTransformMode(prev => prev === 'rotate' ? null : 'rotate'); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [selectedActionSphere]); useFrame(() => { Object.values(groupRefs.current).forEach(group => { if (group) { const distance = new THREE.Vector3(...group.position.toArray()).distanceTo(camera.position); group.visible = distance <= renderDistance; } }); }); const updateSimulationPaths = () => { if (!selectedActionSphere) return; const updatedPaths = simulationPaths.map((path) => { if (path.type === "Conveyor") { return { ...path, points: path.points.map((point) => point.uuid === selectedActionSphere.point.uuid ? { ...point, position: [ selectedActionSphere.point.position.x, selectedActionSphere.point.position.y, selectedActionSphere.point.position.z, ], rotation: [ selectedActionSphere.point.rotation.x, selectedActionSphere.point.rotation.y, selectedActionSphere.point.rotation.z, ] } : point ), }; } return path; }) as ConveyorEventsSchema[]; setSimulationPaths(updatedPaths); }; return ( {simulationPaths.map((path) => { if (path.type === 'Conveyor') { const points = path.points.map(point => new THREE.Vector3(...point.position)); return ( (groupRefs.current[path.modeluuid] = el!)} position={path.assetPosition} rotation={path.assetRotation} onClick={(e) => { if (isConnecting) return; e.stopPropagation(); setSelectedPath({ path, group: groupRefs.current[path.modeluuid] }); setSelectedActionSphere(null); setTransformMode(null); setSubModule('mechanics'); }} onPointerMissed={() => { setSelectedPath(null); setSubModule('properties'); }} > {path.points.map((point, index) => ( (sphereRefs.current[point.uuid] = el!)} onClick={(e) => { if (isConnecting) return; e.stopPropagation(); setSelectedActionSphere({ path, point: sphereRefs.current[point.uuid] }); setSubModule('mechanics'); setSelectedPath(null); }} userData={{ point, path }} onPointerMissed={() => { setSubModule('properties'); setSelectedActionSphere(null); }} > ))} {points.slice(0, -1).map((point, index) => { const nextPoint = points[index + 1]; const segmentCurve = new THREE.CatmullRomCurve3([point, nextPoint]); const tubeGeometry = new THREE.TubeGeometry(segmentCurve, 20, 0.1, 16, false); return ( ); })} ); } else if (path.type === 'Vehicle') { return ( (groupRefs.current[path.modeluuid] = el!)} position={path.assetPosition} onClick={(e) => { if (isConnecting) return; e.stopPropagation(); setSelectedPath({ path, group: groupRefs.current[path.modeluuid] }); setSelectedActionSphere(null); setTransformMode(null); setSubModule('mechanics'); }} onPointerMissed={() => { setSelectedPath(null); setSubModule('properties'); }} > (sphereRefs.current[path.point.uuid] = el!)} onClick={(e) => { if (isConnecting) return; e.stopPropagation(); setSelectedActionSphere({ path, point: sphereRefs.current[path.point.uuid] }); setSubModule('mechanics'); setSelectedPath(null); }} userData={{ point: path.point, path }} onPointerMissed={() => { setSubModule('properties'); setSelectedActionSphere(null); }} > ); } return null; })} {selectedActionSphere && transformMode && ( )} ); } export default PathCreation;