Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-05-24 19:43:23 +00:00
parent f4adaf88f9
commit 29c6c765d3
+53
View File
@@ -0,0 +1,53 @@
import * as THREE from 'three';
/**
* Shared bus between the main 3D viewer and the floating ViewCube widget.
* - mainCameraRef / mainControlsRef: written by ModelViewer each frame
* - requestView(dir): asks the main camera to animate to a canonical view
* along the given world-space direction (unit vector pointing FROM target
* TO camera). e.g. (0,1,0) = top view, (0,0,1) = front.
*/
export const mainCameraRef: { current: THREE.Camera | null } = { current: null };
// OrbitControls instance — typed loosely to avoid drei type churn
export const mainControlsRef: { current: any | null } = { current: null };
export interface ViewAnim {
active: boolean;
startPos: THREE.Vector3;
endPos: THREE.Vector3;
startUp: THREE.Vector3;
endUp: THREE.Vector3;
t: number;
duration: number;
}
export const viewAnim: ViewAnim = {
active: false,
startPos: new THREE.Vector3(),
endPos: new THREE.Vector3(),
startUp: new THREE.Vector3(0, 1, 0),
endUp: new THREE.Vector3(0, 1, 0),
t: 0,
duration: 0.5,
};
export function requestView(dir: THREE.Vector3) {
const cam = mainCameraRef.current;
const controls = mainControlsRef.current;
if (!cam || !controls) return;
const target: THREE.Vector3 = controls.target ?? new THREE.Vector3();
const distance = cam.position.distanceTo(target);
const d = dir.clone().normalize();
const endPos = target.clone().add(d.multiplyScalar(distance));
// Up vector: keep Y up unless we're looking straight up/down
const up = new THREE.Vector3(0, 1, 0);
if (Math.abs(dir.y) > 0.99) {
up.set(0, 0, dir.y > 0 ? -1 : 1);
}
viewAnim.startPos.copy(cam.position);
viewAnim.endPos.copy(endPos);
viewAnim.startUp.copy(cam.up);
viewAnim.endUp.copy(up);
viewAnim.t = 0;
viewAnim.active = true;
}