fix visualizacao
This commit is contained in:
1 parent
401c421313
commit
822ee2d557
1 file changed
+33
-6
@@ -24,11 +24,38 @@ function useClippingPlanes(): THREE.Plane[] {
|
|||||||
}, [enabled, axis, position]);
|
}, [enabled, axis, position]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function FocusController() {
|
function CameraController({ modelFiles }: { modelFiles: string[] }) {
|
||||||
const controlsRef = useRef<CameraControls>(null);
|
const controlsRef = useRef<CameraControls>(null);
|
||||||
const { scene } = useThree();
|
const { scene, camera } = useThree();
|
||||||
const focusRequest = useAtlasStore((s) => s.focusRequest);
|
const focusRequest = useAtlasStore((s) => s.focusRequest);
|
||||||
|
|
||||||
|
// Malhas reais (Z-Anatomy) não seguem a mesma escala/origem que os
|
||||||
|
// modelos esquemáticos antigos (podem vir em cm, ou centralizadas em
|
||||||
|
// 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.
|
||||||
|
useEffect(() => {
|
||||||
|
if (!controlsRef.current || modelFiles.length === 0) return;
|
||||||
|
const id = requestAnimationFrame(() => {
|
||||||
|
const box = new THREE.Box3().setFromObject(scene);
|
||||||
|
if (box.isEmpty()) return;
|
||||||
|
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, {
|
||||||
|
paddingLeft: 0.2,
|
||||||
|
paddingRight: 0.2,
|
||||||
|
paddingTop: 0.2,
|
||||||
|
paddingBottom: 0.2,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return () => cancelAnimationFrame(id);
|
||||||
|
}, [modelFiles, scene, camera]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!focusRequest || !controlsRef.current) return;
|
if (!focusRequest || !controlsRef.current) return;
|
||||||
const obj = scene.getObjectByName(focusRequest.slug);
|
const obj = scene.getObjectByName(focusRequest.slug);
|
||||||
@@ -47,8 +74,8 @@ function FocusController() {
|
|||||||
<CameraControls
|
<CameraControls
|
||||||
ref={controlsRef}
|
ref={controlsRef}
|
||||||
makeDefault
|
makeDefault
|
||||||
minDistance={0.15}
|
minDistance={0.001}
|
||||||
maxDistance={4}
|
maxDistance={1000000}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -89,7 +116,7 @@ export function Scene({ bySlug }: { bySlug: Map<string, Structure> }) {
|
|||||||
return (
|
return (
|
||||||
<Canvas
|
<Canvas
|
||||||
shadows
|
shadows
|
||||||
camera={{ position: [1.2, 1.4, 1.6], fov: 45, near: 0.01, far: 20 }}
|
camera={{ position: [1.2, 1.4, 1.6], fov: 45, near: 0.01, far: 100000 }}
|
||||||
gl={{ localClippingEnabled: true }}
|
gl={{ localClippingEnabled: true }}
|
||||||
>
|
>
|
||||||
<color attach="background" args={["#0b1220"]} />
|
<color attach="background" args={["#0b1220"]} />
|
||||||
@@ -120,7 +147,7 @@ export function Scene({ bySlug }: { bySlug: Map<string, Structure> }) {
|
|||||||
fadeDistance={6}
|
fadeDistance={6}
|
||||||
infiniteGrid
|
infiniteGrid
|
||||||
/>
|
/>
|
||||||
<FocusController />
|
<CameraController modelFiles={modelFiles} />
|
||||||
</Canvas>
|
</Canvas>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user