import { Suspense, useRef, useMemo } from 'react'; import { Canvas, useFrame } from '@react-three/fiber'; import { Float, RoundedBox, MeshDistortMaterial, Sphere } from '@react-three/drei'; import * as THREE from 'three'; import type { LabConstraints, Protocol } from '@/types'; import { cn } from '@/lib/utils'; interface LabScene3DProps { constraints: LabConstraints; protocol: Protocol | null; className?: string; } function LabBench() { return ( {/* Table surface */} {/* Table legs */} {[[-2.2, -0.6, -1], [2.2, -0.6, -1], [-2.2, -0.6, 1], [2.2, -0.6, 1]].map((pos, i) => ( ))} ); } function Equipment({ name, position }: { name: string; position: [number, number, number] }) { const meshRef = useRef(null); const color = useMemo(() => { const colors: Record = { gpu_a100: '#6366f1', gpu_a6000: '#818cf8', wandb_logger: '#10b981', docker_env: '#3b82f6', }; return colors[name] || '#94a3b8'; }, [name]); return ( ); } function Reagent({ name: _name, position }: { name: string; position: [number, number, number] }) { return ( {/* Flask shape */} {/* Neck */} ); } function BudgetIndicator({ budget, budgetRemaining, position }: { budget: number; budgetRemaining: number; position: [number, number, number] }) { const ratio = budget > 0 ? budgetRemaining / budget : 0; const color = ratio > 0.5 ? '#10b981' : ratio > 0.2 ? '#f59e0b' : '#ef4444'; return ( {/* Background bar */} {/* Fill bar */} {/* $ glow */} ); } function SceneContent({ constraints, protocol: _protocol }: { constraints: LabConstraints; protocol: Protocol | null }) { const groupRef = useRef(null); useFrame(({ clock }) => { if (groupRef.current) { groupRef.current.rotation.y = Math.sin(clock.getElapsedTime() * 0.15) * 0.1; } }); const equipPositions: [number, number, number][] = [ [-1.5, -0.5, 0], [-0.5, -0.5, 0], [0.5, -0.5, 0], [1.5, -0.5, 0], ]; const reagentPositions: [number, number, number][] = [ [-1.2, -0.3, 0.8], [-0.4, -0.3, 0.8], [0.4, -0.3, 0.8], [1.2, -0.3, 0.8], ]; return ( {/* Equipment items */} {constraints.equipment_available.slice(0, 4).map((eq, i) => ( ))} {/* Reagent flasks */} {constraints.reagents_available.slice(0, 4).map((rg, i) => ( ))} {/* Budget bar floating above */} {/* Ambient lighting */} ); } export default function LabScene3D({ constraints, protocol, className }: LabScene3DProps) { return (
3D Lab View drag to rotate
Loading 3D scene...
}>
); }