Save plan in Lovable
This commit is contained in:
+27
-55
@@ -1,71 +1,43 @@
|
|||||||
|
|
||||||
|
|
||||||
## Plano: Ferramentas de Medicao Inteligentes (Smart Snap + Auto-Detect)
|
## Plano: Corrigir entrada XR no Meta Quest 3
|
||||||
|
|
||||||
### 3 Funcionalidades
|
### Problema raiz
|
||||||
|
O codigo atual cria **duas sessoes XR em sequencia**: primeiro manualmente via `navigator.xr.requestSession('immersive-ar', ...)` (linha 242), depois via `xrStore.enterAR()` (linha 271). O Quest 3 rejeita a segunda porque ja existe uma sessao ativa. Alem disso, a primeira sessao nao esta conectada ao renderer do Three.js, entao mesmo se funcionasse, nao renderizaria nada.
|
||||||
|
|
||||||
**1. Vertex Snap (snap magnetico)**
|
### Correcoes
|
||||||
- No `MeasureClickHandler`, ao mover o mouse, fazer raycast continuo (`onPointerMove`)
|
|
||||||
- Para cada hit, buscar o vertice mais proximo do ponto de intersecao na geometria do mesh
|
|
||||||
- Se a distancia ao vertice mais proximo for menor que um threshold (ex: 5px em screen space), "snapar" para esse vertice
|
|
||||||
- Renderizar um marcador visual (anel/circulo amarelo) no vertice snappado via `MeasurementOverlay`
|
|
||||||
- Ao clicar, usar o ponto snappado em vez do ponto bruto do raycast
|
|
||||||
- Novo state no store: `snapPoint: MeasurePoint | null` e `setSnapPoint`
|
|
||||||
|
|
||||||
**2. Auto-detect diametro de furos (hover)**
|
**1. Remover a chamada manual a `navigator.xr.requestSession`**
|
||||||
- Ao fazer hover sobre uma face, analisar a geometria local:
|
- Eliminar todo o bloco `try` das linhas 239-268 que tenta criar uma sessao manualmente
|
||||||
- Coletar as edges do `EdgesGeometry` que formam um loop fechado (circulo/oblongo) proximo ao ponto de hover
|
- A lib `@react-three/xr` gerencia a sessao internamente via `xrStore.enterAR()`
|
||||||
- Alternativa mais robusta: analisar os vertices ao redor do ponto de intersecao, detectar se formam um arco/circulo usando fitting de circulo (least-squares circle fit nos vertices vizinhos)
|
|
||||||
- Abordagem pratica: usar as normais das faces -- furos em chapas tem faces com normais apontando para o centro do furo. Agrupar faces cilindricas coplanares e calcular o raio
|
|
||||||
- Apos 1 segundo de hover estavel (debounce), mostrar tooltip HTML com o diametro em mm (1 casa decimal)
|
|
||||||
- Novo state: `hoverInfo: { type: 'hole' | 'edge', position: [x,y,z], value: number } | null`
|
|
||||||
|
|
||||||
**3. Auto-detect comprimento de aresta (hover)**
|
**2. Usar `customSessionInit` no `createXRStore` para image tracking**
|
||||||
- Ao hover proximo de uma edge line, identificar o segmento de aresta mais proximo
|
- A lib suporta `customSessionInit` em `XRSessionInitOptions` que permite injetar opcoes extras na sessao
|
||||||
- Calcular o comprimento desse segmento em mm
|
- Passar `optionalFeatures: ['image-tracking']` e `trackedImages` via `customSessionInit`
|
||||||
- Apos 1 segundo de hover estavel, mostrar tooltip com o comprimento
|
- O `createXRStore` ja adiciona `local-floor`, `hand-tracking`, `anchors`, `plane-detection` automaticamente
|
||||||
|
|
||||||
### Arquivos a modificar
|
**3. Condicionar o emulador**
|
||||||
|
- `emulate: 'metaQuest3'` ativa o emulador IWER em localhost, o que pode interferir no Quest real
|
||||||
|
- Condicionar: so emular se nao estiver em dispositivo XR real (checar `navigator.xr?.isSessionSupported`)
|
||||||
|
- Ou mais simples: so emular em `location.hostname === 'localhost'` E quando `!navigator.xr`
|
||||||
|
|
||||||
**`src/stores/useModelStore.ts`**
|
**4. Arquivo: `src/pages/XRSession.tsx`**
|
||||||
- Adicionar `snapPoint`, `setSnapPoint`, `hoverInfo`, `setHoverInfo`
|
|
||||||
|
|
||||||
**`src/components/three/ModelViewer.tsx`**
|
Mudancas:
|
||||||
- Novo componente `SmartSnapHandler`: useFrame com raycast no mouse, busca vertice mais proximo, atualiza `snapPoint`
|
- Mover criacao do store para dentro do componente (ou lazy init) para poder passar o bitmap como `customSessionInit`
|
||||||
- Novo componente `HoverDetector`: onPointerMove com debounce de 1s, analisa geometria para detectar furos (faces cilindricas) e arestas, atualiza `hoverInfo`
|
- `handleEnterAR`: simplificar para apenas `await xrStore.enterAR()` com listener de `end`
|
||||||
- Atualizar `MeasurementOverlay` para renderizar o snap marker (anel amarelo) e o tooltip de hover
|
- Manter `ImageTrackingAnchor`, `ControllerFineTuning`, `XRModel` sem alteracoes
|
||||||
- Atualizar `MeasureClickHandler` para usar `snapPoint` quando disponivel
|
|
||||||
|
|
||||||
**`src/components/three/SmartMeasure.tsx`** (novo)
|
|
||||||
- Logica de deteccao de furos: analise de curvatura local dos vertices
|
|
||||||
- Logica de deteccao de arestas: segmentos de EdgesGeometry mais proximos ao cursor
|
|
||||||
- Funcoes utilitarias: `findNearestVertex`, `detectHoleRadius`, `findNearestEdge`
|
|
||||||
|
|
||||||
### Detalhes tecnicos
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Vertex Snap:
|
ANTES (bugado):
|
||||||
raycast hit → mesh.geometry.attributes.position
|
1. navigator.xr.requestSession('immersive-ar') ← cria sessao A
|
||||||
→ iterar vertices, transformar para world space (mesh.matrixWorld)
|
2. xrStore.enterAR() ← tenta sessao B → REJEITADA
|
||||||
→ projetar para screen space (camera.project)
|
|
||||||
→ encontrar o mais proximo em pixels (threshold ~8px)
|
|
||||||
→ mostrar anel amarelo nesse ponto
|
|
||||||
|
|
||||||
Deteccao de Furos:
|
DEPOIS (correto):
|
||||||
raycast hit face → pegar faceIndex
|
1. createXRStore({ customSessionInit: { optionalFeatures: ['image-tracking'], trackedImages: [...] } })
|
||||||
→ coletar faces vizinhas com normal similar (cilindrica)
|
2. xrStore.enterAR() ← unica sessao, com image tracking
|
||||||
→ extrair vertices do loop de borda dessas faces
|
|
||||||
→ circle fit (least squares) → raio → diametro em mm
|
|
||||||
→ mostrar tooltip apos 1s de hover estavel
|
|
||||||
|
|
||||||
Deteccao de Arestas:
|
|
||||||
EdgesGeometry ja calculada → array de segmentos [v1, v2]
|
|
||||||
→ projetar todos para screen space
|
|
||||||
→ encontrar segmento mais proximo ao cursor
|
|
||||||
→ comprimento = distancia 3D * 1000 (mm)
|
|
||||||
→ mostrar tooltip apos 1s de hover estavel
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Sem alteracoes em
|
### Sem alteracoes em
|
||||||
- Checklist, compare mode, screenshots, fine tuning, import OBJ/STL/IFC, render modes
|
- ModelViewer, ViewerControls, SmartMeasure, checklist, medicoes, screenshots, PDF, IFC import
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user