Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
@@ -88,8 +88,60 @@ function ViewCubeAnimator() {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Switches between perspective and orthographic projection while keeping
|
||||||
function LoadingFallback() {
|
* the visual framing (position, target, on-screen size of the scene). */
|
||||||
|
function CameraSwitcher() {
|
||||||
|
const mode = useModelStore((s) => s.cameraMode);
|
||||||
|
const { size } = useThree();
|
||||||
|
// Snapshot current view from whichever camera is active right now, before swap.
|
||||||
|
const snap = useMemo(() => {
|
||||||
|
const c = mainCameraRef.current;
|
||||||
|
const ctrl = mainControlsRef.current;
|
||||||
|
const target = (ctrl?.target ?? new THREE.Vector3()).clone();
|
||||||
|
const pos = c ? c.position.clone() : new THREE.Vector3(2, 2, 2);
|
||||||
|
const up = c ? c.up.clone() : new THREE.Vector3(0, 1, 0);
|
||||||
|
const dist = pos.distanceTo(target);
|
||||||
|
// Compute ortho zoom that matches current perspective framing.
|
||||||
|
let zoom = 100;
|
||||||
|
if (c && (c as THREE.PerspectiveCamera).isPerspectiveCamera) {
|
||||||
|
const fov = ((c as THREE.PerspectiveCamera).fov ?? 50) * (Math.PI / 180);
|
||||||
|
const worldHeight = 2 * Math.max(dist, 0.001) * Math.tan(fov / 2);
|
||||||
|
zoom = Math.max(1, size.height / Math.max(worldHeight, 1e-6));
|
||||||
|
} else if (c && (c as THREE.OrthographicCamera).isOrthographicCamera) {
|
||||||
|
zoom = (c as THREE.OrthographicCamera).zoom;
|
||||||
|
}
|
||||||
|
return { target, pos, up, zoom };
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [mode]);
|
||||||
|
// Sync OrbitControls target after camera swap.
|
||||||
|
useEffect(() => {
|
||||||
|
const ctrl = mainControlsRef.current;
|
||||||
|
if (ctrl?.target) ctrl.target.copy(snap.target);
|
||||||
|
ctrl?.update?.();
|
||||||
|
}, [snap]);
|
||||||
|
if (mode === 'ortho') {
|
||||||
|
return (
|
||||||
|
<OrthographicCamera
|
||||||
|
makeDefault
|
||||||
|
position={snap.pos.toArray()}
|
||||||
|
up={snap.up.toArray()}
|
||||||
|
zoom={snap.zoom}
|
||||||
|
near={-1000}
|
||||||
|
far={1000}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<PerspectiveCamera
|
||||||
|
makeDefault
|
||||||
|
position={snap.pos.toArray()}
|
||||||
|
up={snap.up.toArray()}
|
||||||
|
fov={50}
|
||||||
|
near={0.001}
|
||||||
|
far={1000}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Html center>
|
<Html center>
|
||||||
<div className="flex items-center gap-2 rounded-lg bg-card px-4 py-2 text-foreground shadow-lg">
|
<div className="flex items-center gap-2 rounded-lg bg-card px-4 py-2 text-foreground shadow-lg">
|
||||||
|
|||||||
Reference in New Issue
Block a user