import { Text, Grid, Environment } from '@react-three/drei';
import { WindArrow as GlobalWindArrow } from './WindArrow';
import { ViewerOrbitControls as OrbitControls } from './ViewerOrbitControls';
import SceneCanvas from '../SceneCanvas';
import { useCanvasTheme } from '@/lib/theme';
import { ShelterAirflowSystem } from './ShelterAirflowSystem';
import type { ShelterCondition, OpeningPosition, ShelterWindAngle } from '@/lib/nbr-tables/table-shelters';
export interface Shelter3DProps {
condition: ShelterCondition;
depth: number;
width: number;
height: number;
theta: number;
backClosure: number;
leftClosure: number;
rightClosure: number;
openingPos: OpeningPosition;
backRange?: [number, number];
numColumns?: number;
windAngle?: ShelterWindAngle;
viewMode: '3d' | 'elevation' | 'airflow';
}
function ShelterModel({
condition: _condition,
depth,
width,
height,
theta,
backClosure,
leftClosure,
rightClosure,
openingPos,
backRange,
numColumns = 2,
windAngle: _windAngle = 0,
viewMode,
}: Shelter3DProps) {
const isElevation = viewMode === 'elevation';
const theme = useCanvasTheme();
const isDark = theme === 'dark';
// Geometria básica
const halfW = width / 2;
const halfD = depth / 2;
const isAirflow = viewMode === 'airflow';
const thetaRad = (theta * Math.PI) / 180;
const slopeRise = depth * Math.tan(thetaRad);
// Paredes com abertura no topo ou na base (sem caixas/linhas brancas deslocadas)
const renderWallWithGap = (
w: number,
h: number,
closure: number,
pos: OpeningPosition,
rotY = 0,
position: [number, number, number] = [0, 0, 0],
customRange?: [number, number]
) => {
if (closure <= 0) return null;
let op = closure / 100;
let wallH = h * op;
let yPos = position[1] + wallH / 2;
if (customRange && closure < 100) {
const bottomPct = Math.max(0, Math.min(100, customRange[0])) / 100;
const topPct = Math.max(0, Math.min(100, customRange[1])) / 100;
op = Math.max(0.01, topPct - bottomPct);
wallH = h * op;
yPos = position[1] + h * bottomPct + wallH / 2;
} else if (pos === 'top' && closure < 100) {
// Parede na parte de baixo, fresta no topo
yPos = position[1] + wallH / 2;
} else if (pos === 'bottom' && closure < 100) {
// Parede suspensa na parte superior, vão na base
yPos = position[1] + h - wallH / 2;
}
return (
);
};
const overhang = 0.6;
const spanWidth = Math.max(0.1, width - 2 * overhang);
const spacing = spanWidth / Math.max(1, numColumns - 1);
const columnPositions = Array.from({ length: numColumns }).map(
(_, i) => -halfW + overhang + i * spacing
);
return (
{/* 1. Estrutura Metálica Principal (Pilares e Vigas em Balanço - Tubos Quadrados) */}
{columnPositions.map((xPos, idx) => (
{/* Pilar traseiro (lado direito na elevação) */}
{/* Viga horizontal em balanço (TUBO QUAD. 150x150) */}
))}
{/* 2. Cobertura / Marquise */}
{/* 3. Fechamentos de Fundo e Laterais (com suporte a fresta/abertura) */}
{/* Parede de Fundo (Traseira Z = +halfD) */}
{renderWallWithGap(width, height, backClosure, openingPos, 0, [0, 0, halfD], backRange)}
{/* Parede Lateral Esquerda (X = -halfW) */}
{renderWallWithGap(depth, height, leftClosure, 'distributed', Math.PI / 2, [-halfW, 0, 0])}
{/* Parede Lateral Direita (X = +halfW) */}
{renderWallWithGap(depth, height, rightClosure, 'distributed', Math.PI / 2, [halfW, 0, 0])}
{/* Seta de Vento Global (Sempre visível para não pular de posição) */}
Vento
{/* Partículas de Ar */}
{isAirflow && (
)}
{/* Textos Informativos 3D - Virados para quem olha da frente (-Z) */}
{!isAirflow && (
<>
{isElevation ? 'CORTE A-A (Elevação)' : 'Abrigo / Pórtico (NBR 6123)'}
Arrancamento [+Fz ↑]
Empuxo no Fundo [+Fx →]
>
)}
);
}
export function Shelter3D(props: Shelter3DProps) {
const theme = useCanvasTheme();
const isDark = theme === 'dark';
const { width, depth, height, viewMode } = props;
const dist = Math.max(width, depth) * 1.8 + 8;
return (
3D indisponível}
>
);
}
export default Shelter3D;