import { useRef } from 'react'; import { useFrame } from '@react-three/fiber'; import * as THREE from 'three'; import { useStore } from '../store'; // Visual representation of the fluid field (Navier-Stokes snapshot from backend) export default function FluidField() { const { fluidField } = useStore(); const groupRef = useRef(null); useFrame(({ clock }) => { if (!groupRef.current) return; groupRef.current.children.forEach((child, i) => { const mesh = child as THREE.Mesh; // Subtle pulsing animation on field cells mesh.position.y = mesh.userData.baseY + Math.sin(clock.elapsedTime * 2 + i) * 0.05; }); }); if (!fluidField || fluidField.length === 0) return null; const N = Math.sqrt(fluidField.length); const spacing = 1.2; const offset = (N * spacing) / 2; return ( {fluidField.map((elevation, idx) => { const col = idx % N; const row = Math.floor(idx / N); const x = col * spacing - offset; const z = row * spacing - offset; const y = elevation; const intensity = Math.abs(elevation); return ( ); })} {/* Label */} ); }