spacemap 0.1.16 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -20
- package/dist/spacemap.iife.js +110 -110
- package/dist/spacemap.js +110 -110
- package/index.d.ts +29 -9
- package/index.js +169 -28
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -1104,6 +1104,12 @@ export declare interface MapEvents {
|
|
|
1104
1104
|
loading: (loading: boolean) => void;
|
|
1105
1105
|
/** Boot progress, 0 to 1, monotonic within one load. */
|
|
1106
1106
|
progress: (fraction: number) => void;
|
|
1107
|
+
/** The map is at rest. The camera does not move, and the view has every
|
|
1108
|
+
* picture, model, tile and terrain grid that it needs. The event fires once
|
|
1109
|
+
* each time that the map comes to rest after a change. The clock can run. A
|
|
1110
|
+
* covered map is not at rest. The catalogue points and the star background
|
|
1111
|
+
* do not count. */
|
|
1112
|
+
idle: () => void;
|
|
1107
1113
|
/** The data could not be loaded. The map stays mounted and empty. */
|
|
1108
1114
|
error: (message: string) => void;
|
|
1109
1115
|
/** The export was republished while this map was open: its data is now a
|
|
@@ -1367,7 +1373,7 @@ export declare interface PanoramaEntry {
|
|
|
1367
1373
|
* `unknown` means the sphere sits at an arbitrary azimuth, so nothing
|
|
1368
1374
|
* may be drawn or written as a heading. The full set `export/panoramas.py`
|
|
1369
1375
|
* writes — a wider union would erase the literals and stop checking. */
|
|
1370
|
-
orientation?: 'unknown' | 'caption-aligned' | 'matched to an archival sphere' | 'matched to a controlled mosaic';
|
|
1376
|
+
orientation?: 'unknown' | 'caption-aligned' | 'matched to an archival sphere' | 'matched to a controlled mosaic' | 'matched to a terrain model' | 'fitted to the Sun';
|
|
1371
1377
|
/** `estimated` where the sphere's angular bounds were fitted to a
|
|
1372
1378
|
* published flat image rather than read from an archive label. */
|
|
1373
1379
|
geometry?: 'estimated';
|
|
@@ -1847,6 +1853,8 @@ export declare class SimClock {
|
|
|
1847
1853
|
private prevScale;
|
|
1848
1854
|
private stops;
|
|
1849
1855
|
private settleTimer;
|
|
1856
|
+
/** The promises of {@link jumpTo} that wait for a frame at their date. */
|
|
1857
|
+
private arrivals;
|
|
1850
1858
|
constructor(initialJd: number, live?: boolean);
|
|
1851
1859
|
/* Excluded from this release type: tick */
|
|
1852
1860
|
/* Excluded from this release type: setBoundaryStops */
|
|
@@ -1854,9 +1862,12 @@ export declare class SimClock {
|
|
|
1854
1862
|
setTimeScale(magnitude: number): void;
|
|
1855
1863
|
toggleDirection(): void;
|
|
1856
1864
|
/* Excluded from this release type: setJD */
|
|
1857
|
-
/**
|
|
1858
|
-
*
|
|
1859
|
-
|
|
1865
|
+
/** Move the clock to `jd` in one jump, so that listeners react to it once.
|
|
1866
|
+
* The promise resolves when a frame shows the bodies at that date. Until
|
|
1867
|
+
* the data of the date loads, the map shows the date before the jump, and
|
|
1868
|
+
* the measures answer for that date. */
|
|
1869
|
+
jumpTo(jd: number): Promise<void>;
|
|
1870
|
+
/* Excluded from this release type: placed */
|
|
1860
1871
|
/** Rest the settled date on where the clock stands now. */
|
|
1861
1872
|
private settle;
|
|
1862
1873
|
/** The same, once a drag holds still. A clock still playing is left alone: it
|
|
@@ -1871,8 +1882,9 @@ export declare class SimClock {
|
|
|
1871
1882
|
get playing(): boolean;
|
|
1872
1883
|
/** The moment the map is showing. */
|
|
1873
1884
|
get date(): Date;
|
|
1874
|
-
/**
|
|
1875
|
-
|
|
1885
|
+
/** Move the clock to `date` in one jump. The promise resolves as the promise
|
|
1886
|
+
* of {@link jumpTo} does. */
|
|
1887
|
+
setDate(date: Date): Promise<void>;
|
|
1876
1888
|
}
|
|
1877
1889
|
|
|
1878
1890
|
/**
|
|
@@ -2012,9 +2024,17 @@ export declare class SpaceMap {
|
|
|
2012
2024
|
* the move a click on its label makes. Resolves when the camera comes
|
|
2013
2025
|
* round. */
|
|
2014
2026
|
panTo(target: FeatureTarget): Promise<void>;
|
|
2015
|
-
/**
|
|
2016
|
-
*
|
|
2017
|
-
|
|
2027
|
+
/**
|
|
2028
|
+
* Put the camera at a place at once, with no flight. Use it to restore a
|
|
2029
|
+
* stored view. A body that the map has not loaded loads first. The promise
|
|
2030
|
+
* resolves one frame after the camera is in its place. It rejects when the
|
|
2031
|
+
* data of the body does not load. A later move stops this move.
|
|
2032
|
+
*/
|
|
2033
|
+
jumpTo(target: JumpTarget): Promise<void>;
|
|
2034
|
+
/** Whether `id` is in the scene, with a place at the date it shows. */
|
|
2035
|
+
private placedNow;
|
|
2036
|
+
/** The placement of {@link jumpTo}, on a body in the scene. */
|
|
2037
|
+
private snap;
|
|
2018
2038
|
/** Where the camera is now. Null before the first frame, and while nothing
|
|
2019
2039
|
* is focused. */
|
|
2020
2040
|
getCamera(): CameraState | null;
|
package/index.js
CHANGED
|
@@ -110,7 +110,7 @@ var noop = () => {};
|
|
|
110
110
|
function run_all(arr) {
|
|
111
111
|
for (var i = 0; i < arr.length; i++) arr[i]();
|
|
112
112
|
}
|
|
113
|
-
function deferred() {
|
|
113
|
+
function deferred$1() {
|
|
114
114
|
var resolve;
|
|
115
115
|
var reject;
|
|
116
116
|
return {
|
|
@@ -902,7 +902,7 @@ var Batch = class Batch {
|
|
|
902
902
|
this.#discard_callbacks.add(fn);
|
|
903
903
|
}
|
|
904
904
|
settled() {
|
|
905
|
-
return (this.#deferred ??= deferred()).promise;
|
|
905
|
+
return (this.#deferred ??= deferred$1()).promise;
|
|
906
906
|
}
|
|
907
907
|
static ensure() {
|
|
908
908
|
if (current_batch === null) {
|
|
@@ -10378,6 +10378,30 @@ function applySouthTowardParent(obj, bodyPos, parentPos) {
|
|
|
10378
10378
|
function applyUpVector(obj, dir) {
|
|
10379
10379
|
obj.quaternion.setFromUnitVectors(LOCAL_NORTH, dir);
|
|
10380
10380
|
}
|
|
10381
|
+
function landedHeadingAt(headings, jd) {
|
|
10382
|
+
let deg;
|
|
10383
|
+
for (const h of headings ?? []) if (h.jd <= jd) deg = h.deg;
|
|
10384
|
+
return deg;
|
|
10385
|
+
}
|
|
10386
|
+
var LOCAL_FRONT = new Vector3(0, 0, 1);
|
|
10387
|
+
var _up = new Vector3();
|
|
10388
|
+
var _front = new Vector3();
|
|
10389
|
+
var _north = new Vector3();
|
|
10390
|
+
var _east = new Vector3();
|
|
10391
|
+
var _target = new Vector3();
|
|
10392
|
+
var _cross = new Vector3();
|
|
10393
|
+
var _turn = new Quaternion();
|
|
10394
|
+
function turnToHeading(obj, north, headingDeg) {
|
|
10395
|
+
_up.copy(LOCAL_NORTH).applyQuaternion(obj.quaternion);
|
|
10396
|
+
_north.copy(north).addScaledVector(_up, -north.dot(_up)).normalize();
|
|
10397
|
+
_east.crossVectors(_north, _up);
|
|
10398
|
+
const h = headingDeg * DEG2RAD$5;
|
|
10399
|
+
_target.copy(_north).multiplyScalar(Math.cos(h)).addScaledVector(_east, Math.sin(h));
|
|
10400
|
+
_front.copy(LOCAL_FRONT).applyQuaternion(obj.quaternion);
|
|
10401
|
+
_front.addScaledVector(_up, -_front.dot(_up)).normalize();
|
|
10402
|
+
const angle = Math.atan2(_cross.crossVectors(_front, _target).dot(_up), _front.dot(_target));
|
|
10403
|
+
obj.quaternion.premultiply(_turn.setFromAxisAngle(_up, angle));
|
|
10404
|
+
}
|
|
10381
10405
|
var AXIS_VECTORS = {
|
|
10382
10406
|
"+x": new Vector3(1, 0, 0),
|
|
10383
10407
|
"-x": new Vector3(-1, 0, 0),
|
|
@@ -13517,6 +13541,11 @@ function disposeChain(chain) {
|
|
|
13517
13541
|
chain.uniforms.map.value = null;
|
|
13518
13542
|
chain.uniforms.mask.value = null;
|
|
13519
13543
|
}
|
|
13544
|
+
function chainSettled(chain, tiles) {
|
|
13545
|
+
const store = chain.store;
|
|
13546
|
+
if (!store || chain.dead || chain.uniforms.window.value[0].w === 0) return true;
|
|
13547
|
+
return store.windows.every((win) => settled(chain, store, tiles, win));
|
|
13548
|
+
}
|
|
13520
13549
|
function restChain(chain, now) {
|
|
13521
13550
|
switchOff(chain);
|
|
13522
13551
|
if (now - chain.lastUsed > IDLE_DISPOSE_S * 1e3) disposeChain(chain);
|
|
@@ -15765,6 +15794,7 @@ async function loadSpacecraftModel(bo, modelScene, ctx) {
|
|
|
15765
15794
|
try {
|
|
15766
15795
|
const detail = await fetchObjectDetail(bo.body.data.id, false);
|
|
15767
15796
|
bo.body.pointing = detail.global?.pointing;
|
|
15797
|
+
bo.body.landedHeadings = landedHeadings(detail.global?.events?.items);
|
|
15768
15798
|
const attitudeManifest = detail.global?.attitude;
|
|
15769
15799
|
if (attitudeManifest && (bo.modelLoadEpoch ?? 0) === epoch) {
|
|
15770
15800
|
const probeId = bo.body.data.id.replace(/^probe-/, "");
|
|
@@ -15804,8 +15834,9 @@ async function loadSpacecraftModel(bo, modelScene, ctx) {
|
|
|
15804
15834
|
bo.model = root;
|
|
15805
15835
|
bo.modelName = slug;
|
|
15806
15836
|
setHaloLoading(bo, false);
|
|
15807
|
-
|
|
15808
|
-
|
|
15837
|
+
const spanM = meta.exports[tier]?.scale_meters;
|
|
15838
|
+
if (spanM) {
|
|
15839
|
+
const spanKm = spanM / 2e3;
|
|
15809
15840
|
bo.body.data.radiusKm = spanKm * (meta.body_span_ratio ?? 1);
|
|
15810
15841
|
bo.radiusScene = kmToScene(effectiveRadiusKm(bo.body.data));
|
|
15811
15842
|
bo.modelUnitOverride = meta.body_span_ratio ? kmToScene(spanKm) : void 0;
|
|
@@ -15918,6 +15949,7 @@ function unloadBodyModel(bo) {
|
|
|
15918
15949
|
bo.model = null;
|
|
15919
15950
|
bo.modelName = void 0;
|
|
15920
15951
|
bo.body.pointing = void 0;
|
|
15952
|
+
bo.body.landedHeadings = void 0;
|
|
15921
15953
|
bo.body.attitudeTrack = void 0;
|
|
15922
15954
|
bo.body.modelBaseFrame = void 0;
|
|
15923
15955
|
if (bo.mesh && restoreSphere) bo.mesh.visible = true;
|
|
@@ -15937,6 +15969,17 @@ function setHaloLoading(bo, loading) {
|
|
|
15937
15969
|
bo.loadingShown = void 0;
|
|
15938
15970
|
}
|
|
15939
15971
|
}
|
|
15972
|
+
function landedHeadings(events) {
|
|
15973
|
+
const out = [];
|
|
15974
|
+
for (const e of events ?? []) {
|
|
15975
|
+
const deg = e.type === "landing" ? e.site?.heading_deg : void 0;
|
|
15976
|
+
if (deg !== void 0) out.push({
|
|
15977
|
+
jd: e.jd,
|
|
15978
|
+
deg
|
|
15979
|
+
});
|
|
15980
|
+
}
|
|
15981
|
+
return out.length ? out : void 0;
|
|
15982
|
+
}
|
|
15940
15983
|
function withBaseFrame(scene, q) {
|
|
15941
15984
|
if (!q) return scene;
|
|
15942
15985
|
const wrapper = new Group();
|
|
@@ -18708,6 +18751,7 @@ var SimClock = class {
|
|
|
18708
18751
|
prevScale = 1;
|
|
18709
18752
|
stops = null;
|
|
18710
18753
|
settleTimer = null;
|
|
18754
|
+
arrivals = [];
|
|
18711
18755
|
constructor(initialJd, live = false) {
|
|
18712
18756
|
this.jd = initialJd;
|
|
18713
18757
|
this.settledJd = initialJd;
|
|
@@ -18764,6 +18808,19 @@ var SimClock = class {
|
|
|
18764
18808
|
this.setJD(jd);
|
|
18765
18809
|
this.jumps++;
|
|
18766
18810
|
this.settle();
|
|
18811
|
+
const jumps = this.jumps;
|
|
18812
|
+
return new Promise((resolve) => this.arrivals.push({
|
|
18813
|
+
jumps,
|
|
18814
|
+
resolve
|
|
18815
|
+
}));
|
|
18816
|
+
}
|
|
18817
|
+
placed(jumps) {
|
|
18818
|
+
if (this.arrivals.length === 0) return;
|
|
18819
|
+
this.arrivals = this.arrivals.filter((arrival) => {
|
|
18820
|
+
if (arrival.jumps > jumps) return true;
|
|
18821
|
+
arrival.resolve();
|
|
18822
|
+
return false;
|
|
18823
|
+
});
|
|
18767
18824
|
}
|
|
18768
18825
|
settle() {
|
|
18769
18826
|
if (this.settleTimer !== null) clearTimeout(this.settleTimer);
|
|
@@ -18804,7 +18861,7 @@ var SimClock = class {
|
|
|
18804
18861
|
return jdToDate(this.jd);
|
|
18805
18862
|
}
|
|
18806
18863
|
setDate(date) {
|
|
18807
|
-
this.jumpTo(dateToJD(date));
|
|
18864
|
+
return this.jumpTo(dateToJD(date));
|
|
18808
18865
|
}
|
|
18809
18866
|
};
|
|
18810
18867
|
|
|
@@ -21100,6 +21157,7 @@ var SystemDataLoader = class {
|
|
|
21100
21157
|
lastBaryId = null;
|
|
21101
21158
|
pendingUnloads = /* @__PURE__ */ new Set();
|
|
21102
21159
|
prefetched = /* @__PURE__ */ new Set();
|
|
21160
|
+
loads = 0;
|
|
21103
21161
|
constructor(scene, ctx, renderer, textureLoader, bodyObjects, clock, onLoaded) {
|
|
21104
21162
|
this.scene = scene;
|
|
21105
21163
|
this.ctx = ctx;
|
|
@@ -21145,10 +21203,14 @@ var SystemDataLoader = class {
|
|
|
21145
21203
|
return isTopLevelParent(baryId) ? null : baryId;
|
|
21146
21204
|
}
|
|
21147
21205
|
load(baryId) {
|
|
21206
|
+
this.loads++;
|
|
21148
21207
|
loadSystemData(baryId, this.bodyObjects, this.scene, this.textureLoader, this.clock.jd, this.renderer.capabilities.maxTextureSize, this.ctx).then(() => {
|
|
21149
21208
|
this.onLoaded();
|
|
21150
21209
|
this.ctx.bodies.orientationVersion++;
|
|
21151
|
-
});
|
|
21210
|
+
}).finally(() => this.loads--);
|
|
21211
|
+
}
|
|
21212
|
+
isLoading() {
|
|
21213
|
+
return this.loads > 0;
|
|
21152
21214
|
}
|
|
21153
21215
|
drainPendingUnloads() {
|
|
21154
21216
|
if (this.pendingUnloads.size === 0) return;
|
|
@@ -24514,6 +24576,7 @@ var OutOfRangeNotifier = class {
|
|
|
24514
24576
|
//#region src/lib/scene/position/landed-probe.ts
|
|
24515
24577
|
var lastSeat = /* @__PURE__ */ new Map();
|
|
24516
24578
|
var _upScene = new Vector3();
|
|
24579
|
+
var _northScene = new Vector3();
|
|
24517
24580
|
function renderLandedProbe(d, probe, landed, jd, where, ctx, bodyObjects) {
|
|
24518
24581
|
const sample = landedPositionAt(landed, jd, landedOpenEnded(probe));
|
|
24519
24582
|
if (!sample) return null;
|
|
@@ -24543,13 +24606,15 @@ function renderLandedProbe(d, probe, landed, jd, where, ctx, bodyObjects) {
|
|
|
24543
24606
|
const quat = bodyQuaternion(landingBody.orientation, jd, landingBody.nutPrec);
|
|
24544
24607
|
const tmp = new Vector3(bx, by, bz).applyQuaternion(quat);
|
|
24545
24608
|
const up = eff ? _upScene.set(eff.normal[0], eff.normal[1], eff.normal[2]).applyQuaternion(quat) : null;
|
|
24609
|
+
const north = _northScene.set(-Math.sin(latR) * Math.cos(lngR), Math.cos(latR), Math.sin(latR) * Math.sin(lngR)).applyQuaternion(quat);
|
|
24546
24610
|
d.parentId = bodyKey;
|
|
24547
24611
|
return {
|
|
24548
24612
|
x: bodyWorldPos[0] + kmToScene(tmp.x),
|
|
24549
24613
|
y: bodyWorldPos[1] + kmToScene(tmp.y),
|
|
24550
24614
|
z: bodyWorldPos[2] + kmToScene(tmp.z),
|
|
24551
24615
|
parentPos: bodyWorldPos,
|
|
24552
|
-
up
|
|
24616
|
+
up,
|
|
24617
|
+
north
|
|
24553
24618
|
};
|
|
24554
24619
|
}
|
|
24555
24620
|
|
|
@@ -24800,8 +24865,12 @@ var Placer = class {
|
|
|
24800
24865
|
const up = landedRender.up;
|
|
24801
24866
|
if (bo?.mesh) if (up) applyUpVector(bo.mesh, up);
|
|
24802
24867
|
else applySouthTowardParent(bo.mesh, pos, landedRender.parentPos);
|
|
24803
|
-
if (bo?.model)
|
|
24804
|
-
|
|
24868
|
+
if (bo?.model) {
|
|
24869
|
+
if (up) applyUpVector(bo.model, up);
|
|
24870
|
+
else applySouthTowardParent(bo.model, pos, landedRender.parentPos);
|
|
24871
|
+
const heading = landedHeadingAt(body.landedHeadings, jd);
|
|
24872
|
+
if (heading !== void 0) turnToHeading(bo.model, landedRender.north, heading);
|
|
24873
|
+
}
|
|
24805
24874
|
return pos;
|
|
24806
24875
|
}
|
|
24807
24876
|
const primary = resolveProbePrimary(located.probe, jd, located.fitCenterNaifId, ctx.chebStore ?? null, (id) => this.at(id, jd) !== null);
|
|
@@ -25571,6 +25640,10 @@ function gridGeometry(grid) {
|
|
|
25571
25640
|
return geometry;
|
|
25572
25641
|
}
|
|
25573
25642
|
var tiledStates = /* @__PURE__ */ new WeakMap();
|
|
25643
|
+
var deferred = /* @__PURE__ */ new WeakSet();
|
|
25644
|
+
function terrainSettled(bo) {
|
|
25645
|
+
return !tiledStates.get(bo)?.abort && !deferred.has(bo);
|
|
25646
|
+
}
|
|
25574
25647
|
var MAX_BUILD_FAILURES = 2;
|
|
25575
25648
|
function heightTilesOf(bo) {
|
|
25576
25649
|
const tiles = bo.displacementMeta?.tiles;
|
|
@@ -25625,7 +25698,10 @@ function updateTiledWindow(bo, mesh, tiles, altitude, centerTheta, centerPhi, in
|
|
|
25625
25698
|
if (held) {
|
|
25626
25699
|
const still = drift(centerTheta, centerPhi, held.centerTheta, held.centerPhi);
|
|
25627
25700
|
if (kept === stepLevel && still < RECENTER_FRAC * held.angRadius) return true;
|
|
25628
|
-
if (performance.now() - held.builtAt < REBUILD_MIN_MS)
|
|
25701
|
+
if (performance.now() - held.builtAt < REBUILD_MIN_MS) {
|
|
25702
|
+
deferred.add(bo);
|
|
25703
|
+
return true;
|
|
25704
|
+
}
|
|
25629
25705
|
}
|
|
25630
25706
|
const grid = planNestedGrid(centerTheta, centerPhi, altitude, .5 * meta.scale_km / radiusKm, finest, bandCells, stepLevel);
|
|
25631
25707
|
const thetas = grid.rows.at;
|
|
@@ -25687,6 +25763,7 @@ function updateTiledWindow(bo, mesh, tiles, altitude, centerTheta, centerPhi, in
|
|
|
25687
25763
|
return !!held;
|
|
25688
25764
|
}
|
|
25689
25765
|
function updateTerrainWindow(bo, camera, eligible, invalidate) {
|
|
25766
|
+
deferred.delete(bo);
|
|
25690
25767
|
const mesh = bo.mesh;
|
|
25691
25768
|
const tex = bo.displacementMap;
|
|
25692
25769
|
if (!eligible || !mesh || !tex) {
|
|
@@ -25725,7 +25802,10 @@ function updateTerrainWindow(bo, camera, eligible, invalidate) {
|
|
|
25725
25802
|
if (w.stepLevel === stepLevel) {
|
|
25726
25803
|
if (drift(centerTheta, centerPhi, w.centerTheta, w.centerPhi) < RECENTER_FRAC * w.angRadius) return true;
|
|
25727
25804
|
}
|
|
25728
|
-
if (performance.now() - w.builtAt < REBUILD_MIN_MS)
|
|
25805
|
+
if (performance.now() - w.builtAt < REBUILD_MIN_MS) {
|
|
25806
|
+
deferred.add(bo);
|
|
25807
|
+
return true;
|
|
25808
|
+
}
|
|
25729
25809
|
}
|
|
25730
25810
|
const thetaLo = Math.max(0, centerTheta - angRadius);
|
|
25731
25811
|
const thetaHi = Math.min(Math.PI, centerTheta + angRadius);
|
|
@@ -25822,6 +25902,15 @@ function desiredDemTier(altitudeRadii, current) {
|
|
|
25822
25902
|
if (tierRank(down) < tierRank(current)) return down;
|
|
25823
25903
|
return current;
|
|
25824
25904
|
}
|
|
25905
|
+
function bodyLoading(bo) {
|
|
25906
|
+
if (bo.textureLoading || bo.displacementLoading || bo.clouds?.textureLoading) return true;
|
|
25907
|
+
if (bo.appearance?.loading || bo.modelLoadPromise) return true;
|
|
25908
|
+
const surface = bo.tileOverlay;
|
|
25909
|
+
if (surface && bo.surfaceTiles && !chainSettled(surface.chain, bo.surfaceTiles)) return true;
|
|
25910
|
+
const relief = bo.reliefTiles;
|
|
25911
|
+
if (relief && !chainSettled(relief.chain, relief.tiles)) return true;
|
|
25912
|
+
return !terrainSettled(bo);
|
|
25913
|
+
}
|
|
25825
25914
|
function updateTextureLOD(bodyObjects, camera, renderer, ctx, textureLoader, focusedId, jd, appearances, invalidate) {
|
|
25826
25915
|
appearances.apply(bodyObjects, textureLoader);
|
|
25827
25916
|
const fovRad = camera.fov * Math.PI / 180;
|
|
@@ -25876,6 +25965,13 @@ function updateTextureLOD(bodyObjects, camera, renderer, ctx, textureLoader, foc
|
|
|
25876
25965
|
}
|
|
25877
25966
|
}
|
|
25878
25967
|
|
|
25968
|
+
//#endregion
|
|
25969
|
+
//#region src/lib/scene/perf/calibration-state.svelte.ts
|
|
25970
|
+
var calibrationUi = proxy({
|
|
25971
|
+
progress: null,
|
|
25972
|
+
bootPending: false
|
|
25973
|
+
});
|
|
25974
|
+
|
|
25879
25975
|
//#endregion
|
|
25880
25976
|
//#region src/lib/scene/animation/focus.ts
|
|
25881
25977
|
var FOCUS_DURATION_MS = FOCUS_ROT_PACING.refMs;
|
|
@@ -27262,6 +27358,11 @@ var SceneRenderer = class SceneRenderer {
|
|
|
27262
27358
|
lastRenderedFocusKey = "";
|
|
27263
27359
|
lastRenderedCamPos = new Vector3(NaN, NaN, NaN);
|
|
27264
27360
|
lastRenderedCamQuat = new Quaternion();
|
|
27361
|
+
restCamPos = new Vector3(NaN, NaN, NaN);
|
|
27362
|
+
restCamQuat = new Quaternion();
|
|
27363
|
+
restFocusKey = "";
|
|
27364
|
+
atRest = false;
|
|
27365
|
+
focusLoads = 0;
|
|
27265
27366
|
unsubscribeBodiesAdded = null;
|
|
27266
27367
|
_trailView = {
|
|
27267
27368
|
camX: 0,
|
|
@@ -27691,6 +27792,7 @@ var SceneRenderer = class SceneRenderer {
|
|
|
27691
27792
|
this.lastRenderedCamPos.copy(this.camera.position);
|
|
27692
27793
|
this.lastRenderedCamQuat.copy(this.camera.quaternion);
|
|
27693
27794
|
this.applyJdUpdate(true);
|
|
27795
|
+
if (!this.dateHeld() && !this.seekAwaitsData) this.clock.placed(this.seenJumps);
|
|
27694
27796
|
this.refreshTravelFocus();
|
|
27695
27797
|
this.callbacks.onFrame?.(this.sceneJd, renderedDtMs);
|
|
27696
27798
|
const controlsSettled = this.holdingCamera ? this.applyHeldCamera() : stepFocusAnimation(this.focus, this.camera, this.controls, () => this.repositionAll(), () => this.pointClouds.rebuildBasis());
|
|
@@ -27766,7 +27868,27 @@ var SceneRenderer = class SceneRenderer {
|
|
|
27766
27868
|
this.renderModelOverlay();
|
|
27767
27869
|
this.labelRenderer.render(this.scene, this.camera);
|
|
27768
27870
|
if (this.haloDebug.active) this.haloDebug.draw(this.bodyObjects, this.camera, this.focus.focusTruePos, this.focusController.current?.data.id, this.renderer.domElement.clientWidth, this.renderer.domElement.clientHeight);
|
|
27769
|
-
|
|
27871
|
+
this.checkRest(nowMs);
|
|
27872
|
+
};
|
|
27873
|
+
checkRest(nowMs) {
|
|
27874
|
+
const moved = this.cameraMovedFrom(this.restCamPos, this.restCamQuat) || this.focusKey() !== this.restFocusKey;
|
|
27875
|
+
this.restCamPos.copy(this.camera.position);
|
|
27876
|
+
this.restCamQuat.copy(this.camera.quaternion);
|
|
27877
|
+
this.restFocusKey = this.focusKey();
|
|
27878
|
+
if (moved || this.settling(nowMs)) this.atRest = false;
|
|
27879
|
+
else if (!this.atRest) {
|
|
27880
|
+
this.atRest = true;
|
|
27881
|
+
this.callbacks.onIdle?.();
|
|
27882
|
+
}
|
|
27883
|
+
}
|
|
27884
|
+
settling(nowMs) {
|
|
27885
|
+
if (this.covered || this.ctx.loading || calibrationUi.bootPending) return true;
|
|
27886
|
+
if (nowMs - this.focus.focusStartTime < this.focus.focusDurationMs) return true;
|
|
27887
|
+
if (this.jumpJd !== null || this.seekAwaitsData) return true;
|
|
27888
|
+
if (this.focusLoads > 0 || this.systemData.isLoading()) return true;
|
|
27889
|
+
for (const bo of this.bodyObjects.values()) if (bo.group.visible && bodyLoading(bo)) return true;
|
|
27890
|
+
return false;
|
|
27891
|
+
}
|
|
27770
27892
|
syncSceneSamples(insideShell) {
|
|
27771
27893
|
const target = this.composer.readBuffer;
|
|
27772
27894
|
const samples = insideShell ? 0 : Math.min(this.tier.sceneSamples, this.maxSceneSamples);
|
|
@@ -28167,11 +28289,14 @@ var SceneRenderer = class SceneRenderer {
|
|
|
28167
28289
|
if (nowMs - this.focus.focusStartTime < this.focus.focusDurationMs || this.focusKey() !== this.lastRenderedFocusKey || this.ctx.bodies.minorStreaming || this.pointClouds.hasPendingSceneAdds() || this.systemData.hasPendingUnloads()) return true;
|
|
28168
28290
|
if (this.covered) return false;
|
|
28169
28291
|
if (this.frameIndex - this.lastRenderedFrame >= SceneRenderer.IDLE_HEARTBEAT_FRAMES) return true;
|
|
28170
|
-
|
|
28171
|
-
if (cam.position.distanceToSquared(this.lastRenderedCamPos) > cam.position.lengthSq() * 1e-10 || 8 * (1 - Math.abs(cam.quaternion.dot(this.lastRenderedCamQuat))) > 1e-8 || this.frameIndex < this.wakeUntilFrame || this.haloDebug.active) return true;
|
|
28292
|
+
if (this.cameraMovedFrom(this.lastRenderedCamPos, this.lastRenderedCamQuat) || this.frameIndex < this.wakeUntilFrame || this.haloDebug.active) return true;
|
|
28172
28293
|
if (this.clock.jd === this.lastRenderedJd) return false;
|
|
28173
28294
|
return Math.abs(this.clock.timeScale) > 1 || nowMs - this.lastRenderMs >= SceneRenderer.REALTIME_FRAME_MS;
|
|
28174
28295
|
}
|
|
28296
|
+
cameraMovedFrom(pos, quat) {
|
|
28297
|
+
const cam = this.camera;
|
|
28298
|
+
return !(cam.position.distanceToSquared(pos) <= cam.position.lengthSq() * 1e-10 && 8 * (1 - Math.abs(cam.quaternion.dot(quat))) <= 1e-8);
|
|
28299
|
+
}
|
|
28175
28300
|
onControlsEnd = () => {
|
|
28176
28301
|
this.pendingUrlWrite = true;
|
|
28177
28302
|
this.focusController.clearPendingInitialView();
|
|
@@ -28187,13 +28312,15 @@ var SceneRenderer = class SceneRenderer {
|
|
|
28187
28312
|
maybeLoadTexture(body) {
|
|
28188
28313
|
const bo = this.bodyObjects.get(body.data.id);
|
|
28189
28314
|
if (!bo) return;
|
|
28315
|
+
this.focusLoads += 2;
|
|
28316
|
+
const done = () => this.focusLoads--;
|
|
28190
28317
|
loadBodyTexture(bo, this.textureLoader, this.sceneJd, this.scene, this.renderer.capabilities.maxTextureSize, this.ctx).then(() => {
|
|
28191
28318
|
if (this.focusController.current?.data.id !== body.data.id) return;
|
|
28192
28319
|
if (body.orientation && bo.mesh) {
|
|
28193
28320
|
applyOrientation(bo.mesh, body.orientation, this.sceneJd, body.nutPrec);
|
|
28194
28321
|
this.focusController.reapplyInitialViewIfPending();
|
|
28195
28322
|
}
|
|
28196
|
-
});
|
|
28323
|
+
}).finally(done);
|
|
28197
28324
|
loadBodyModel(bo, this.modelScene, this.ctx).then(() => {
|
|
28198
28325
|
if (this.focusController.current?.data.id === bo.body.data.id) this.controls.minDistance = minCameraDistance(bo.body, modelMinRadiusKm(bo));
|
|
28199
28326
|
if (this.ctx.layers.skipped.has("nomenclature")) return;
|
|
@@ -28203,7 +28330,7 @@ var SceneRenderer = class SceneRenderer {
|
|
|
28203
28330
|
});
|
|
28204
28331
|
}).then(() => {
|
|
28205
28332
|
if (this.selectedFeatureId !== null) setActiveFeatureLabel(bo, this.selectedFeatureId);
|
|
28206
|
-
});
|
|
28333
|
+
}).finally(done);
|
|
28207
28334
|
}
|
|
28208
28335
|
reapplyBodyLayers() {
|
|
28209
28336
|
const focused = this.focusController.current;
|
|
@@ -28661,7 +28788,8 @@ var SceneRenderer = class SceneRenderer {
|
|
|
28661
28788
|
setCovered(covered) {
|
|
28662
28789
|
if (this.covered === covered) return;
|
|
28663
28790
|
this.covered = covered;
|
|
28664
|
-
if (
|
|
28791
|
+
if (covered) this.atRest = false;
|
|
28792
|
+
else this.invalidate();
|
|
28665
28793
|
}
|
|
28666
28794
|
isContextLost() {
|
|
28667
28795
|
return this.renderer.getContext().isContextLost();
|
|
@@ -28754,13 +28882,6 @@ function disposeTexture(value) {
|
|
|
28754
28882
|
if (value && typeof value === "object" && value.isTexture) value.dispose();
|
|
28755
28883
|
}
|
|
28756
28884
|
|
|
28757
|
-
//#endregion
|
|
28758
|
-
//#region src/lib/scene/perf/calibration-state.svelte.ts
|
|
28759
|
-
var calibrationUi = proxy({
|
|
28760
|
-
progress: null,
|
|
28761
|
-
bootPending: false
|
|
28762
|
-
});
|
|
28763
|
-
|
|
28764
28885
|
//#endregion
|
|
28765
28886
|
//#region src/lib/scene/perf/atmosphere-benchmark.ts
|
|
28766
28887
|
var EARTH_RADIUS_KM = 6371;
|
|
@@ -31223,6 +31344,7 @@ var SpaceMap = class {
|
|
|
31223
31344
|
clock: /* @__PURE__ */ new Set(),
|
|
31224
31345
|
loading: /* @__PURE__ */ new Set(),
|
|
31225
31346
|
progress: /* @__PURE__ */ new Set(),
|
|
31347
|
+
idle: /* @__PURE__ */ new Set(),
|
|
31226
31348
|
error: /* @__PURE__ */ new Set(),
|
|
31227
31349
|
datastale: /* @__PURE__ */ new Set(),
|
|
31228
31350
|
notice: /* @__PURE__ */ new Set(),
|
|
@@ -31494,6 +31616,7 @@ var SpaceMap = class {
|
|
|
31494
31616
|
dtMs
|
|
31495
31617
|
});
|
|
31496
31618
|
},
|
|
31619
|
+
onIdle: () => this.emit("idle"),
|
|
31497
31620
|
onCameraPosition: (latitude, longitude, zoom) => {
|
|
31498
31621
|
const body = this.focusedBody?.data.id;
|
|
31499
31622
|
if (body === void 0) return;
|
|
@@ -31728,20 +31851,38 @@ var SpaceMap = class {
|
|
|
31728
31851
|
panTo(target) {
|
|
31729
31852
|
return this.toFeature(this.targetBody(target), target.feature, "pan");
|
|
31730
31853
|
}
|
|
31731
|
-
jumpTo(target) {
|
|
31854
|
+
async jumpTo(target) {
|
|
31732
31855
|
const body = this.targetBody(target);
|
|
31856
|
+
if (this.placedNow(body) && target.facing === void 0 || this.placedNow(target.facing)) this.navigation++;
|
|
31857
|
+
else {
|
|
31858
|
+
const loading = this.goTo(body, {
|
|
31859
|
+
clock: "keep",
|
|
31860
|
+
camera: "none"
|
|
31861
|
+
});
|
|
31862
|
+
const token = this.navigation;
|
|
31863
|
+
const arrival = await loading;
|
|
31864
|
+
if (arrival.outcome === "failed") throw arrival.error;
|
|
31865
|
+
if (arrival.outcome !== "placed" || token !== this.navigation) return;
|
|
31866
|
+
}
|
|
31867
|
+
this.snap(target, body);
|
|
31868
|
+
return this.settled(0);
|
|
31869
|
+
}
|
|
31870
|
+
placedNow(id) {
|
|
31871
|
+
const body = this.ctx.getBody(id);
|
|
31872
|
+
return !!body && !!this.renderer?.placeOf(body);
|
|
31873
|
+
}
|
|
31874
|
+
snap(target, body) {
|
|
31733
31875
|
if (target.facing !== void 0) {
|
|
31734
31876
|
this.snapToBodyFacing(body, target.facing, target.elevationDeg ?? 0, this.framing(target, body));
|
|
31735
|
-
return
|
|
31877
|
+
return;
|
|
31736
31878
|
}
|
|
31737
31879
|
if (target.feature) {
|
|
31738
31880
|
const { featureId, lat, lon, diameterM } = target.feature;
|
|
31739
31881
|
this.focusOnFeature(body, featureId, lat, lon, diameterM, null, "snap");
|
|
31740
|
-
return
|
|
31882
|
+
return;
|
|
31741
31883
|
}
|
|
31742
31884
|
const camera = this.getCamera();
|
|
31743
31885
|
this.snapToBody(body, target.lat ?? camera?.lat ?? 45, target.lon ?? camera?.lon ?? 0, this.framing(target, body));
|
|
31744
|
-
return this;
|
|
31745
31886
|
}
|
|
31746
31887
|
getCamera() {
|
|
31747
31888
|
const renderer = this.renderer;
|
package/package.json
CHANGED