visualizacao do exame fisico
This commit is contained in:
1 parent
be94073fbb
commit
38833147f8
3 files changed
+104
-15
No files matched your search
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user