Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-05-24 19:43:37 +00:00
parent 29c6c765d3
commit 5f9f5b5bc8
+33 -1
View File
@@ -54,11 +54,43 @@ export function elementKey(modelId: string, el: THREE.Object3D): string {
export const sceneRef: { current: THREE.Scene | null } = { current: null }; export const sceneRef: { current: THREE.Scene | null } = { current: null };
function SceneRefCapture() { function SceneRefCapture() {
const { scene } = useThree(); const { scene, camera } = useThree();
useEffect(() => { useEffect(() => {
sceneRef.current = scene; sceneRef.current = scene;
return () => { if (sceneRef.current === scene) sceneRef.current = null; }; return () => { if (sceneRef.current === scene) sceneRef.current = null; };
}, [scene]); }, [scene]);
useEffect(() => {
// Expose the main camera to the ViewCube bus
// (lazy-imported to avoid circular deps)
import('./viewCubeBus').then(({ mainCameraRef }) => {
mainCameraRef.current = camera;
});
return () => {
import('./viewCubeBus').then(({ mainCameraRef }) => {
if (mainCameraRef.current === camera) mainCameraRef.current = null;
});
};
}, [camera]);
return null;
}
/** Drives the camera animation requested by the ViewCube. */
function ViewCubeAnimator() {
const { camera } = useThree();
useFrame((_state, delta) => {
// Eager require to avoid async stalling per-frame
const bus = require('./viewCubeBus');
const anim = bus.viewAnim;
if (!anim.active) return;
anim.t = Math.min(1, anim.t + delta / anim.duration);
const k = anim.t < 0.5 ? 2 * anim.t * anim.t : 1 - Math.pow(-2 * anim.t + 2, 2) / 2;
camera.position.lerpVectors(anim.startPos, anim.endPos, k);
camera.up.lerpVectors(anim.startUp, anim.endUp, k).normalize();
const controls = bus.mainControlsRef.current;
if (controls?.target) camera.lookAt(controls.target);
controls?.update?.();
if (anim.t >= 1) anim.active = false;
});
return null; return null;
} }