import React, { useRef } from 'react'; import { TransformControls, Text } from '@react-three/drei'; import * as THREE from 'three'; import { SimObject, ObjectType, AxisObject, CylinderObject, LedObject, SwitchObject } from '../types'; interface ObjectProps { data: SimObject; isSelected: boolean; isPlaying?: boolean; onSelect: (id: string) => void; onUpdate: (id: string, updates: Partial) => void; onInteract?: (id: string) => void; } // -- Helper Material -- const selectedMaterial = new THREE.MeshBasicMaterial({ color: '#4ade80', wireframe: true, transparent: true, opacity: 0.5 }); // -- Linear Axis Component -- export const LinearAxis: React.FC = ({ data, isSelected, isPlaying, onSelect }) => { const axis = data as AxisObject; const railLength = 5; const normalizedPos = ((axis.currentValue - axis.min) / (axis.max - axis.min)) * railLength; const safePos = isNaN(normalizedPos) ? 0 : Math.max(0, Math.min(railLength, normalizedPos)); return ( { e.stopPropagation(); if (!isPlaying) onSelect(axis.id); }} > {axis.name} ({axis.currentValue.toFixed(1)}) {isSelected && !isPlaying && ( )} ); }; // -- Rotary Axis Component -- export const RotaryAxis: React.FC = ({ data, isSelected, isPlaying, onSelect }) => { const axis = data as AxisObject; const rotationAngle = (axis.currentValue % 360) * (Math.PI / 180); return ( { e.stopPropagation(); if (!isPlaying) onSelect(axis.id); }} > {axis.name} ({axis.currentValue.toFixed(0)}°) {isSelected && !isPlaying && ( )} ); }; // -- Cylinder Component -- export const Cylinder: React.FC = ({ data, isSelected, isPlaying, onSelect }) => { const cyl = data as CylinderObject; const housingLen = 2; const extension = Math.min(cyl.stroke, Math.max(0, cyl.currentPosition)); return ( { e.stopPropagation(); if (!isPlaying) onSelect(cyl.id); }} > {cyl.name} {isSelected && !isPlaying && ( )} ); }; // -- Switch Component -- export const Switch: React.FC = ({ data, isSelected, isPlaying, onSelect, onInteract }) => { const sw = data as SwitchObject; return ( { e.stopPropagation(); if (!isPlaying) onSelect(sw.id); if(onInteract) onInteract(sw.id); }} > {sw.name} {isSelected && !isPlaying && ( )} ); }; // -- LED Component -- export const Led: React.FC = ({ data, isSelected, isPlaying, onSelect }) => { const led = data as LedObject; return ( { e.stopPropagation(); if (!isPlaying) onSelect(led.id); }} > {led.name} {isSelected && !isPlaying && ( )} ); }; export const EditableObject: React.FC = (props) => { const { data, enableTransform, isPlaying, onUpdate } = props; const handleTransformChange = (e: any) => { if (e.target.object) { const o = e.target.object; onUpdate(data.id, { position: { x: o.position.x, y: o.position.y, z: o.position.z }, rotation: { x: o.rotation.x, y: o.rotation.y, z: o.rotation.z } }); } }; const Component = data.type === ObjectType.AXIS_LINEAR ? LinearAxis : data.type === ObjectType.AXIS_ROTARY ? RotaryAxis : data.type === ObjectType.CYLINDER ? Cylinder : data.type === ObjectType.SWITCH ? Switch : Led; return ( <> {props.isSelected && enableTransform && !isPlaying && ( )} ); };