Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-05-19 20:57:29 +00:00
parent 01f420814b
commit b52bf3605a
+36 -38
View File
@@ -1,46 +1,44 @@
## Contexto # Plano: Mini-menu de Captura (Foto + Vídeo) no Modo AR
O grid vermelho/azul que aparece perto de paredes/objetos é o **Space Sense / Guardian** do Quest 3 — renderizado pelo runtime da Meta, não pelo app. O app não consegue desligá-lo por código. Porém, **a sensibilidade desse sistema aumenta** quando a WebXR session pede features como `mesh-detection`, `depth-sensing`, `anchors`, etc. Hoje o app usa `createXRStore({...})` sem lista explícita de features, então a lib `@react-three/xr` solicita o conjunto default — que inclui várias features que não usamos. ## Objetivo
Adicionar dentro do HUD flutuante do modo AR um pequeno menu de captura com:
- **📸 Foto** — screenshot do canvas (já existe lógica, expor no AR)
- **● Gravar / ⏸ Pausar / ▶ Retomar / ■ Parar** — gravação de vídeo do canvas WebXR
## O que vou fazer (Onda 2, sem quebrar nada) ## O que será implementado
**Auditoria do `createXRStore` em `src/pages/XRSession.tsx`** para pedir só o que realmente usamos: ### 1. Novo hook `useCanvasRecorder` (`src/hooks/useCanvasRecorder.ts`)
- Usa `canvas.captureStream(30)` + `MediaRecorder` (codec `video/webm;codecs=vp9` com fallback p/ vp8).
- Estados expostos: `status` (`idle | recording | paused`), `elapsedMs`.
- Métodos: `start()`, `pause()`, `resume()`, `stop()`.
- Ao parar: monta `Blob` webm, gera `URL.createObjectURL`, dispara download automático (`tracksteel-AR-<timestamp>.webm`) e também salva uma referência opcional para galeria futura.
- Captura screenshot via `canvas.toDataURL('image/png')` reutilizando o store (`addScreenshot`) — mesma lógica já presente em `XRHud.tsx`.
- **Manter (usado):** ### 2. Nova aba "Captura" no HUD 3D (`src/components/three/XRHudInWorld.tsx`)
- `hit-test` — usado por `XRHitTestPlacement` - Adicionar tab `capture` (ícone 🎥) na barra de tabs (junto com Cena, Ferram., Inspeção, Compart., WebXR).
- `plane-detection` — usado por `XRHitTestPlacement` (snap) e `XRPlaneOverlay` - Componente `CaptureTab` com botões 3D (`XR3DButton`):
- `local-floor` — reference space padrão - **📸 Foto** — chama screenshot, mostra toast "Foto capturada".
- `hand-tracking` — usado - **● REC** (vermelho quando gravando) — inicia/para gravação.
- **Remover do request (não usado):** - **⏸ Pause / ▶ Resume** — alterna pausa (desabilitado quando idle).
- `mesh-detection` — não há leitor de meshes no código - **■ Stop** — finaliza e baixa o arquivo.
- `anchors` — não criamos âncoras persistentes - Texto de status: `● 00:12` em vermelho enquanto grava, amarelo quando pausado.
- `depth-sensing` — não usado - Indicador visual flutuante (pequeno círculo vermelho pulsante) visível mesmo com painel fechado quando estiver gravando — anexado ao `headLockRef`.
- `light-estimation` — não usado
Configuração proposta (passada para `createXRStore`): ### 3. Integração
- O hook recebe o `<canvas>` via `document.querySelector('canvas')` (mesmo padrão usado em `XRHud.tsx`/`handleScreenshot`).
- Nenhuma mudança no store global é necessária — o estado de gravação vive no hook, instanciado no nível do `XRSession.tsx` e passado por props ao `XRHudInWorld`, OU mantido dentro do próprio `CaptureTab` via singleton simples.
```ts ## Detalhes técnicos
const store = createXRStore({ - `MediaRecorder` com `canvas.captureStream(30)` funciona dentro de sessão WebXR no Quest 3 (Chromium-based browser do Quest suporta).
hand: { left: true, right: true }, - Áudio do microfone **não** será incluído (pode ser adicionado depois se solicitado).
controller: { left: true, right: true }, - Vídeo gerado é `.webm`; o usuário pode converter para `.mp4` fora do app se quiser.
sessionInit: { - O download é feito ao parar a gravação — o arquivo aparece no armazenamento do Quest (pasta Downloads do browser).
requiredFeatures: ['local-floor'],
optionalFeatures: ['hit-test', 'plane-detection', 'hand-tracking'],
},
});
```
Tudo continua como `optionalFeatures`, então se o Quest não suportar algum, a sessão ainda inicia. Nenhuma ferramenta atual (hit-test, snap em planos, mãos, grip, joystick, medição, screenshot, inspeção, compartilhamento) depende das features removidas. ## Arquivos afetados
- `src/hooks/useCanvasRecorder.ts` (novo)
- `src/components/three/XRHudInWorld.tsx` (nova tab + CaptureTab + indicador REC)
## O que NÃO faço ## Fora do escopo
- Galeria de vídeos dentro do app (apenas download direto por enquanto).
- Não mexo em `useModelStore`, `XRHud`, `XRHudInWorld`, `XRHitTestPlacement`, `XRPlaneOverlay` — comportamento das ferramentas fica igual. - Áudio/microfone na gravação.
- Não adiciono botão de "desligar Guardian" — impossível por código. - Streaming/upload para nuvem.
## Resultado esperado
Reduz a chance de o Space Sense ativar o grid de segurança perto de objetos, porque a sessão XR não pede mais permissões além das necessárias. Se o grid continuar aparecendo, é configuração do headset (Settings → Segurança → Space Sense) e o usuário precisa desligar lá — posso adicionar depois um painel "Ajuda" com o passo-a-passo se quiser.
## Arquivo alterado
- `src/pages/XRSession.tsx` (apenas o objeto passado para `createXRStore`)