visualizacao do exame fisico

This commit is contained in:
Rodrigo Bertoldo de Sousa Martins committed 2026-09-11 09:38:43 -03:00
1 parent be94073fbb
commit 38833147f8
3 files changed
+104 -15

No files matched your search

+36 -4
View File
@@ -1,11 +1,17 @@
import { useEffect, useState } from "react";
import { useThree } from "@react-three/fiber";
import { useEffect, useRef, useState } from "react";
import { useFrame, useThree } from "@react-three/fiber";
import { Html } from "@react-three/drei";
import * as THREE from "three";
import { useAtlasStore } from "../../store/useAtlasStore.js";
import type { ExamPoint, ExamTechnique, ExamAnchor } from "../../data/physicalExam.js";
import type { ExamPoint, ExamTechnique, ExamAnchor, ExamSide } from "../../data/physicalExam.js";
import { TECHNIQUES } from "../../data/physicalExam.js";
// Mesma convenção usada em PlanesPage (AXES: "Anterior" aponta pra +Z) —
// assumimos que o corpo real do Z-Anatomy segue a mesma orientação. Se na
// prática ficar invertido (pontos anteriores só aparecem vendo de trás),
// é só trocar o sinal aqui.
const ANTERIOR_DIR = new THREE.Vector3(0, 0, 1);
// Os pontos de exame são ancorados no bounding box de OSSOS REAIS do
// esqueleto (esterno, costelas, vértebras, bacia, crânio, rádio, tíbia) em
// vez de uma fração do corpo inteiro — assim herdam a escala/posição
@@ -130,10 +136,14 @@ export function ExamMarkers({
points,
selectedId,
onSelect,
onSideChange,
}: {
points: ExamPoint[];
selectedId: string | null;
onSelect: (id: string) => void;
// Avisa a página (fora do Canvas) de que lado o usuário está vendo agora
// — só pra mostrar uma dica textual, opcional.
onSideChange?: (side: ExamSide) => void;
}) {
const { scene } = useThree();
// As mesmas CameraControls registradas pelo Scene.tsx (makeDefault) —
@@ -206,9 +216,31 @@ export function ExamMarkers({
return bodyBox;
}
// Só mostra os pontos do lado que a câmera está encarando (anterior ou
// posterior) — senão um ponto da frente e um das costas ficam colados no
// mesmo lugar aparente na tela, e não dá pra saber em qual se está
// clicando. Atualiza a cada frame, mas só dispara re-render quando o
// lado realmente muda (não a cada frame).
const [visibleSide, setVisibleSide] = useState<ExamSide>("anterior");
const visibleSideRef = useRef<ExamSide>("anterior");
useFrame(({ camera }) => {
const center = bodyBox?.getCenter(new THREE.Vector3()) ?? anchors.thorax?.getCenter(new THREE.Vector3());
if (!center) return;
const toCamera = camera.position.clone().sub(center);
if (toCamera.lengthSq() < 1e-8) return;
const side: ExamSide = toCamera.dot(ANTERIOR_DIR) >= 0 ? "anterior" : "posterior";
if (side !== visibleSideRef.current) {
visibleSideRef.current = side;
setVisibleSide(side);
onSideChange?.(side);
}
});
return (
<>
{points.map((p) => {
{points
.filter((p) => p.side === visibleSide)
.map((p) => {
const box = resolveBox(p.anchor);
if (!box) return null;
const [fx, fy, fz] = p.fraction;