use corpo real exame fisico
This commit is contained in:
1 parent
939293ba60
commit
7e8963135b
4 files changed
+166
-108
No files matched your search
@@ -0,0 +1,58 @@
|
||||
import { Html } from "@react-three/drei";
|
||||
import * as THREE from "three";
|
||||
import { useAtlasStore } from "../../store/useAtlasStore.js";
|
||||
import type { ExamPoint, ExamTechnique } from "../../data/physicalExam.js";
|
||||
import { TECHNIQUES } from "../../data/physicalExam.js";
|
||||
|
||||
// Roda DENTRO do mesmo <Canvas> do Scene (recebido via prop "children" —
|
||||
// ver Scene.tsx) pra poder usar <Html> do drei e o bounding box real do
|
||||
// corpo carregado (contentBox no store, o mesmo usado pelo plano de corte e
|
||||
// pela navegação rápida por região). Cada ponto de exame é dado como
|
||||
// FRAÇÃO do corpo (ver data/physicalExam.ts), convertida aqui pra
|
||||
// coordenada absoluta — assim os pontos acompanham o corpo real não
|
||||
// importa a escala/origem carregada.
|
||||
export function ExamMarkers({
|
||||
points,
|
||||
selectedId,
|
||||
onSelect,
|
||||
}: {
|
||||
points: ExamPoint[];
|
||||
selectedId: string | null;
|
||||
onSelect: (id: string) => void;
|
||||
}) {
|
||||
const contentBox = useAtlasStore((s) => s.contentBox);
|
||||
if (!contentBox) return null;
|
||||
|
||||
const min = new THREE.Vector3(...contentBox.min);
|
||||
const max = new THREE.Vector3(...contentBox.max);
|
||||
const techniqueColor = (t: ExamTechnique) => TECHNIQUES.find((x) => x.key === t)?.color ?? "#fff";
|
||||
|
||||
return (
|
||||
<>
|
||||
{points.map((p) => {
|
||||
const [fx, fy, fz] = p.fraction;
|
||||
const position: [number, number, number] = [
|
||||
THREE.MathUtils.lerp(min.x, max.x, fx),
|
||||
THREE.MathUtils.lerp(min.y, max.y, fy),
|
||||
THREE.MathUtils.lerp(min.z, max.z, fz),
|
||||
];
|
||||
const isSelected = p.id === selectedId;
|
||||
const color = techniqueColor(p.technique);
|
||||
return (
|
||||
<Html key={p.id} position={position} center distanceFactor={4} zIndexRange={[10, 0]}>
|
||||
<button
|
||||
onClick={() => onSelect(p.id)}
|
||||
title={p.name}
|
||||
className="w-4 h-4 rounded-full border-2 border-white/80 transition-transform hover:scale-125"
|
||||
style={{
|
||||
backgroundColor: color,
|
||||
boxShadow: isSelected ? `0 0 0 5px ${color}55` : undefined,
|
||||
transform: isSelected ? "scale(1.4)" : undefined,
|
||||
}}
|
||||
/>
|
||||
</Html>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user