mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
Release God's Eye View as open source
This commit is contained in:
1 parent
a5aaea7e16
commit
880a672b5e
433 files changed
+219893
-23
No files matched your search
@@ -0,0 +1,91 @@
|
||||
import * as Cesium from 'cesium';
|
||||
import { holdContinuousRender, releaseContinuousRender } from './renderGovernor.js';
|
||||
|
||||
/**
|
||||
* OrbitController — smooth orbit around a target point.
|
||||
* Uses scene.preRender for frame-rate-independent 60fps updates.
|
||||
* Toggle with O key; auto-stops on POI/city change.
|
||||
*/
|
||||
export class OrbitController {
|
||||
constructor(viewer) {
|
||||
this.viewer = viewer;
|
||||
this.active = false;
|
||||
this.target = null;
|
||||
this.radius = 500;
|
||||
this.pitch = -30;
|
||||
this.speed = Cesium.Math.toRadians(6); // ~6°/sec → full rotation in ~60s
|
||||
this.angle = 0;
|
||||
this._removeListener = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start orbiting around a target position.
|
||||
* @param {Cesium.Cartesian3} targetCartesian - The point to orbit around
|
||||
* @param {object} options
|
||||
* @param {number} options.radius - Distance from target in meters
|
||||
* @param {number} options.pitch - Tilt angle in degrees (negative = looking down)
|
||||
* @param {number} options.speed - Degrees per second (default 6)
|
||||
*/
|
||||
start(targetCartesian, options = {}) {
|
||||
if (!targetCartesian) return;
|
||||
|
||||
this.target = targetCartesian;
|
||||
this.radius = options.radius || this.radius;
|
||||
this.pitch = options.pitch || this.pitch;
|
||||
this.speed = Cesium.Math.toRadians(options.speed || 6);
|
||||
this.active = true;
|
||||
// Orbit mutates the camera from preRender — without a hold the loop
|
||||
// starves after its first idle frame. (perf wave 2)
|
||||
holdContinuousRender('camera-orbit');
|
||||
|
||||
// Start from the camera's current heading for seamless transition
|
||||
this.angle = this.viewer.camera.heading;
|
||||
|
||||
let lastTime = Date.now();
|
||||
this._removeListener = this.viewer.scene.preRender.addEventListener(() => {
|
||||
if (!this.active) return;
|
||||
|
||||
const now = Date.now();
|
||||
const dt = (now - lastTime) / 1000;
|
||||
lastTime = now;
|
||||
|
||||
this.angle += this.speed * dt;
|
||||
|
||||
const hpr = new Cesium.HeadingPitchRange(
|
||||
this.angle,
|
||||
Cesium.Math.toRadians(this.pitch),
|
||||
this.radius
|
||||
);
|
||||
this.viewer.camera.lookAt(this.target, hpr);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop orbiting. Camera freezes at current position and user regains control.
|
||||
*/
|
||||
stop() {
|
||||
this.active = false;
|
||||
releaseContinuousRender('camera-orbit');
|
||||
if (this._removeListener) {
|
||||
this._removeListener();
|
||||
this._removeListener = null;
|
||||
}
|
||||
// Unlock camera for free interaction
|
||||
this.viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle orbit on/off.
|
||||
* @param {Cesium.Cartesian3} targetCartesian - Required when starting
|
||||
* @param {object} options - Passed to start()
|
||||
* @returns {boolean} Whether orbit is now active
|
||||
*/
|
||||
toggle(targetCartesian, options) {
|
||||
if (this.active) {
|
||||
this.stop();
|
||||
} else {
|
||||
this.start(targetCartesian, options);
|
||||
}
|
||||
return this.active;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user