This commit is contained in:
Rodrigo Bertoldo de Sousa Martins committed 2026-09-08 13:53:07 -03:00
1 parent 1e921b4084
commit 87085d7020
1 file changed
+25 -2
+25 -2
View File
@@ -24,6 +24,29 @@ function useClippingPlanes(): THREE.Plane[] {
}, [enabled, axis, position]); }, [enabled, axis, position]);
} }
function isFiniteVec3(v: THREE.Vector3): boolean {
return Number.isFinite(v.x) && Number.isFinite(v.y) && Number.isFinite(v.z);
}
// Une o bounding box só das malhas VISÍVEIS e com geometria válida —
// alguns objetos do dataset real (anotações/curvas do Z-Anatomy) podem ter
// vértices degenerados/NaN, e Box3.setFromObject(scene) ingenuamente
// incluiria isso, distorcendo o enquadramento (ou escondendo tudo o mais
// fora do "zoom" resultante).
function computeVisibleBoundingBox(root: THREE.Object3D): THREE.Box3 {
const union = new THREE.Box3();
const tmp = new THREE.Box3();
root.traverse((obj) => {
const mesh = obj as THREE.Mesh;
if (!mesh.isMesh || !mesh.visible) return;
tmp.setFromObject(mesh);
if (tmp.isEmpty()) return;
if (!isFiniteVec3(tmp.min) || !isFiniteVec3(tmp.max)) return;
union.union(tmp);
});
return union;
}
function CameraController({ modelFiles }: { modelFiles: string[] }) { function CameraController({ modelFiles }: { modelFiles: string[] }) {
const controlsRef = useRef<CameraControls>(null); const controlsRef = useRef<CameraControls>(null);
const { scene, camera } = useThree(); const { scene, camera } = useThree();
@@ -37,7 +60,7 @@ function CameraController({ modelFiles }: { modelFiles: string[] }) {
useEffect(() => { useEffect(() => {
if (!controlsRef.current || modelFiles.length === 0) return; if (!controlsRef.current || modelFiles.length === 0) return;
const id = requestAnimationFrame(() => { const id = requestAnimationFrame(() => {
const box = new THREE.Box3().setFromObject(scene); const box = computeVisibleBoundingBox(scene);
if (box.isEmpty()) return; if (box.isEmpty()) return;
const size = box.getSize(new THREE.Vector3()).length(); const size = box.getSize(new THREE.Vector3()).length();
// Ajusta os planos de corte da câmera ao tamanho real do conteúdo — // Ajusta os planos de corte da câmera ao tamanho real do conteúdo —
@@ -60,7 +83,7 @@ function CameraController({ modelFiles }: { modelFiles: string[] }) {
if (!focusRequest || !controlsRef.current) return; if (!focusRequest || !controlsRef.current) return;
const obj = scene.getObjectByName(focusRequest.slug); const obj = scene.getObjectByName(focusRequest.slug);
if (!obj) return; if (!obj) return;
const box = new THREE.Box3().setFromObject(obj); const box = computeVisibleBoundingBox(obj);
if (box.isEmpty()) return; if (box.isEmpty()) return;
controlsRef.current.fitToBox(box, true, { controlsRef.current.fitToBox(box, true, {
paddingLeft: 0.4, paddingLeft: 0.4,