import { useMemo } from 'react';
import { Grid, Environment, Text } from '@react-three/drei';
import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import * as THREE from 'three';
import SceneCanvas from '../SceneCanvas';
import FallbackDiagram from '../FallbackDiagram';
import { WindArrow } from './WindArrow';
import { useCanvasTheme } from '@/lib/theme';
export interface Bridge3DInput {
/** Maior vão Lₚ (m) */
lp: number;
/** Largura do tabuleiro B (m) */
width: number;
/** Altura do tabuleiro z (m) */
deckHeight: number;
/** Altura equivalente H_eq (m) — soma de áreas expostas por metro */
heg: number;
/** Coeficiente de arrasto Cx (adimensional) */
cx: number;
/** Coeficiente de sustentação Cz (adimensional) */
cz: number;
/** Força de arrasto por unidade de comprimento Fx (kN/m) */
fxPerLength: number;
/** Força de sustentação por unidade de comprimento Fz (kN/m) */
fzPerLength: number;
/** Ângulo de ataque do vento (graus) */
alpha: number;
}
function BridgeModel({
lp,
width,
deckHeight,
heg,
cx,
alpha,
}: Bridge3DInput) {
const theme = useCanvasTheme();
const isDark = theme === 'dark';
const halfL = lp / 2;
const halfW = width / 2;
const deckThickness = Math.max(heg, 0.8);
const deckY = deckHeight;
// Cor do tabuleiro baseada em Cx
const deckColor = useMemo(() => {
const intensity = Math.min(1, Math.abs(cx) / 3);
const hue = 200 - intensity * 60;
const l = isDark ? (60 - intensity * 8) : (50 - intensity * 8);
return new THREE.Color(`hsl(${hue}, ${55 + intensity * 30}%, ${l}%)`);
}, [cx, isDark]);
// Pilar heights: posicionar 3 pilares ao longo do vão
const pillarHeights = useMemo(() => [deckY - 0.5, deckY - 0.5, deckY - 0.5], [deckY]);
const barrierColor = isDark ? '#cbd5e1' : '#94a3b8';
const pillarColor = isDark ? '#94a3b8' : '#64748b';
return (
{/* Tabuleiro (deck) */}
{/* Guarda-rodas/barreira lateral */}
{/* Pilares (3 ao longo do comprimento) */}
{pillarHeights.map((h, i) => {
const x = i === 0 ? -halfL + halfL * 0.3 : i === 1 ? 0 : halfL - halfL * 0.3;
return (
);
})}
{/* Solo / água */}
{/* Seta de Vento (bate no meio do tabuleiro) */}
Lp={lp}m | B={width}m | Cx={cx.toFixed(2)}
);
}
export default function Bridge3DViewer(input: Bridge3DInput) {
const theme = useCanvasTheme();
const isDark = theme === 'dark';
const { lp, deckHeight, width } = input;
const dist = Math.max(lp * 0.6, deckHeight * 2);
const fallback = (
);
return (
);
}