astro-viewer 3.10.0 → 3.12.0
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 +66 -4
- package/dist/astroviewer.cjs +911 -154
- package/dist/astroviewer.cjs.map +1 -1
- package/dist/astroviewer.js +911 -154
- package/dist/astroviewer.js.map +1 -1
- package/dist/astroviewer.min.js +1 -1
- package/dist/astroviewer.min.js.map +1 -1
- package/lib-esm/AstroSphere.d.ts +37 -2
- package/lib-esm/AstroSphere.d.ts.map +1 -1
- package/lib-esm/AstroSphere.js +249 -70
- package/lib-esm/AstroSphere.js.map +1 -1
- package/lib-esm/AstroViewer.d.ts +15 -1
- package/lib-esm/AstroViewer.d.ts.map +1 -1
- package/lib-esm/AstroViewer.js +41 -4
- package/lib-esm/AstroViewer.js.map +1 -1
- package/lib-esm/Camera.d.ts +14 -0
- package/lib-esm/Camera.d.ts.map +1 -1
- package/lib-esm/Camera.js +118 -8
- package/lib-esm/Camera.js.map +1 -1
- package/lib-esm/index.d.ts +1 -0
- package/lib-esm/index.d.ts.map +1 -1
- package/lib-esm/index.js +1 -0
- package/lib-esm/index.js.map +1 -1
- package/lib-esm/model/Source.d.ts +11 -0
- package/lib-esm/model/Source.d.ts.map +1 -1
- package/lib-esm/model/Source.js +8 -1
- package/lib-esm/model/Source.js.map +1 -1
- package/lib-esm/model/catalogues/CatalogueGL.d.ts +36 -5
- package/lib-esm/model/catalogues/CatalogueGL.d.ts.map +1 -1
- package/lib-esm/model/catalogues/CatalogueGL.js +329 -57
- package/lib-esm/model/catalogues/CatalogueGL.js.map +1 -1
- package/lib-esm/model/earth/XYZMap.d.ts +4 -1
- package/lib-esm/model/earth/XYZMap.d.ts.map +1 -1
- package/lib-esm/model/earth/XYZMap.js +35 -2
- package/lib-esm/model/earth/XYZMap.js.map +1 -1
- package/lib-esm/model/footprints/FootprintSetGL.d.ts +1 -0
- package/lib-esm/model/footprints/FootprintSetGL.d.ts.map +1 -1
- package/lib-esm/model/footprints/FootprintSetGL.js +13 -3
- package/lib-esm/model/footprints/FootprintSetGL.js.map +1 -1
- package/lib-esm/model/grid/EquatorialGrid.d.ts +1 -0
- package/lib-esm/model/grid/EquatorialGrid.d.ts.map +1 -1
- package/lib-esm/model/grid/EquatorialGrid.js +3 -0
- package/lib-esm/model/grid/EquatorialGrid.js.map +1 -1
- package/lib-esm/model/grid/HealpixGrid.d.ts +1 -0
- package/lib-esm/model/grid/HealpixGrid.d.ts.map +1 -1
- package/lib-esm/model/grid/HealpixGrid.js +3 -0
- package/lib-esm/model/grid/HealpixGrid.js.map +1 -1
- package/lib-esm/model/grid/LonLatGrid.d.ts +1 -0
- package/lib-esm/model/grid/LonLatGrid.d.ts.map +1 -1
- package/lib-esm/model/grid/LonLatGrid.js +3 -0
- package/lib-esm/model/grid/LonLatGrid.js.map +1 -1
- package/lib-esm/model/meships/MeshHiPS.d.ts +4 -0
- package/lib-esm/model/meships/MeshHiPS.d.ts.map +1 -1
- package/lib-esm/model/meships/MeshHiPS.js +11 -1
- package/lib-esm/model/meships/MeshHiPS.js.map +1 -1
- package/lib-esm/model/terra/TerraPointSetGL.d.ts +1 -0
- package/lib-esm/model/terra/TerraPointSetGL.d.ts.map +1 -1
- package/lib-esm/model/terra/TerraPointSetGL.js +39 -1
- package/lib-esm/model/terra/TerraPointSetGL.js.map +1 -1
- package/lib-esm/shader/CatalogueShaderProgram.d.ts +4 -0
- package/lib-esm/shader/CatalogueShaderProgram.d.ts.map +1 -1
- package/lib-esm/shader/CatalogueShaderProgram.js +6 -0
- package/lib-esm/shader/CatalogueShaderProgram.js.map +1 -1
- package/lib-esm/shader/ShaderManager.d.ts.map +1 -1
- package/lib-esm/shader/ShaderManager.js +7 -4
- package/lib-esm/shader/ShaderManager.js.map +1 -1
- package/lib-esm/shader/XYZShaderProgram.d.ts +3 -0
- package/lib-esm/shader/XYZShaderProgram.d.ts.map +1 -1
- package/lib-esm/shader/XYZShaderProgram.js +11 -3
- package/lib-esm/shader/XYZShaderProgram.js.map +1 -1
- package/lib-esm/utils/Utils.d.ts +12 -0
- package/lib-esm/utils/Utils.d.ts.map +1 -1
- package/lib-esm/utils/Utils.js +26 -0
- package/lib-esm/utils/Utils.js.map +1 -1
- package/package.json +2 -2
package/dist/astroviewer.js
CHANGED
|
@@ -53,6 +53,7 @@ __webpack_require__.d(vec3_namespaceObject, {
|
|
|
53
53
|
dot: () => (dot),
|
|
54
54
|
fromValues: () => (vec3_fromValues),
|
|
55
55
|
length: () => (vec3_length),
|
|
56
|
+
lerp: () => (lerp),
|
|
56
57
|
normalize: () => (normalize),
|
|
57
58
|
scale: () => (vec3_scale),
|
|
58
59
|
scaleAndAdd: () => (scaleAndAdd),
|
|
@@ -3640,12 +3641,18 @@ class AstroSphere {
|
|
|
3640
3641
|
_activeHiPS = null;
|
|
3641
3642
|
_activeHiPSLayers = [];
|
|
3642
3643
|
_activeXYZ2 = null;
|
|
3644
|
+
_earthRasterOverlays = [];
|
|
3645
|
+
_earthRasterOverlaySequence = 0;
|
|
3643
3646
|
_activeMeshHiPS = null;
|
|
3644
3647
|
_activeBaseLayer = null;
|
|
3648
|
+
_activeDomain = "astronomy";
|
|
3649
|
+
domainCameraStates = {};
|
|
3645
3650
|
startup = true;
|
|
3646
3651
|
fov;
|
|
3647
|
-
|
|
3648
|
-
|
|
3652
|
+
astronomyCatalogues = [];
|
|
3653
|
+
earthPointSets = [];
|
|
3654
|
+
astronomyFootprintSets = [];
|
|
3655
|
+
earthFootprintSets = [];
|
|
3649
3656
|
activePolylineSets = [];
|
|
3650
3657
|
activeSensorCones = [];
|
|
3651
3658
|
activeSatelliteObjects = [];
|
|
@@ -3878,9 +3885,7 @@ class AstroSphere {
|
|
|
3878
3885
|
return true;
|
|
3879
3886
|
}
|
|
3880
3887
|
emitCameraChanged(reason) {
|
|
3881
|
-
//
|
|
3882
|
-
if (!this._activeHiPS && !this._activeXYZ2 && !this._activeMeshHiPS)
|
|
3883
|
-
return;
|
|
3888
|
+
// Camera interaction remains meaningful even when no base layer is active.
|
|
3884
3889
|
if (!this._healpixGrid?.fovObj)
|
|
3885
3890
|
return;
|
|
3886
3891
|
const detail = this.getCurrentStatus();
|
|
@@ -3906,6 +3911,7 @@ class AstroSphere {
|
|
|
3906
3911
|
const handleMouseDown = (event) => {
|
|
3907
3912
|
canvas.setPointerCapture(event.pointerId);
|
|
3908
3913
|
this.mouseDown = true;
|
|
3914
|
+
this._camera.cancelFlyTo();
|
|
3909
3915
|
const rect = canvas.getBoundingClientRect();
|
|
3910
3916
|
this.lastMouseX = event.clientX - rect.left; // locale al canvas
|
|
3911
3917
|
this.lastMouseY = event.clientY - rect.top; // locale al canvas
|
|
@@ -3944,8 +3950,11 @@ class AstroSphere {
|
|
|
3944
3950
|
if (mousePoint && mousePoint.length > 0) {
|
|
3945
3951
|
this.mouseHelper.update(mousePoint);
|
|
3946
3952
|
this.updateLastMousePoint();
|
|
3947
|
-
for (const cat of this.
|
|
3948
|
-
const
|
|
3953
|
+
for (const cat of this.getActivePointSets()) {
|
|
3954
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
3955
|
+
if (!activeModelMatrix)
|
|
3956
|
+
continue;
|
|
3957
|
+
const clickResult = cat.selectPrimarySourceFromClick(this.mouseHelper, activeModelMatrix, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
3949
3958
|
if (!clickResult?.sources.length)
|
|
3950
3959
|
continue;
|
|
3951
3960
|
this._webgl.canvas.dispatchEvent(new CustomEvent("source-clicked", {
|
|
@@ -3958,7 +3967,7 @@ class AstroSphere {
|
|
|
3958
3967
|
composed: true,
|
|
3959
3968
|
}));
|
|
3960
3969
|
}
|
|
3961
|
-
for (const fset of this.
|
|
3970
|
+
for (const fset of this.getActiveFootprintSets()) {
|
|
3962
3971
|
const clickResult = fset.selectPrimaryFootprintFromClick(this.mouseHelper);
|
|
3963
3972
|
if (!clickResult?.footprints.length)
|
|
3964
3973
|
continue;
|
|
@@ -4032,6 +4041,7 @@ class AstroSphere {
|
|
|
4032
4041
|
const handleMouseWheel = (event) => {
|
|
4033
4042
|
const currentFov = this._healpixGrid.getMinFoV();
|
|
4034
4043
|
const zoomStep = this.computeZoomStep(currentFov, event.deltaY);
|
|
4044
|
+
this._camera.cancelFlyTo();
|
|
4035
4045
|
// Apply wheel zoom immediately and discard any queued inertia so reversing
|
|
4036
4046
|
// direction feels responsive instead of "buffered".
|
|
4037
4047
|
this.zoomInertia = 0;
|
|
@@ -4054,8 +4064,11 @@ class AstroSphere {
|
|
|
4054
4064
|
}
|
|
4055
4065
|
this.mouseHelper.update(mousePoint);
|
|
4056
4066
|
this.updateLastMousePoint();
|
|
4057
|
-
for (const cat of this.
|
|
4058
|
-
const
|
|
4067
|
+
for (const cat of this.getActivePointSets()) {
|
|
4068
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4069
|
+
if (!activeModelMatrix)
|
|
4070
|
+
continue;
|
|
4071
|
+
const pickResult = cat.getSourcesFromPointer(this.mouseHelper, activeModelMatrix, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
4059
4072
|
if (!pickResult?.sources.length)
|
|
4060
4073
|
continue;
|
|
4061
4074
|
this._webgl.canvas.dispatchEvent(new CustomEvent("source-contextmenu", {
|
|
@@ -4070,7 +4083,7 @@ class AstroSphere {
|
|
|
4070
4083
|
}));
|
|
4071
4084
|
break;
|
|
4072
4085
|
}
|
|
4073
|
-
for (const fset of this.
|
|
4086
|
+
for (const fset of this.getActiveFootprintSets()) {
|
|
4074
4087
|
const pickResult = fset.getFootprintsFromPointer(this.mouseHelper);
|
|
4075
4088
|
if (!pickResult?.footprints.length)
|
|
4076
4089
|
continue;
|
|
@@ -4160,19 +4173,22 @@ class AstroSphere {
|
|
|
4160
4173
|
return new HiPS_js_1.HiPS(1, [0.0, 0.0, 0.0], 0, 0, hipsDescriptor, this._webgl, this._healpixGrid);
|
|
4161
4174
|
}
|
|
4162
4175
|
activateHiPS(hipsDescriptor) {
|
|
4176
|
+
if (this._activeHiPSLayers.length > 0) {
|
|
4177
|
+
throw new Error("Cannot load a HiPS base layer while stacked layers are active.");
|
|
4178
|
+
}
|
|
4163
4179
|
const tileBuffer = this._healpixGrid.visibleTilesManager.tileBuffer;
|
|
4164
|
-
|
|
4165
|
-
tileBuffer.removeHiPS(
|
|
4180
|
+
if (this._activeHiPS) {
|
|
4181
|
+
tileBuffer.removeHiPS(this._activeHiPS);
|
|
4166
4182
|
}
|
|
4167
|
-
this._activeHiPSLayers = [];
|
|
4168
4183
|
const hips = this.createHiPS(hipsDescriptor);
|
|
4169
|
-
this._activeHiPSLayers.push(hips);
|
|
4170
4184
|
this._activeHiPS = hips;
|
|
4185
|
+
this._activeDomain = "astronomy";
|
|
4171
4186
|
this._activeBaseLayer = "hips";
|
|
4172
4187
|
return hips;
|
|
4173
4188
|
}
|
|
4174
4189
|
setHiPSOpacity(hips, opacity) {
|
|
4175
|
-
|
|
4190
|
+
const isBaseLayer = this._activeHiPSLayers.length === 0 && this._activeHiPS === hips;
|
|
4191
|
+
if (!isBaseLayer && !this._activeHiPSLayers.includes(hips)) {
|
|
4176
4192
|
throw new Error("HiPS layer is not active in this AstroSphere.");
|
|
4177
4193
|
}
|
|
4178
4194
|
hips.setOpacity(opacity);
|
|
@@ -4180,6 +4196,13 @@ class AstroSphere {
|
|
|
4180
4196
|
addHiPS(hipsDescriptor) {
|
|
4181
4197
|
const normalizeURL = (url) => String(url).replace(/\/+$/, "");
|
|
4182
4198
|
const descriptorURL = normalizeURL(hipsDescriptor.url);
|
|
4199
|
+
// Entering stack mode discards the standalone base HiPS. Base mode and
|
|
4200
|
+
// stack mode are intentionally mutually exclusive.
|
|
4201
|
+
if (this._activeHiPSLayers.length === 0 && this._activeHiPS) {
|
|
4202
|
+
const tileBuffer = this._healpixGrid.visibleTilesManager.tileBuffer;
|
|
4203
|
+
tileBuffer.removeHiPS(this._activeHiPS);
|
|
4204
|
+
this._activeHiPS = null;
|
|
4205
|
+
}
|
|
4183
4206
|
const existing = this._activeHiPSLayers.find((hips) => normalizeURL(hips.baseURL) === descriptorURL);
|
|
4184
4207
|
if (existing) {
|
|
4185
4208
|
throw new Error(`HiPS already active: ${String(hipsDescriptor.url)}`);
|
|
@@ -4187,6 +4210,7 @@ class AstroSphere {
|
|
|
4187
4210
|
const hips = this.createHiPS(hipsDescriptor);
|
|
4188
4211
|
this._activeHiPSLayers.push(hips);
|
|
4189
4212
|
this._activeHiPS = hips;
|
|
4213
|
+
this._activeDomain = "astronomy";
|
|
4190
4214
|
this._activeBaseLayer = "hips";
|
|
4191
4215
|
return hips;
|
|
4192
4216
|
}
|
|
@@ -4211,8 +4235,13 @@ class AstroSphere {
|
|
|
4211
4235
|
}
|
|
4212
4236
|
removeAllHiPS() {
|
|
4213
4237
|
const tileBuffer = this._healpixGrid.visibleTilesManager.tileBuffer;
|
|
4214
|
-
|
|
4215
|
-
tileBuffer.removeHiPS(
|
|
4238
|
+
if (this._activeHiPSLayers.length === 0 && this._activeHiPS) {
|
|
4239
|
+
tileBuffer.removeHiPS(this._activeHiPS);
|
|
4240
|
+
}
|
|
4241
|
+
else {
|
|
4242
|
+
for (const hips of this._activeHiPSLayers) {
|
|
4243
|
+
tileBuffer.removeHiPS(hips);
|
|
4244
|
+
}
|
|
4216
4245
|
}
|
|
4217
4246
|
this._activeHiPSLayers = [];
|
|
4218
4247
|
this._activeHiPS = null;
|
|
@@ -4225,39 +4254,169 @@ class AstroSphere {
|
|
|
4225
4254
|
this._activeBaseLayer = "xyz";
|
|
4226
4255
|
}
|
|
4227
4256
|
activateXYZ2(config) {
|
|
4257
|
+
this._activeDomain = "earth";
|
|
4228
4258
|
this._activeXYZ2 = new XYZMap_js_1.XYZMap(1, [0.0, 0.0, 0.0], 0, 0, config, this._webgl, this.gridLabelContainers);
|
|
4229
4259
|
this._activeBaseLayer = "xyz";
|
|
4230
4260
|
}
|
|
4231
4261
|
activateMeshHiPS(descriptor) {
|
|
4262
|
+
this._activeDomain = "mesh";
|
|
4232
4263
|
this._activeMeshHiPS = new MeshHiPS_js_1.MeshHiPS(descriptor.meshRadius, [0.0, 0.0, 0.0], 0, 0, descriptor, this._webgl, this._healpixGrid);
|
|
4233
4264
|
this._activeBaseLayer = "meships";
|
|
4234
4265
|
}
|
|
4266
|
+
setMeshHiPSColor(color) {
|
|
4267
|
+
this._activeMeshHiPS?.setColor(color);
|
|
4268
|
+
}
|
|
4269
|
+
setMeshHiPSWireframe(wireframe) {
|
|
4270
|
+
this._activeMeshHiPS?.setWireframe(wireframe);
|
|
4271
|
+
}
|
|
4235
4272
|
activateWMTS(config) {
|
|
4273
|
+
this._activeDomain = "earth";
|
|
4236
4274
|
const adapter = new WMTSAdapter_js_1.WMTSAdapter(config);
|
|
4237
4275
|
const xyzConfig = adapter.toXYZLayerConfig();
|
|
4238
4276
|
this._activeXYZ2 = new XYZMap_js_1.XYZMap(1, [0.0, 0.0, 0.0], 0, 0, new XYZMapDescriptor_js_1.XYZMapDescriptor(config.layer ? `WMTS ${config.layer}` : "WMTS Earth2 Layer", xyzConfig.urlTemplate, xyzConfig.minZoom ?? 0, xyzConfig.maxZoom ?? 8, xyzConfig.segmentsPerSide ?? 48, xyzConfig.maxCachedTiles ?? 384, 8, xyzConfig.urlResolver), this._webgl, this.gridLabelContainers);
|
|
4239
4277
|
this._activeBaseLayer = "xyz";
|
|
4240
4278
|
}
|
|
4241
|
-
|
|
4279
|
+
addXYZRasterOverlay(config) {
|
|
4280
|
+
const map = new XYZMap_js_1.XYZMap(1, [0.0, 0.0, 0.0], 0, 0, config, this._webgl, this.gridLabelContainers);
|
|
4281
|
+
return this.addEarthRasterOverlay(config.name, "xyz", map);
|
|
4282
|
+
}
|
|
4283
|
+
addWMTSRasterOverlay(config) {
|
|
4284
|
+
const adapter = new WMTSAdapter_js_1.WMTSAdapter(config);
|
|
4285
|
+
const xyzConfig = adapter.toXYZLayerConfig();
|
|
4286
|
+
const name = config.layer ? `WMTS ${config.layer}` : "WMTS Earth Raster Overlay";
|
|
4287
|
+
const map = new XYZMap_js_1.XYZMap(1, [0.0, 0.0, 0.0], 0, 0, new XYZMapDescriptor_js_1.XYZMapDescriptor(name, xyzConfig.urlTemplate, xyzConfig.minZoom ?? 0, xyzConfig.maxZoom ?? 8, xyzConfig.segmentsPerSide ?? 48, xyzConfig.maxCachedTiles ?? 384, 8, xyzConfig.urlResolver), this._webgl, this.gridLabelContainers);
|
|
4288
|
+
return this.addEarthRasterOverlay(name, "wmts", map);
|
|
4289
|
+
}
|
|
4290
|
+
getEarthRasterOverlays() {
|
|
4291
|
+
return this._earthRasterOverlays.map(({ map: _map, ...overlay }) => ({ ...overlay }));
|
|
4292
|
+
}
|
|
4293
|
+
setEarthRasterOverlayOpacity(id, opacity) {
|
|
4294
|
+
const overlay = this._earthRasterOverlays.find((entry) => entry.id === id);
|
|
4295
|
+
if (!overlay)
|
|
4296
|
+
return;
|
|
4297
|
+
overlay.opacity = Math.min(1, Math.max(0, opacity));
|
|
4298
|
+
overlay.map.setOpacity(overlay.opacity);
|
|
4299
|
+
}
|
|
4300
|
+
setEarthRasterOverlayVisible(id, visible) {
|
|
4301
|
+
const overlay = this._earthRasterOverlays.find((entry) => entry.id === id);
|
|
4302
|
+
if (overlay)
|
|
4303
|
+
overlay.visible = visible;
|
|
4304
|
+
}
|
|
4305
|
+
removeEarthRasterOverlay(id) {
|
|
4306
|
+
this._earthRasterOverlays = this._earthRasterOverlays.filter((entry) => entry.id !== id);
|
|
4307
|
+
}
|
|
4308
|
+
removeAllEarthRasterOverlays() {
|
|
4309
|
+
this._earthRasterOverlays = [];
|
|
4310
|
+
}
|
|
4311
|
+
addEarthRasterOverlay(name, sourceType, map) {
|
|
4312
|
+
const overlay = {
|
|
4313
|
+
id: `earth-raster-${++this._earthRasterOverlaySequence}`,
|
|
4314
|
+
name,
|
|
4315
|
+
sourceType,
|
|
4316
|
+
visible: true,
|
|
4317
|
+
opacity: 0.65,
|
|
4318
|
+
map,
|
|
4319
|
+
};
|
|
4320
|
+
map.setOpacity(overlay.opacity);
|
|
4321
|
+
this._earthRasterOverlays.push(overlay);
|
|
4322
|
+
const { map: _map, ...info } = overlay;
|
|
4323
|
+
return { ...info };
|
|
4324
|
+
}
|
|
4325
|
+
setActiveDomain(domain) {
|
|
4326
|
+
if (domain !== this._activeDomain) {
|
|
4327
|
+
this.clearGridLabelsForDomain(this._activeDomain);
|
|
4328
|
+
this.domainCameraStates[this._activeDomain] = this._camera.getViewState();
|
|
4329
|
+
const targetCameraState = this.domainCameraStates[domain];
|
|
4330
|
+
if (targetCameraState) {
|
|
4331
|
+
this._camera.restoreViewState(targetCameraState);
|
|
4332
|
+
}
|
|
4333
|
+
this.inertiaX = 0;
|
|
4334
|
+
this.inertiaY = 0;
|
|
4335
|
+
this.zoomInertia = 0;
|
|
4336
|
+
this._cameraStatusChanged = true;
|
|
4337
|
+
}
|
|
4338
|
+
this._activeDomain = domain;
|
|
4339
|
+
if (domain === "astronomy") {
|
|
4340
|
+
this._activeBaseLayer = this._activeHiPS ? "hips" : null;
|
|
4341
|
+
}
|
|
4342
|
+
else if (domain === "earth") {
|
|
4343
|
+
this._activeBaseLayer = this._activeXYZ2 ? "xyz" : null;
|
|
4344
|
+
}
|
|
4345
|
+
else {
|
|
4346
|
+
this._activeBaseLayer = this._activeMeshHiPS ? "meships" : null;
|
|
4347
|
+
}
|
|
4348
|
+
// A hover from the previous vertical must not leak into the new one.
|
|
4349
|
+
this.lastHoveredSource = null;
|
|
4350
|
+
this.lastHoveredCatalogue = null;
|
|
4351
|
+
}
|
|
4352
|
+
clearGridLabelsForDomain(domain) {
|
|
4353
|
+
if (domain === "astronomy") {
|
|
4354
|
+
this._healpixGrid?.clearLabels();
|
|
4355
|
+
this._equatorialGrid?.clearLabels();
|
|
4356
|
+
return;
|
|
4357
|
+
}
|
|
4358
|
+
if (domain === "earth") {
|
|
4359
|
+
this._activeXYZ2?.clearLonLatGridLabels?.();
|
|
4360
|
+
}
|
|
4361
|
+
}
|
|
4362
|
+
get activeDomain() {
|
|
4363
|
+
return this._activeDomain;
|
|
4364
|
+
}
|
|
4365
|
+
getActivePointSets() {
|
|
4366
|
+
if (this._activeDomain === "astronomy")
|
|
4367
|
+
return this.astronomyCatalogues;
|
|
4368
|
+
if (this._activeDomain === "earth")
|
|
4369
|
+
return this.earthPointSets;
|
|
4370
|
+
return [];
|
|
4371
|
+
}
|
|
4372
|
+
getActiveFootprintSets() {
|
|
4373
|
+
if (this._activeDomain === "astronomy")
|
|
4374
|
+
return this.astronomyFootprintSets;
|
|
4375
|
+
if (this._activeDomain === "earth")
|
|
4376
|
+
return this.earthFootprintSets;
|
|
4377
|
+
return [];
|
|
4378
|
+
}
|
|
4379
|
+
// Astronomy catalogue ownership
|
|
4242
4380
|
async showCatalogue(cat) {
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4381
|
+
if (cat && !this.astronomyCatalogues.includes(cat)) {
|
|
4382
|
+
this.astronomyCatalogues.push(cat);
|
|
4383
|
+
}
|
|
4246
4384
|
return cat;
|
|
4247
4385
|
}
|
|
4248
4386
|
deleteCatalogue(catalogue) {
|
|
4249
|
-
this.
|
|
4387
|
+
this.astronomyCatalogues = this.astronomyCatalogues.filter((c) => c !== catalogue);
|
|
4250
4388
|
}
|
|
4251
|
-
//
|
|
4252
|
-
//
|
|
4389
|
+
// Earth point-set ownership. TerraPointSetGL still extends CatalogueGL in
|
|
4390
|
+
// 3.12, but it no longer shares the Astronomy lifecycle collection.
|
|
4391
|
+
async showTerraPointSet(pointSet) {
|
|
4392
|
+
if (pointSet && !this.earthPointSets.includes(pointSet)) {
|
|
4393
|
+
this.earthPointSets.push(pointSet);
|
|
4394
|
+
}
|
|
4395
|
+
return pointSet;
|
|
4396
|
+
}
|
|
4397
|
+
deleteTerraPointSet(pointSet) {
|
|
4398
|
+
this.earthPointSets = this.earthPointSets.filter((set) => set !== pointSet);
|
|
4399
|
+
}
|
|
4400
|
+
// Astronomy footprint ownership
|
|
4253
4401
|
async showFootprintSet(fset) {
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4402
|
+
if (fset && !this.astronomyFootprintSets.includes(fset)) {
|
|
4403
|
+
this.astronomyFootprintSets.push(fset);
|
|
4404
|
+
}
|
|
4257
4405
|
return fset;
|
|
4258
4406
|
}
|
|
4259
4407
|
deleteFootprintSet(footprintSet) {
|
|
4260
|
-
this.
|
|
4408
|
+
this.astronomyFootprintSets = this.astronomyFootprintSets.filter((fst) => fst !== footprintSet);
|
|
4409
|
+
}
|
|
4410
|
+
// Earth footprint ownership. TerraFootprintSetGL still reuses the common
|
|
4411
|
+
// FootprintSetGL rendering implementation, but has an independent lifecycle.
|
|
4412
|
+
async showTerraFootprintSet(footprintSet) {
|
|
4413
|
+
if (footprintSet && !this.earthFootprintSets.includes(footprintSet)) {
|
|
4414
|
+
this.earthFootprintSets.push(footprintSet);
|
|
4415
|
+
}
|
|
4416
|
+
return footprintSet;
|
|
4417
|
+
}
|
|
4418
|
+
deleteTerraFootprintSet(footprintSet) {
|
|
4419
|
+
this.earthFootprintSets = this.earthFootprintSets.filter((fst) => fst !== footprintSet);
|
|
4261
4420
|
}
|
|
4262
4421
|
async showPolylineSet(polylineSet) {
|
|
4263
4422
|
if (polylineSet)
|
|
@@ -4287,8 +4446,8 @@ class AstroSphere {
|
|
|
4287
4446
|
satelliteObject.dispose();
|
|
4288
4447
|
}
|
|
4289
4448
|
getHoveredFootprints() {
|
|
4290
|
-
|
|
4291
|
-
this.
|
|
4449
|
+
const footprintsHovered = [];
|
|
4450
|
+
this.getActiveFootprintSets().forEach((fset) => {
|
|
4292
4451
|
footprintsHovered.push(fset.hoveredFootprints);
|
|
4293
4452
|
});
|
|
4294
4453
|
return footprintsHovered;
|
|
@@ -4297,6 +4456,9 @@ class AstroSphere {
|
|
|
4297
4456
|
goTo(raDeg, decDeg) {
|
|
4298
4457
|
this._camera.goTo(raDeg, decDeg);
|
|
4299
4458
|
}
|
|
4459
|
+
flyTo(raDeg, decDeg, durationMs = 1200) {
|
|
4460
|
+
this._camera.flyTo(raDeg, decDeg, durationMs);
|
|
4461
|
+
}
|
|
4300
4462
|
getActiveCoordinateMode() {
|
|
4301
4463
|
if (this._activeBaseLayer === "xyz") {
|
|
4302
4464
|
return "lonlat";
|
|
@@ -4517,8 +4679,6 @@ class AstroSphere {
|
|
|
4517
4679
|
return;
|
|
4518
4680
|
if (!this._webgl)
|
|
4519
4681
|
return;
|
|
4520
|
-
if (!this._activeHiPS && !this._activeXYZ2 && !this._activeMeshHiPS)
|
|
4521
|
-
return;
|
|
4522
4682
|
if (!this._healpixGrid || Object.keys(this._healpixGrid).length === 0)
|
|
4523
4683
|
return;
|
|
4524
4684
|
if (this._healpixGrid.fovObj === undefined)
|
|
@@ -4532,6 +4692,16 @@ class AstroSphere {
|
|
|
4532
4692
|
let PHI = 0;
|
|
4533
4693
|
this._webgl.viewport(0, 0, this._webgl.drawingBufferWidth, this._webgl.drawingBufferHeight);
|
|
4534
4694
|
this._webgl.clear(this._webgl.COLOR_BUFFER_BIT | this._webgl.DEPTH_BUFFER_BIT);
|
|
4695
|
+
const now = performance.now();
|
|
4696
|
+
const cameraFlying = this._camera.updateFlyTo(now);
|
|
4697
|
+
if (cameraFlying) {
|
|
4698
|
+
this.inertiaX = 0;
|
|
4699
|
+
this.inertiaY = 0;
|
|
4700
|
+
this.lastCameraMotionAt = now;
|
|
4701
|
+
this._cameraStatusChanged = true;
|
|
4702
|
+
this.updateCentralPoint();
|
|
4703
|
+
this._perspectiveMatrixManager.computePerspectiveMatrix(canvas, this._camera, Config_js_1.bootSetup.camera_fov_deg, Config_js_1.bootSetup.camera_near_plane, Global_js_1.default.insideSphere);
|
|
4704
|
+
}
|
|
4535
4705
|
// Zoom inertia
|
|
4536
4706
|
if (this.zoomInertia !== 0) {
|
|
4537
4707
|
if (Math.abs(this.zoomInertia) > 0.0001) {
|
|
@@ -4620,8 +4790,10 @@ class AstroSphere {
|
|
|
4620
4790
|
this._webgl.enable(this._webgl.CULL_FACE);
|
|
4621
4791
|
this._webgl.cullFace(Global_js_1.default.insideSphere ? this._webgl.FRONT : this._webgl.BACK);
|
|
4622
4792
|
this._webgl.blendFunc(this._webgl.SRC_ALPHA, this._webgl.ONE_MINUS_SRC_ALPHA);
|
|
4623
|
-
if (this._activeBaseLayer === "hips" && this.
|
|
4624
|
-
const maxHiPSOrder =
|
|
4793
|
+
if (this._activeBaseLayer === "hips" && this._activeHiPS) {
|
|
4794
|
+
const maxHiPSOrder = this._activeHiPSLayers.length > 0
|
|
4795
|
+
? Math.max(...this._activeHiPSLayers.map((hips) => hips.maxOrder))
|
|
4796
|
+
: this._activeHiPS.maxOrder;
|
|
4625
4797
|
const visibleOrder = Math.min(this._healpixGrid.visibleorder, maxHiPSOrder);
|
|
4626
4798
|
this._healpixGrid.visibleTilesManager.computeVisiblePixels(visibleOrder, this._webgl, this._camera, this._perspectiveMatrixManager.pMatrix);
|
|
4627
4799
|
}
|
|
@@ -4656,12 +4828,19 @@ class AstroSphere {
|
|
|
4656
4828
|
}
|
|
4657
4829
|
if (this._activeBaseLayer === "xyz") {
|
|
4658
4830
|
this._activeXYZ2?.draw(skyEntityDrawInput);
|
|
4831
|
+
for (const overlay of this._earthRasterOverlays) {
|
|
4832
|
+
if (overlay.visible) {
|
|
4833
|
+
overlay.map.draw(skyEntityDrawInput, true);
|
|
4834
|
+
}
|
|
4835
|
+
}
|
|
4659
4836
|
}
|
|
4660
4837
|
if (this._activeBaseLayer === "meships") {
|
|
4661
4838
|
this._activeMeshHiPS?.draw(skyEntityDrawInput);
|
|
4662
4839
|
}
|
|
4663
|
-
this.
|
|
4664
|
-
|
|
4840
|
+
if (this._activeDomain === "astronomy") {
|
|
4841
|
+
this._healpixGrid.draw(skyEntityDrawInput);
|
|
4842
|
+
this._equatorialGrid.draw(skyEntityDrawInput);
|
|
4843
|
+
}
|
|
4665
4844
|
this._webgl.enable(this._webgl.DEPTH_TEST);
|
|
4666
4845
|
this._webgl.disable(this._webgl.CULL_FACE);
|
|
4667
4846
|
if (this.startup) {
|
|
@@ -4680,52 +4859,53 @@ class AstroSphere {
|
|
|
4680
4859
|
decDMS,
|
|
4681
4860
|
});
|
|
4682
4861
|
}
|
|
4683
|
-
this.
|
|
4684
|
-
const activeModelMatrix = this.
|
|
4685
|
-
this._activeXYZ2?.getModelMatrix() ??
|
|
4686
|
-
this._activeMeshHiPS?.getModelMatrix();
|
|
4862
|
+
this.getActivePointSets().forEach((cat) => {
|
|
4863
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4687
4864
|
if (activeModelMatrix) {
|
|
4688
4865
|
cat.draw(activeModelMatrix, this.mouseHelper, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
4689
4866
|
}
|
|
4690
4867
|
});
|
|
4691
4868
|
this.emitHoveredSourceIfChanged();
|
|
4692
|
-
this.
|
|
4693
|
-
const activeModelMatrix = this.
|
|
4694
|
-
this._activeXYZ2?.getModelMatrix() ??
|
|
4695
|
-
this._activeMeshHiPS?.getModelMatrix();
|
|
4869
|
+
this.getActiveFootprintSets().forEach((fst) => {
|
|
4870
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4696
4871
|
if (activeModelMatrix) {
|
|
4697
4872
|
fst.draw(activeModelMatrix, this.mouseHelper, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
4698
4873
|
}
|
|
4699
4874
|
});
|
|
4700
|
-
this.
|
|
4701
|
-
|
|
4702
|
-
this.
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
}
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4875
|
+
if (this._activeDomain === "earth") {
|
|
4876
|
+
this.activePolylineSets.forEach((polylineSet) => {
|
|
4877
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4878
|
+
if (activeModelMatrix) {
|
|
4879
|
+
polylineSet.draw(activeModelMatrix, this.mouseHelper, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
4880
|
+
}
|
|
4881
|
+
});
|
|
4882
|
+
this.activeSensorCones.forEach((sensorCone) => {
|
|
4883
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4884
|
+
if (activeModelMatrix) {
|
|
4885
|
+
sensorCone.draw(this._perspectiveMatrixManager.pMatrix, this._camera.getCameraMatrix(), activeModelMatrix);
|
|
4886
|
+
}
|
|
4887
|
+
});
|
|
4888
|
+
this.activeSatelliteObjects.forEach((satelliteObject) => {
|
|
4889
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4890
|
+
if (activeModelMatrix) {
|
|
4891
|
+
satelliteObject.draw(this._perspectiveMatrixManager.pMatrix, this._camera.getCameraMatrix(), activeModelMatrix);
|
|
4892
|
+
}
|
|
4893
|
+
});
|
|
4894
|
+
}
|
|
4895
|
+
}
|
|
4896
|
+
getActiveDomainModelMatrix() {
|
|
4897
|
+
if (this._activeDomain === "astronomy") {
|
|
4898
|
+
return (this._activeHiPS?.getModelMatrix() ?? this._healpixGrid.getModelMatrix());
|
|
4899
|
+
}
|
|
4900
|
+
if (this._activeDomain === "earth") {
|
|
4901
|
+
return (this._activeXYZ2?.getModelMatrix() ?? this._healpixGrid.getModelMatrix());
|
|
4902
|
+
}
|
|
4903
|
+
return (this._activeMeshHiPS?.getModelMatrix() ?? this._healpixGrid.getModelMatrix());
|
|
4724
4904
|
}
|
|
4725
4905
|
emitHoveredSourceIfChanged() {
|
|
4726
4906
|
let nextHoveredSource = null;
|
|
4727
4907
|
let nextHoveredCatalogue = null;
|
|
4728
|
-
for (const cat of this.
|
|
4908
|
+
for (const cat of this.getActivePointSets()) {
|
|
4729
4909
|
const hovered = cat.getPrimaryHoveredSource();
|
|
4730
4910
|
if (!hovered)
|
|
4731
4911
|
continue;
|
|
@@ -4854,25 +5034,25 @@ class AstroViewer {
|
|
|
4854
5034
|
return new TerraPointSetGL_js_1.TerraPointSetGL(pointSetName, pointSetDescription, providerUrl, metadataManager, this.webgl, this.astroSphere.healpixGrid.visibleTilesManager);
|
|
4855
5035
|
}
|
|
4856
5036
|
showTerraPointSet(pointSet) {
|
|
4857
|
-
this.astroSphere.
|
|
5037
|
+
this.astroSphere.showTerraPointSet(pointSet);
|
|
4858
5038
|
}
|
|
4859
5039
|
hideTerraPointSet(pointSet, isVisible) {
|
|
4860
5040
|
pointSet.setIsVisible(isVisible);
|
|
4861
5041
|
}
|
|
4862
5042
|
deleteTerraPointSet(pointSet) {
|
|
4863
|
-
this.astroSphere.
|
|
5043
|
+
this.astroSphere.deleteTerraPointSet(pointSet);
|
|
4864
5044
|
}
|
|
4865
5045
|
createTerraFootprintSet(footprintSetName, footprintSetDescription, providerUrl, metadataManager) {
|
|
4866
5046
|
return new TerraFootprintSetGL_js_1.TerraFootprintSetGL(footprintSetName, footprintSetDescription, providerUrl, metadataManager, this.webgl);
|
|
4867
5047
|
}
|
|
4868
5048
|
showTerraFootprintSet(footprintSet) {
|
|
4869
|
-
this.astroSphere.
|
|
5049
|
+
this.astroSphere.showTerraFootprintSet(footprintSet);
|
|
4870
5050
|
}
|
|
4871
5051
|
hideTerraFootprintSet(footprintSet, isVisible) {
|
|
4872
5052
|
footprintSet.setIsVisible(isVisible);
|
|
4873
5053
|
}
|
|
4874
5054
|
deleteTerraFootprintSet(footprintSet) {
|
|
4875
|
-
this.astroSphere.
|
|
5055
|
+
this.astroSphere.deleteTerraFootprintSet(footprintSet);
|
|
4876
5056
|
}
|
|
4877
5057
|
createTerraPolylineSet(polylineSetName, polylineSetDescription, providerUrl, metadataManager) {
|
|
4878
5058
|
return new TerraPolylineSetGL_js_1.TerraPolylineSetGL(polylineSetName, polylineSetDescription, providerUrl, metadataManager, this.webgl);
|
|
@@ -4925,6 +5105,12 @@ class AstroViewer {
|
|
|
4925
5105
|
getDefaultHiPSURL() {
|
|
4926
5106
|
return Config_js_1.bootSetup.defaultHipsUrl;
|
|
4927
5107
|
}
|
|
5108
|
+
setActiveDomain(domain) {
|
|
5109
|
+
this.astroSphere.setActiveDomain(domain);
|
|
5110
|
+
}
|
|
5111
|
+
getActiveDomain() {
|
|
5112
|
+
return this.astroSphere.activeDomain;
|
|
5113
|
+
}
|
|
4928
5114
|
activateHiPS(hipsDescriptor) {
|
|
4929
5115
|
this.astroSphere.activateHiPS(hipsDescriptor);
|
|
4930
5116
|
}
|
|
@@ -4938,9 +5124,37 @@ class AstroViewer {
|
|
|
4938
5124
|
activateWMTS(config) {
|
|
4939
5125
|
this.astroSphere.activateWMTS(config);
|
|
4940
5126
|
}
|
|
5127
|
+
addXYZRasterOverlay(config) {
|
|
5128
|
+
const descriptor = new XYZMapDescriptor_js_1.XYZMapDescriptor(config.name ?? "XYZ Earth Raster Overlay", config.urlTemplate, config.minZoom ?? 0, config.maxZoom ?? 8, config.segmentsPerSide ?? 48, config.maxCachedTiles ?? 384, 8, config.urlResolver);
|
|
5129
|
+
return this.astroSphere.addXYZRasterOverlay(descriptor);
|
|
5130
|
+
}
|
|
5131
|
+
addWMTSRasterOverlay(config) {
|
|
5132
|
+
return this.astroSphere.addWMTSRasterOverlay(config);
|
|
5133
|
+
}
|
|
5134
|
+
getEarthRasterOverlays() {
|
|
5135
|
+
return this.astroSphere.getEarthRasterOverlays();
|
|
5136
|
+
}
|
|
5137
|
+
setEarthRasterOverlayOpacity(id, opacity) {
|
|
5138
|
+
this.astroSphere.setEarthRasterOverlayOpacity(id, opacity);
|
|
5139
|
+
}
|
|
5140
|
+
setEarthRasterOverlayVisible(id, visible) {
|
|
5141
|
+
this.astroSphere.setEarthRasterOverlayVisible(id, visible);
|
|
5142
|
+
}
|
|
5143
|
+
removeEarthRasterOverlay(id) {
|
|
5144
|
+
this.astroSphere.removeEarthRasterOverlay(id);
|
|
5145
|
+
}
|
|
5146
|
+
removeAllEarthRasterOverlays() {
|
|
5147
|
+
this.astroSphere.removeAllEarthRasterOverlays();
|
|
5148
|
+
}
|
|
4941
5149
|
activateMeshHiPS(config) {
|
|
4942
5150
|
this.astroSphere.activateMeshHiPS(new MeshHiPSDescriptor_js_1.MeshHiPSDescriptor(config));
|
|
4943
5151
|
}
|
|
5152
|
+
setMeshHiPSColor(color) {
|
|
5153
|
+
this.astroSphere.setMeshHiPSColor(color);
|
|
5154
|
+
}
|
|
5155
|
+
setMeshHiPSWireframe(wireframe) {
|
|
5156
|
+
this.astroSphere.setMeshHiPSWireframe(wireframe);
|
|
5157
|
+
}
|
|
4944
5158
|
setXYZMaxConcurrentRequests(value) {
|
|
4945
5159
|
XYZTileRequestScheduler_js_1.xyzTileRequestScheduler.setMaxConcurrent(value);
|
|
4946
5160
|
}
|
|
@@ -5063,6 +5277,9 @@ class AstroViewer {
|
|
|
5063
5277
|
// console.log(`AstroViewer.goTo goto(${raDeg}, ${decDeg})`)
|
|
5064
5278
|
this.astroSphere.goTo(raDeg, decDeg);
|
|
5065
5279
|
}
|
|
5280
|
+
flyTo(raDeg, decDeg, durationMs = 1200) {
|
|
5281
|
+
this.astroSphere.flyTo(raDeg, decDeg, durationMs);
|
|
5282
|
+
}
|
|
5066
5283
|
getActiveCoordinateMode() {
|
|
5067
5284
|
return this.astroSphere.getActiveCoordinateMode();
|
|
5068
5285
|
}
|
|
@@ -5385,6 +5602,7 @@ class Camera {
|
|
|
5385
5602
|
lockRotX = false;
|
|
5386
5603
|
lockRotY = false;
|
|
5387
5604
|
lockRotZ = false;
|
|
5605
|
+
flyToAnimation = null;
|
|
5388
5606
|
constructor(in_position, in_sphere) {
|
|
5389
5607
|
this.init(in_position, in_sphere);
|
|
5390
5608
|
}
|
|
@@ -5394,7 +5612,11 @@ class Camera {
|
|
|
5394
5612
|
this.vMatrix = gl_matrix_1.mat4.create();
|
|
5395
5613
|
this.T = gl_matrix_1.mat4.create();
|
|
5396
5614
|
this.R = gl_matrix_1.mat4.create();
|
|
5397
|
-
gl_matrix_1.mat4.translate(this.T, this.T, [
|
|
5615
|
+
gl_matrix_1.mat4.translate(this.T, this.T, [
|
|
5616
|
+
this.cam_pos[0],
|
|
5617
|
+
this.cam_pos[1],
|
|
5618
|
+
this.cam_pos[2],
|
|
5619
|
+
]);
|
|
5398
5620
|
// reset helpers
|
|
5399
5621
|
this.FoV = this.previousFoV = 180.0;
|
|
5400
5622
|
this.move = gl_matrix_1.vec3.clone([0, 0, 0]);
|
|
@@ -5403,11 +5625,15 @@ class Camera {
|
|
|
5403
5625
|
this.goTo(raDeg, decDeg);
|
|
5404
5626
|
}
|
|
5405
5627
|
goTo(raDeg, decDeg) {
|
|
5628
|
+
this.cancelFlyTo();
|
|
5406
5629
|
this.goToPhiTheta((0, Utils_js_1.astroDegToSpherical)(raDeg, decDeg));
|
|
5407
5630
|
}
|
|
5408
5631
|
goToPhiTheta(ptDeg) {
|
|
5409
5632
|
const xyz = (0, Utils_js_1.sphericalToCartesian)(ptDeg.phi, ptDeg.theta, this.cam_pos[2]);
|
|
5410
|
-
|
|
5633
|
+
this.applyCameraPosition(gl_matrix_1.vec3.fromValues(xyz[0], xyz[1], xyz[2]));
|
|
5634
|
+
}
|
|
5635
|
+
applyCameraPosition(cameraPosition) {
|
|
5636
|
+
const targetDirection = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), cameraPosition);
|
|
5411
5637
|
const celestialNorth = gl_matrix_1.vec3.fromValues(0.0, 0.0, 1.0);
|
|
5412
5638
|
const northProjection = gl_matrix_1.vec3.scale(gl_matrix_1.vec3.create(), targetDirection, gl_matrix_1.vec3.dot(celestialNorth, targetDirection));
|
|
5413
5639
|
const cameraUp = gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), celestialNorth, northProjection);
|
|
@@ -5418,9 +5644,13 @@ class Camera {
|
|
|
5418
5644
|
gl_matrix_1.vec3.normalize(cameraUp, cameraUp);
|
|
5419
5645
|
}
|
|
5420
5646
|
let cameraMatrix = gl_matrix_1.mat4.create();
|
|
5421
|
-
cameraMatrix = gl_matrix_1.mat4.translate(cameraMatrix, cameraMatrix,
|
|
5647
|
+
cameraMatrix = gl_matrix_1.mat4.translate(cameraMatrix, cameraMatrix, cameraPosition);
|
|
5422
5648
|
const focusPoint = [0.0, 0.0, 0.0];
|
|
5423
|
-
const cameraPos = [
|
|
5649
|
+
const cameraPos = [
|
|
5650
|
+
cameraMatrix[12],
|
|
5651
|
+
cameraMatrix[13],
|
|
5652
|
+
cameraMatrix[14],
|
|
5653
|
+
];
|
|
5424
5654
|
cameraMatrix = gl_matrix_1.mat4.targetTo(cameraMatrix, cameraPos, focusPoint, cameraUp);
|
|
5425
5655
|
this.R = gl_matrix_1.mat4.clone(cameraMatrix);
|
|
5426
5656
|
this.R[12] = 0;
|
|
@@ -5432,6 +5662,81 @@ class Camera {
|
|
|
5432
5662
|
}
|
|
5433
5663
|
this.vMatrix = viewMatrix;
|
|
5434
5664
|
}
|
|
5665
|
+
flyTo(raDeg, decDeg, durationMs = 1200) {
|
|
5666
|
+
const targetSpherical = (0, Utils_js_1.astroDegToSpherical)(raDeg, decDeg);
|
|
5667
|
+
const targetPositionValues = (0, Utils_js_1.sphericalToCartesian)(targetSpherical.phi, targetSpherical.theta, this.cam_pos[2]);
|
|
5668
|
+
const targetPosition = gl_matrix_1.vec3.fromValues(targetPositionValues[0], targetPositionValues[1], targetPositionValues[2]);
|
|
5669
|
+
const currentPosition = this.getCameraPosition();
|
|
5670
|
+
const startDirection = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), gl_matrix_1.vec3.fromValues(currentPosition[0], currentPosition[1], currentPosition[2]));
|
|
5671
|
+
const targetDirection = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), targetPosition);
|
|
5672
|
+
this.flyToAnimation = {
|
|
5673
|
+
startDirection,
|
|
5674
|
+
targetDirection,
|
|
5675
|
+
targetPosition,
|
|
5676
|
+
startTime: performance.now(),
|
|
5677
|
+
durationMs: Math.max(1, durationMs),
|
|
5678
|
+
};
|
|
5679
|
+
}
|
|
5680
|
+
updateFlyTo(now) {
|
|
5681
|
+
const animation = this.flyToAnimation;
|
|
5682
|
+
if (!animation) {
|
|
5683
|
+
return false;
|
|
5684
|
+
}
|
|
5685
|
+
const elapsed = now - animation.startTime;
|
|
5686
|
+
const progress = Math.min(1, elapsed / animation.durationMs);
|
|
5687
|
+
const easedProgress = progress < 0.5
|
|
5688
|
+
? 4 * progress * progress * progress
|
|
5689
|
+
: 1 - Math.pow(-2 * progress + 2, 3) / 2;
|
|
5690
|
+
const direction = this.slerpDirection(animation.startDirection, animation.targetDirection, easedProgress);
|
|
5691
|
+
const radius = Math.abs(this.cam_pos[2]);
|
|
5692
|
+
const cameraPosition = gl_matrix_1.vec3.scale(gl_matrix_1.vec3.create(), direction, radius);
|
|
5693
|
+
this.applyCameraPosition(cameraPosition);
|
|
5694
|
+
if (progress >= 1) {
|
|
5695
|
+
this.applyCameraPosition(animation.targetPosition);
|
|
5696
|
+
this.flyToAnimation = null;
|
|
5697
|
+
}
|
|
5698
|
+
return true;
|
|
5699
|
+
}
|
|
5700
|
+
slerpDirection(start, end, t) {
|
|
5701
|
+
const dot = Math.max(-1, Math.min(1, gl_matrix_1.vec3.dot(start, end)));
|
|
5702
|
+
/*
|
|
5703
|
+
* For almost identical directions, normalized linear interpolation is
|
|
5704
|
+
* numerically more stable than the general SLERP formula.
|
|
5705
|
+
*/
|
|
5706
|
+
if (dot > 0.999999) {
|
|
5707
|
+
const result = gl_matrix_1.vec3.lerp(gl_matrix_1.vec3.create(), start, end, t);
|
|
5708
|
+
return gl_matrix_1.vec3.normalize(result, result);
|
|
5709
|
+
}
|
|
5710
|
+
/*
|
|
5711
|
+
* The normal SLERP formula becomes singular for antipodal vectors because
|
|
5712
|
+
* sin(pi) = 0. In that case choose a stable vector orthogonal to start and
|
|
5713
|
+
* rotate through that great circle.
|
|
5714
|
+
*/
|
|
5715
|
+
if (dot < -0.999999) {
|
|
5716
|
+
const referenceAxis = Math.abs(start[0]) < 0.9
|
|
5717
|
+
? gl_matrix_1.vec3.fromValues(1, 0, 0)
|
|
5718
|
+
: gl_matrix_1.vec3.fromValues(0, 1, 0);
|
|
5719
|
+
const orthogonal = gl_matrix_1.vec3.cross(gl_matrix_1.vec3.create(), start, referenceAxis);
|
|
5720
|
+
gl_matrix_1.vec3.normalize(orthogonal, orthogonal);
|
|
5721
|
+
const angle = Math.PI * t;
|
|
5722
|
+
const result = gl_matrix_1.vec3.create();
|
|
5723
|
+
gl_matrix_1.vec3.scale(result, start, Math.cos(angle));
|
|
5724
|
+
gl_matrix_1.vec3.scaleAndAdd(result, result, orthogonal, Math.sin(angle));
|
|
5725
|
+
return gl_matrix_1.vec3.normalize(result, result);
|
|
5726
|
+
}
|
|
5727
|
+
const angle = Math.acos(dot);
|
|
5728
|
+
const sinAngle = Math.sin(angle);
|
|
5729
|
+
const startWeight = Math.sin((1 - t) * angle) / sinAngle;
|
|
5730
|
+
const endWeight = Math.sin(t * angle) / sinAngle;
|
|
5731
|
+
const result = gl_matrix_1.vec3.create();
|
|
5732
|
+
result[0] = start[0] * startWeight + end[0] * endWeight;
|
|
5733
|
+
result[1] = start[1] * startWeight + end[1] * endWeight;
|
|
5734
|
+
result[2] = start[2] * startWeight + end[2] * endWeight;
|
|
5735
|
+
return gl_matrix_1.vec3.normalize(result, result);
|
|
5736
|
+
}
|
|
5737
|
+
cancelFlyTo() {
|
|
5738
|
+
this.flyToAnimation = null;
|
|
5739
|
+
}
|
|
5435
5740
|
toggleInsideSphere() {
|
|
5436
5741
|
// if (inside !== global.insideSphere) {
|
|
5437
5742
|
// global.insideSphere = inside;
|
|
@@ -5653,6 +5958,22 @@ class Camera {
|
|
|
5653
5958
|
}
|
|
5654
5959
|
return [inv[12], inv[13], inv[14]];
|
|
5655
5960
|
}
|
|
5961
|
+
getViewState() {
|
|
5962
|
+
return {
|
|
5963
|
+
position: [this.cam_pos[0], this.cam_pos[1], this.cam_pos[2]],
|
|
5964
|
+
viewMatrix: gl_matrix_1.mat4.clone(this.vMatrix),
|
|
5965
|
+
translationMatrix: gl_matrix_1.mat4.clone(this.T),
|
|
5966
|
+
rotationMatrix: gl_matrix_1.mat4.clone(this.R),
|
|
5967
|
+
};
|
|
5968
|
+
}
|
|
5969
|
+
restoreViewState(state) {
|
|
5970
|
+
this.cancelFlyTo();
|
|
5971
|
+
this.cam_pos = gl_matrix_1.vec3.fromValues(...state.position);
|
|
5972
|
+
this.vMatrix = gl_matrix_1.mat4.clone(state.viewMatrix);
|
|
5973
|
+
this.T = gl_matrix_1.mat4.clone(state.translationMatrix);
|
|
5974
|
+
this.R = gl_matrix_1.mat4.clone(state.rotationMatrix);
|
|
5975
|
+
this.move = gl_matrix_1.vec3.create();
|
|
5976
|
+
}
|
|
5656
5977
|
setCameraMatrix(viewMatrix) {
|
|
5657
5978
|
this.vMatrix = viewMatrix;
|
|
5658
5979
|
}
|
|
@@ -5689,9 +6010,15 @@ class Camera {
|
|
|
5689
6010
|
clearRotationLock() {
|
|
5690
6011
|
this.lockRotX = this.lockRotY = this.lockRotZ = false;
|
|
5691
6012
|
}
|
|
5692
|
-
isRotationLockedX() {
|
|
5693
|
-
|
|
5694
|
-
|
|
6013
|
+
isRotationLockedX() {
|
|
6014
|
+
return this.lockRotX;
|
|
6015
|
+
}
|
|
6016
|
+
isRotationLockedY() {
|
|
6017
|
+
return this.lockRotY;
|
|
6018
|
+
}
|
|
6019
|
+
isRotationLockedZ() {
|
|
6020
|
+
return this.lockRotZ;
|
|
6021
|
+
}
|
|
5695
6022
|
}
|
|
5696
6023
|
exports["default"] = Camera;
|
|
5697
6024
|
|
|
@@ -5864,7 +6191,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5864
6191
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5865
6192
|
};
|
|
5866
6193
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
5867
|
-
exports.Footprint = exports.Source = exports.MeshHiPSDescriptor = exports.MeshHiPS = exports.WMTSAdapter = exports.XYZMap = exports.HiPS = exports.createColorMapFromSamples = exports.COLOR_MAP_SAMPLE_COUNT = exports.ColorMaps = exports.GeoJSONParser = exports.CoordsType = exports.FoVUtils = exports.CartesianOpts = exports.PointInitOpts = exports.AstroOpts = exports.SphericalOpts = exports.Point = exports.ColumnType = exports.MetadataInit = exports.MetadataColumn = exports.MetadataManager = exports.ObservationTrackViewerAdapter = exports.ObservationTrackTimeline = exports.footprintToRing = exports.createObservationTrackTimeline = exports.SensorConeGL = exports.SatelliteObjectGL = exports.TerraPolylineSetGL = exports.TerraFootprintSetGL = exports.TerraPointSetGL = exports.CatalogueGL = exports.FootprintSetGL = exports.HoveredFootprintDetail = exports.SphereFoV = exports.FoV = exports.HiPSDescriptor = exports.AstroViewer = void 0;
|
|
6194
|
+
exports.Footprint = exports.Source = exports.MeshHiPSDescriptor = exports.MeshHiPS = exports.WMTSAdapter = exports.XYZMap = exports.HiPS = exports.createColorMapFromSamples = exports.COLOR_MAP_SAMPLE_COUNT = exports.ColorMaps = exports.GeoJSONParser = exports.CoordsType = exports.FoVUtils = exports.decDMSToDeg = exports.raHMSToDeg = exports.CartesianOpts = exports.PointInitOpts = exports.AstroOpts = exports.SphericalOpts = exports.Point = exports.ColumnType = exports.MetadataInit = exports.MetadataColumn = exports.MetadataManager = exports.ObservationTrackViewerAdapter = exports.ObservationTrackTimeline = exports.footprintToRing = exports.createObservationTrackTimeline = exports.SensorConeGL = exports.SatelliteObjectGL = exports.TerraPolylineSetGL = exports.TerraFootprintSetGL = exports.TerraPointSetGL = exports.CatalogueGL = exports.FootprintSetGL = exports.HoveredFootprintDetail = exports.SphereFoV = exports.FoV = exports.HiPSDescriptor = exports.AstroViewer = void 0;
|
|
5868
6195
|
var AstroViewer_js_1 = __webpack_require__(772);
|
|
5869
6196
|
Object.defineProperty(exports, "AstroViewer", ({ enumerable: true, get: function () { return AstroViewer_js_1.AstroViewer; } }));
|
|
5870
6197
|
var HiPSDescriptor_js_1 = __webpack_require__(5087);
|
|
@@ -5905,6 +6232,9 @@ Object.defineProperty(exports, "SphericalOpts", ({ enumerable: true, get: functi
|
|
|
5905
6232
|
Object.defineProperty(exports, "AstroOpts", ({ enumerable: true, get: function () { return Point_js_1.AstroOpts; } }));
|
|
5906
6233
|
Object.defineProperty(exports, "PointInitOpts", ({ enumerable: true, get: function () { return Point_js_1.PointInitOpts; } }));
|
|
5907
6234
|
Object.defineProperty(exports, "CartesianOpts", ({ enumerable: true, get: function () { return Point_js_1.CartesianOpts; } }));
|
|
6235
|
+
var Utils_js_1 = __webpack_require__(7930);
|
|
6236
|
+
Object.defineProperty(exports, "raHMSToDeg", ({ enumerable: true, get: function () { return Utils_js_1.raHMSToDeg; } }));
|
|
6237
|
+
Object.defineProperty(exports, "decDMSToDeg", ({ enumerable: true, get: function () { return Utils_js_1.decDMSToDeg; } }));
|
|
5908
6238
|
var FoVUtils_js_1 = __webpack_require__(8083);
|
|
5909
6239
|
Object.defineProperty(exports, "FoVUtils", ({ enumerable: true, get: function () { return FoVUtils_js_1.FoVUtils; } }));
|
|
5910
6240
|
var CoordsType_js_1 = __webpack_require__(8145);
|
|
@@ -7903,6 +8233,7 @@ class Source {
|
|
|
7903
8233
|
_h_pix;
|
|
7904
8234
|
_shapesize;
|
|
7905
8235
|
_brightnessFactor;
|
|
8236
|
+
_mediaStyle;
|
|
7906
8237
|
/**
|
|
7907
8238
|
* @param in_point Point.js (Cartesian/RA-Dec wrapper)
|
|
7908
8239
|
* @param in_details Optional array of key/value metadata
|
|
@@ -7911,7 +8242,7 @@ class Source {
|
|
|
7911
8242
|
this._point = in_point;
|
|
7912
8243
|
this._details = in_details;
|
|
7913
8244
|
this._shapesize = 16.0;
|
|
7914
|
-
this._brightnessFactor =
|
|
8245
|
+
this._brightnessFactor = 3.0;
|
|
7915
8246
|
this.computeHealpixPixel();
|
|
7916
8247
|
}
|
|
7917
8248
|
getDetailByindex(index) {
|
|
@@ -7955,6 +8286,12 @@ class Source {
|
|
|
7955
8286
|
set brightnessFactor(factor) {
|
|
7956
8287
|
this._brightnessFactor = factor;
|
|
7957
8288
|
}
|
|
8289
|
+
get mediaStyle() {
|
|
8290
|
+
return this._mediaStyle;
|
|
8291
|
+
}
|
|
8292
|
+
set mediaStyle(style) {
|
|
8293
|
+
this._mediaStyle = style;
|
|
8294
|
+
}
|
|
7958
8295
|
}
|
|
7959
8296
|
exports.Source = Source;
|
|
7960
8297
|
|
|
@@ -8182,6 +8519,9 @@ exports.SphereFoV = SphereFoV;
|
|
|
8182
8519
|
*
|
|
8183
8520
|
* See LICENSE.md, LICENSE-AGPL.md, and LICENSE-COMMERCIAL.md for details.
|
|
8184
8521
|
*/
|
|
8522
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8523
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8524
|
+
};
|
|
8185
8525
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
8186
8526
|
exports.CatalogueGL = void 0;
|
|
8187
8527
|
const Source_js_1 = __webpack_require__(146);
|
|
@@ -8190,11 +8530,14 @@ const CoordsType_js_1 = __webpack_require__(8145);
|
|
|
8190
8530
|
const Utils_js_1 = __webpack_require__(7930);
|
|
8191
8531
|
const CatalogueShaderProgram_js_1 = __webpack_require__(3559);
|
|
8192
8532
|
const MetadataManager_js_1 = __webpack_require__(5403);
|
|
8533
|
+
const gl_matrix_1 = __webpack_require__(3890);
|
|
8534
|
+
const healpix_1 = __webpack_require__(4851);
|
|
8535
|
+
const Global_js_1 = __importDefault(__webpack_require__(4382));
|
|
8193
8536
|
class CatalogueGL {
|
|
8194
8537
|
_kind = "CatalogueGL";
|
|
8195
8538
|
static ELEM_SIZE = 6;
|
|
8196
8539
|
static BYTES_X_ELEM = new Float32Array().BYTES_PER_ELEMENT;
|
|
8197
|
-
static STANDARD_SHAPE_SIZE =
|
|
8540
|
+
static STANDARD_SHAPE_SIZE = 16.0;
|
|
8198
8541
|
static STANDARD_SHAPE_HUE = 3.0;
|
|
8199
8542
|
_ready;
|
|
8200
8543
|
_name;
|
|
@@ -8221,6 +8564,9 @@ class CatalogueGL {
|
|
|
8221
8564
|
_providerUrl;
|
|
8222
8565
|
_catalogueShaderProgram;
|
|
8223
8566
|
_visibleTilesManager;
|
|
8567
|
+
_mediaOverlayHost = null;
|
|
8568
|
+
_mediaElements = [];
|
|
8569
|
+
_svgMediaDataUrls = new Map();
|
|
8224
8570
|
constructor(catalogueName, catalogueDescription, providerUrl, metadataManager, webgl, visibleTilesManager) {
|
|
8225
8571
|
this._webgl = webgl;
|
|
8226
8572
|
this._ready = false;
|
|
@@ -8391,9 +8737,10 @@ class CatalogueGL {
|
|
|
8391
8737
|
* @param in_data Rows of TAP results
|
|
8392
8738
|
* @param columnsmeta TapMetadataList (unused here because `CatalogueProps` already holds indices)
|
|
8393
8739
|
*/
|
|
8394
|
-
addSources(in_data, columnsmeta) {
|
|
8740
|
+
addSources(in_data, columnsmeta, options = {}) {
|
|
8395
8741
|
this._ready = false;
|
|
8396
8742
|
this._sources = [];
|
|
8743
|
+
this.clearMediaOverlay();
|
|
8397
8744
|
this._metadataManager = new MetadataManager_js_1.MetadataManager(columnsmeta);
|
|
8398
8745
|
// const raDataIndex = (this.catalogueProps.raColumn as any).index ?? (this.catalogueProps.raColumn as any)._index;
|
|
8399
8746
|
// const decDataIndex = (this.catalogueProps.decColumn as any).index ?? (this.catalogueProps.decColumn as any)._index;
|
|
@@ -8407,6 +8754,10 @@ class CatalogueGL {
|
|
|
8407
8754
|
decDeg: in_data[j][decDataIndex],
|
|
8408
8755
|
}, CoordsType_js_1.CoordsType.ASTRO);
|
|
8409
8756
|
const source = new Source_js_1.Source(point, in_data[j]);
|
|
8757
|
+
const mediaStyle = this.extractMediaStyle(in_data[j], columnsmeta, options.mediaColumns);
|
|
8758
|
+
if (mediaStyle) {
|
|
8759
|
+
source.mediaStyle = mediaStyle;
|
|
8760
|
+
}
|
|
8410
8761
|
// Ensure optional fields exist
|
|
8411
8762
|
source.shapeSize = source.shapeSize ?? CatalogueGL.STANDARD_SHAPE_SIZE;
|
|
8412
8763
|
source.brightnessFactor = 3;
|
|
@@ -8426,11 +8777,226 @@ class CatalogueGL {
|
|
|
8426
8777
|
this._ready = true;
|
|
8427
8778
|
this._bufferInitialised = false;
|
|
8428
8779
|
}
|
|
8780
|
+
getColumnIndex(columnsmeta, columnName) {
|
|
8781
|
+
if (!columnName)
|
|
8782
|
+
return -1;
|
|
8783
|
+
return (columnsmeta.find((column) => column.name === columnName)?.index ?? -1);
|
|
8784
|
+
}
|
|
8785
|
+
readCell(row, columnsmeta, columnName) {
|
|
8786
|
+
const idx = this.getColumnIndex(columnsmeta, columnName);
|
|
8787
|
+
return idx >= 0 ? row[idx] : undefined;
|
|
8788
|
+
}
|
|
8789
|
+
extractMediaStyle(row, columnsmeta, mediaColumns) {
|
|
8790
|
+
if (!mediaColumns?.src)
|
|
8791
|
+
return undefined;
|
|
8792
|
+
const rawSrc = this.readCell(row, columnsmeta, mediaColumns.src);
|
|
8793
|
+
const src = String(rawSrc ?? "").trim();
|
|
8794
|
+
if (!src)
|
|
8795
|
+
return undefined;
|
|
8796
|
+
const rawKind = String(this.readCell(row, columnsmeta, mediaColumns.type) ?? "sprite")
|
|
8797
|
+
.trim()
|
|
8798
|
+
.toLowerCase();
|
|
8799
|
+
const kind = rawKind === "model"
|
|
8800
|
+
? "model"
|
|
8801
|
+
: rawKind === "image"
|
|
8802
|
+
? "image"
|
|
8803
|
+
: rawKind === "icon"
|
|
8804
|
+
? "icon"
|
|
8805
|
+
: rawKind === "circle"
|
|
8806
|
+
? "circle"
|
|
8807
|
+
: "sprite";
|
|
8808
|
+
if (kind === "circle" || kind === "model")
|
|
8809
|
+
return undefined;
|
|
8810
|
+
const scale = Number(this.readCell(row, columnsmeta, mediaColumns.scale));
|
|
8811
|
+
const rotationDeg = Number(this.readCell(row, columnsmeta, mediaColumns.rotation));
|
|
8812
|
+
const opacity = Number(this.readCell(row, columnsmeta, mediaColumns.opacity));
|
|
8813
|
+
return {
|
|
8814
|
+
kind,
|
|
8815
|
+
src,
|
|
8816
|
+
scale: Number.isFinite(scale) && scale > 0 ? scale : undefined,
|
|
8817
|
+
rotationDeg: Number.isFinite(rotationDeg) ? rotationDeg : undefined,
|
|
8818
|
+
opacity: Number.isFinite(opacity)
|
|
8819
|
+
? Math.max(0, Math.min(1, opacity))
|
|
8820
|
+
: undefined,
|
|
8821
|
+
};
|
|
8822
|
+
}
|
|
8429
8823
|
clearSources() {
|
|
8430
8824
|
this._sources = [];
|
|
8431
8825
|
this.hoveredIndexes = [];
|
|
8432
8826
|
this._healpixDensityMap.clear();
|
|
8433
8827
|
this.vertexCataloguePosition = new Float32Array(0);
|
|
8828
|
+
this.clearMediaOverlay();
|
|
8829
|
+
}
|
|
8830
|
+
clearMediaOverlay() {
|
|
8831
|
+
this._mediaElements.forEach((el) => el.remove());
|
|
8832
|
+
this._mediaElements = [];
|
|
8833
|
+
if (this._mediaOverlayHost) {
|
|
8834
|
+
this._mediaOverlayHost.remove();
|
|
8835
|
+
this._mediaOverlayHost = null;
|
|
8836
|
+
}
|
|
8837
|
+
}
|
|
8838
|
+
ensureMediaOverlayHost() {
|
|
8839
|
+
const canvas = this._webgl?.canvas;
|
|
8840
|
+
const parent = canvas?.parentElement;
|
|
8841
|
+
if (!canvas || !parent)
|
|
8842
|
+
return null;
|
|
8843
|
+
const parentStyle = window.getComputedStyle(parent);
|
|
8844
|
+
if (parentStyle.position === "static") {
|
|
8845
|
+
parent.style.position = "relative";
|
|
8846
|
+
}
|
|
8847
|
+
if (!this._mediaOverlayHost) {
|
|
8848
|
+
const host = document.createElement("div");
|
|
8849
|
+
host.dataset.astroCatalogueMedia = "true";
|
|
8850
|
+
host.style.position = "absolute";
|
|
8851
|
+
host.style.left = `${canvas.offsetLeft}px`;
|
|
8852
|
+
host.style.top = `${canvas.offsetTop}px`;
|
|
8853
|
+
host.style.width = `${canvas.clientWidth}px`;
|
|
8854
|
+
host.style.height = `${canvas.clientHeight}px`;
|
|
8855
|
+
host.style.pointerEvents = "none";
|
|
8856
|
+
host.style.overflow = "hidden";
|
|
8857
|
+
host.style.zIndex = "4";
|
|
8858
|
+
canvas.style.position = canvas.style.position || "relative";
|
|
8859
|
+
canvas.style.zIndex = canvas.style.zIndex || "0";
|
|
8860
|
+
parent.appendChild(host);
|
|
8861
|
+
this._mediaOverlayHost = host;
|
|
8862
|
+
}
|
|
8863
|
+
else {
|
|
8864
|
+
this._mediaOverlayHost.style.left = `${canvas.offsetLeft}px`;
|
|
8865
|
+
this._mediaOverlayHost.style.top = `${canvas.offsetTop}px`;
|
|
8866
|
+
this._mediaOverlayHost.style.width = `${canvas.clientWidth}px`;
|
|
8867
|
+
this._mediaOverlayHost.style.height = `${canvas.clientHeight}px`;
|
|
8868
|
+
}
|
|
8869
|
+
return this._mediaOverlayHost;
|
|
8870
|
+
}
|
|
8871
|
+
ensureMediaElement(index, style) {
|
|
8872
|
+
let img = this._mediaElements[index];
|
|
8873
|
+
if (!img) {
|
|
8874
|
+
img = document.createElement("img");
|
|
8875
|
+
img.loading = "lazy";
|
|
8876
|
+
img.decoding = "async";
|
|
8877
|
+
img.style.position = "absolute";
|
|
8878
|
+
img.style.objectFit = "contain";
|
|
8879
|
+
img.style.pointerEvents = "none";
|
|
8880
|
+
img.style.transformOrigin = "center center";
|
|
8881
|
+
img.style.filter = "drop-shadow(0 1px 2px rgba(0, 0, 0, 0.55))";
|
|
8882
|
+
img.style.willChange = "transform, left, top";
|
|
8883
|
+
this._mediaElements[index] = img;
|
|
8884
|
+
}
|
|
8885
|
+
const src = String(style.src ?? "").trim();
|
|
8886
|
+
const resolvedSrc = src ? new URL(src, document.baseURI).href : "";
|
|
8887
|
+
if (resolvedSrc && img.getAttribute("src") !== resolvedSrc) {
|
|
8888
|
+
img.removeAttribute("data-astro-media-src-index");
|
|
8889
|
+
img.removeAttribute("data-astro-media-loaded");
|
|
8890
|
+
img.onerror = null;
|
|
8891
|
+
img.onload = null;
|
|
8892
|
+
img.setAttribute("src", resolvedSrc);
|
|
8893
|
+
if (/\.svg(?:[?#].*)?$/i.test(resolvedSrc)) {
|
|
8894
|
+
void this.loadSvgMediaAsDataUrl(img, resolvedSrc);
|
|
8895
|
+
}
|
|
8896
|
+
}
|
|
8897
|
+
return img;
|
|
8898
|
+
}
|
|
8899
|
+
async loadSvgMediaAsDataUrl(img, resolvedSrc) {
|
|
8900
|
+
try {
|
|
8901
|
+
let dataUrl = this._svgMediaDataUrls.get(resolvedSrc);
|
|
8902
|
+
if (!dataUrl) {
|
|
8903
|
+
const response = await fetch(resolvedSrc);
|
|
8904
|
+
if (!response.ok)
|
|
8905
|
+
return;
|
|
8906
|
+
const svg = await response.text();
|
|
8907
|
+
if (!/^\s*<svg[\s>]/i.test(svg))
|
|
8908
|
+
return;
|
|
8909
|
+
dataUrl = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
8910
|
+
this._svgMediaDataUrls.set(resolvedSrc, dataUrl);
|
|
8911
|
+
}
|
|
8912
|
+
if (img.getAttribute("src") === resolvedSrc) {
|
|
8913
|
+
img.setAttribute("src", dataUrl);
|
|
8914
|
+
}
|
|
8915
|
+
}
|
|
8916
|
+
catch {
|
|
8917
|
+
// Keep the direct image src; remote servers may already provide a valid MIME type.
|
|
8918
|
+
}
|
|
8919
|
+
}
|
|
8920
|
+
isSourceOnVisibleHemisphere(source, in_mMatrix, vMatrix) {
|
|
8921
|
+
if (Global_js_1.default.insideSphere)
|
|
8922
|
+
return true;
|
|
8923
|
+
const invView = gl_matrix_1.mat4.create();
|
|
8924
|
+
if (!gl_matrix_1.mat4.invert(invView, vMatrix))
|
|
8925
|
+
return true;
|
|
8926
|
+
const cameraPos = gl_matrix_1.vec3.fromValues(invView[12], invView[13], invView[14]);
|
|
8927
|
+
const worldPoint4 = gl_matrix_1.vec4.fromValues(source.point.x, source.point.y, source.point.z, 1);
|
|
8928
|
+
gl_matrix_1.vec4.transformMat4(worldPoint4, worldPoint4, in_mMatrix);
|
|
8929
|
+
const worldPoint = gl_matrix_1.vec3.fromValues(worldPoint4[0], worldPoint4[1], worldPoint4[2]);
|
|
8930
|
+
const normal = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), worldPoint);
|
|
8931
|
+
const toCamera = gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), cameraPos, worldPoint);
|
|
8932
|
+
return gl_matrix_1.vec3.dot(normal, toCamera) > 0;
|
|
8933
|
+
}
|
|
8934
|
+
updateMediaOverlay(in_mMatrix, vMatrix, pMatrix) {
|
|
8935
|
+
const sourcesWithMedia = this._sources.filter((source) => !!source.mediaStyle?.src);
|
|
8936
|
+
if (!sourcesWithMedia.length) {
|
|
8937
|
+
this.clearMediaOverlay();
|
|
8938
|
+
return;
|
|
8939
|
+
}
|
|
8940
|
+
const host = this.ensureMediaOverlayHost();
|
|
8941
|
+
const canvas = this._webgl.canvas;
|
|
8942
|
+
if (!host || !canvas.clientWidth || !canvas.clientHeight)
|
|
8943
|
+
return;
|
|
8944
|
+
const modelView = gl_matrix_1.mat4.create();
|
|
8945
|
+
const mvp = gl_matrix_1.mat4.create();
|
|
8946
|
+
gl_matrix_1.mat4.multiply(modelView, vMatrix, in_mMatrix);
|
|
8947
|
+
gl_matrix_1.mat4.multiply(mvp, pMatrix, modelView);
|
|
8948
|
+
const width = canvas.clientWidth;
|
|
8949
|
+
const height = canvas.clientHeight;
|
|
8950
|
+
for (let i = 0; i < this._sources.length; i++) {
|
|
8951
|
+
const source = this._sources[i];
|
|
8952
|
+
const style = source.mediaStyle;
|
|
8953
|
+
const img = this._mediaElements[i];
|
|
8954
|
+
if (!style?.src) {
|
|
8955
|
+
if (img)
|
|
8956
|
+
img.style.display = "none";
|
|
8957
|
+
continue;
|
|
8958
|
+
}
|
|
8959
|
+
if (!this.isSourceOnVisibleHemisphere(source, in_mMatrix, vMatrix)) {
|
|
8960
|
+
if (img)
|
|
8961
|
+
img.style.display = "none";
|
|
8962
|
+
continue;
|
|
8963
|
+
}
|
|
8964
|
+
const projected = gl_matrix_1.vec4.fromValues(source.point.x, source.point.y, source.point.z, 1);
|
|
8965
|
+
gl_matrix_1.vec4.transformMat4(projected, projected, mvp);
|
|
8966
|
+
if (!projected[3]) {
|
|
8967
|
+
if (img)
|
|
8968
|
+
img.style.display = "none";
|
|
8969
|
+
continue;
|
|
8970
|
+
}
|
|
8971
|
+
const ndcX = projected[0] / projected[3];
|
|
8972
|
+
const ndcY = projected[1] / projected[3];
|
|
8973
|
+
const ndcZ = projected[2] / projected[3];
|
|
8974
|
+
if (ndcX < -1.15 ||
|
|
8975
|
+
ndcX > 1.15 ||
|
|
8976
|
+
ndcY < -1.15 ||
|
|
8977
|
+
ndcY > 1.15 ||
|
|
8978
|
+
ndcZ < -1.15 ||
|
|
8979
|
+
ndcZ > 1.15) {
|
|
8980
|
+
if (img)
|
|
8981
|
+
img.style.display = "none";
|
|
8982
|
+
continue;
|
|
8983
|
+
}
|
|
8984
|
+
const mediaEl = this.ensureMediaElement(i, style);
|
|
8985
|
+
if (!mediaEl.parentElement)
|
|
8986
|
+
host.appendChild(mediaEl);
|
|
8987
|
+
const px = (ndcX * 0.5 + 0.5) * width;
|
|
8988
|
+
const py = (1 - (ndcY * 0.5 + 0.5)) * height;
|
|
8989
|
+
const baseSize = source.shapeSize || CatalogueGL.STANDARD_SHAPE_SIZE;
|
|
8990
|
+
const size = Math.max(8, baseSize * (style.scale ?? 2.4));
|
|
8991
|
+
const rotation = style.rotationDeg ?? 0;
|
|
8992
|
+
mediaEl.style.display = "block";
|
|
8993
|
+
mediaEl.style.left = `${px - size / 2}px`;
|
|
8994
|
+
mediaEl.style.top = `${py - size / 2}px`;
|
|
8995
|
+
mediaEl.style.width = `${size}px`;
|
|
8996
|
+
mediaEl.style.height = `${size}px`;
|
|
8997
|
+
mediaEl.style.opacity = `${style.opacity ?? 1}`;
|
|
8998
|
+
mediaEl.style.transform = `rotate(${rotation}deg)`;
|
|
8999
|
+
}
|
|
8434
9000
|
}
|
|
8435
9001
|
sourceMatches(left, right) {
|
|
8436
9002
|
if (left === right)
|
|
@@ -8542,33 +9108,46 @@ class CatalogueGL {
|
|
|
8542
9108
|
this._webgl.bufferData(this._webgl.ARRAY_BUFFER, this.vertexCataloguePosition, this._webgl.STATIC_DRAW);
|
|
8543
9109
|
this._bufferInitialised = true;
|
|
8544
9110
|
}
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
9111
|
+
static MIN_HIT_RADIUS_PX = 6;
|
|
9112
|
+
static HIT_PADDING_PX = 3;
|
|
9113
|
+
static CANDIDATE_RADIUS_PX = 16;
|
|
9114
|
+
getCanvas() {
|
|
9115
|
+
return this._webgl.canvas;
|
|
9116
|
+
}
|
|
9117
|
+
getHitRadiusPx(source) {
|
|
9118
|
+
const markerSize = source.shapeSize ?? CatalogueGL.STANDARD_SHAPE_SIZE;
|
|
9119
|
+
return Math.max(CatalogueGL.MIN_HIT_RADIUS_PX, markerSize / 2 + CatalogueGL.HIT_PADDING_PX);
|
|
9120
|
+
}
|
|
9121
|
+
getCandidateSearchRadiusRad(pMatrix) {
|
|
9122
|
+
const canvas = this._webgl.canvas;
|
|
9123
|
+
const width = Math.max(1, canvas.clientWidth);
|
|
9124
|
+
const height = Math.max(1, canvas.clientHeight);
|
|
9125
|
+
// pMatrix[0] and pMatrix[5] are the perspective scale factors for X/Y.
|
|
9126
|
+
// Convert a small screen-space radius to a conservative angular radius.
|
|
9127
|
+
const fovXRad = 2 * Math.atan(1 / Math.abs(pMatrix[0]));
|
|
9128
|
+
const fovYRad = 2 * Math.atan(1 / Math.abs(pMatrix[5]));
|
|
9129
|
+
const radPerPixel = Math.max(fovXRad / width, fovYRad / height);
|
|
9130
|
+
return CatalogueGL.CANDIDATE_RADIUS_PX * radPerPixel;
|
|
9131
|
+
}
|
|
9132
|
+
projectPointToScreen(point, mvp, width, height) {
|
|
9133
|
+
const projected = gl_matrix_1.vec4.fromValues(point.x, point.y, point.z, 1);
|
|
9134
|
+
gl_matrix_1.vec4.transformMat4(projected, projected, mvp);
|
|
9135
|
+
if (projected[3] <= 0)
|
|
9136
|
+
return null;
|
|
9137
|
+
const ndcX = projected[0] / projected[3];
|
|
9138
|
+
const ndcY = projected[1] / projected[3];
|
|
9139
|
+
return [(ndcX * 0.5 + 0.5) * width, (1 - (ndcY * 0.5 + 0.5)) * height];
|
|
9140
|
+
}
|
|
9141
|
+
clearSelection() {
|
|
9142
|
+
for (const idx of this.selectedIndexes) {
|
|
9143
|
+
const base = idx * CatalogueGL.ELEM_SIZE;
|
|
9144
|
+
if (base + 4 >= this.vertexCataloguePosition.length)
|
|
9145
|
+
continue;
|
|
9146
|
+
this.vertexCataloguePosition[base + 3] = 0.0;
|
|
9147
|
+
this.vertexCataloguePosition[base + 4] =
|
|
9148
|
+
this._sources[idx]?.shapeSize ?? CatalogueGL.STANDARD_SHAPE_SIZE;
|
|
8571
9149
|
}
|
|
9150
|
+
this.selectedIndexes = [];
|
|
8572
9151
|
}
|
|
8573
9152
|
setSelectedIndexes(selectedIndex) {
|
|
8574
9153
|
selectedIndex.forEach((idx) => {
|
|
@@ -8595,8 +9174,8 @@ class CatalogueGL {
|
|
|
8595
9174
|
* Run click-picking and update selection with the nearest candidate in current pixel.
|
|
8596
9175
|
* Returns the selected source or null if no source was hit.
|
|
8597
9176
|
*/
|
|
8598
|
-
getSourcesFromPointer(in_mouseHelper) {
|
|
8599
|
-
const pickedIndexes = this.checkClicking(in_mouseHelper);
|
|
9177
|
+
getSourcesFromPointer(in_mouseHelper, in_mMatrix, vMatrix, pMatrix) {
|
|
9178
|
+
const pickedIndexes = this.checkClicking(in_mouseHelper, in_mMatrix, vMatrix, pMatrix);
|
|
8600
9179
|
if (!pickedIndexes.length) {
|
|
8601
9180
|
return {
|
|
8602
9181
|
sources: [],
|
|
@@ -8615,8 +9194,8 @@ class CatalogueGL {
|
|
|
8615
9194
|
* Run click-picking and update selection with the nearest candidate in current pixel.
|
|
8616
9195
|
* Returns the selected source or null if no source was hit.
|
|
8617
9196
|
*/
|
|
8618
|
-
selectPrimarySourceFromClick(in_mouseHelper) {
|
|
8619
|
-
const picked = this.getSourcesFromPointer(in_mouseHelper);
|
|
9197
|
+
selectPrimarySourceFromClick(in_mouseHelper, in_mMatrix, vMatrix, pMatrix) {
|
|
9198
|
+
const picked = this.getSourcesFromPointer(in_mouseHelper, in_mMatrix, vMatrix, pMatrix);
|
|
8620
9199
|
const clickedIndexes = picked?.pickedIndexes ?? [];
|
|
8621
9200
|
// if (!clickedIndexes.length) {
|
|
8622
9201
|
// this.setSelectedIndexes([]);
|
|
@@ -8652,42 +9231,65 @@ class CatalogueGL {
|
|
|
8652
9231
|
const idx = this.hoveredIndexes[0];
|
|
8653
9232
|
return this._sources[idx] ?? null;
|
|
8654
9233
|
}
|
|
8655
|
-
findNearestSourceIndex(in_mouseHelper) {
|
|
8656
|
-
if (in_mouseHelper.
|
|
8657
|
-
in_mouseHelper.y == null ||
|
|
8658
|
-
in_mouseHelper.z == null) {
|
|
9234
|
+
findNearestSourceIndex(in_mouseHelper, in_mMatrix, vMatrix, pMatrix) {
|
|
9235
|
+
if (in_mouseHelper.xyz == null)
|
|
8659
9236
|
return null;
|
|
9237
|
+
const healpix = Global_js_1.default.getHealpix(Global_js_1.default.selectionOrder);
|
|
9238
|
+
const mouseVec = new healpix_1.Vec3(...in_mouseHelper.xyz);
|
|
9239
|
+
const mousePointing = new healpix_1.Pointing(mouseVec, false);
|
|
9240
|
+
const searchRadiusRad = this.getCandidateSearchRadiusRad(pMatrix);
|
|
9241
|
+
const rangeSet = healpix.queryDiscInclusive(mousePointing, searchRadiusRad, 4);
|
|
9242
|
+
const pixels = rangeSet.r;
|
|
9243
|
+
const candidateIndexes = new Set();
|
|
9244
|
+
for (const pixel of pixels) {
|
|
9245
|
+
const indexes = this._healpixDensityMap.get(pixel);
|
|
9246
|
+
if (!indexes)
|
|
9247
|
+
continue;
|
|
9248
|
+
indexes.forEach((idx) => candidateIndexes.add(idx));
|
|
8660
9249
|
}
|
|
8661
|
-
|
|
8662
|
-
|
|
9250
|
+
if (!candidateIndexes.size)
|
|
9251
|
+
return null;
|
|
9252
|
+
const canvas = this._webgl.canvas;
|
|
9253
|
+
const width = canvas.clientWidth;
|
|
9254
|
+
const height = canvas.clientHeight;
|
|
9255
|
+
if (!width || !height)
|
|
8663
9256
|
return null;
|
|
8664
|
-
const
|
|
8665
|
-
|
|
9257
|
+
const modelView = gl_matrix_1.mat4.create();
|
|
9258
|
+
const mvp = gl_matrix_1.mat4.create();
|
|
9259
|
+
gl_matrix_1.mat4.multiply(modelView, vMatrix, in_mMatrix);
|
|
9260
|
+
gl_matrix_1.mat4.multiply(mvp, pMatrix, modelView);
|
|
9261
|
+
const mousePoint = new Point_js_1.Point({
|
|
9262
|
+
x: in_mouseHelper.xyz[0],
|
|
9263
|
+
y: in_mouseHelper.xyz[1],
|
|
9264
|
+
z: in_mouseHelper.xyz[2],
|
|
9265
|
+
}, CoordsType_js_1.CoordsType.CARTESIAN);
|
|
9266
|
+
const mouseScreen = this.projectPointToScreen(mousePoint, mvp, width, height);
|
|
9267
|
+
if (!mouseScreen)
|
|
8666
9268
|
return null;
|
|
8667
|
-
const selR = this.getSelectionRadius();
|
|
8668
9269
|
let nearestIndex = null;
|
|
8669
|
-
let
|
|
8670
|
-
for (const sourceIdx of
|
|
9270
|
+
let nearestDistancePx = Number.POSITIVE_INFINITY;
|
|
9271
|
+
for (const sourceIdx of candidateIndexes) {
|
|
8671
9272
|
const source = this._sources[sourceIdx];
|
|
8672
9273
|
if (!source)
|
|
8673
9274
|
continue;
|
|
8674
|
-
const
|
|
8675
|
-
|
|
8676
|
-
|
|
8677
|
-
const
|
|
8678
|
-
if (
|
|
8679
|
-
|
|
9275
|
+
const sourceScreen = this.projectPointToScreen(source.point, mvp, width, height);
|
|
9276
|
+
if (!sourceScreen)
|
|
9277
|
+
continue;
|
|
9278
|
+
const distancePx = Math.hypot(sourceScreen[0] - mouseScreen[0], sourceScreen[1] - mouseScreen[1]);
|
|
9279
|
+
if (distancePx <= this.getHitRadiusPx(source) &&
|
|
9280
|
+
distancePx < nearestDistancePx) {
|
|
9281
|
+
nearestDistancePx = distancePx;
|
|
8680
9282
|
nearestIndex = sourceIdx;
|
|
8681
9283
|
}
|
|
8682
9284
|
}
|
|
8683
9285
|
return nearestIndex;
|
|
8684
9286
|
}
|
|
8685
|
-
checkClicking(in_mouseHelper) {
|
|
8686
|
-
const nearestIndex = this.findNearestSourceIndex(in_mouseHelper);
|
|
9287
|
+
checkClicking(in_mouseHelper, in_mMatrix, vMatrix, pMatrix) {
|
|
9288
|
+
const nearestIndex = this.findNearestSourceIndex(in_mouseHelper, in_mMatrix, vMatrix, pMatrix);
|
|
8687
9289
|
return nearestIndex == null ? [] : [nearestIndex];
|
|
8688
9290
|
}
|
|
8689
|
-
checkHovering(in_mouseHelper) {
|
|
8690
|
-
const nearestIndex = this.findNearestSourceIndex(in_mouseHelper);
|
|
9291
|
+
checkHovering(in_mouseHelper, in_mMatrix, vMatrix, pMatrix) {
|
|
9292
|
+
const nearestIndex = this.findNearestSourceIndex(in_mouseHelper, in_mMatrix, vMatrix, pMatrix);
|
|
8691
9293
|
return nearestIndex == null ? [] : [nearestIndex];
|
|
8692
9294
|
}
|
|
8693
9295
|
/**
|
|
@@ -8723,6 +9325,13 @@ class CatalogueGL {
|
|
|
8723
9325
|
if (this._catalogueShaderProgram.locations.color) {
|
|
8724
9326
|
this._webgl.uniform4f(this._catalogueShaderProgram.locations.color, rgb[0], rgb[1], rgb[2], 1.0);
|
|
8725
9327
|
}
|
|
9328
|
+
const interactionColors = (0, Utils_js_1.interactionColorsFromHex)(this._shapeColor);
|
|
9329
|
+
if (this._catalogueShaderProgram.locations.hoverColor) {
|
|
9330
|
+
this._webgl.uniform4f(this._catalogueShaderProgram.locations.hoverColor, ...interactionColors.hover, 1.0);
|
|
9331
|
+
}
|
|
9332
|
+
if (this._catalogueShaderProgram.locations.selectedColor) {
|
|
9333
|
+
this._webgl.uniform4f(this._catalogueShaderProgram.locations.selectedColor, ...interactionColors.selected, 1.0);
|
|
9334
|
+
}
|
|
8726
9335
|
// selected flags
|
|
8727
9336
|
for (let s = 0; s < this.selectedIndexes.length; s++) {
|
|
8728
9337
|
const idx = this.selectedIndexes[s];
|
|
@@ -8733,7 +9342,8 @@ class CatalogueGL {
|
|
|
8733
9342
|
// clear old hovered
|
|
8734
9343
|
for (let k = 0; k < this.hoveredIndexes.length; k++) {
|
|
8735
9344
|
const base = this.hoveredIndexes[k] * CatalogueGL.ELEM_SIZE;
|
|
8736
|
-
|
|
9345
|
+
if (this.selectedIndexes.includes(this.hoveredIndexes[k]))
|
|
9346
|
+
continue;
|
|
8737
9347
|
this.vertexCataloguePosition[base + 3] = 0.0; // not hovered
|
|
8738
9348
|
this.vertexCataloguePosition[base + 4] =
|
|
8739
9349
|
this._sources[this.hoveredIndexes[k]].shapeSize; // size
|
|
@@ -8747,7 +9357,7 @@ class CatalogueGL {
|
|
|
8747
9357
|
// this.vertexCataloguePosition[base + 3] = 0.0; // not hovered
|
|
8748
9358
|
// this.vertexCataloguePosition[base + 4] = this._sources[this.hoveredIndexes[k]].shapeSize; // size
|
|
8749
9359
|
// }
|
|
8750
|
-
this.hoveredIndexes = this.checkHovering(in_mouseHelper);
|
|
9360
|
+
this.hoveredIndexes = this.checkHovering(in_mouseHelper, in_mMatrix, vMatrix, pMatrix);
|
|
8751
9361
|
// // new hovered
|
|
8752
9362
|
// for (let i = 0; i < this.hoveredIndexes.length; i++) {
|
|
8753
9363
|
// const idx = this.hoveredIndexes[i];
|
|
@@ -8761,7 +9371,8 @@ class CatalogueGL {
|
|
|
8761
9371
|
for (let i = 0; i < this.hoveredIndexes.length; i++) {
|
|
8762
9372
|
const idx = this.hoveredIndexes[i];
|
|
8763
9373
|
const base = idx * CatalogueGL.ELEM_SIZE;
|
|
8764
|
-
|
|
9374
|
+
if (this.selectedIndexes.includes(idx))
|
|
9375
|
+
continue;
|
|
8765
9376
|
this.vertexCataloguePosition[base + 3] = 1.0; // hovered
|
|
8766
9377
|
this.vertexCataloguePosition[base + 4] = this._sources[idx].shapeSize; // size
|
|
8767
9378
|
}
|
|
@@ -8770,6 +9381,7 @@ class CatalogueGL {
|
|
|
8770
9381
|
// draw
|
|
8771
9382
|
const numItems = this.vertexCataloguePosition.length / CatalogueGL.ELEM_SIZE;
|
|
8772
9383
|
this._webgl.drawArrays(this._webgl.POINTS, 0, numItems);
|
|
9384
|
+
this.updateMediaOverlay(in_mMatrix, vMatrix, pMatrix);
|
|
8773
9385
|
this._oldMouseCoords = in_mouseHelper.xyz;
|
|
8774
9386
|
}
|
|
8775
9387
|
}
|
|
@@ -9168,6 +9780,7 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9168
9780
|
_latLonGrid;
|
|
9169
9781
|
_colorMapIdx = 0;
|
|
9170
9782
|
_colorMap = ColorMaps_js_1.ColorMaps['native'];
|
|
9783
|
+
_opacity = 1;
|
|
9171
9784
|
constructor(radius, position, xrad, yrad, descriptor, webgl, gridLabelContainers) {
|
|
9172
9785
|
super(radius, position, xrad, yrad, descriptor.name, webgl, false);
|
|
9173
9786
|
this._descriptor = descriptor;
|
|
@@ -9182,6 +9795,10 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9182
9795
|
const fov = 180;
|
|
9183
9796
|
this._zoom = XYZFoVHelper_js_1.xyzFovHelper.getZoom(fov);
|
|
9184
9797
|
}
|
|
9798
|
+
setOpacity(opacity) {
|
|
9799
|
+
this._opacity = Math.min(1, Math.max(0, opacity));
|
|
9800
|
+
this._xyzShaderProgram.setOpacity(this._opacity);
|
|
9801
|
+
}
|
|
9185
9802
|
changeColorMap(colorMap) {
|
|
9186
9803
|
this._colorMap = colorMap;
|
|
9187
9804
|
switch (colorMap.name) {
|
|
@@ -9229,6 +9846,9 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9229
9846
|
initShaders() {
|
|
9230
9847
|
this._xyzShaderProgram.enableProgram();
|
|
9231
9848
|
}
|
|
9849
|
+
clearLonLatGridLabels() {
|
|
9850
|
+
this._latLonGrid.clearLabels();
|
|
9851
|
+
}
|
|
9232
9852
|
isLonLatGridVisible() {
|
|
9233
9853
|
return this._latLonGrid.isVisible();
|
|
9234
9854
|
}
|
|
@@ -9243,7 +9863,7 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9243
9863
|
// this._zoom = this.resolveVisibleZoom(fov)
|
|
9244
9864
|
this._zoom = XYZFoVHelper_js_1.xyzFovHelper.getZoom(fov);
|
|
9245
9865
|
}
|
|
9246
|
-
draw(input) {
|
|
9866
|
+
draw(input, asOverlay = false) {
|
|
9247
9867
|
const vMatrix = input.camera.getCameraMatrix();
|
|
9248
9868
|
if (!vMatrix)
|
|
9249
9869
|
return;
|
|
@@ -9253,6 +9873,18 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9253
9873
|
this.refresh(input);
|
|
9254
9874
|
const mMatrix = this.getModelMatrix();
|
|
9255
9875
|
this._xyzShaderProgram.setRuntimeColorMap(this._colorMap);
|
|
9876
|
+
this._xyzShaderProgram.setOpacity(this._opacity);
|
|
9877
|
+
const depthTestWasEnabled = this._webgl.isEnabled(this._webgl.DEPTH_TEST);
|
|
9878
|
+
const blendWasEnabled = this._webgl.isEnabled(this._webgl.BLEND);
|
|
9879
|
+
const blendSrcRgb = this._webgl.getParameter(this._webgl.BLEND_SRC_RGB);
|
|
9880
|
+
const blendDstRgb = this._webgl.getParameter(this._webgl.BLEND_DST_RGB);
|
|
9881
|
+
const blendSrcAlpha = this._webgl.getParameter(this._webgl.BLEND_SRC_ALPHA);
|
|
9882
|
+
const blendDstAlpha = this._webgl.getParameter(this._webgl.BLEND_DST_ALPHA);
|
|
9883
|
+
if (asOverlay) {
|
|
9884
|
+
this._webgl.disable(this._webgl.DEPTH_TEST);
|
|
9885
|
+
this._webgl.enable(this._webgl.BLEND);
|
|
9886
|
+
this._webgl.blendFunc(this._webgl.SRC_ALPHA, this._webgl.ONE_MINUS_SRC_ALPHA);
|
|
9887
|
+
}
|
|
9256
9888
|
const tileSelection = this._visibleTilesManager.computeVisibleTiles(this._zoom, this, this._webgl, input.camera, input.pMatrix);
|
|
9257
9889
|
const visibleTiles = tileSelection.visibleTiles;
|
|
9258
9890
|
const ancestorsMap = tileSelection.ancestorsMap;
|
|
@@ -9270,7 +9902,20 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9270
9902
|
const ancestorTile = this.findBestAvailableAncestor(tile.coord);
|
|
9271
9903
|
ancestorTile?.draw(tileSelection.currentZoom, [tile.coord], ancestorsMap, pMatrix, vMatrix, mMatrix, this._colorMapIdx);
|
|
9272
9904
|
}
|
|
9273
|
-
|
|
9905
|
+
if (asOverlay) {
|
|
9906
|
+
if (depthTestWasEnabled)
|
|
9907
|
+
this._webgl.enable(this._webgl.DEPTH_TEST);
|
|
9908
|
+
else
|
|
9909
|
+
this._webgl.disable(this._webgl.DEPTH_TEST);
|
|
9910
|
+
this._webgl.blendFuncSeparate(blendSrcRgb, blendDstRgb, blendSrcAlpha, blendDstAlpha);
|
|
9911
|
+
if (blendWasEnabled)
|
|
9912
|
+
this._webgl.enable(this._webgl.BLEND);
|
|
9913
|
+
else
|
|
9914
|
+
this._webgl.disable(this._webgl.BLEND);
|
|
9915
|
+
}
|
|
9916
|
+
else {
|
|
9917
|
+
this._latLonGrid.draw(input);
|
|
9918
|
+
}
|
|
9274
9919
|
}
|
|
9275
9920
|
createTile(coord) {
|
|
9276
9921
|
return new XYZAnchestorTile_js_1.XYZAnchestorTile(coord, this.resolveTileUrl(coord), this._webgl, this._xyzShaderProgram, this._meshBuilder, this._descriptor.segmentsPerSide);
|
|
@@ -10564,6 +11209,10 @@ class FootprintSetGL {
|
|
|
10564
11209
|
}
|
|
10565
11210
|
return clickedIndexes;
|
|
10566
11211
|
}
|
|
11212
|
+
clearSelection() {
|
|
11213
|
+
this.selectedIndexes = [];
|
|
11214
|
+
this.refreshSelectedFootprints();
|
|
11215
|
+
}
|
|
10567
11216
|
setSelectedIndexes(selectedIndex) {
|
|
10568
11217
|
selectedIndex.forEach((idx) => {
|
|
10569
11218
|
if (idx < 0 || idx >= this.footprintPolygons.length)
|
|
@@ -10865,9 +11514,10 @@ class FootprintSetGL {
|
|
|
10865
11514
|
if (in_mouseHelper != null && in_mouseHelper.xyz != this.oldMouseCoords) {
|
|
10866
11515
|
this.checkSelection(in_mouseHelper);
|
|
10867
11516
|
}
|
|
11517
|
+
const interactionColors = (0, Utils_js_1.interactionColorsFromHex)(this._shapeColor);
|
|
10868
11518
|
if (this._hoveredFootprints.length > 0) {
|
|
10869
11519
|
// TODO POINT_SIZE doesn't have any effect on line thickness!! it only applies to points
|
|
10870
|
-
const rgb =
|
|
11520
|
+
const rgb = interactionColors.hover;
|
|
10871
11521
|
const alpha = 1.0;
|
|
10872
11522
|
this._webgl.uniform4f(this._footprintShaderProgram.locations.color, rgb[0], rgb[1], rgb[2], alpha);
|
|
10873
11523
|
this._webgl.uniform1f(this._footprintShaderProgram.locations.pointSize, 14.0); // <--- POINT_SIZE in LINE_LOOP is not applicable
|
|
@@ -10882,7 +11532,7 @@ class FootprintSetGL {
|
|
|
10882
11532
|
this._webgl.drawElements(this._webgl.LINE_LOOP, this.hoveredVertexPosition.length / 3 + this.nHoveredPrimitiveFlags, this._webgl.UNSIGNED_INT, 0);
|
|
10883
11533
|
}
|
|
10884
11534
|
if (this._selectedFootprints.length > 0) {
|
|
10885
|
-
const rgb =
|
|
11535
|
+
const rgb = interactionColors.selected;
|
|
10886
11536
|
const alpha = 1.0;
|
|
10887
11537
|
this._webgl.uniform4f(this._footprintShaderProgram.locations.color, rgb[0], rgb[1], rgb[2], alpha);
|
|
10888
11538
|
this._webgl.uniform1f(this._footprintShaderProgram.locations.pointSize, 14.0); // <--- POINT_SIZE in LINE_LOOP is not applicable
|
|
@@ -10895,6 +11545,11 @@ class FootprintSetGL {
|
|
|
10895
11545
|
this._webgl.bufferData(this._webgl.ELEMENT_ARRAY_BUFFER, this.selectedElementIndexes, this._webgl.STATIC_DRAW);
|
|
10896
11546
|
// this._gl.drawElements (this._gl.LINE_LOOP, this._selectedVertexPosition.length / 3 + this._nSlectedPrimitiveFlags,this._gl.UNSIGNED_SHORT, 0);
|
|
10897
11547
|
this._webgl.drawElements(this._webgl.LINE_LOOP, this.selectedVertexPosition.length / 3 + this.nSlectedPrimitiveFlags, this._webgl.UNSIGNED_INT, 0);
|
|
11548
|
+
// Keep selection visually distinct from hover without relying on
|
|
11549
|
+
// non-portable line widths. Reuse the selected geometry as small
|
|
11550
|
+
// vertex markers; POINT_SIZE is supported for POINTS in WebGL2.
|
|
11551
|
+
this._webgl.uniform1f(this._footprintShaderProgram.locations.pointSize, 4.0);
|
|
11552
|
+
this._webgl.drawElements(this._webgl.POINTS, this.selectedVertexPosition.length / 3 + this.nSlectedPrimitiveFlags, this._webgl.UNSIGNED_INT, 0);
|
|
10898
11553
|
}
|
|
10899
11554
|
this._webgl.bindBuffer(this._webgl.ARRAY_BUFFER, this.vertexCataloguePositionBuffer);
|
|
10900
11555
|
this._webgl.vertexAttribPointer(this._footprintShaderProgram.locations.position, FootprintSetGL.ELEM_SIZE, this._webgl.FLOAT, false, FootprintSetGL.BYTES_X_ELEM * FootprintSetGL.ELEM_SIZE, 0);
|
|
@@ -11128,6 +11783,9 @@ class EquatorialGrid extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
11128
11783
|
gl.uniform4f(uColor, rgb[0], rgb[1], rgb[2], 1.0);
|
|
11129
11784
|
}
|
|
11130
11785
|
}
|
|
11786
|
+
clearLabels() {
|
|
11787
|
+
this.gridText.resetDivSets();
|
|
11788
|
+
}
|
|
11131
11789
|
isVisible() {
|
|
11132
11790
|
return this.showGrid;
|
|
11133
11791
|
}
|
|
@@ -11724,6 +12382,9 @@ class HealpixGrid extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
11724
12382
|
this.gridText.resetDivSets();
|
|
11725
12383
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
|
|
11726
12384
|
}
|
|
12385
|
+
clearLabels() {
|
|
12386
|
+
this.gridText.resetDivSets();
|
|
12387
|
+
}
|
|
11727
12388
|
get visibleorder() {
|
|
11728
12389
|
return this._visibleorder;
|
|
11729
12390
|
}
|
|
@@ -11958,6 +12619,9 @@ class LatLonGrid extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
11958
12619
|
gl.uniform4f(uColor, rgb[0], rgb[1], rgb[2], 1.0);
|
|
11959
12620
|
}
|
|
11960
12621
|
}
|
|
12622
|
+
clearLabels() {
|
|
12623
|
+
this.gridText.resetDivSets();
|
|
12624
|
+
}
|
|
11961
12625
|
draw(input) {
|
|
11962
12626
|
if (!this._showGrid) {
|
|
11963
12627
|
this.gridText.resetDivSets();
|
|
@@ -14626,6 +15290,8 @@ class MeshHiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
14626
15290
|
_currentOrder;
|
|
14627
15291
|
_visibleTiles = [];
|
|
14628
15292
|
_coverageTiles = [];
|
|
15293
|
+
_color;
|
|
15294
|
+
_wireframe;
|
|
14629
15295
|
constructor(radius, position, xrad, yrad, _descriptor, webgl, _healpixGrid) {
|
|
14630
15296
|
super(radius, position, xrad, yrad, _descriptor.name, webgl, false);
|
|
14631
15297
|
this._descriptor = _descriptor;
|
|
@@ -14634,6 +15300,8 @@ class MeshHiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
14634
15300
|
this._shaderProgram = new MeshHiPSShaderProgram_js_1.MeshHiPSShaderProgram(webgl);
|
|
14635
15301
|
this._shaderProgram.enableProgram();
|
|
14636
15302
|
this._currentOrder = _descriptor.selectedOrder;
|
|
15303
|
+
this._color = [..._descriptor.color];
|
|
15304
|
+
this._wireframe = _descriptor.wireframe;
|
|
14637
15305
|
}
|
|
14638
15306
|
get currentOrder() {
|
|
14639
15307
|
return this._currentOrder;
|
|
@@ -14656,6 +15324,12 @@ class MeshHiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
14656
15324
|
getProperty(key) {
|
|
14657
15325
|
return this._descriptor.getProperty(key);
|
|
14658
15326
|
}
|
|
15327
|
+
setColor(color) {
|
|
15328
|
+
this._color = [...color];
|
|
15329
|
+
}
|
|
15330
|
+
setWireframe(wireframe) {
|
|
15331
|
+
this._wireframe = wireframe;
|
|
15332
|
+
}
|
|
14659
15333
|
refreshOrder(fovDeg) {
|
|
14660
15334
|
if (this._descriptor.fixedOrder) {
|
|
14661
15335
|
this._currentOrder = this._descriptor.selectedOrder;
|
|
@@ -14695,7 +15369,7 @@ class MeshHiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
14695
15369
|
for (const coord of byOrder.get(order) ?? []) {
|
|
14696
15370
|
this._tiles
|
|
14697
15371
|
.get(this.tileKey(coord))
|
|
14698
|
-
?.draw(pMatrix, vMatrix, mMatrix, this.
|
|
15372
|
+
?.draw(pMatrix, vMatrix, mMatrix, this._color, this._wireframe);
|
|
14699
15373
|
}
|
|
14700
15374
|
}
|
|
14701
15375
|
if (wasCullFace)
|
|
@@ -16486,6 +17160,7 @@ exports.TerraFootprintSetGL = TerraFootprintSetGL;
|
|
|
16486
17160
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
16487
17161
|
exports.TerraPointSetGL = void 0;
|
|
16488
17162
|
const CatalogueGL_js_1 = __webpack_require__(1232);
|
|
17163
|
+
const gl_matrix_1 = __webpack_require__(3890);
|
|
16489
17164
|
const MetadataManager_js_1 = __webpack_require__(5403);
|
|
16490
17165
|
const Point_js_1 = __webpack_require__(6553);
|
|
16491
17166
|
const CoordsType_js_1 = __webpack_require__(8145);
|
|
@@ -16520,8 +17195,45 @@ class TerraPointSetGL extends CatalogueGL_js_1.CatalogueGL {
|
|
|
16520
17195
|
this._ready = true;
|
|
16521
17196
|
this._bufferInitialised = false;
|
|
16522
17197
|
}
|
|
17198
|
+
findNearestSourceIndex(inMouseHelper, inMatrix, viewMatrix, projectionMatrix) {
|
|
17199
|
+
if (inMouseHelper.xyz == null)
|
|
17200
|
+
return null;
|
|
17201
|
+
const canvas = this.getCanvas();
|
|
17202
|
+
const width = canvas.clientWidth;
|
|
17203
|
+
const height = canvas.clientHeight;
|
|
17204
|
+
if (!width || !height)
|
|
17205
|
+
return null;
|
|
17206
|
+
const modelView = gl_matrix_1.mat4.create();
|
|
17207
|
+
const mvp = gl_matrix_1.mat4.create();
|
|
17208
|
+
gl_matrix_1.mat4.multiply(modelView, viewMatrix, inMatrix);
|
|
17209
|
+
gl_matrix_1.mat4.multiply(mvp, projectionMatrix, modelView);
|
|
17210
|
+
const mousePoint = new Point_js_1.Point({
|
|
17211
|
+
x: inMouseHelper.xyz[0],
|
|
17212
|
+
y: inMouseHelper.xyz[1],
|
|
17213
|
+
z: inMouseHelper.xyz[2],
|
|
17214
|
+
}, CoordsType_js_1.CoordsType.CARTESIAN);
|
|
17215
|
+
const mouseScreen = this.projectPointToScreen(mousePoint, mvp, width, height);
|
|
17216
|
+
if (!mouseScreen)
|
|
17217
|
+
return null;
|
|
17218
|
+
let nearestIndex = null;
|
|
17219
|
+
let nearestDistancePx = Number.POSITIVE_INFINITY;
|
|
17220
|
+
for (let index = 0; index < this._sources.length; index += 1) {
|
|
17221
|
+
const source = this._sources[index];
|
|
17222
|
+
if (!source)
|
|
17223
|
+
continue;
|
|
17224
|
+
const sourceScreen = this.projectPointToScreen(source.point, mvp, width, height);
|
|
17225
|
+
if (!sourceScreen)
|
|
17226
|
+
continue;
|
|
17227
|
+
const distancePx = Math.hypot(sourceScreen[0] - mouseScreen[0], sourceScreen[1] - mouseScreen[1]);
|
|
17228
|
+
if (distancePx <= this.getHitRadiusPx(source) &&
|
|
17229
|
+
distancePx < nearestDistancePx) {
|
|
17230
|
+
nearestDistancePx = distancePx;
|
|
17231
|
+
nearestIndex = index;
|
|
17232
|
+
}
|
|
17233
|
+
}
|
|
17234
|
+
return nearestIndex;
|
|
17235
|
+
}
|
|
16523
17236
|
draw(inMatrix, inMouseHelper, viewMatrix, projectionMatrix) {
|
|
16524
|
-
this._oldMouseCoords = inMouseHelper?.xyz ?? null;
|
|
16525
17237
|
super.draw(inMatrix, inMouseHelper, viewMatrix, projectionMatrix);
|
|
16526
17238
|
}
|
|
16527
17239
|
}
|
|
@@ -16753,6 +17465,8 @@ class CatalogueShaderProgram {
|
|
|
16753
17465
|
this._webgl = webgl;
|
|
16754
17466
|
this.gl_uniforms = {
|
|
16755
17467
|
vertex_color: 'u_fragcolor',
|
|
17468
|
+
hover_color: 'u_hovercolor',
|
|
17469
|
+
selected_color: 'u_selectedcolor',
|
|
16756
17470
|
m_perspective: 'uPMatrix',
|
|
16757
17471
|
m_model_view: 'uMVMatrix'
|
|
16758
17472
|
};
|
|
@@ -16766,6 +17480,8 @@ class CatalogueShaderProgram {
|
|
|
16766
17480
|
pMatrix: null,
|
|
16767
17481
|
mvMatrix: null,
|
|
16768
17482
|
color: null,
|
|
17483
|
+
hoverColor: null,
|
|
17484
|
+
selectedColor: null,
|
|
16769
17485
|
position: -1,
|
|
16770
17486
|
hovered: -1,
|
|
16771
17487
|
pointSize: -1,
|
|
@@ -16815,6 +17531,8 @@ class CatalogueShaderProgram {
|
|
|
16815
17531
|
this.locations.pointSize = gl.getAttribLocation(this.shaderProgram, this.gl_attributes.point_size);
|
|
16816
17532
|
this.locations.brightness = gl.getAttribLocation(this.shaderProgram, this.gl_attributes.point_hue);
|
|
16817
17533
|
this.locations.color = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.vertex_color);
|
|
17534
|
+
this.locations.hoverColor = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.hover_color);
|
|
17535
|
+
this.locations.selectedColor = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.selected_color);
|
|
16818
17536
|
}
|
|
16819
17537
|
enableShaders(pMatrix, modelMatrix, viewMatrix) {
|
|
16820
17538
|
// const gl = global.gl as GL
|
|
@@ -17505,6 +18223,8 @@ class ShaderManager {
|
|
|
17505
18223
|
in float v_brightness;
|
|
17506
18224
|
|
|
17507
18225
|
uniform vec4 u_fragcolor;
|
|
18226
|
+
uniform vec4 u_hovercolor;
|
|
18227
|
+
uniform vec4 u_selectedcolor;
|
|
17508
18228
|
|
|
17509
18229
|
out vec4 fragColor;
|
|
17510
18230
|
|
|
@@ -17561,11 +18281,12 @@ class ShaderManager {
|
|
|
17561
18281
|
#endif
|
|
17562
18282
|
|
|
17563
18283
|
if (v_selected == 1.0){
|
|
17564
|
-
|
|
17565
|
-
fragColor = vec4(1.0, 0.0, 0.0, 1.0) * (alpha);
|
|
18284
|
+
fragColor = u_hovercolor * alpha;
|
|
17566
18285
|
} else if (v_selected == 2.0){
|
|
17567
|
-
//
|
|
17568
|
-
|
|
18286
|
+
// Persistent selection: keep the dataset colour as an outer ring
|
|
18287
|
+
// and use the hover colour for the fill. This remains visible for
|
|
18288
|
+
// both light and dark user-selected base colours.
|
|
18289
|
+
fragColor = (r > 0.72 ? u_fragcolor : u_hovercolor) * alpha;
|
|
17569
18290
|
}else{
|
|
17570
18291
|
if (r < 0.4) {
|
|
17571
18292
|
discard;
|
|
@@ -17973,6 +18694,7 @@ class XYZShaderProgram {
|
|
|
17973
18694
|
_shaderProgram;
|
|
17974
18695
|
_colorMapBlockIndex = null;
|
|
17975
18696
|
_colorMapBuffer = null;
|
|
18697
|
+
_opacity = 1;
|
|
17976
18698
|
_runtimeColorMap;
|
|
17977
18699
|
_colorMapVariableInfo = {
|
|
17978
18700
|
r_palette: { index: 0, offset: 0 },
|
|
@@ -17987,6 +18709,7 @@ class XYZShaderProgram {
|
|
|
17987
18709
|
vMatrix: null,
|
|
17988
18710
|
sampler: null,
|
|
17989
18711
|
colorMapIdx: null,
|
|
18712
|
+
opacity: null,
|
|
17990
18713
|
vertexPositionAttribute: -1,
|
|
17991
18714
|
textureCoordAttribute: -1,
|
|
17992
18715
|
};
|
|
@@ -18007,6 +18730,9 @@ class XYZShaderProgram {
|
|
|
18007
18730
|
enableProgram() {
|
|
18008
18731
|
this._webgl.useProgram(this.shaderProgram);
|
|
18009
18732
|
}
|
|
18733
|
+
setOpacity(opacity) {
|
|
18734
|
+
this._opacity = Math.min(1, Math.max(0, opacity));
|
|
18735
|
+
}
|
|
18010
18736
|
setRuntimeColorMap(colorMap) {
|
|
18011
18737
|
this._runtimeColorMap = colorMap;
|
|
18012
18738
|
}
|
|
@@ -18019,6 +18745,7 @@ class XYZShaderProgram {
|
|
|
18019
18745
|
this.locations.vMatrix = gl.getUniformLocation(program, 'uVMatrix');
|
|
18020
18746
|
this.locations.sampler = gl.getUniformLocation(program, 'uSampler');
|
|
18021
18747
|
this.locations.colorMapIdx = gl.getUniformLocation(program, 'cmapIdx');
|
|
18748
|
+
this.locations.opacity = gl.getUniformLocation(program, 'uOpacity');
|
|
18022
18749
|
this.locations.vertexPositionAttribute = gl.getAttribLocation(program, 'aVertexPosition');
|
|
18023
18750
|
this.locations.textureCoordAttribute = gl.getAttribLocation(program, 'aTextureCoord');
|
|
18024
18751
|
gl.uniformMatrix4fv(this.locations.pMatrix, false, pMatrix);
|
|
@@ -18026,6 +18753,7 @@ class XYZShaderProgram {
|
|
|
18026
18753
|
gl.uniformMatrix4fv(this.locations.mMatrix, false, mMatrix);
|
|
18027
18754
|
gl.uniform1i(this.locations.sampler, 0);
|
|
18028
18755
|
gl.uniform1i(this.locations.colorMapIdx, colorMapIdx);
|
|
18756
|
+
gl.uniform1f(this.locations.opacity, this._opacity);
|
|
18029
18757
|
if (colorMapIdx >= 2) {
|
|
18030
18758
|
this.uploadColorMap(colorMapIdx);
|
|
18031
18759
|
}
|
|
@@ -18048,6 +18776,7 @@ class XYZShaderProgram {
|
|
|
18048
18776
|
in vec2 vTextureCoord;
|
|
18049
18777
|
uniform sampler2D uSampler;
|
|
18050
18778
|
uniform int cmapIdx;
|
|
18779
|
+
uniform float uOpacity;
|
|
18051
18780
|
|
|
18052
18781
|
layout (std140) uniform colormap {
|
|
18053
18782
|
float r_palette[256];
|
|
@@ -18062,7 +18791,7 @@ class XYZShaderProgram {
|
|
|
18062
18791
|
|
|
18063
18792
|
if (cmapIdx == 1) {
|
|
18064
18793
|
float gray = 0.21 * color.r + 0.71 * color.g + 0.07 * color.b;
|
|
18065
|
-
outColor = vec4(vec3(gray), color.a);
|
|
18794
|
+
outColor = vec4(vec3(gray), color.a * uOpacity);
|
|
18066
18795
|
return;
|
|
18067
18796
|
}
|
|
18068
18797
|
|
|
@@ -18075,12 +18804,12 @@ class XYZShaderProgram {
|
|
|
18075
18804
|
r_palette[rIndex] / 256.0,
|
|
18076
18805
|
g_palette[gIndex] / 256.0,
|
|
18077
18806
|
b_palette[bIndex] / 256.0,
|
|
18078
|
-
color.a
|
|
18807
|
+
color.a * uOpacity
|
|
18079
18808
|
);
|
|
18080
18809
|
return;
|
|
18081
18810
|
}
|
|
18082
18811
|
|
|
18083
|
-
outColor = color;
|
|
18812
|
+
outColor = vec4(color.rgb, color.a * uOpacity);
|
|
18084
18813
|
}`);
|
|
18085
18814
|
gl.attachShader(this._shaderProgram, vertexShader);
|
|
18086
18815
|
gl.attachShader(this._shaderProgram, fragmentShader);
|
|
@@ -19291,7 +20020,6 @@ exports["default"] = STCSParser;
|
|
|
19291
20020
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
19292
20021
|
|
|
19293
20022
|
"use strict";
|
|
19294
|
-
var __webpack_unused_export__;
|
|
19295
20023
|
|
|
19296
20024
|
/*
|
|
19297
20025
|
* AstroViewer
|
|
@@ -19303,9 +20031,10 @@ var __webpack_unused_export__;
|
|
|
19303
20031
|
*
|
|
19304
20032
|
* See LICENSE.md, LICENSE-AGPL.md, and LICENSE-COMMERCIAL.md for details.
|
|
19305
20033
|
*/
|
|
19306
|
-
|
|
20034
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
19307
20035
|
exports.cartesianToSpherical = cartesianToSpherical;
|
|
19308
20036
|
exports.colorHex2RGB = colorHex2RGB;
|
|
20037
|
+
exports.interactionColorsFromHex = interactionColorsFromHex;
|
|
19309
20038
|
exports.degToRad = degToRad;
|
|
19310
20039
|
exports.radToDeg = radToDeg;
|
|
19311
20040
|
exports.sphericalToAstroDeg = sphericalToAstroDeg;
|
|
@@ -19313,6 +20042,8 @@ exports.sphericalToCartesian = sphericalToCartesian;
|
|
|
19313
20042
|
exports.astroDegToSpherical = astroDegToSpherical;
|
|
19314
20043
|
exports.raDegToHMS = raDegToHMS;
|
|
19315
20044
|
exports.decDegToDMS = decDegToDMS;
|
|
20045
|
+
exports.raHMSToDeg = raHMSToDeg;
|
|
20046
|
+
exports.decDMSToDeg = decDMSToDeg;
|
|
19316
20047
|
/**
|
|
19317
20048
|
* @author Fabrizio Giordano (Fab)
|
|
19318
20049
|
*/
|
|
@@ -19343,6 +20074,25 @@ function colorHex2RGB(hexColor) {
|
|
|
19343
20074
|
const rgb3 = (dec3 / 255).toFixed(2);
|
|
19344
20075
|
return [parseFloat(rgb1), parseFloat(rgb2), parseFloat(rgb3)];
|
|
19345
20076
|
}
|
|
20077
|
+
/**
|
|
20078
|
+
* Derive interaction colours from the object's normal colour.
|
|
20079
|
+
* Dark colours move towards white; light colours move towards black.
|
|
20080
|
+
* Selection uses the stronger contrast so selected > hover > normal.
|
|
20081
|
+
*/
|
|
20082
|
+
function interactionColorsFromHex(hexColor) {
|
|
20083
|
+
const base = colorHex2RGB(hexColor);
|
|
20084
|
+
const luminance = 0.2126 * base[0] + 0.7152 * base[1] + 0.0722 * base[2];
|
|
20085
|
+
const target = luminance < 0.55 ? 1.0 : 0.0;
|
|
20086
|
+
const mix = (amount) => [
|
|
20087
|
+
base[0] + (target - base[0]) * amount,
|
|
20088
|
+
base[1] + (target - base[1]) * amount,
|
|
20089
|
+
base[2] + (target - base[2]) * amount,
|
|
20090
|
+
];
|
|
20091
|
+
return {
|
|
20092
|
+
hover: mix(0.45),
|
|
20093
|
+
selected: mix(0.45),
|
|
20094
|
+
};
|
|
20095
|
+
}
|
|
19346
20096
|
function degToRad(degrees) {
|
|
19347
20097
|
return (degrees / 180) * Math.PI;
|
|
19348
20098
|
}
|
|
@@ -19389,6 +20139,13 @@ function decDegToDMS(decDeg) {
|
|
|
19389
20139
|
d = d * sign;
|
|
19390
20140
|
return { d, m, s };
|
|
19391
20141
|
}
|
|
20142
|
+
function raHMSToDeg(hms) {
|
|
20143
|
+
return 15 * (hms.h + hms.m / 60 + hms.s / 3600);
|
|
20144
|
+
}
|
|
20145
|
+
function decDMSToDeg(dms) {
|
|
20146
|
+
const sign = dms.d < 0 || Object.is(dms.d, -0) ? -1 : 1;
|
|
20147
|
+
return sign * (Math.abs(dms.d) + dms.m / 60 + dms.s / 3600);
|
|
20148
|
+
}
|
|
19392
20149
|
|
|
19393
20150
|
|
|
19394
20151
|
/***/ },
|