fix new exam
This commit is contained in:
1 parent
7e8834fbfd
commit
93f92d9587
1 file changed
+27
-6
@@ -136,6 +136,14 @@ export function ExamMarkers({
|
||||
onSelect: (id: string) => void;
|
||||
}) {
|
||||
const { scene } = useThree();
|
||||
// As mesmas CameraControls registradas pelo Scene.tsx (makeDefault) —
|
||||
// acessadas aqui pra enquadrar a câmera na região dos pontos assim que
|
||||
// os ossos são achados, sem depender/competir com o efeito de
|
||||
// enquadramento "corpo inteiro" do Scene.tsx (que tem sua própria
|
||||
// corrida contra o carregamento assíncrono do modelo).
|
||||
const controls = useThree((state) => state.controls) as unknown as {
|
||||
fitToBox: (box: THREE.Box3, enableTransition: boolean, opts?: Record<string, number>) => void;
|
||||
} | null;
|
||||
const contentBox = useAtlasStore((s) => s.contentBox);
|
||||
const [anchors, setAnchors] = useState<AnchorBoxes>({});
|
||||
|
||||
@@ -143,17 +151,30 @@ export function ExamMarkers({
|
||||
let cancelled = false;
|
||||
let attempts = 0;
|
||||
let timer: ReturnType<typeof setTimeout>;
|
||||
let framed = false;
|
||||
const cache = new Map<string, THREE.Box3>();
|
||||
function tryCompute() {
|
||||
if (cancelled) return;
|
||||
const boxes = computeAnchorBoxes(scene, cache);
|
||||
setAnchors(boxes);
|
||||
attempts += 1;
|
||||
// Só continua tentando o que ainda falta (thorax/pelvis/head) — uma
|
||||
// vez achados, cada Box3 fica em cache e não é recalculado de novo,
|
||||
// então parar assim que os 3 principais existirem evita trabalho
|
||||
// repetido (percorrer geometria) rodando junto com o resto da cena.
|
||||
|
||||
// Assim que der pra montar um box com tórax+bacia+crânio, enquadra a
|
||||
// câmera nele DIRETAMENTE (uma vez só) — garante que a câmera mostre
|
||||
// exatamente a região onde os pontos de exame estão, não importa o
|
||||
// que outro efeito de câmera esteja fazendo.
|
||||
const gotCore = boxes.thorax && boxes.pelvis && boxes.head;
|
||||
if (gotCore && !framed && controls) {
|
||||
framed = true;
|
||||
const region = boxes.thorax!.clone().union(boxes.pelvis!).union(boxes.head!);
|
||||
controls.fitToBox(region, true, {
|
||||
paddingLeft: 0.3,
|
||||
paddingRight: 0.3,
|
||||
paddingTop: 0.2,
|
||||
paddingBottom: 0.2,
|
||||
});
|
||||
}
|
||||
|
||||
if (!gotCore && attempts < 30) {
|
||||
timer = setTimeout(tryCompute, 300);
|
||||
} else if (!boxes.thorax) {
|
||||
@@ -170,7 +191,7 @@ export function ExamMarkers({
|
||||
cancelled = true;
|
||||
clearTimeout(timer);
|
||||
};
|
||||
}, [scene]);
|
||||
}, [scene, controls]);
|
||||
|
||||
const techniqueColor = (t: ExamTechnique) => TECHNIQUES.find((x) => x.key === t)?.color ?? "#fff";
|
||||
const bodyBox = contentBox
|
||||
@@ -199,7 +220,7 @@ export function ExamMarkers({
|
||||
const isSelected = p.id === selectedId;
|
||||
const color = techniqueColor(p.technique);
|
||||
return (
|
||||
<Html key={p.id} position={position} center distanceFactor={4} zIndexRange={[10, 0]}>
|
||||
<Html key={p.id} position={position} center distanceFactor={4}>
|
||||
<button
|
||||
onClick={() => onSelect(p.id)}
|
||||
title={p.name}
|
||||
|
||||
Reference in new issue
Block a user