fix exame fisico

This commit is contained in:
Rodrigo Bertoldo de Sousa Martins committed 2026-09-10 21:49:26 -03:00
1 parent 43df670a55
commit 7e8834fbfd
1 file changed
+38 -7
+38 -7
View File
@@ -119,30 +119,61 @@ function CameraController({ modelFiles }: { modelFiles: string[] }) {
// outro ponto) — em vez de assumir uma posição de câmera fixa, sempre
// que o conjunto de arquivos carregados muda, enquadra a câmera no
// bounding box real de tudo que está na cena.
//
// O carregamento do .glb é assíncrono (Suspense) e pode levar bem mais
// que 1 frame — um único requestAnimationFrame às vezes media a cena
// ainda vazia/parcial (só 1-2 ossos montados) e nunca corrige depois,
// porque "modelFiles" não muda de novo uma vez carregado. Por isso agora
// fica tentando de novo a cada 200ms até o tamanho do conteúdo ficar
// ESTÁVEL (duas leituras seguidas iguais = terminou de montar), só então
// enquadra a câmera.
useEffect(() => {
if (!controlsRef.current || modelFiles.length === 0) return;
const id = requestAnimationFrame(() => {
if (modelFiles.length === 0) return;
let cancelled = false;
let attempts = 0;
let lastSize = -1;
let timer: ReturnType<typeof setTimeout>;
function tryFit() {
if (cancelled || !controlsRef.current) return;
const box = computeVisibleBoundingBox(scene);
if (box.isEmpty()) return;
attempts += 1;
if (box.isEmpty()) {
if (attempts < 50) timer = setTimeout(tryFit, 200);
return;
}
const size = box.getSize(new THREE.Vector3()).length();
const stable = Math.abs(size - lastSize) < lastSize * 0.01;
lastSize = size;
if (!stable && attempts < 50) {
timer = setTimeout(tryFit, 200);
return;
}
setContentBox({
min: [box.min.x, box.min.y, box.min.z],
max: [box.max.x, box.max.y, box.max.z],
});
const size = box.getSize(new THREE.Vector3()).length();
// Ajusta os planos de corte da câmera ao tamanho real do conteúdo —
// um "far" fixo pequeno cortaria (tornaria invisível) um modelo bem
// maior do que o esperado.
camera.near = Math.max(size / 1000, 0.001);
camera.far = size * 100;
if (camera instanceof THREE.PerspectiveCamera) camera.updateProjectionMatrix();
controlsRef.current?.fitToBox(box, true, {
controlsRef.current.fitToBox(box, true, {
paddingLeft: 0.2,
paddingRight: 0.2,
paddingTop: 0.2,
paddingBottom: 0.2,
});
});
return () => cancelAnimationFrame(id);
}
const id = requestAnimationFrame(tryFit);
return () => {
cancelled = true;
cancelAnimationFrame(id);
clearTimeout(timer);
};
}, [modelFiles, scene, camera, setContentBox]);
useEffect(() => {