import { useState } from 'react'; import { Eye, LayoutGrid, Grid3X3, Box, Ruler, Trash2, Camera, Move, RotateCw, RefreshCw, ChevronUp, ChevronDown, Grip, ClipboardCheck, X, Crosshair, Magnet, HelpCircle, Maximize2, } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Slider } from '@/components/ui/slider'; import { ScrollArea } from '@/components/ui/scroll-area'; import { useModelStore } from '@/stores/useModelStore'; import { InspectionChecklist } from '@/components/InspectionChecklist'; import { ScaleSelector } from '@/components/ScaleSelector'; import { toast } from 'sonner'; const POSITION_STEP = 0.001; const ROTATION_STEP = 0.1; interface XRHudProps { freeMove: boolean; onToggleFreeMove: () => void; placementMode?: boolean; onTogglePlacement?: () => void; snapToPlanes?: boolean; onToggleSnap?: () => void; allowScale?: boolean; onToggleAllowScale?: () => void; } const helpItems = [ { title: 'Agarrar a peça (Grip)', icon: '✊', desc: 'Aproxime o controle e APERTE O GRIP LATERAL — a peça vira extensão da sua mão (mover + girar em 6 eixos). Solte o grip para fixar na posição.', }, { title: 'Two-Hand (girar/escalar)', icon: '🤲', desc: 'Aperte o grip dos DOIS controles ao mesmo tempo. Gire os punhos para rotacionar a peça pelo eixo entre as mãos. Aproxime/afaste para escalar (apenas se o toggle "Escala" estiver ON).', }, { title: 'Posicionar (Hit-Test)', icon: '🎯', desc: 'Aponte para uma superfície real e toque para posicionar o modelo. O retículo verde indica onde o modelo será colocado.', }, { title: 'Snap (Planos)', icon: '🧲', desc: 'Quando ativado, o modelo se alinha automaticamente a planos detectados (chão, parede, mesa). O retículo fica azul quando snap está ativo.', }, { title: 'Joystick (ajuste fino)', icon: '🕹️', desc: 'Esquerdo: X (lateral) / Z (frente-trás). Direito: rotação Y / altura Y. Aperte o TRIGGER para acelerar (leve = passo fino, forte = passo rápido). O joystick é desativado enquanto você segura o grip (que tem prioridade para agarrar).', }, { title: 'Grid', icon: '📐', desc: 'Exibe/oculta a grade de referência para auxiliar no alinhamento visual do modelo com o ambiente.', }, { title: 'Sólido / Wire / Bordas', icon: '🔲', desc: 'Alterna entre modos de renderização: Sólido (preenchido), Wireframe (malha de arame), Bordas (apenas contornos).', }, { title: 'Medir', icon: '📏', desc: 'Ative e toque em dois pontos no modelo para medir a distância entre eles em milímetros. O snap de vértice auxilia na precisão.', }, { title: 'Screenshot', icon: '📸', desc: 'Captura uma imagem da visão AR atual. As capturas ficam salvas na galeria do viewer.', }, { title: 'Inspeção', icon: '📋', desc: 'Abre o checklist de inspeção para aprovar ou rejeitar itens como dimensões, furos, soldas e posição das placas.', }, { title: 'Opacidade', icon: '👁️', desc: 'Ajusta a transparência do modelo de 0% (invisível) a 100% (opaco) para visualizar através da peça.', }, { title: 'Posição (mm)', icon: '↔️', desc: 'Ajuste fino da posição do modelo nos eixos X, Y e Z com incrementos de 1mm usando os botões +/−.', }, { title: 'Rotação X° / Y° / Z°', icon: '🔄', desc: 'Rotaciona o modelo ao redor de cada eixo com incrementos de 0.1°. X = inclinação frontal, Y = giro lateral, Z = tombamento.', }, { title: 'Botões A/B (Touch Plus)', icon: '🎮', desc: 'Atualmente reservados para o sistema (menu Meta). O fluxo natural usa Grip para agarrar e Trigger para acelerar o joystick.', }, ]; export function XRHud({ freeMove, onToggleFreeMove, placementMode = false, onTogglePlacement, snapToPlanes = true, onToggleSnap, allowScale = false, onToggleAllowScale }: XRHudProps) { const [expanded, setExpanded] = useState(false); const [checklistOpen, setChecklistOpen] = useState(false); const [helpOpen, setHelpOpen] = useState(false); const { opacity, setOpacity, renderMode, setRenderMode, showGrid, setShowGrid, measureMode, setMeasureMode, measurements, clearMeasurements, measurePoints, fineTuning, setFineTuning, resetFineTuning, addScreenshot, checklist, } = useModelStore(); const approved = checklist.filter(i => i.status === 'approved').length; const rejected = checklist.filter(i => i.status === 'rejected').length; const total = checklist.length; const handleScreenshot = () => { const canvas = document.querySelector('canvas'); if (!canvas) return; const dataUrl = canvas.toDataURL('image/png'); addScreenshot(dataUrl); toast.success('Screenshot capturado!'); }; return ( <> {/* ── Slide-out checklist panel ── */}
Inspeção
{approved + rejected}/{total}
{/* ── Slide-out help panel ── */}
Ajuda — Ferramentas AR
{helpItems.map((item) => (
{item.icon} {item.title}

{item.desc}

))}
{/* ── Bottom HUD ── */}
{/* Expanded panel */} {expanded && (
{/* Opacity */}
Opacidade
{Math.round(opacity * 100)}%
setOpacity(v / 100)} />
{/* Fine Tuning */}
Posição (mm)
{(['posX', 'posY', 'posZ'] as const).map((axis) => (
{axis.slice(-1).toUpperCase()} {(fineTuning[axis] * 1000).toFixed(1)}
))}
{/* Rotation X, Y, Z */}
Rotação
{(['rotX', 'rotY', 'rotZ'] as const).map((axis) => (
{axis.slice(-1).toUpperCase()}° {fineTuning[axis].toFixed(1)}
))}
)} {/* Main toolbar */}
{/* Help button */} {/* Hit-test placement toggle */} {onTogglePlacement && ( )} {/* Snap to planes toggle */} {onToggleSnap && ( )} {/* Two-hand scale toggle */} {onToggleAllowScale && ( )} {/* Scale presets */} {measurements.length > 0 && ( )} {/* Checklist toggle */}
); }