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...
}>
);
}