init
This commit is contained in:
71
src/worldState.js
Normal file
71
src/worldState.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import { Vector3, Quaternion } from 'three';
|
||||
import { Geodetic, PointOfView, radians } from '@takram/three-geospatial';
|
||||
|
||||
const EARTH_RADIUS = 6378137;
|
||||
|
||||
export const worldState = {
|
||||
position: new Vector3(0, EARTH_RADIUS + 100000, 0),
|
||||
quaternion: new Quaternion(),
|
||||
speed: 1000.0,
|
||||
stageRotationY: 0,
|
||||
};
|
||||
|
||||
// Pre-allocated temp objects (avoid GC in useFrame)
|
||||
const _up = new Vector3();
|
||||
const _quat = new Quaternion();
|
||||
const _unitY = new Vector3(0, 1, 0);
|
||||
|
||||
export function getSurfaceBasis(position) {
|
||||
if (!position) return _quat.identity();
|
||||
_up.copy(position).normalize();
|
||||
if (_up.lengthSq() < 0.1) return _quat.identity();
|
||||
return _quat.setFromUnitVectors(_unitY, _up);
|
||||
}
|
||||
|
||||
// Non-mutating version for cases that need a copy
|
||||
const _basisOut = new Quaternion();
|
||||
export function getSurfaceBasisCopy(position) {
|
||||
getSurfaceBasis(position);
|
||||
return _basisOut.copy(_quat);
|
||||
}
|
||||
|
||||
export function getEllipsoidRadius(position) {
|
||||
const a = 6378137.0;
|
||||
const b = 6356752.314245;
|
||||
const r = position.length();
|
||||
if (r < 100) return a;
|
||||
const sinPhi = position.z / r;
|
||||
const cosPhi = Math.sqrt(1 - sinPhi * sinPhi);
|
||||
const aCos = a * cosPhi;
|
||||
const bSin = b * sinPhi;
|
||||
return Math.sqrt(
|
||||
((a * aCos) ** 2 + (b * bSin) ** 2) / (aCos ** 2 + bSin ** 2)
|
||||
);
|
||||
}
|
||||
|
||||
export const LOCATIONS = [
|
||||
{ name: 'Tokyo', longitude: 139.7671, latitude: 35.6812, heading: 180, pitch: -5, distance: 1100 },
|
||||
{ name: 'Fuji', longitude: 138.7278, latitude: 35.3206, heading: 0, pitch: -10, distance: 4000 },
|
||||
{ name: 'Space', longitude: 139.7671, latitude: 35.6812, heading: 0, pitch: -90, distance: 100000 },
|
||||
];
|
||||
|
||||
export function teleportTo(location) {
|
||||
const { longitude, latitude, heading, pitch, distance } = location;
|
||||
const position = new Vector3();
|
||||
const globalQuaternion = new Quaternion();
|
||||
const up = new Vector3(0, 1, 0);
|
||||
|
||||
const truePosition = new Geodetic(radians(longitude), radians(latitude), distance).toECEF();
|
||||
|
||||
new PointOfView(distance, radians(heading), radians(pitch)).decompose(
|
||||
new Geodetic(radians(longitude), radians(latitude)).toECEF(),
|
||||
position,
|
||||
globalQuaternion,
|
||||
up
|
||||
);
|
||||
|
||||
worldState.position.copy(truePosition);
|
||||
|
||||
const basis = getSurfaceBasisCopy(truePosition);
|
||||
worldState.quaternion.copy(basis.invert().multiply(globalQuaternion));
|
||||
}
|
||||
Reference in New Issue
Block a user