import { useMemo } from 'react';
import * as THREE from 'three';
import { Html } from '@react-three/drei';
import { BUILDINGS, COLORS } from '../constants';
interface BuildingsProps {
detailMode?: boolean;
onBuildingClick?: (building: string) => void;
}
function WindowGrid({ width, height, depth }: { width: number; height: number; depth: number }) {
const windows = useMemo(() => {
const cols = 4;
const rows = 3;
const winW = 1.5;
const winH = 0.8;
const winD = 0.05;
const gapX = (width - cols * winW) / (cols + 1);
const gapY = (height - rows * winH) / (rows + 1);
const items: { pos: [number, number, number] }[] = [];
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
const x = -width / 2 + gapX + winW / 2 + c * (winW + gapX);
const y = -height / 2 + gapY + winH / 2 + r * (winH + gapY);
items.push({ pos: [x, y, depth / 2 + winD / 2] });
}
}
return items;
}, [width, height, depth]);
return (
{windows.map((w, i) => (
))}
);
}
function Building({
label,
position,
size,
opacity,
onClick,
}: {
label: string;
position: [number, number, number];
size: [number, number, number];
opacity: number;
onClick?: () => void;
}) {
const [w, h, d] = size;
const edgesGeo = useMemo(() => {
const box = new THREE.BoxGeometry(w, h, d);
return new THREE.EdgesGeometry(box);
}, [w, h, d]);
const labelStyle: React.CSSProperties = {
fontSize: '13px',
color: COLORS.text,
background: 'rgba(6, 30, 62, 0.8)',
padding: '2px 8px',
borderRadius: '4px',
border: '1px solid rgba(0, 212, 255, 0.2)',
whiteSpace: 'nowrap',
pointerEvents: 'none',
};
return (
{ e.stopPropagation(); onClick(); } : undefined}>
{/* Main body */}
{/* Edge highlight */}
{/* Windows on front face */}
{/* Label */}
{label}
);
}
export default function Buildings({ detailMode, onBuildingClick }: BuildingsProps) {
const opacity = detailMode ? 0.15 : 0.85;
return (
onBuildingClick('east') : undefined}
/>
onBuildingClick('west') : undefined}
/>
);
}