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.cjs
CHANGED
|
@@ -43,6 +43,7 @@ __webpack_require__.d(vec3_namespaceObject, {
|
|
|
43
43
|
dot: () => (dot),
|
|
44
44
|
fromValues: () => (vec3_fromValues),
|
|
45
45
|
length: () => (vec3_length),
|
|
46
|
+
lerp: () => (lerp),
|
|
46
47
|
normalize: () => (normalize),
|
|
47
48
|
scale: () => (vec3_scale),
|
|
48
49
|
scaleAndAdd: () => (scaleAndAdd),
|
|
@@ -3629,12 +3630,18 @@ class AstroSphere {
|
|
|
3629
3630
|
_activeHiPS = null;
|
|
3630
3631
|
_activeHiPSLayers = [];
|
|
3631
3632
|
_activeXYZ2 = null;
|
|
3633
|
+
_earthRasterOverlays = [];
|
|
3634
|
+
_earthRasterOverlaySequence = 0;
|
|
3632
3635
|
_activeMeshHiPS = null;
|
|
3633
3636
|
_activeBaseLayer = null;
|
|
3637
|
+
_activeDomain = "astronomy";
|
|
3638
|
+
domainCameraStates = {};
|
|
3634
3639
|
startup = true;
|
|
3635
3640
|
fov;
|
|
3636
|
-
|
|
3637
|
-
|
|
3641
|
+
astronomyCatalogues = [];
|
|
3642
|
+
earthPointSets = [];
|
|
3643
|
+
astronomyFootprintSets = [];
|
|
3644
|
+
earthFootprintSets = [];
|
|
3638
3645
|
activePolylineSets = [];
|
|
3639
3646
|
activeSensorCones = [];
|
|
3640
3647
|
activeSatelliteObjects = [];
|
|
@@ -3867,9 +3874,7 @@ class AstroSphere {
|
|
|
3867
3874
|
return true;
|
|
3868
3875
|
}
|
|
3869
3876
|
emitCameraChanged(reason) {
|
|
3870
|
-
//
|
|
3871
|
-
if (!this._activeHiPS && !this._activeXYZ2 && !this._activeMeshHiPS)
|
|
3872
|
-
return;
|
|
3877
|
+
// Camera interaction remains meaningful even when no base layer is active.
|
|
3873
3878
|
if (!this._healpixGrid?.fovObj)
|
|
3874
3879
|
return;
|
|
3875
3880
|
const detail = this.getCurrentStatus();
|
|
@@ -3895,6 +3900,7 @@ class AstroSphere {
|
|
|
3895
3900
|
const handleMouseDown = (event) => {
|
|
3896
3901
|
canvas.setPointerCapture(event.pointerId);
|
|
3897
3902
|
this.mouseDown = true;
|
|
3903
|
+
this._camera.cancelFlyTo();
|
|
3898
3904
|
const rect = canvas.getBoundingClientRect();
|
|
3899
3905
|
this.lastMouseX = event.clientX - rect.left; // locale al canvas
|
|
3900
3906
|
this.lastMouseY = event.clientY - rect.top; // locale al canvas
|
|
@@ -3933,8 +3939,11 @@ class AstroSphere {
|
|
|
3933
3939
|
if (mousePoint && mousePoint.length > 0) {
|
|
3934
3940
|
this.mouseHelper.update(mousePoint);
|
|
3935
3941
|
this.updateLastMousePoint();
|
|
3936
|
-
for (const cat of this.
|
|
3937
|
-
const
|
|
3942
|
+
for (const cat of this.getActivePointSets()) {
|
|
3943
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
3944
|
+
if (!activeModelMatrix)
|
|
3945
|
+
continue;
|
|
3946
|
+
const clickResult = cat.selectPrimarySourceFromClick(this.mouseHelper, activeModelMatrix, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
3938
3947
|
if (!clickResult?.sources.length)
|
|
3939
3948
|
continue;
|
|
3940
3949
|
this._webgl.canvas.dispatchEvent(new CustomEvent("source-clicked", {
|
|
@@ -3947,7 +3956,7 @@ class AstroSphere {
|
|
|
3947
3956
|
composed: true,
|
|
3948
3957
|
}));
|
|
3949
3958
|
}
|
|
3950
|
-
for (const fset of this.
|
|
3959
|
+
for (const fset of this.getActiveFootprintSets()) {
|
|
3951
3960
|
const clickResult = fset.selectPrimaryFootprintFromClick(this.mouseHelper);
|
|
3952
3961
|
if (!clickResult?.footprints.length)
|
|
3953
3962
|
continue;
|
|
@@ -4021,6 +4030,7 @@ class AstroSphere {
|
|
|
4021
4030
|
const handleMouseWheel = (event) => {
|
|
4022
4031
|
const currentFov = this._healpixGrid.getMinFoV();
|
|
4023
4032
|
const zoomStep = this.computeZoomStep(currentFov, event.deltaY);
|
|
4033
|
+
this._camera.cancelFlyTo();
|
|
4024
4034
|
// Apply wheel zoom immediately and discard any queued inertia so reversing
|
|
4025
4035
|
// direction feels responsive instead of "buffered".
|
|
4026
4036
|
this.zoomInertia = 0;
|
|
@@ -4043,8 +4053,11 @@ class AstroSphere {
|
|
|
4043
4053
|
}
|
|
4044
4054
|
this.mouseHelper.update(mousePoint);
|
|
4045
4055
|
this.updateLastMousePoint();
|
|
4046
|
-
for (const cat of this.
|
|
4047
|
-
const
|
|
4056
|
+
for (const cat of this.getActivePointSets()) {
|
|
4057
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4058
|
+
if (!activeModelMatrix)
|
|
4059
|
+
continue;
|
|
4060
|
+
const pickResult = cat.getSourcesFromPointer(this.mouseHelper, activeModelMatrix, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
4048
4061
|
if (!pickResult?.sources.length)
|
|
4049
4062
|
continue;
|
|
4050
4063
|
this._webgl.canvas.dispatchEvent(new CustomEvent("source-contextmenu", {
|
|
@@ -4059,7 +4072,7 @@ class AstroSphere {
|
|
|
4059
4072
|
}));
|
|
4060
4073
|
break;
|
|
4061
4074
|
}
|
|
4062
|
-
for (const fset of this.
|
|
4075
|
+
for (const fset of this.getActiveFootprintSets()) {
|
|
4063
4076
|
const pickResult = fset.getFootprintsFromPointer(this.mouseHelper);
|
|
4064
4077
|
if (!pickResult?.footprints.length)
|
|
4065
4078
|
continue;
|
|
@@ -4149,19 +4162,22 @@ class AstroSphere {
|
|
|
4149
4162
|
return new HiPS_js_1.HiPS(1, [0.0, 0.0, 0.0], 0, 0, hipsDescriptor, this._webgl, this._healpixGrid);
|
|
4150
4163
|
}
|
|
4151
4164
|
activateHiPS(hipsDescriptor) {
|
|
4165
|
+
if (this._activeHiPSLayers.length > 0) {
|
|
4166
|
+
throw new Error("Cannot load a HiPS base layer while stacked layers are active.");
|
|
4167
|
+
}
|
|
4152
4168
|
const tileBuffer = this._healpixGrid.visibleTilesManager.tileBuffer;
|
|
4153
|
-
|
|
4154
|
-
tileBuffer.removeHiPS(
|
|
4169
|
+
if (this._activeHiPS) {
|
|
4170
|
+
tileBuffer.removeHiPS(this._activeHiPS);
|
|
4155
4171
|
}
|
|
4156
|
-
this._activeHiPSLayers = [];
|
|
4157
4172
|
const hips = this.createHiPS(hipsDescriptor);
|
|
4158
|
-
this._activeHiPSLayers.push(hips);
|
|
4159
4173
|
this._activeHiPS = hips;
|
|
4174
|
+
this._activeDomain = "astronomy";
|
|
4160
4175
|
this._activeBaseLayer = "hips";
|
|
4161
4176
|
return hips;
|
|
4162
4177
|
}
|
|
4163
4178
|
setHiPSOpacity(hips, opacity) {
|
|
4164
|
-
|
|
4179
|
+
const isBaseLayer = this._activeHiPSLayers.length === 0 && this._activeHiPS === hips;
|
|
4180
|
+
if (!isBaseLayer && !this._activeHiPSLayers.includes(hips)) {
|
|
4165
4181
|
throw new Error("HiPS layer is not active in this AstroSphere.");
|
|
4166
4182
|
}
|
|
4167
4183
|
hips.setOpacity(opacity);
|
|
@@ -4169,6 +4185,13 @@ class AstroSphere {
|
|
|
4169
4185
|
addHiPS(hipsDescriptor) {
|
|
4170
4186
|
const normalizeURL = (url) => String(url).replace(/\/+$/, "");
|
|
4171
4187
|
const descriptorURL = normalizeURL(hipsDescriptor.url);
|
|
4188
|
+
// Entering stack mode discards the standalone base HiPS. Base mode and
|
|
4189
|
+
// stack mode are intentionally mutually exclusive.
|
|
4190
|
+
if (this._activeHiPSLayers.length === 0 && this._activeHiPS) {
|
|
4191
|
+
const tileBuffer = this._healpixGrid.visibleTilesManager.tileBuffer;
|
|
4192
|
+
tileBuffer.removeHiPS(this._activeHiPS);
|
|
4193
|
+
this._activeHiPS = null;
|
|
4194
|
+
}
|
|
4172
4195
|
const existing = this._activeHiPSLayers.find((hips) => normalizeURL(hips.baseURL) === descriptorURL);
|
|
4173
4196
|
if (existing) {
|
|
4174
4197
|
throw new Error(`HiPS already active: ${String(hipsDescriptor.url)}`);
|
|
@@ -4176,6 +4199,7 @@ class AstroSphere {
|
|
|
4176
4199
|
const hips = this.createHiPS(hipsDescriptor);
|
|
4177
4200
|
this._activeHiPSLayers.push(hips);
|
|
4178
4201
|
this._activeHiPS = hips;
|
|
4202
|
+
this._activeDomain = "astronomy";
|
|
4179
4203
|
this._activeBaseLayer = "hips";
|
|
4180
4204
|
return hips;
|
|
4181
4205
|
}
|
|
@@ -4200,8 +4224,13 @@ class AstroSphere {
|
|
|
4200
4224
|
}
|
|
4201
4225
|
removeAllHiPS() {
|
|
4202
4226
|
const tileBuffer = this._healpixGrid.visibleTilesManager.tileBuffer;
|
|
4203
|
-
|
|
4204
|
-
tileBuffer.removeHiPS(
|
|
4227
|
+
if (this._activeHiPSLayers.length === 0 && this._activeHiPS) {
|
|
4228
|
+
tileBuffer.removeHiPS(this._activeHiPS);
|
|
4229
|
+
}
|
|
4230
|
+
else {
|
|
4231
|
+
for (const hips of this._activeHiPSLayers) {
|
|
4232
|
+
tileBuffer.removeHiPS(hips);
|
|
4233
|
+
}
|
|
4205
4234
|
}
|
|
4206
4235
|
this._activeHiPSLayers = [];
|
|
4207
4236
|
this._activeHiPS = null;
|
|
@@ -4214,39 +4243,169 @@ class AstroSphere {
|
|
|
4214
4243
|
this._activeBaseLayer = "xyz";
|
|
4215
4244
|
}
|
|
4216
4245
|
activateXYZ2(config) {
|
|
4246
|
+
this._activeDomain = "earth";
|
|
4217
4247
|
this._activeXYZ2 = new XYZMap_js_1.XYZMap(1, [0.0, 0.0, 0.0], 0, 0, config, this._webgl, this.gridLabelContainers);
|
|
4218
4248
|
this._activeBaseLayer = "xyz";
|
|
4219
4249
|
}
|
|
4220
4250
|
activateMeshHiPS(descriptor) {
|
|
4251
|
+
this._activeDomain = "mesh";
|
|
4221
4252
|
this._activeMeshHiPS = new MeshHiPS_js_1.MeshHiPS(descriptor.meshRadius, [0.0, 0.0, 0.0], 0, 0, descriptor, this._webgl, this._healpixGrid);
|
|
4222
4253
|
this._activeBaseLayer = "meships";
|
|
4223
4254
|
}
|
|
4255
|
+
setMeshHiPSColor(color) {
|
|
4256
|
+
this._activeMeshHiPS?.setColor(color);
|
|
4257
|
+
}
|
|
4258
|
+
setMeshHiPSWireframe(wireframe) {
|
|
4259
|
+
this._activeMeshHiPS?.setWireframe(wireframe);
|
|
4260
|
+
}
|
|
4224
4261
|
activateWMTS(config) {
|
|
4262
|
+
this._activeDomain = "earth";
|
|
4225
4263
|
const adapter = new WMTSAdapter_js_1.WMTSAdapter(config);
|
|
4226
4264
|
const xyzConfig = adapter.toXYZLayerConfig();
|
|
4227
4265
|
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);
|
|
4228
4266
|
this._activeBaseLayer = "xyz";
|
|
4229
4267
|
}
|
|
4230
|
-
|
|
4268
|
+
addXYZRasterOverlay(config) {
|
|
4269
|
+
const map = new XYZMap_js_1.XYZMap(1, [0.0, 0.0, 0.0], 0, 0, config, this._webgl, this.gridLabelContainers);
|
|
4270
|
+
return this.addEarthRasterOverlay(config.name, "xyz", map);
|
|
4271
|
+
}
|
|
4272
|
+
addWMTSRasterOverlay(config) {
|
|
4273
|
+
const adapter = new WMTSAdapter_js_1.WMTSAdapter(config);
|
|
4274
|
+
const xyzConfig = adapter.toXYZLayerConfig();
|
|
4275
|
+
const name = config.layer ? `WMTS ${config.layer}` : "WMTS Earth Raster Overlay";
|
|
4276
|
+
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);
|
|
4277
|
+
return this.addEarthRasterOverlay(name, "wmts", map);
|
|
4278
|
+
}
|
|
4279
|
+
getEarthRasterOverlays() {
|
|
4280
|
+
return this._earthRasterOverlays.map(({ map: _map, ...overlay }) => ({ ...overlay }));
|
|
4281
|
+
}
|
|
4282
|
+
setEarthRasterOverlayOpacity(id, opacity) {
|
|
4283
|
+
const overlay = this._earthRasterOverlays.find((entry) => entry.id === id);
|
|
4284
|
+
if (!overlay)
|
|
4285
|
+
return;
|
|
4286
|
+
overlay.opacity = Math.min(1, Math.max(0, opacity));
|
|
4287
|
+
overlay.map.setOpacity(overlay.opacity);
|
|
4288
|
+
}
|
|
4289
|
+
setEarthRasterOverlayVisible(id, visible) {
|
|
4290
|
+
const overlay = this._earthRasterOverlays.find((entry) => entry.id === id);
|
|
4291
|
+
if (overlay)
|
|
4292
|
+
overlay.visible = visible;
|
|
4293
|
+
}
|
|
4294
|
+
removeEarthRasterOverlay(id) {
|
|
4295
|
+
this._earthRasterOverlays = this._earthRasterOverlays.filter((entry) => entry.id !== id);
|
|
4296
|
+
}
|
|
4297
|
+
removeAllEarthRasterOverlays() {
|
|
4298
|
+
this._earthRasterOverlays = [];
|
|
4299
|
+
}
|
|
4300
|
+
addEarthRasterOverlay(name, sourceType, map) {
|
|
4301
|
+
const overlay = {
|
|
4302
|
+
id: `earth-raster-${++this._earthRasterOverlaySequence}`,
|
|
4303
|
+
name,
|
|
4304
|
+
sourceType,
|
|
4305
|
+
visible: true,
|
|
4306
|
+
opacity: 0.65,
|
|
4307
|
+
map,
|
|
4308
|
+
};
|
|
4309
|
+
map.setOpacity(overlay.opacity);
|
|
4310
|
+
this._earthRasterOverlays.push(overlay);
|
|
4311
|
+
const { map: _map, ...info } = overlay;
|
|
4312
|
+
return { ...info };
|
|
4313
|
+
}
|
|
4314
|
+
setActiveDomain(domain) {
|
|
4315
|
+
if (domain !== this._activeDomain) {
|
|
4316
|
+
this.clearGridLabelsForDomain(this._activeDomain);
|
|
4317
|
+
this.domainCameraStates[this._activeDomain] = this._camera.getViewState();
|
|
4318
|
+
const targetCameraState = this.domainCameraStates[domain];
|
|
4319
|
+
if (targetCameraState) {
|
|
4320
|
+
this._camera.restoreViewState(targetCameraState);
|
|
4321
|
+
}
|
|
4322
|
+
this.inertiaX = 0;
|
|
4323
|
+
this.inertiaY = 0;
|
|
4324
|
+
this.zoomInertia = 0;
|
|
4325
|
+
this._cameraStatusChanged = true;
|
|
4326
|
+
}
|
|
4327
|
+
this._activeDomain = domain;
|
|
4328
|
+
if (domain === "astronomy") {
|
|
4329
|
+
this._activeBaseLayer = this._activeHiPS ? "hips" : null;
|
|
4330
|
+
}
|
|
4331
|
+
else if (domain === "earth") {
|
|
4332
|
+
this._activeBaseLayer = this._activeXYZ2 ? "xyz" : null;
|
|
4333
|
+
}
|
|
4334
|
+
else {
|
|
4335
|
+
this._activeBaseLayer = this._activeMeshHiPS ? "meships" : null;
|
|
4336
|
+
}
|
|
4337
|
+
// A hover from the previous vertical must not leak into the new one.
|
|
4338
|
+
this.lastHoveredSource = null;
|
|
4339
|
+
this.lastHoveredCatalogue = null;
|
|
4340
|
+
}
|
|
4341
|
+
clearGridLabelsForDomain(domain) {
|
|
4342
|
+
if (domain === "astronomy") {
|
|
4343
|
+
this._healpixGrid?.clearLabels();
|
|
4344
|
+
this._equatorialGrid?.clearLabels();
|
|
4345
|
+
return;
|
|
4346
|
+
}
|
|
4347
|
+
if (domain === "earth") {
|
|
4348
|
+
this._activeXYZ2?.clearLonLatGridLabels?.();
|
|
4349
|
+
}
|
|
4350
|
+
}
|
|
4351
|
+
get activeDomain() {
|
|
4352
|
+
return this._activeDomain;
|
|
4353
|
+
}
|
|
4354
|
+
getActivePointSets() {
|
|
4355
|
+
if (this._activeDomain === "astronomy")
|
|
4356
|
+
return this.astronomyCatalogues;
|
|
4357
|
+
if (this._activeDomain === "earth")
|
|
4358
|
+
return this.earthPointSets;
|
|
4359
|
+
return [];
|
|
4360
|
+
}
|
|
4361
|
+
getActiveFootprintSets() {
|
|
4362
|
+
if (this._activeDomain === "astronomy")
|
|
4363
|
+
return this.astronomyFootprintSets;
|
|
4364
|
+
if (this._activeDomain === "earth")
|
|
4365
|
+
return this.earthFootprintSets;
|
|
4366
|
+
return [];
|
|
4367
|
+
}
|
|
4368
|
+
// Astronomy catalogue ownership
|
|
4231
4369
|
async showCatalogue(cat) {
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4370
|
+
if (cat && !this.astronomyCatalogues.includes(cat)) {
|
|
4371
|
+
this.astronomyCatalogues.push(cat);
|
|
4372
|
+
}
|
|
4235
4373
|
return cat;
|
|
4236
4374
|
}
|
|
4237
4375
|
deleteCatalogue(catalogue) {
|
|
4238
|
-
this.
|
|
4376
|
+
this.astronomyCatalogues = this.astronomyCatalogues.filter((c) => c !== catalogue);
|
|
4239
4377
|
}
|
|
4240
|
-
//
|
|
4241
|
-
//
|
|
4378
|
+
// Earth point-set ownership. TerraPointSetGL still extends CatalogueGL in
|
|
4379
|
+
// 3.12, but it no longer shares the Astronomy lifecycle collection.
|
|
4380
|
+
async showTerraPointSet(pointSet) {
|
|
4381
|
+
if (pointSet && !this.earthPointSets.includes(pointSet)) {
|
|
4382
|
+
this.earthPointSets.push(pointSet);
|
|
4383
|
+
}
|
|
4384
|
+
return pointSet;
|
|
4385
|
+
}
|
|
4386
|
+
deleteTerraPointSet(pointSet) {
|
|
4387
|
+
this.earthPointSets = this.earthPointSets.filter((set) => set !== pointSet);
|
|
4388
|
+
}
|
|
4389
|
+
// Astronomy footprint ownership
|
|
4242
4390
|
async showFootprintSet(fset) {
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4391
|
+
if (fset && !this.astronomyFootprintSets.includes(fset)) {
|
|
4392
|
+
this.astronomyFootprintSets.push(fset);
|
|
4393
|
+
}
|
|
4246
4394
|
return fset;
|
|
4247
4395
|
}
|
|
4248
4396
|
deleteFootprintSet(footprintSet) {
|
|
4249
|
-
this.
|
|
4397
|
+
this.astronomyFootprintSets = this.astronomyFootprintSets.filter((fst) => fst !== footprintSet);
|
|
4398
|
+
}
|
|
4399
|
+
// Earth footprint ownership. TerraFootprintSetGL still reuses the common
|
|
4400
|
+
// FootprintSetGL rendering implementation, but has an independent lifecycle.
|
|
4401
|
+
async showTerraFootprintSet(footprintSet) {
|
|
4402
|
+
if (footprintSet && !this.earthFootprintSets.includes(footprintSet)) {
|
|
4403
|
+
this.earthFootprintSets.push(footprintSet);
|
|
4404
|
+
}
|
|
4405
|
+
return footprintSet;
|
|
4406
|
+
}
|
|
4407
|
+
deleteTerraFootprintSet(footprintSet) {
|
|
4408
|
+
this.earthFootprintSets = this.earthFootprintSets.filter((fst) => fst !== footprintSet);
|
|
4250
4409
|
}
|
|
4251
4410
|
async showPolylineSet(polylineSet) {
|
|
4252
4411
|
if (polylineSet)
|
|
@@ -4276,8 +4435,8 @@ class AstroSphere {
|
|
|
4276
4435
|
satelliteObject.dispose();
|
|
4277
4436
|
}
|
|
4278
4437
|
getHoveredFootprints() {
|
|
4279
|
-
|
|
4280
|
-
this.
|
|
4438
|
+
const footprintsHovered = [];
|
|
4439
|
+
this.getActiveFootprintSets().forEach((fset) => {
|
|
4281
4440
|
footprintsHovered.push(fset.hoveredFootprints);
|
|
4282
4441
|
});
|
|
4283
4442
|
return footprintsHovered;
|
|
@@ -4286,6 +4445,9 @@ class AstroSphere {
|
|
|
4286
4445
|
goTo(raDeg, decDeg) {
|
|
4287
4446
|
this._camera.goTo(raDeg, decDeg);
|
|
4288
4447
|
}
|
|
4448
|
+
flyTo(raDeg, decDeg, durationMs = 1200) {
|
|
4449
|
+
this._camera.flyTo(raDeg, decDeg, durationMs);
|
|
4450
|
+
}
|
|
4289
4451
|
getActiveCoordinateMode() {
|
|
4290
4452
|
if (this._activeBaseLayer === "xyz") {
|
|
4291
4453
|
return "lonlat";
|
|
@@ -4506,8 +4668,6 @@ class AstroSphere {
|
|
|
4506
4668
|
return;
|
|
4507
4669
|
if (!this._webgl)
|
|
4508
4670
|
return;
|
|
4509
|
-
if (!this._activeHiPS && !this._activeXYZ2 && !this._activeMeshHiPS)
|
|
4510
|
-
return;
|
|
4511
4671
|
if (!this._healpixGrid || Object.keys(this._healpixGrid).length === 0)
|
|
4512
4672
|
return;
|
|
4513
4673
|
if (this._healpixGrid.fovObj === undefined)
|
|
@@ -4521,6 +4681,16 @@ class AstroSphere {
|
|
|
4521
4681
|
let PHI = 0;
|
|
4522
4682
|
this._webgl.viewport(0, 0, this._webgl.drawingBufferWidth, this._webgl.drawingBufferHeight);
|
|
4523
4683
|
this._webgl.clear(this._webgl.COLOR_BUFFER_BIT | this._webgl.DEPTH_BUFFER_BIT);
|
|
4684
|
+
const now = performance.now();
|
|
4685
|
+
const cameraFlying = this._camera.updateFlyTo(now);
|
|
4686
|
+
if (cameraFlying) {
|
|
4687
|
+
this.inertiaX = 0;
|
|
4688
|
+
this.inertiaY = 0;
|
|
4689
|
+
this.lastCameraMotionAt = now;
|
|
4690
|
+
this._cameraStatusChanged = true;
|
|
4691
|
+
this.updateCentralPoint();
|
|
4692
|
+
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);
|
|
4693
|
+
}
|
|
4524
4694
|
// Zoom inertia
|
|
4525
4695
|
if (this.zoomInertia !== 0) {
|
|
4526
4696
|
if (Math.abs(this.zoomInertia) > 0.0001) {
|
|
@@ -4609,8 +4779,10 @@ class AstroSphere {
|
|
|
4609
4779
|
this._webgl.enable(this._webgl.CULL_FACE);
|
|
4610
4780
|
this._webgl.cullFace(Global_js_1.default.insideSphere ? this._webgl.FRONT : this._webgl.BACK);
|
|
4611
4781
|
this._webgl.blendFunc(this._webgl.SRC_ALPHA, this._webgl.ONE_MINUS_SRC_ALPHA);
|
|
4612
|
-
if (this._activeBaseLayer === "hips" && this.
|
|
4613
|
-
const maxHiPSOrder =
|
|
4782
|
+
if (this._activeBaseLayer === "hips" && this._activeHiPS) {
|
|
4783
|
+
const maxHiPSOrder = this._activeHiPSLayers.length > 0
|
|
4784
|
+
? Math.max(...this._activeHiPSLayers.map((hips) => hips.maxOrder))
|
|
4785
|
+
: this._activeHiPS.maxOrder;
|
|
4614
4786
|
const visibleOrder = Math.min(this._healpixGrid.visibleorder, maxHiPSOrder);
|
|
4615
4787
|
this._healpixGrid.visibleTilesManager.computeVisiblePixels(visibleOrder, this._webgl, this._camera, this._perspectiveMatrixManager.pMatrix);
|
|
4616
4788
|
}
|
|
@@ -4645,12 +4817,19 @@ class AstroSphere {
|
|
|
4645
4817
|
}
|
|
4646
4818
|
if (this._activeBaseLayer === "xyz") {
|
|
4647
4819
|
this._activeXYZ2?.draw(skyEntityDrawInput);
|
|
4820
|
+
for (const overlay of this._earthRasterOverlays) {
|
|
4821
|
+
if (overlay.visible) {
|
|
4822
|
+
overlay.map.draw(skyEntityDrawInput, true);
|
|
4823
|
+
}
|
|
4824
|
+
}
|
|
4648
4825
|
}
|
|
4649
4826
|
if (this._activeBaseLayer === "meships") {
|
|
4650
4827
|
this._activeMeshHiPS?.draw(skyEntityDrawInput);
|
|
4651
4828
|
}
|
|
4652
|
-
this.
|
|
4653
|
-
|
|
4829
|
+
if (this._activeDomain === "astronomy") {
|
|
4830
|
+
this._healpixGrid.draw(skyEntityDrawInput);
|
|
4831
|
+
this._equatorialGrid.draw(skyEntityDrawInput);
|
|
4832
|
+
}
|
|
4654
4833
|
this._webgl.enable(this._webgl.DEPTH_TEST);
|
|
4655
4834
|
this._webgl.disable(this._webgl.CULL_FACE);
|
|
4656
4835
|
if (this.startup) {
|
|
@@ -4669,52 +4848,53 @@ class AstroSphere {
|
|
|
4669
4848
|
decDMS,
|
|
4670
4849
|
});
|
|
4671
4850
|
}
|
|
4672
|
-
this.
|
|
4673
|
-
const activeModelMatrix = this.
|
|
4674
|
-
this._activeXYZ2?.getModelMatrix() ??
|
|
4675
|
-
this._activeMeshHiPS?.getModelMatrix();
|
|
4851
|
+
this.getActivePointSets().forEach((cat) => {
|
|
4852
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4676
4853
|
if (activeModelMatrix) {
|
|
4677
4854
|
cat.draw(activeModelMatrix, this.mouseHelper, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
4678
4855
|
}
|
|
4679
4856
|
});
|
|
4680
4857
|
this.emitHoveredSourceIfChanged();
|
|
4681
|
-
this.
|
|
4682
|
-
const activeModelMatrix = this.
|
|
4683
|
-
this._activeXYZ2?.getModelMatrix() ??
|
|
4684
|
-
this._activeMeshHiPS?.getModelMatrix();
|
|
4858
|
+
this.getActiveFootprintSets().forEach((fst) => {
|
|
4859
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4685
4860
|
if (activeModelMatrix) {
|
|
4686
4861
|
fst.draw(activeModelMatrix, this.mouseHelper, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
4687
4862
|
}
|
|
4688
4863
|
});
|
|
4689
|
-
this.
|
|
4690
|
-
|
|
4691
|
-
this.
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
}
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4864
|
+
if (this._activeDomain === "earth") {
|
|
4865
|
+
this.activePolylineSets.forEach((polylineSet) => {
|
|
4866
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4867
|
+
if (activeModelMatrix) {
|
|
4868
|
+
polylineSet.draw(activeModelMatrix, this.mouseHelper, this._camera.getCameraMatrix(), this._perspectiveMatrixManager.pMatrix);
|
|
4869
|
+
}
|
|
4870
|
+
});
|
|
4871
|
+
this.activeSensorCones.forEach((sensorCone) => {
|
|
4872
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4873
|
+
if (activeModelMatrix) {
|
|
4874
|
+
sensorCone.draw(this._perspectiveMatrixManager.pMatrix, this._camera.getCameraMatrix(), activeModelMatrix);
|
|
4875
|
+
}
|
|
4876
|
+
});
|
|
4877
|
+
this.activeSatelliteObjects.forEach((satelliteObject) => {
|
|
4878
|
+
const activeModelMatrix = this.getActiveDomainModelMatrix();
|
|
4879
|
+
if (activeModelMatrix) {
|
|
4880
|
+
satelliteObject.draw(this._perspectiveMatrixManager.pMatrix, this._camera.getCameraMatrix(), activeModelMatrix);
|
|
4881
|
+
}
|
|
4882
|
+
});
|
|
4883
|
+
}
|
|
4884
|
+
}
|
|
4885
|
+
getActiveDomainModelMatrix() {
|
|
4886
|
+
if (this._activeDomain === "astronomy") {
|
|
4887
|
+
return (this._activeHiPS?.getModelMatrix() ?? this._healpixGrid.getModelMatrix());
|
|
4888
|
+
}
|
|
4889
|
+
if (this._activeDomain === "earth") {
|
|
4890
|
+
return (this._activeXYZ2?.getModelMatrix() ?? this._healpixGrid.getModelMatrix());
|
|
4891
|
+
}
|
|
4892
|
+
return (this._activeMeshHiPS?.getModelMatrix() ?? this._healpixGrid.getModelMatrix());
|
|
4713
4893
|
}
|
|
4714
4894
|
emitHoveredSourceIfChanged() {
|
|
4715
4895
|
let nextHoveredSource = null;
|
|
4716
4896
|
let nextHoveredCatalogue = null;
|
|
4717
|
-
for (const cat of this.
|
|
4897
|
+
for (const cat of this.getActivePointSets()) {
|
|
4718
4898
|
const hovered = cat.getPrimaryHoveredSource();
|
|
4719
4899
|
if (!hovered)
|
|
4720
4900
|
continue;
|
|
@@ -4842,25 +5022,25 @@ class AstroViewer {
|
|
|
4842
5022
|
return new TerraPointSetGL_js_1.TerraPointSetGL(pointSetName, pointSetDescription, providerUrl, metadataManager, this.webgl, this.astroSphere.healpixGrid.visibleTilesManager);
|
|
4843
5023
|
}
|
|
4844
5024
|
showTerraPointSet(pointSet) {
|
|
4845
|
-
this.astroSphere.
|
|
5025
|
+
this.astroSphere.showTerraPointSet(pointSet);
|
|
4846
5026
|
}
|
|
4847
5027
|
hideTerraPointSet(pointSet, isVisible) {
|
|
4848
5028
|
pointSet.setIsVisible(isVisible);
|
|
4849
5029
|
}
|
|
4850
5030
|
deleteTerraPointSet(pointSet) {
|
|
4851
|
-
this.astroSphere.
|
|
5031
|
+
this.astroSphere.deleteTerraPointSet(pointSet);
|
|
4852
5032
|
}
|
|
4853
5033
|
createTerraFootprintSet(footprintSetName, footprintSetDescription, providerUrl, metadataManager) {
|
|
4854
5034
|
return new TerraFootprintSetGL_js_1.TerraFootprintSetGL(footprintSetName, footprintSetDescription, providerUrl, metadataManager, this.webgl);
|
|
4855
5035
|
}
|
|
4856
5036
|
showTerraFootprintSet(footprintSet) {
|
|
4857
|
-
this.astroSphere.
|
|
5037
|
+
this.astroSphere.showTerraFootprintSet(footprintSet);
|
|
4858
5038
|
}
|
|
4859
5039
|
hideTerraFootprintSet(footprintSet, isVisible) {
|
|
4860
5040
|
footprintSet.setIsVisible(isVisible);
|
|
4861
5041
|
}
|
|
4862
5042
|
deleteTerraFootprintSet(footprintSet) {
|
|
4863
|
-
this.astroSphere.
|
|
5043
|
+
this.astroSphere.deleteTerraFootprintSet(footprintSet);
|
|
4864
5044
|
}
|
|
4865
5045
|
createTerraPolylineSet(polylineSetName, polylineSetDescription, providerUrl, metadataManager) {
|
|
4866
5046
|
return new TerraPolylineSetGL_js_1.TerraPolylineSetGL(polylineSetName, polylineSetDescription, providerUrl, metadataManager, this.webgl);
|
|
@@ -4913,6 +5093,12 @@ class AstroViewer {
|
|
|
4913
5093
|
getDefaultHiPSURL() {
|
|
4914
5094
|
return Config_js_1.bootSetup.defaultHipsUrl;
|
|
4915
5095
|
}
|
|
5096
|
+
setActiveDomain(domain) {
|
|
5097
|
+
this.astroSphere.setActiveDomain(domain);
|
|
5098
|
+
}
|
|
5099
|
+
getActiveDomain() {
|
|
5100
|
+
return this.astroSphere.activeDomain;
|
|
5101
|
+
}
|
|
4916
5102
|
activateHiPS(hipsDescriptor) {
|
|
4917
5103
|
this.astroSphere.activateHiPS(hipsDescriptor);
|
|
4918
5104
|
}
|
|
@@ -4926,9 +5112,37 @@ class AstroViewer {
|
|
|
4926
5112
|
activateWMTS(config) {
|
|
4927
5113
|
this.astroSphere.activateWMTS(config);
|
|
4928
5114
|
}
|
|
5115
|
+
addXYZRasterOverlay(config) {
|
|
5116
|
+
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);
|
|
5117
|
+
return this.astroSphere.addXYZRasterOverlay(descriptor);
|
|
5118
|
+
}
|
|
5119
|
+
addWMTSRasterOverlay(config) {
|
|
5120
|
+
return this.astroSphere.addWMTSRasterOverlay(config);
|
|
5121
|
+
}
|
|
5122
|
+
getEarthRasterOverlays() {
|
|
5123
|
+
return this.astroSphere.getEarthRasterOverlays();
|
|
5124
|
+
}
|
|
5125
|
+
setEarthRasterOverlayOpacity(id, opacity) {
|
|
5126
|
+
this.astroSphere.setEarthRasterOverlayOpacity(id, opacity);
|
|
5127
|
+
}
|
|
5128
|
+
setEarthRasterOverlayVisible(id, visible) {
|
|
5129
|
+
this.astroSphere.setEarthRasterOverlayVisible(id, visible);
|
|
5130
|
+
}
|
|
5131
|
+
removeEarthRasterOverlay(id) {
|
|
5132
|
+
this.astroSphere.removeEarthRasterOverlay(id);
|
|
5133
|
+
}
|
|
5134
|
+
removeAllEarthRasterOverlays() {
|
|
5135
|
+
this.astroSphere.removeAllEarthRasterOverlays();
|
|
5136
|
+
}
|
|
4929
5137
|
activateMeshHiPS(config) {
|
|
4930
5138
|
this.astroSphere.activateMeshHiPS(new MeshHiPSDescriptor_js_1.MeshHiPSDescriptor(config));
|
|
4931
5139
|
}
|
|
5140
|
+
setMeshHiPSColor(color) {
|
|
5141
|
+
this.astroSphere.setMeshHiPSColor(color);
|
|
5142
|
+
}
|
|
5143
|
+
setMeshHiPSWireframe(wireframe) {
|
|
5144
|
+
this.astroSphere.setMeshHiPSWireframe(wireframe);
|
|
5145
|
+
}
|
|
4932
5146
|
setXYZMaxConcurrentRequests(value) {
|
|
4933
5147
|
XYZTileRequestScheduler_js_1.xyzTileRequestScheduler.setMaxConcurrent(value);
|
|
4934
5148
|
}
|
|
@@ -5051,6 +5265,9 @@ class AstroViewer {
|
|
|
5051
5265
|
// console.log(`AstroViewer.goTo goto(${raDeg}, ${decDeg})`)
|
|
5052
5266
|
this.astroSphere.goTo(raDeg, decDeg);
|
|
5053
5267
|
}
|
|
5268
|
+
flyTo(raDeg, decDeg, durationMs = 1200) {
|
|
5269
|
+
this.astroSphere.flyTo(raDeg, decDeg, durationMs);
|
|
5270
|
+
}
|
|
5054
5271
|
getActiveCoordinateMode() {
|
|
5055
5272
|
return this.astroSphere.getActiveCoordinateMode();
|
|
5056
5273
|
}
|
|
@@ -5372,6 +5589,7 @@ class Camera {
|
|
|
5372
5589
|
lockRotX = false;
|
|
5373
5590
|
lockRotY = false;
|
|
5374
5591
|
lockRotZ = false;
|
|
5592
|
+
flyToAnimation = null;
|
|
5375
5593
|
constructor(in_position, in_sphere) {
|
|
5376
5594
|
this.init(in_position, in_sphere);
|
|
5377
5595
|
}
|
|
@@ -5381,7 +5599,11 @@ class Camera {
|
|
|
5381
5599
|
this.vMatrix = gl_matrix_1.mat4.create();
|
|
5382
5600
|
this.T = gl_matrix_1.mat4.create();
|
|
5383
5601
|
this.R = gl_matrix_1.mat4.create();
|
|
5384
|
-
gl_matrix_1.mat4.translate(this.T, this.T, [
|
|
5602
|
+
gl_matrix_1.mat4.translate(this.T, this.T, [
|
|
5603
|
+
this.cam_pos[0],
|
|
5604
|
+
this.cam_pos[1],
|
|
5605
|
+
this.cam_pos[2],
|
|
5606
|
+
]);
|
|
5385
5607
|
// reset helpers
|
|
5386
5608
|
this.FoV = this.previousFoV = 180.0;
|
|
5387
5609
|
this.move = gl_matrix_1.vec3.clone([0, 0, 0]);
|
|
@@ -5390,11 +5612,15 @@ class Camera {
|
|
|
5390
5612
|
this.goTo(raDeg, decDeg);
|
|
5391
5613
|
}
|
|
5392
5614
|
goTo(raDeg, decDeg) {
|
|
5615
|
+
this.cancelFlyTo();
|
|
5393
5616
|
this.goToPhiTheta((0, Utils_js_1.astroDegToSpherical)(raDeg, decDeg));
|
|
5394
5617
|
}
|
|
5395
5618
|
goToPhiTheta(ptDeg) {
|
|
5396
5619
|
const xyz = (0, Utils_js_1.sphericalToCartesian)(ptDeg.phi, ptDeg.theta, this.cam_pos[2]);
|
|
5397
|
-
|
|
5620
|
+
this.applyCameraPosition(gl_matrix_1.vec3.fromValues(xyz[0], xyz[1], xyz[2]));
|
|
5621
|
+
}
|
|
5622
|
+
applyCameraPosition(cameraPosition) {
|
|
5623
|
+
const targetDirection = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), cameraPosition);
|
|
5398
5624
|
const celestialNorth = gl_matrix_1.vec3.fromValues(0.0, 0.0, 1.0);
|
|
5399
5625
|
const northProjection = gl_matrix_1.vec3.scale(gl_matrix_1.vec3.create(), targetDirection, gl_matrix_1.vec3.dot(celestialNorth, targetDirection));
|
|
5400
5626
|
const cameraUp = gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), celestialNorth, northProjection);
|
|
@@ -5405,9 +5631,13 @@ class Camera {
|
|
|
5405
5631
|
gl_matrix_1.vec3.normalize(cameraUp, cameraUp);
|
|
5406
5632
|
}
|
|
5407
5633
|
let cameraMatrix = gl_matrix_1.mat4.create();
|
|
5408
|
-
cameraMatrix = gl_matrix_1.mat4.translate(cameraMatrix, cameraMatrix,
|
|
5634
|
+
cameraMatrix = gl_matrix_1.mat4.translate(cameraMatrix, cameraMatrix, cameraPosition);
|
|
5409
5635
|
const focusPoint = [0.0, 0.0, 0.0];
|
|
5410
|
-
const cameraPos = [
|
|
5636
|
+
const cameraPos = [
|
|
5637
|
+
cameraMatrix[12],
|
|
5638
|
+
cameraMatrix[13],
|
|
5639
|
+
cameraMatrix[14],
|
|
5640
|
+
];
|
|
5411
5641
|
cameraMatrix = gl_matrix_1.mat4.targetTo(cameraMatrix, cameraPos, focusPoint, cameraUp);
|
|
5412
5642
|
this.R = gl_matrix_1.mat4.clone(cameraMatrix);
|
|
5413
5643
|
this.R[12] = 0;
|
|
@@ -5419,6 +5649,81 @@ class Camera {
|
|
|
5419
5649
|
}
|
|
5420
5650
|
this.vMatrix = viewMatrix;
|
|
5421
5651
|
}
|
|
5652
|
+
flyTo(raDeg, decDeg, durationMs = 1200) {
|
|
5653
|
+
const targetSpherical = (0, Utils_js_1.astroDegToSpherical)(raDeg, decDeg);
|
|
5654
|
+
const targetPositionValues = (0, Utils_js_1.sphericalToCartesian)(targetSpherical.phi, targetSpherical.theta, this.cam_pos[2]);
|
|
5655
|
+
const targetPosition = gl_matrix_1.vec3.fromValues(targetPositionValues[0], targetPositionValues[1], targetPositionValues[2]);
|
|
5656
|
+
const currentPosition = this.getCameraPosition();
|
|
5657
|
+
const startDirection = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), gl_matrix_1.vec3.fromValues(currentPosition[0], currentPosition[1], currentPosition[2]));
|
|
5658
|
+
const targetDirection = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), targetPosition);
|
|
5659
|
+
this.flyToAnimation = {
|
|
5660
|
+
startDirection,
|
|
5661
|
+
targetDirection,
|
|
5662
|
+
targetPosition,
|
|
5663
|
+
startTime: performance.now(),
|
|
5664
|
+
durationMs: Math.max(1, durationMs),
|
|
5665
|
+
};
|
|
5666
|
+
}
|
|
5667
|
+
updateFlyTo(now) {
|
|
5668
|
+
const animation = this.flyToAnimation;
|
|
5669
|
+
if (!animation) {
|
|
5670
|
+
return false;
|
|
5671
|
+
}
|
|
5672
|
+
const elapsed = now - animation.startTime;
|
|
5673
|
+
const progress = Math.min(1, elapsed / animation.durationMs);
|
|
5674
|
+
const easedProgress = progress < 0.5
|
|
5675
|
+
? 4 * progress * progress * progress
|
|
5676
|
+
: 1 - Math.pow(-2 * progress + 2, 3) / 2;
|
|
5677
|
+
const direction = this.slerpDirection(animation.startDirection, animation.targetDirection, easedProgress);
|
|
5678
|
+
const radius = Math.abs(this.cam_pos[2]);
|
|
5679
|
+
const cameraPosition = gl_matrix_1.vec3.scale(gl_matrix_1.vec3.create(), direction, radius);
|
|
5680
|
+
this.applyCameraPosition(cameraPosition);
|
|
5681
|
+
if (progress >= 1) {
|
|
5682
|
+
this.applyCameraPosition(animation.targetPosition);
|
|
5683
|
+
this.flyToAnimation = null;
|
|
5684
|
+
}
|
|
5685
|
+
return true;
|
|
5686
|
+
}
|
|
5687
|
+
slerpDirection(start, end, t) {
|
|
5688
|
+
const dot = Math.max(-1, Math.min(1, gl_matrix_1.vec3.dot(start, end)));
|
|
5689
|
+
/*
|
|
5690
|
+
* For almost identical directions, normalized linear interpolation is
|
|
5691
|
+
* numerically more stable than the general SLERP formula.
|
|
5692
|
+
*/
|
|
5693
|
+
if (dot > 0.999999) {
|
|
5694
|
+
const result = gl_matrix_1.vec3.lerp(gl_matrix_1.vec3.create(), start, end, t);
|
|
5695
|
+
return gl_matrix_1.vec3.normalize(result, result);
|
|
5696
|
+
}
|
|
5697
|
+
/*
|
|
5698
|
+
* The normal SLERP formula becomes singular for antipodal vectors because
|
|
5699
|
+
* sin(pi) = 0. In that case choose a stable vector orthogonal to start and
|
|
5700
|
+
* rotate through that great circle.
|
|
5701
|
+
*/
|
|
5702
|
+
if (dot < -0.999999) {
|
|
5703
|
+
const referenceAxis = Math.abs(start[0]) < 0.9
|
|
5704
|
+
? gl_matrix_1.vec3.fromValues(1, 0, 0)
|
|
5705
|
+
: gl_matrix_1.vec3.fromValues(0, 1, 0);
|
|
5706
|
+
const orthogonal = gl_matrix_1.vec3.cross(gl_matrix_1.vec3.create(), start, referenceAxis);
|
|
5707
|
+
gl_matrix_1.vec3.normalize(orthogonal, orthogonal);
|
|
5708
|
+
const angle = Math.PI * t;
|
|
5709
|
+
const result = gl_matrix_1.vec3.create();
|
|
5710
|
+
gl_matrix_1.vec3.scale(result, start, Math.cos(angle));
|
|
5711
|
+
gl_matrix_1.vec3.scaleAndAdd(result, result, orthogonal, Math.sin(angle));
|
|
5712
|
+
return gl_matrix_1.vec3.normalize(result, result);
|
|
5713
|
+
}
|
|
5714
|
+
const angle = Math.acos(dot);
|
|
5715
|
+
const sinAngle = Math.sin(angle);
|
|
5716
|
+
const startWeight = Math.sin((1 - t) * angle) / sinAngle;
|
|
5717
|
+
const endWeight = Math.sin(t * angle) / sinAngle;
|
|
5718
|
+
const result = gl_matrix_1.vec3.create();
|
|
5719
|
+
result[0] = start[0] * startWeight + end[0] * endWeight;
|
|
5720
|
+
result[1] = start[1] * startWeight + end[1] * endWeight;
|
|
5721
|
+
result[2] = start[2] * startWeight + end[2] * endWeight;
|
|
5722
|
+
return gl_matrix_1.vec3.normalize(result, result);
|
|
5723
|
+
}
|
|
5724
|
+
cancelFlyTo() {
|
|
5725
|
+
this.flyToAnimation = null;
|
|
5726
|
+
}
|
|
5422
5727
|
toggleInsideSphere() {
|
|
5423
5728
|
// if (inside !== global.insideSphere) {
|
|
5424
5729
|
// global.insideSphere = inside;
|
|
@@ -5640,6 +5945,22 @@ class Camera {
|
|
|
5640
5945
|
}
|
|
5641
5946
|
return [inv[12], inv[13], inv[14]];
|
|
5642
5947
|
}
|
|
5948
|
+
getViewState() {
|
|
5949
|
+
return {
|
|
5950
|
+
position: [this.cam_pos[0], this.cam_pos[1], this.cam_pos[2]],
|
|
5951
|
+
viewMatrix: gl_matrix_1.mat4.clone(this.vMatrix),
|
|
5952
|
+
translationMatrix: gl_matrix_1.mat4.clone(this.T),
|
|
5953
|
+
rotationMatrix: gl_matrix_1.mat4.clone(this.R),
|
|
5954
|
+
};
|
|
5955
|
+
}
|
|
5956
|
+
restoreViewState(state) {
|
|
5957
|
+
this.cancelFlyTo();
|
|
5958
|
+
this.cam_pos = gl_matrix_1.vec3.fromValues(...state.position);
|
|
5959
|
+
this.vMatrix = gl_matrix_1.mat4.clone(state.viewMatrix);
|
|
5960
|
+
this.T = gl_matrix_1.mat4.clone(state.translationMatrix);
|
|
5961
|
+
this.R = gl_matrix_1.mat4.clone(state.rotationMatrix);
|
|
5962
|
+
this.move = gl_matrix_1.vec3.create();
|
|
5963
|
+
}
|
|
5643
5964
|
setCameraMatrix(viewMatrix) {
|
|
5644
5965
|
this.vMatrix = viewMatrix;
|
|
5645
5966
|
}
|
|
@@ -5676,9 +5997,15 @@ class Camera {
|
|
|
5676
5997
|
clearRotationLock() {
|
|
5677
5998
|
this.lockRotX = this.lockRotY = this.lockRotZ = false;
|
|
5678
5999
|
}
|
|
5679
|
-
isRotationLockedX() {
|
|
5680
|
-
|
|
5681
|
-
|
|
6000
|
+
isRotationLockedX() {
|
|
6001
|
+
return this.lockRotX;
|
|
6002
|
+
}
|
|
6003
|
+
isRotationLockedY() {
|
|
6004
|
+
return this.lockRotY;
|
|
6005
|
+
}
|
|
6006
|
+
isRotationLockedZ() {
|
|
6007
|
+
return this.lockRotZ;
|
|
6008
|
+
}
|
|
5682
6009
|
}
|
|
5683
6010
|
exports["default"] = Camera;
|
|
5684
6011
|
|
|
@@ -5848,7 +6175,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5848
6175
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5849
6176
|
};
|
|
5850
6177
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
5851
|
-
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;
|
|
6178
|
+
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;
|
|
5852
6179
|
var AstroViewer_js_1 = __webpack_require__(772);
|
|
5853
6180
|
Object.defineProperty(exports, "AstroViewer", ({ enumerable: true, get: function () { return AstroViewer_js_1.AstroViewer; } }));
|
|
5854
6181
|
var HiPSDescriptor_js_1 = __webpack_require__(5087);
|
|
@@ -5889,6 +6216,9 @@ Object.defineProperty(exports, "SphericalOpts", ({ enumerable: true, get: functi
|
|
|
5889
6216
|
Object.defineProperty(exports, "AstroOpts", ({ enumerable: true, get: function () { return Point_js_1.AstroOpts; } }));
|
|
5890
6217
|
Object.defineProperty(exports, "PointInitOpts", ({ enumerable: true, get: function () { return Point_js_1.PointInitOpts; } }));
|
|
5891
6218
|
Object.defineProperty(exports, "CartesianOpts", ({ enumerable: true, get: function () { return Point_js_1.CartesianOpts; } }));
|
|
6219
|
+
var Utils_js_1 = __webpack_require__(7930);
|
|
6220
|
+
Object.defineProperty(exports, "raHMSToDeg", ({ enumerable: true, get: function () { return Utils_js_1.raHMSToDeg; } }));
|
|
6221
|
+
Object.defineProperty(exports, "decDMSToDeg", ({ enumerable: true, get: function () { return Utils_js_1.decDMSToDeg; } }));
|
|
5892
6222
|
var FoVUtils_js_1 = __webpack_require__(8083);
|
|
5893
6223
|
Object.defineProperty(exports, "FoVUtils", ({ enumerable: true, get: function () { return FoVUtils_js_1.FoVUtils; } }));
|
|
5894
6224
|
var CoordsType_js_1 = __webpack_require__(8145);
|
|
@@ -7880,6 +8210,7 @@ class Source {
|
|
|
7880
8210
|
_h_pix;
|
|
7881
8211
|
_shapesize;
|
|
7882
8212
|
_brightnessFactor;
|
|
8213
|
+
_mediaStyle;
|
|
7883
8214
|
/**
|
|
7884
8215
|
* @param in_point Point.js (Cartesian/RA-Dec wrapper)
|
|
7885
8216
|
* @param in_details Optional array of key/value metadata
|
|
@@ -7888,7 +8219,7 @@ class Source {
|
|
|
7888
8219
|
this._point = in_point;
|
|
7889
8220
|
this._details = in_details;
|
|
7890
8221
|
this._shapesize = 16.0;
|
|
7891
|
-
this._brightnessFactor =
|
|
8222
|
+
this._brightnessFactor = 3.0;
|
|
7892
8223
|
this.computeHealpixPixel();
|
|
7893
8224
|
}
|
|
7894
8225
|
getDetailByindex(index) {
|
|
@@ -7932,6 +8263,12 @@ class Source {
|
|
|
7932
8263
|
set brightnessFactor(factor) {
|
|
7933
8264
|
this._brightnessFactor = factor;
|
|
7934
8265
|
}
|
|
8266
|
+
get mediaStyle() {
|
|
8267
|
+
return this._mediaStyle;
|
|
8268
|
+
}
|
|
8269
|
+
set mediaStyle(style) {
|
|
8270
|
+
this._mediaStyle = style;
|
|
8271
|
+
}
|
|
7935
8272
|
}
|
|
7936
8273
|
exports.Source = Source;
|
|
7937
8274
|
|
|
@@ -8157,6 +8494,9 @@ exports.SphereFoV = SphereFoV;
|
|
|
8157
8494
|
*
|
|
8158
8495
|
* See LICENSE.md, LICENSE-AGPL.md, and LICENSE-COMMERCIAL.md for details.
|
|
8159
8496
|
*/
|
|
8497
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8498
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8499
|
+
};
|
|
8160
8500
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
8161
8501
|
exports.CatalogueGL = void 0;
|
|
8162
8502
|
const Source_js_1 = __webpack_require__(146);
|
|
@@ -8165,11 +8505,14 @@ const CoordsType_js_1 = __webpack_require__(8145);
|
|
|
8165
8505
|
const Utils_js_1 = __webpack_require__(7930);
|
|
8166
8506
|
const CatalogueShaderProgram_js_1 = __webpack_require__(3559);
|
|
8167
8507
|
const MetadataManager_js_1 = __webpack_require__(5403);
|
|
8508
|
+
const gl_matrix_1 = __webpack_require__(3890);
|
|
8509
|
+
const healpix_1 = __webpack_require__(4851);
|
|
8510
|
+
const Global_js_1 = __importDefault(__webpack_require__(4382));
|
|
8168
8511
|
class CatalogueGL {
|
|
8169
8512
|
_kind = "CatalogueGL";
|
|
8170
8513
|
static ELEM_SIZE = 6;
|
|
8171
8514
|
static BYTES_X_ELEM = new Float32Array().BYTES_PER_ELEMENT;
|
|
8172
|
-
static STANDARD_SHAPE_SIZE =
|
|
8515
|
+
static STANDARD_SHAPE_SIZE = 16.0;
|
|
8173
8516
|
static STANDARD_SHAPE_HUE = 3.0;
|
|
8174
8517
|
_ready;
|
|
8175
8518
|
_name;
|
|
@@ -8196,6 +8539,9 @@ class CatalogueGL {
|
|
|
8196
8539
|
_providerUrl;
|
|
8197
8540
|
_catalogueShaderProgram;
|
|
8198
8541
|
_visibleTilesManager;
|
|
8542
|
+
_mediaOverlayHost = null;
|
|
8543
|
+
_mediaElements = [];
|
|
8544
|
+
_svgMediaDataUrls = new Map();
|
|
8199
8545
|
constructor(catalogueName, catalogueDescription, providerUrl, metadataManager, webgl, visibleTilesManager) {
|
|
8200
8546
|
this._webgl = webgl;
|
|
8201
8547
|
this._ready = false;
|
|
@@ -8366,9 +8712,10 @@ class CatalogueGL {
|
|
|
8366
8712
|
* @param in_data Rows of TAP results
|
|
8367
8713
|
* @param columnsmeta TapMetadataList (unused here because `CatalogueProps` already holds indices)
|
|
8368
8714
|
*/
|
|
8369
|
-
addSources(in_data, columnsmeta) {
|
|
8715
|
+
addSources(in_data, columnsmeta, options = {}) {
|
|
8370
8716
|
this._ready = false;
|
|
8371
8717
|
this._sources = [];
|
|
8718
|
+
this.clearMediaOverlay();
|
|
8372
8719
|
this._metadataManager = new MetadataManager_js_1.MetadataManager(columnsmeta);
|
|
8373
8720
|
// const raDataIndex = (this.catalogueProps.raColumn as any).index ?? (this.catalogueProps.raColumn as any)._index;
|
|
8374
8721
|
// const decDataIndex = (this.catalogueProps.decColumn as any).index ?? (this.catalogueProps.decColumn as any)._index;
|
|
@@ -8382,6 +8729,10 @@ class CatalogueGL {
|
|
|
8382
8729
|
decDeg: in_data[j][decDataIndex],
|
|
8383
8730
|
}, CoordsType_js_1.CoordsType.ASTRO);
|
|
8384
8731
|
const source = new Source_js_1.Source(point, in_data[j]);
|
|
8732
|
+
const mediaStyle = this.extractMediaStyle(in_data[j], columnsmeta, options.mediaColumns);
|
|
8733
|
+
if (mediaStyle) {
|
|
8734
|
+
source.mediaStyle = mediaStyle;
|
|
8735
|
+
}
|
|
8385
8736
|
// Ensure optional fields exist
|
|
8386
8737
|
source.shapeSize = source.shapeSize ?? CatalogueGL.STANDARD_SHAPE_SIZE;
|
|
8387
8738
|
source.brightnessFactor = 3;
|
|
@@ -8401,11 +8752,226 @@ class CatalogueGL {
|
|
|
8401
8752
|
this._ready = true;
|
|
8402
8753
|
this._bufferInitialised = false;
|
|
8403
8754
|
}
|
|
8755
|
+
getColumnIndex(columnsmeta, columnName) {
|
|
8756
|
+
if (!columnName)
|
|
8757
|
+
return -1;
|
|
8758
|
+
return (columnsmeta.find((column) => column.name === columnName)?.index ?? -1);
|
|
8759
|
+
}
|
|
8760
|
+
readCell(row, columnsmeta, columnName) {
|
|
8761
|
+
const idx = this.getColumnIndex(columnsmeta, columnName);
|
|
8762
|
+
return idx >= 0 ? row[idx] : undefined;
|
|
8763
|
+
}
|
|
8764
|
+
extractMediaStyle(row, columnsmeta, mediaColumns) {
|
|
8765
|
+
if (!mediaColumns?.src)
|
|
8766
|
+
return undefined;
|
|
8767
|
+
const rawSrc = this.readCell(row, columnsmeta, mediaColumns.src);
|
|
8768
|
+
const src = String(rawSrc ?? "").trim();
|
|
8769
|
+
if (!src)
|
|
8770
|
+
return undefined;
|
|
8771
|
+
const rawKind = String(this.readCell(row, columnsmeta, mediaColumns.type) ?? "sprite")
|
|
8772
|
+
.trim()
|
|
8773
|
+
.toLowerCase();
|
|
8774
|
+
const kind = rawKind === "model"
|
|
8775
|
+
? "model"
|
|
8776
|
+
: rawKind === "image"
|
|
8777
|
+
? "image"
|
|
8778
|
+
: rawKind === "icon"
|
|
8779
|
+
? "icon"
|
|
8780
|
+
: rawKind === "circle"
|
|
8781
|
+
? "circle"
|
|
8782
|
+
: "sprite";
|
|
8783
|
+
if (kind === "circle" || kind === "model")
|
|
8784
|
+
return undefined;
|
|
8785
|
+
const scale = Number(this.readCell(row, columnsmeta, mediaColumns.scale));
|
|
8786
|
+
const rotationDeg = Number(this.readCell(row, columnsmeta, mediaColumns.rotation));
|
|
8787
|
+
const opacity = Number(this.readCell(row, columnsmeta, mediaColumns.opacity));
|
|
8788
|
+
return {
|
|
8789
|
+
kind,
|
|
8790
|
+
src,
|
|
8791
|
+
scale: Number.isFinite(scale) && scale > 0 ? scale : undefined,
|
|
8792
|
+
rotationDeg: Number.isFinite(rotationDeg) ? rotationDeg : undefined,
|
|
8793
|
+
opacity: Number.isFinite(opacity)
|
|
8794
|
+
? Math.max(0, Math.min(1, opacity))
|
|
8795
|
+
: undefined,
|
|
8796
|
+
};
|
|
8797
|
+
}
|
|
8404
8798
|
clearSources() {
|
|
8405
8799
|
this._sources = [];
|
|
8406
8800
|
this.hoveredIndexes = [];
|
|
8407
8801
|
this._healpixDensityMap.clear();
|
|
8408
8802
|
this.vertexCataloguePosition = new Float32Array(0);
|
|
8803
|
+
this.clearMediaOverlay();
|
|
8804
|
+
}
|
|
8805
|
+
clearMediaOverlay() {
|
|
8806
|
+
this._mediaElements.forEach((el) => el.remove());
|
|
8807
|
+
this._mediaElements = [];
|
|
8808
|
+
if (this._mediaOverlayHost) {
|
|
8809
|
+
this._mediaOverlayHost.remove();
|
|
8810
|
+
this._mediaOverlayHost = null;
|
|
8811
|
+
}
|
|
8812
|
+
}
|
|
8813
|
+
ensureMediaOverlayHost() {
|
|
8814
|
+
const canvas = this._webgl?.canvas;
|
|
8815
|
+
const parent = canvas?.parentElement;
|
|
8816
|
+
if (!canvas || !parent)
|
|
8817
|
+
return null;
|
|
8818
|
+
const parentStyle = window.getComputedStyle(parent);
|
|
8819
|
+
if (parentStyle.position === "static") {
|
|
8820
|
+
parent.style.position = "relative";
|
|
8821
|
+
}
|
|
8822
|
+
if (!this._mediaOverlayHost) {
|
|
8823
|
+
const host = document.createElement("div");
|
|
8824
|
+
host.dataset.astroCatalogueMedia = "true";
|
|
8825
|
+
host.style.position = "absolute";
|
|
8826
|
+
host.style.left = `${canvas.offsetLeft}px`;
|
|
8827
|
+
host.style.top = `${canvas.offsetTop}px`;
|
|
8828
|
+
host.style.width = `${canvas.clientWidth}px`;
|
|
8829
|
+
host.style.height = `${canvas.clientHeight}px`;
|
|
8830
|
+
host.style.pointerEvents = "none";
|
|
8831
|
+
host.style.overflow = "hidden";
|
|
8832
|
+
host.style.zIndex = "4";
|
|
8833
|
+
canvas.style.position = canvas.style.position || "relative";
|
|
8834
|
+
canvas.style.zIndex = canvas.style.zIndex || "0";
|
|
8835
|
+
parent.appendChild(host);
|
|
8836
|
+
this._mediaOverlayHost = host;
|
|
8837
|
+
}
|
|
8838
|
+
else {
|
|
8839
|
+
this._mediaOverlayHost.style.left = `${canvas.offsetLeft}px`;
|
|
8840
|
+
this._mediaOverlayHost.style.top = `${canvas.offsetTop}px`;
|
|
8841
|
+
this._mediaOverlayHost.style.width = `${canvas.clientWidth}px`;
|
|
8842
|
+
this._mediaOverlayHost.style.height = `${canvas.clientHeight}px`;
|
|
8843
|
+
}
|
|
8844
|
+
return this._mediaOverlayHost;
|
|
8845
|
+
}
|
|
8846
|
+
ensureMediaElement(index, style) {
|
|
8847
|
+
let img = this._mediaElements[index];
|
|
8848
|
+
if (!img) {
|
|
8849
|
+
img = document.createElement("img");
|
|
8850
|
+
img.loading = "lazy";
|
|
8851
|
+
img.decoding = "async";
|
|
8852
|
+
img.style.position = "absolute";
|
|
8853
|
+
img.style.objectFit = "contain";
|
|
8854
|
+
img.style.pointerEvents = "none";
|
|
8855
|
+
img.style.transformOrigin = "center center";
|
|
8856
|
+
img.style.filter = "drop-shadow(0 1px 2px rgba(0, 0, 0, 0.55))";
|
|
8857
|
+
img.style.willChange = "transform, left, top";
|
|
8858
|
+
this._mediaElements[index] = img;
|
|
8859
|
+
}
|
|
8860
|
+
const src = String(style.src ?? "").trim();
|
|
8861
|
+
const resolvedSrc = src ? new URL(src, document.baseURI).href : "";
|
|
8862
|
+
if (resolvedSrc && img.getAttribute("src") !== resolvedSrc) {
|
|
8863
|
+
img.removeAttribute("data-astro-media-src-index");
|
|
8864
|
+
img.removeAttribute("data-astro-media-loaded");
|
|
8865
|
+
img.onerror = null;
|
|
8866
|
+
img.onload = null;
|
|
8867
|
+
img.setAttribute("src", resolvedSrc);
|
|
8868
|
+
if (/\.svg(?:[?#].*)?$/i.test(resolvedSrc)) {
|
|
8869
|
+
void this.loadSvgMediaAsDataUrl(img, resolvedSrc);
|
|
8870
|
+
}
|
|
8871
|
+
}
|
|
8872
|
+
return img;
|
|
8873
|
+
}
|
|
8874
|
+
async loadSvgMediaAsDataUrl(img, resolvedSrc) {
|
|
8875
|
+
try {
|
|
8876
|
+
let dataUrl = this._svgMediaDataUrls.get(resolvedSrc);
|
|
8877
|
+
if (!dataUrl) {
|
|
8878
|
+
const response = await fetch(resolvedSrc);
|
|
8879
|
+
if (!response.ok)
|
|
8880
|
+
return;
|
|
8881
|
+
const svg = await response.text();
|
|
8882
|
+
if (!/^\s*<svg[\s>]/i.test(svg))
|
|
8883
|
+
return;
|
|
8884
|
+
dataUrl = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`;
|
|
8885
|
+
this._svgMediaDataUrls.set(resolvedSrc, dataUrl);
|
|
8886
|
+
}
|
|
8887
|
+
if (img.getAttribute("src") === resolvedSrc) {
|
|
8888
|
+
img.setAttribute("src", dataUrl);
|
|
8889
|
+
}
|
|
8890
|
+
}
|
|
8891
|
+
catch {
|
|
8892
|
+
// Keep the direct image src; remote servers may already provide a valid MIME type.
|
|
8893
|
+
}
|
|
8894
|
+
}
|
|
8895
|
+
isSourceOnVisibleHemisphere(source, in_mMatrix, vMatrix) {
|
|
8896
|
+
if (Global_js_1.default.insideSphere)
|
|
8897
|
+
return true;
|
|
8898
|
+
const invView = gl_matrix_1.mat4.create();
|
|
8899
|
+
if (!gl_matrix_1.mat4.invert(invView, vMatrix))
|
|
8900
|
+
return true;
|
|
8901
|
+
const cameraPos = gl_matrix_1.vec3.fromValues(invView[12], invView[13], invView[14]);
|
|
8902
|
+
const worldPoint4 = gl_matrix_1.vec4.fromValues(source.point.x, source.point.y, source.point.z, 1);
|
|
8903
|
+
gl_matrix_1.vec4.transformMat4(worldPoint4, worldPoint4, in_mMatrix);
|
|
8904
|
+
const worldPoint = gl_matrix_1.vec3.fromValues(worldPoint4[0], worldPoint4[1], worldPoint4[2]);
|
|
8905
|
+
const normal = gl_matrix_1.vec3.normalize(gl_matrix_1.vec3.create(), worldPoint);
|
|
8906
|
+
const toCamera = gl_matrix_1.vec3.subtract(gl_matrix_1.vec3.create(), cameraPos, worldPoint);
|
|
8907
|
+
return gl_matrix_1.vec3.dot(normal, toCamera) > 0;
|
|
8908
|
+
}
|
|
8909
|
+
updateMediaOverlay(in_mMatrix, vMatrix, pMatrix) {
|
|
8910
|
+
const sourcesWithMedia = this._sources.filter((source) => !!source.mediaStyle?.src);
|
|
8911
|
+
if (!sourcesWithMedia.length) {
|
|
8912
|
+
this.clearMediaOverlay();
|
|
8913
|
+
return;
|
|
8914
|
+
}
|
|
8915
|
+
const host = this.ensureMediaOverlayHost();
|
|
8916
|
+
const canvas = this._webgl.canvas;
|
|
8917
|
+
if (!host || !canvas.clientWidth || !canvas.clientHeight)
|
|
8918
|
+
return;
|
|
8919
|
+
const modelView = gl_matrix_1.mat4.create();
|
|
8920
|
+
const mvp = gl_matrix_1.mat4.create();
|
|
8921
|
+
gl_matrix_1.mat4.multiply(modelView, vMatrix, in_mMatrix);
|
|
8922
|
+
gl_matrix_1.mat4.multiply(mvp, pMatrix, modelView);
|
|
8923
|
+
const width = canvas.clientWidth;
|
|
8924
|
+
const height = canvas.clientHeight;
|
|
8925
|
+
for (let i = 0; i < this._sources.length; i++) {
|
|
8926
|
+
const source = this._sources[i];
|
|
8927
|
+
const style = source.mediaStyle;
|
|
8928
|
+
const img = this._mediaElements[i];
|
|
8929
|
+
if (!style?.src) {
|
|
8930
|
+
if (img)
|
|
8931
|
+
img.style.display = "none";
|
|
8932
|
+
continue;
|
|
8933
|
+
}
|
|
8934
|
+
if (!this.isSourceOnVisibleHemisphere(source, in_mMatrix, vMatrix)) {
|
|
8935
|
+
if (img)
|
|
8936
|
+
img.style.display = "none";
|
|
8937
|
+
continue;
|
|
8938
|
+
}
|
|
8939
|
+
const projected = gl_matrix_1.vec4.fromValues(source.point.x, source.point.y, source.point.z, 1);
|
|
8940
|
+
gl_matrix_1.vec4.transformMat4(projected, projected, mvp);
|
|
8941
|
+
if (!projected[3]) {
|
|
8942
|
+
if (img)
|
|
8943
|
+
img.style.display = "none";
|
|
8944
|
+
continue;
|
|
8945
|
+
}
|
|
8946
|
+
const ndcX = projected[0] / projected[3];
|
|
8947
|
+
const ndcY = projected[1] / projected[3];
|
|
8948
|
+
const ndcZ = projected[2] / projected[3];
|
|
8949
|
+
if (ndcX < -1.15 ||
|
|
8950
|
+
ndcX > 1.15 ||
|
|
8951
|
+
ndcY < -1.15 ||
|
|
8952
|
+
ndcY > 1.15 ||
|
|
8953
|
+
ndcZ < -1.15 ||
|
|
8954
|
+
ndcZ > 1.15) {
|
|
8955
|
+
if (img)
|
|
8956
|
+
img.style.display = "none";
|
|
8957
|
+
continue;
|
|
8958
|
+
}
|
|
8959
|
+
const mediaEl = this.ensureMediaElement(i, style);
|
|
8960
|
+
if (!mediaEl.parentElement)
|
|
8961
|
+
host.appendChild(mediaEl);
|
|
8962
|
+
const px = (ndcX * 0.5 + 0.5) * width;
|
|
8963
|
+
const py = (1 - (ndcY * 0.5 + 0.5)) * height;
|
|
8964
|
+
const baseSize = source.shapeSize || CatalogueGL.STANDARD_SHAPE_SIZE;
|
|
8965
|
+
const size = Math.max(8, baseSize * (style.scale ?? 2.4));
|
|
8966
|
+
const rotation = style.rotationDeg ?? 0;
|
|
8967
|
+
mediaEl.style.display = "block";
|
|
8968
|
+
mediaEl.style.left = `${px - size / 2}px`;
|
|
8969
|
+
mediaEl.style.top = `${py - size / 2}px`;
|
|
8970
|
+
mediaEl.style.width = `${size}px`;
|
|
8971
|
+
mediaEl.style.height = `${size}px`;
|
|
8972
|
+
mediaEl.style.opacity = `${style.opacity ?? 1}`;
|
|
8973
|
+
mediaEl.style.transform = `rotate(${rotation}deg)`;
|
|
8974
|
+
}
|
|
8409
8975
|
}
|
|
8410
8976
|
sourceMatches(left, right) {
|
|
8411
8977
|
if (left === right)
|
|
@@ -8517,33 +9083,46 @@ class CatalogueGL {
|
|
|
8517
9083
|
this._webgl.bufferData(this._webgl.ARRAY_BUFFER, this.vertexCataloguePosition, this._webgl.STATIC_DRAW);
|
|
8518
9084
|
this._bufferInitialised = true;
|
|
8519
9085
|
}
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
9086
|
+
static MIN_HIT_RADIUS_PX = 6;
|
|
9087
|
+
static HIT_PADDING_PX = 3;
|
|
9088
|
+
static CANDIDATE_RADIUS_PX = 16;
|
|
9089
|
+
getCanvas() {
|
|
9090
|
+
return this._webgl.canvas;
|
|
9091
|
+
}
|
|
9092
|
+
getHitRadiusPx(source) {
|
|
9093
|
+
const markerSize = source.shapeSize ?? CatalogueGL.STANDARD_SHAPE_SIZE;
|
|
9094
|
+
return Math.max(CatalogueGL.MIN_HIT_RADIUS_PX, markerSize / 2 + CatalogueGL.HIT_PADDING_PX);
|
|
9095
|
+
}
|
|
9096
|
+
getCandidateSearchRadiusRad(pMatrix) {
|
|
9097
|
+
const canvas = this._webgl.canvas;
|
|
9098
|
+
const width = Math.max(1, canvas.clientWidth);
|
|
9099
|
+
const height = Math.max(1, canvas.clientHeight);
|
|
9100
|
+
// pMatrix[0] and pMatrix[5] are the perspective scale factors for X/Y.
|
|
9101
|
+
// Convert a small screen-space radius to a conservative angular radius.
|
|
9102
|
+
const fovXRad = 2 * Math.atan(1 / Math.abs(pMatrix[0]));
|
|
9103
|
+
const fovYRad = 2 * Math.atan(1 / Math.abs(pMatrix[5]));
|
|
9104
|
+
const radPerPixel = Math.max(fovXRad / width, fovYRad / height);
|
|
9105
|
+
return CatalogueGL.CANDIDATE_RADIUS_PX * radPerPixel;
|
|
9106
|
+
}
|
|
9107
|
+
projectPointToScreen(point, mvp, width, height) {
|
|
9108
|
+
const projected = gl_matrix_1.vec4.fromValues(point.x, point.y, point.z, 1);
|
|
9109
|
+
gl_matrix_1.vec4.transformMat4(projected, projected, mvp);
|
|
9110
|
+
if (projected[3] <= 0)
|
|
9111
|
+
return null;
|
|
9112
|
+
const ndcX = projected[0] / projected[3];
|
|
9113
|
+
const ndcY = projected[1] / projected[3];
|
|
9114
|
+
return [(ndcX * 0.5 + 0.5) * width, (1 - (ndcY * 0.5 + 0.5)) * height];
|
|
9115
|
+
}
|
|
9116
|
+
clearSelection() {
|
|
9117
|
+
for (const idx of this.selectedIndexes) {
|
|
9118
|
+
const base = idx * CatalogueGL.ELEM_SIZE;
|
|
9119
|
+
if (base + 4 >= this.vertexCataloguePosition.length)
|
|
9120
|
+
continue;
|
|
9121
|
+
this.vertexCataloguePosition[base + 3] = 0.0;
|
|
9122
|
+
this.vertexCataloguePosition[base + 4] =
|
|
9123
|
+
this._sources[idx]?.shapeSize ?? CatalogueGL.STANDARD_SHAPE_SIZE;
|
|
8546
9124
|
}
|
|
9125
|
+
this.selectedIndexes = [];
|
|
8547
9126
|
}
|
|
8548
9127
|
setSelectedIndexes(selectedIndex) {
|
|
8549
9128
|
selectedIndex.forEach((idx) => {
|
|
@@ -8570,8 +9149,8 @@ class CatalogueGL {
|
|
|
8570
9149
|
* Run click-picking and update selection with the nearest candidate in current pixel.
|
|
8571
9150
|
* Returns the selected source or null if no source was hit.
|
|
8572
9151
|
*/
|
|
8573
|
-
getSourcesFromPointer(in_mouseHelper) {
|
|
8574
|
-
const pickedIndexes = this.checkClicking(in_mouseHelper);
|
|
9152
|
+
getSourcesFromPointer(in_mouseHelper, in_mMatrix, vMatrix, pMatrix) {
|
|
9153
|
+
const pickedIndexes = this.checkClicking(in_mouseHelper, in_mMatrix, vMatrix, pMatrix);
|
|
8575
9154
|
if (!pickedIndexes.length) {
|
|
8576
9155
|
return {
|
|
8577
9156
|
sources: [],
|
|
@@ -8590,8 +9169,8 @@ class CatalogueGL {
|
|
|
8590
9169
|
* Run click-picking and update selection with the nearest candidate in current pixel.
|
|
8591
9170
|
* Returns the selected source or null if no source was hit.
|
|
8592
9171
|
*/
|
|
8593
|
-
selectPrimarySourceFromClick(in_mouseHelper) {
|
|
8594
|
-
const picked = this.getSourcesFromPointer(in_mouseHelper);
|
|
9172
|
+
selectPrimarySourceFromClick(in_mouseHelper, in_mMatrix, vMatrix, pMatrix) {
|
|
9173
|
+
const picked = this.getSourcesFromPointer(in_mouseHelper, in_mMatrix, vMatrix, pMatrix);
|
|
8595
9174
|
const clickedIndexes = picked?.pickedIndexes ?? [];
|
|
8596
9175
|
// if (!clickedIndexes.length) {
|
|
8597
9176
|
// this.setSelectedIndexes([]);
|
|
@@ -8627,42 +9206,65 @@ class CatalogueGL {
|
|
|
8627
9206
|
const idx = this.hoveredIndexes[0];
|
|
8628
9207
|
return this._sources[idx] ?? null;
|
|
8629
9208
|
}
|
|
8630
|
-
findNearestSourceIndex(in_mouseHelper) {
|
|
8631
|
-
if (in_mouseHelper.
|
|
8632
|
-
in_mouseHelper.y == null ||
|
|
8633
|
-
in_mouseHelper.z == null) {
|
|
9209
|
+
findNearestSourceIndex(in_mouseHelper, in_mMatrix, vMatrix, pMatrix) {
|
|
9210
|
+
if (in_mouseHelper.xyz == null)
|
|
8634
9211
|
return null;
|
|
9212
|
+
const healpix = Global_js_1.default.getHealpix(Global_js_1.default.selectionOrder);
|
|
9213
|
+
const mouseVec = new healpix_1.Vec3(...in_mouseHelper.xyz);
|
|
9214
|
+
const mousePointing = new healpix_1.Pointing(mouseVec, false);
|
|
9215
|
+
const searchRadiusRad = this.getCandidateSearchRadiusRad(pMatrix);
|
|
9216
|
+
const rangeSet = healpix.queryDiscInclusive(mousePointing, searchRadiusRad, 4);
|
|
9217
|
+
const pixels = rangeSet.r;
|
|
9218
|
+
const candidateIndexes = new Set();
|
|
9219
|
+
for (const pixel of pixels) {
|
|
9220
|
+
const indexes = this._healpixDensityMap.get(pixel);
|
|
9221
|
+
if (!indexes)
|
|
9222
|
+
continue;
|
|
9223
|
+
indexes.forEach((idx) => candidateIndexes.add(idx));
|
|
8635
9224
|
}
|
|
8636
|
-
|
|
8637
|
-
|
|
9225
|
+
if (!candidateIndexes.size)
|
|
9226
|
+
return null;
|
|
9227
|
+
const canvas = this._webgl.canvas;
|
|
9228
|
+
const width = canvas.clientWidth;
|
|
9229
|
+
const height = canvas.clientHeight;
|
|
9230
|
+
if (!width || !height)
|
|
8638
9231
|
return null;
|
|
8639
|
-
const
|
|
8640
|
-
|
|
9232
|
+
const modelView = gl_matrix_1.mat4.create();
|
|
9233
|
+
const mvp = gl_matrix_1.mat4.create();
|
|
9234
|
+
gl_matrix_1.mat4.multiply(modelView, vMatrix, in_mMatrix);
|
|
9235
|
+
gl_matrix_1.mat4.multiply(mvp, pMatrix, modelView);
|
|
9236
|
+
const mousePoint = new Point_js_1.Point({
|
|
9237
|
+
x: in_mouseHelper.xyz[0],
|
|
9238
|
+
y: in_mouseHelper.xyz[1],
|
|
9239
|
+
z: in_mouseHelper.xyz[2],
|
|
9240
|
+
}, CoordsType_js_1.CoordsType.CARTESIAN);
|
|
9241
|
+
const mouseScreen = this.projectPointToScreen(mousePoint, mvp, width, height);
|
|
9242
|
+
if (!mouseScreen)
|
|
8641
9243
|
return null;
|
|
8642
|
-
const selR = this.getSelectionRadius();
|
|
8643
9244
|
let nearestIndex = null;
|
|
8644
|
-
let
|
|
8645
|
-
for (const sourceIdx of
|
|
9245
|
+
let nearestDistancePx = Number.POSITIVE_INFINITY;
|
|
9246
|
+
for (const sourceIdx of candidateIndexes) {
|
|
8646
9247
|
const source = this._sources[sourceIdx];
|
|
8647
9248
|
if (!source)
|
|
8648
9249
|
continue;
|
|
8649
|
-
const
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
const
|
|
8653
|
-
if (
|
|
8654
|
-
|
|
9250
|
+
const sourceScreen = this.projectPointToScreen(source.point, mvp, width, height);
|
|
9251
|
+
if (!sourceScreen)
|
|
9252
|
+
continue;
|
|
9253
|
+
const distancePx = Math.hypot(sourceScreen[0] - mouseScreen[0], sourceScreen[1] - mouseScreen[1]);
|
|
9254
|
+
if (distancePx <= this.getHitRadiusPx(source) &&
|
|
9255
|
+
distancePx < nearestDistancePx) {
|
|
9256
|
+
nearestDistancePx = distancePx;
|
|
8655
9257
|
nearestIndex = sourceIdx;
|
|
8656
9258
|
}
|
|
8657
9259
|
}
|
|
8658
9260
|
return nearestIndex;
|
|
8659
9261
|
}
|
|
8660
|
-
checkClicking(in_mouseHelper) {
|
|
8661
|
-
const nearestIndex = this.findNearestSourceIndex(in_mouseHelper);
|
|
9262
|
+
checkClicking(in_mouseHelper, in_mMatrix, vMatrix, pMatrix) {
|
|
9263
|
+
const nearestIndex = this.findNearestSourceIndex(in_mouseHelper, in_mMatrix, vMatrix, pMatrix);
|
|
8662
9264
|
return nearestIndex == null ? [] : [nearestIndex];
|
|
8663
9265
|
}
|
|
8664
|
-
checkHovering(in_mouseHelper) {
|
|
8665
|
-
const nearestIndex = this.findNearestSourceIndex(in_mouseHelper);
|
|
9266
|
+
checkHovering(in_mouseHelper, in_mMatrix, vMatrix, pMatrix) {
|
|
9267
|
+
const nearestIndex = this.findNearestSourceIndex(in_mouseHelper, in_mMatrix, vMatrix, pMatrix);
|
|
8666
9268
|
return nearestIndex == null ? [] : [nearestIndex];
|
|
8667
9269
|
}
|
|
8668
9270
|
/**
|
|
@@ -8698,6 +9300,13 @@ class CatalogueGL {
|
|
|
8698
9300
|
if (this._catalogueShaderProgram.locations.color) {
|
|
8699
9301
|
this._webgl.uniform4f(this._catalogueShaderProgram.locations.color, rgb[0], rgb[1], rgb[2], 1.0);
|
|
8700
9302
|
}
|
|
9303
|
+
const interactionColors = (0, Utils_js_1.interactionColorsFromHex)(this._shapeColor);
|
|
9304
|
+
if (this._catalogueShaderProgram.locations.hoverColor) {
|
|
9305
|
+
this._webgl.uniform4f(this._catalogueShaderProgram.locations.hoverColor, ...interactionColors.hover, 1.0);
|
|
9306
|
+
}
|
|
9307
|
+
if (this._catalogueShaderProgram.locations.selectedColor) {
|
|
9308
|
+
this._webgl.uniform4f(this._catalogueShaderProgram.locations.selectedColor, ...interactionColors.selected, 1.0);
|
|
9309
|
+
}
|
|
8701
9310
|
// selected flags
|
|
8702
9311
|
for (let s = 0; s < this.selectedIndexes.length; s++) {
|
|
8703
9312
|
const idx = this.selectedIndexes[s];
|
|
@@ -8708,7 +9317,8 @@ class CatalogueGL {
|
|
|
8708
9317
|
// clear old hovered
|
|
8709
9318
|
for (let k = 0; k < this.hoveredIndexes.length; k++) {
|
|
8710
9319
|
const base = this.hoveredIndexes[k] * CatalogueGL.ELEM_SIZE;
|
|
8711
|
-
|
|
9320
|
+
if (this.selectedIndexes.includes(this.hoveredIndexes[k]))
|
|
9321
|
+
continue;
|
|
8712
9322
|
this.vertexCataloguePosition[base + 3] = 0.0; // not hovered
|
|
8713
9323
|
this.vertexCataloguePosition[base + 4] =
|
|
8714
9324
|
this._sources[this.hoveredIndexes[k]].shapeSize; // size
|
|
@@ -8722,7 +9332,7 @@ class CatalogueGL {
|
|
|
8722
9332
|
// this.vertexCataloguePosition[base + 3] = 0.0; // not hovered
|
|
8723
9333
|
// this.vertexCataloguePosition[base + 4] = this._sources[this.hoveredIndexes[k]].shapeSize; // size
|
|
8724
9334
|
// }
|
|
8725
|
-
this.hoveredIndexes = this.checkHovering(in_mouseHelper);
|
|
9335
|
+
this.hoveredIndexes = this.checkHovering(in_mouseHelper, in_mMatrix, vMatrix, pMatrix);
|
|
8726
9336
|
// // new hovered
|
|
8727
9337
|
// for (let i = 0; i < this.hoveredIndexes.length; i++) {
|
|
8728
9338
|
// const idx = this.hoveredIndexes[i];
|
|
@@ -8736,7 +9346,8 @@ class CatalogueGL {
|
|
|
8736
9346
|
for (let i = 0; i < this.hoveredIndexes.length; i++) {
|
|
8737
9347
|
const idx = this.hoveredIndexes[i];
|
|
8738
9348
|
const base = idx * CatalogueGL.ELEM_SIZE;
|
|
8739
|
-
|
|
9349
|
+
if (this.selectedIndexes.includes(idx))
|
|
9350
|
+
continue;
|
|
8740
9351
|
this.vertexCataloguePosition[base + 3] = 1.0; // hovered
|
|
8741
9352
|
this.vertexCataloguePosition[base + 4] = this._sources[idx].shapeSize; // size
|
|
8742
9353
|
}
|
|
@@ -8745,6 +9356,7 @@ class CatalogueGL {
|
|
|
8745
9356
|
// draw
|
|
8746
9357
|
const numItems = this.vertexCataloguePosition.length / CatalogueGL.ELEM_SIZE;
|
|
8747
9358
|
this._webgl.drawArrays(this._webgl.POINTS, 0, numItems);
|
|
9359
|
+
this.updateMediaOverlay(in_mMatrix, vMatrix, pMatrix);
|
|
8748
9360
|
this._oldMouseCoords = in_mouseHelper.xyz;
|
|
8749
9361
|
}
|
|
8750
9362
|
}
|
|
@@ -9139,6 +9751,7 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9139
9751
|
_latLonGrid;
|
|
9140
9752
|
_colorMapIdx = 0;
|
|
9141
9753
|
_colorMap = ColorMaps_js_1.ColorMaps['native'];
|
|
9754
|
+
_opacity = 1;
|
|
9142
9755
|
constructor(radius, position, xrad, yrad, descriptor, webgl, gridLabelContainers) {
|
|
9143
9756
|
super(radius, position, xrad, yrad, descriptor.name, webgl, false);
|
|
9144
9757
|
this._descriptor = descriptor;
|
|
@@ -9153,6 +9766,10 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9153
9766
|
const fov = 180;
|
|
9154
9767
|
this._zoom = XYZFoVHelper_js_1.xyzFovHelper.getZoom(fov);
|
|
9155
9768
|
}
|
|
9769
|
+
setOpacity(opacity) {
|
|
9770
|
+
this._opacity = Math.min(1, Math.max(0, opacity));
|
|
9771
|
+
this._xyzShaderProgram.setOpacity(this._opacity);
|
|
9772
|
+
}
|
|
9156
9773
|
changeColorMap(colorMap) {
|
|
9157
9774
|
this._colorMap = colorMap;
|
|
9158
9775
|
switch (colorMap.name) {
|
|
@@ -9200,6 +9817,9 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9200
9817
|
initShaders() {
|
|
9201
9818
|
this._xyzShaderProgram.enableProgram();
|
|
9202
9819
|
}
|
|
9820
|
+
clearLonLatGridLabels() {
|
|
9821
|
+
this._latLonGrid.clearLabels();
|
|
9822
|
+
}
|
|
9203
9823
|
isLonLatGridVisible() {
|
|
9204
9824
|
return this._latLonGrid.isVisible();
|
|
9205
9825
|
}
|
|
@@ -9214,7 +9834,7 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9214
9834
|
// this._zoom = this.resolveVisibleZoom(fov)
|
|
9215
9835
|
this._zoom = XYZFoVHelper_js_1.xyzFovHelper.getZoom(fov);
|
|
9216
9836
|
}
|
|
9217
|
-
draw(input) {
|
|
9837
|
+
draw(input, asOverlay = false) {
|
|
9218
9838
|
const vMatrix = input.camera.getCameraMatrix();
|
|
9219
9839
|
if (!vMatrix)
|
|
9220
9840
|
return;
|
|
@@ -9224,6 +9844,18 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9224
9844
|
this.refresh(input);
|
|
9225
9845
|
const mMatrix = this.getModelMatrix();
|
|
9226
9846
|
this._xyzShaderProgram.setRuntimeColorMap(this._colorMap);
|
|
9847
|
+
this._xyzShaderProgram.setOpacity(this._opacity);
|
|
9848
|
+
const depthTestWasEnabled = this._webgl.isEnabled(this._webgl.DEPTH_TEST);
|
|
9849
|
+
const blendWasEnabled = this._webgl.isEnabled(this._webgl.BLEND);
|
|
9850
|
+
const blendSrcRgb = this._webgl.getParameter(this._webgl.BLEND_SRC_RGB);
|
|
9851
|
+
const blendDstRgb = this._webgl.getParameter(this._webgl.BLEND_DST_RGB);
|
|
9852
|
+
const blendSrcAlpha = this._webgl.getParameter(this._webgl.BLEND_SRC_ALPHA);
|
|
9853
|
+
const blendDstAlpha = this._webgl.getParameter(this._webgl.BLEND_DST_ALPHA);
|
|
9854
|
+
if (asOverlay) {
|
|
9855
|
+
this._webgl.disable(this._webgl.DEPTH_TEST);
|
|
9856
|
+
this._webgl.enable(this._webgl.BLEND);
|
|
9857
|
+
this._webgl.blendFunc(this._webgl.SRC_ALPHA, this._webgl.ONE_MINUS_SRC_ALPHA);
|
|
9858
|
+
}
|
|
9227
9859
|
const tileSelection = this._visibleTilesManager.computeVisibleTiles(this._zoom, this, this._webgl, input.camera, input.pMatrix);
|
|
9228
9860
|
const visibleTiles = tileSelection.visibleTiles;
|
|
9229
9861
|
const ancestorsMap = tileSelection.ancestorsMap;
|
|
@@ -9241,7 +9873,20 @@ class XYZMap extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
9241
9873
|
const ancestorTile = this.findBestAvailableAncestor(tile.coord);
|
|
9242
9874
|
ancestorTile?.draw(tileSelection.currentZoom, [tile.coord], ancestorsMap, pMatrix, vMatrix, mMatrix, this._colorMapIdx);
|
|
9243
9875
|
}
|
|
9244
|
-
|
|
9876
|
+
if (asOverlay) {
|
|
9877
|
+
if (depthTestWasEnabled)
|
|
9878
|
+
this._webgl.enable(this._webgl.DEPTH_TEST);
|
|
9879
|
+
else
|
|
9880
|
+
this._webgl.disable(this._webgl.DEPTH_TEST);
|
|
9881
|
+
this._webgl.blendFuncSeparate(blendSrcRgb, blendDstRgb, blendSrcAlpha, blendDstAlpha);
|
|
9882
|
+
if (blendWasEnabled)
|
|
9883
|
+
this._webgl.enable(this._webgl.BLEND);
|
|
9884
|
+
else
|
|
9885
|
+
this._webgl.disable(this._webgl.BLEND);
|
|
9886
|
+
}
|
|
9887
|
+
else {
|
|
9888
|
+
this._latLonGrid.draw(input);
|
|
9889
|
+
}
|
|
9245
9890
|
}
|
|
9246
9891
|
createTile(coord) {
|
|
9247
9892
|
return new XYZAnchestorTile_js_1.XYZAnchestorTile(coord, this.resolveTileUrl(coord), this._webgl, this._xyzShaderProgram, this._meshBuilder, this._descriptor.segmentsPerSide);
|
|
@@ -10527,6 +11172,10 @@ class FootprintSetGL {
|
|
|
10527
11172
|
}
|
|
10528
11173
|
return clickedIndexes;
|
|
10529
11174
|
}
|
|
11175
|
+
clearSelection() {
|
|
11176
|
+
this.selectedIndexes = [];
|
|
11177
|
+
this.refreshSelectedFootprints();
|
|
11178
|
+
}
|
|
10530
11179
|
setSelectedIndexes(selectedIndex) {
|
|
10531
11180
|
selectedIndex.forEach((idx) => {
|
|
10532
11181
|
if (idx < 0 || idx >= this.footprintPolygons.length)
|
|
@@ -10828,9 +11477,10 @@ class FootprintSetGL {
|
|
|
10828
11477
|
if (in_mouseHelper != null && in_mouseHelper.xyz != this.oldMouseCoords) {
|
|
10829
11478
|
this.checkSelection(in_mouseHelper);
|
|
10830
11479
|
}
|
|
11480
|
+
const interactionColors = (0, Utils_js_1.interactionColorsFromHex)(this._shapeColor);
|
|
10831
11481
|
if (this._hoveredFootprints.length > 0) {
|
|
10832
11482
|
// TODO POINT_SIZE doesn't have any effect on line thickness!! it only applies to points
|
|
10833
|
-
const rgb =
|
|
11483
|
+
const rgb = interactionColors.hover;
|
|
10834
11484
|
const alpha = 1.0;
|
|
10835
11485
|
this._webgl.uniform4f(this._footprintShaderProgram.locations.color, rgb[0], rgb[1], rgb[2], alpha);
|
|
10836
11486
|
this._webgl.uniform1f(this._footprintShaderProgram.locations.pointSize, 14.0); // <--- POINT_SIZE in LINE_LOOP is not applicable
|
|
@@ -10845,7 +11495,7 @@ class FootprintSetGL {
|
|
|
10845
11495
|
this._webgl.drawElements(this._webgl.LINE_LOOP, this.hoveredVertexPosition.length / 3 + this.nHoveredPrimitiveFlags, this._webgl.UNSIGNED_INT, 0);
|
|
10846
11496
|
}
|
|
10847
11497
|
if (this._selectedFootprints.length > 0) {
|
|
10848
|
-
const rgb =
|
|
11498
|
+
const rgb = interactionColors.selected;
|
|
10849
11499
|
const alpha = 1.0;
|
|
10850
11500
|
this._webgl.uniform4f(this._footprintShaderProgram.locations.color, rgb[0], rgb[1], rgb[2], alpha);
|
|
10851
11501
|
this._webgl.uniform1f(this._footprintShaderProgram.locations.pointSize, 14.0); // <--- POINT_SIZE in LINE_LOOP is not applicable
|
|
@@ -10858,6 +11508,11 @@ class FootprintSetGL {
|
|
|
10858
11508
|
this._webgl.bufferData(this._webgl.ELEMENT_ARRAY_BUFFER, this.selectedElementIndexes, this._webgl.STATIC_DRAW);
|
|
10859
11509
|
// this._gl.drawElements (this._gl.LINE_LOOP, this._selectedVertexPosition.length / 3 + this._nSlectedPrimitiveFlags,this._gl.UNSIGNED_SHORT, 0);
|
|
10860
11510
|
this._webgl.drawElements(this._webgl.LINE_LOOP, this.selectedVertexPosition.length / 3 + this.nSlectedPrimitiveFlags, this._webgl.UNSIGNED_INT, 0);
|
|
11511
|
+
// Keep selection visually distinct from hover without relying on
|
|
11512
|
+
// non-portable line widths. Reuse the selected geometry as small
|
|
11513
|
+
// vertex markers; POINT_SIZE is supported for POINTS in WebGL2.
|
|
11514
|
+
this._webgl.uniform1f(this._footprintShaderProgram.locations.pointSize, 4.0);
|
|
11515
|
+
this._webgl.drawElements(this._webgl.POINTS, this.selectedVertexPosition.length / 3 + this.nSlectedPrimitiveFlags, this._webgl.UNSIGNED_INT, 0);
|
|
10861
11516
|
}
|
|
10862
11517
|
this._webgl.bindBuffer(this._webgl.ARRAY_BUFFER, this.vertexCataloguePositionBuffer);
|
|
10863
11518
|
this._webgl.vertexAttribPointer(this._footprintShaderProgram.locations.position, FootprintSetGL.ELEM_SIZE, this._webgl.FLOAT, false, FootprintSetGL.BYTES_X_ELEM * FootprintSetGL.ELEM_SIZE, 0);
|
|
@@ -11090,6 +11745,9 @@ class EquatorialGrid extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
11090
11745
|
gl.uniform4f(uColor, rgb[0], rgb[1], rgb[2], 1.0);
|
|
11091
11746
|
}
|
|
11092
11747
|
}
|
|
11748
|
+
clearLabels() {
|
|
11749
|
+
this.gridText.resetDivSets();
|
|
11750
|
+
}
|
|
11093
11751
|
isVisible() {
|
|
11094
11752
|
return this.showGrid;
|
|
11095
11753
|
}
|
|
@@ -11684,6 +12342,9 @@ class HealpixGrid extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
11684
12342
|
this.gridText.resetDivSets();
|
|
11685
12343
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
|
|
11686
12344
|
}
|
|
12345
|
+
clearLabels() {
|
|
12346
|
+
this.gridText.resetDivSets();
|
|
12347
|
+
}
|
|
11687
12348
|
get visibleorder() {
|
|
11688
12349
|
return this._visibleorder;
|
|
11689
12350
|
}
|
|
@@ -11917,6 +12578,9 @@ class LatLonGrid extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
11917
12578
|
gl.uniform4f(uColor, rgb[0], rgb[1], rgb[2], 1.0);
|
|
11918
12579
|
}
|
|
11919
12580
|
}
|
|
12581
|
+
clearLabels() {
|
|
12582
|
+
this.gridText.resetDivSets();
|
|
12583
|
+
}
|
|
11920
12584
|
draw(input) {
|
|
11921
12585
|
if (!this._showGrid) {
|
|
11922
12586
|
this.gridText.resetDivSets();
|
|
@@ -14574,6 +15238,8 @@ class MeshHiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
14574
15238
|
_currentOrder;
|
|
14575
15239
|
_visibleTiles = [];
|
|
14576
15240
|
_coverageTiles = [];
|
|
15241
|
+
_color;
|
|
15242
|
+
_wireframe;
|
|
14577
15243
|
constructor(radius, position, xrad, yrad, _descriptor, webgl, _healpixGrid) {
|
|
14578
15244
|
super(radius, position, xrad, yrad, _descriptor.name, webgl, false);
|
|
14579
15245
|
this._descriptor = _descriptor;
|
|
@@ -14582,6 +15248,8 @@ class MeshHiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
14582
15248
|
this._shaderProgram = new MeshHiPSShaderProgram_js_1.MeshHiPSShaderProgram(webgl);
|
|
14583
15249
|
this._shaderProgram.enableProgram();
|
|
14584
15250
|
this._currentOrder = _descriptor.selectedOrder;
|
|
15251
|
+
this._color = [..._descriptor.color];
|
|
15252
|
+
this._wireframe = _descriptor.wireframe;
|
|
14585
15253
|
}
|
|
14586
15254
|
get currentOrder() {
|
|
14587
15255
|
return this._currentOrder;
|
|
@@ -14604,6 +15272,12 @@ class MeshHiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
14604
15272
|
getProperty(key) {
|
|
14605
15273
|
return this._descriptor.getProperty(key);
|
|
14606
15274
|
}
|
|
15275
|
+
setColor(color) {
|
|
15276
|
+
this._color = [...color];
|
|
15277
|
+
}
|
|
15278
|
+
setWireframe(wireframe) {
|
|
15279
|
+
this._wireframe = wireframe;
|
|
15280
|
+
}
|
|
14607
15281
|
refreshOrder(fovDeg) {
|
|
14608
15282
|
if (this._descriptor.fixedOrder) {
|
|
14609
15283
|
this._currentOrder = this._descriptor.selectedOrder;
|
|
@@ -14643,7 +15317,7 @@ class MeshHiPS extends AbstractSkyEntity_js_1.AbstractSkyEntity {
|
|
|
14643
15317
|
for (const coord of byOrder.get(order) ?? []) {
|
|
14644
15318
|
this._tiles
|
|
14645
15319
|
.get(this.tileKey(coord))
|
|
14646
|
-
?.draw(pMatrix, vMatrix, mMatrix, this.
|
|
15320
|
+
?.draw(pMatrix, vMatrix, mMatrix, this._color, this._wireframe);
|
|
14647
15321
|
}
|
|
14648
15322
|
}
|
|
14649
15323
|
if (wasCullFace)
|
|
@@ -16424,6 +17098,7 @@ exports.TerraFootprintSetGL = TerraFootprintSetGL;
|
|
|
16424
17098
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
16425
17099
|
exports.TerraPointSetGL = void 0;
|
|
16426
17100
|
const CatalogueGL_js_1 = __webpack_require__(1232);
|
|
17101
|
+
const gl_matrix_1 = __webpack_require__(3890);
|
|
16427
17102
|
const MetadataManager_js_1 = __webpack_require__(5403);
|
|
16428
17103
|
const Point_js_1 = __webpack_require__(6553);
|
|
16429
17104
|
const CoordsType_js_1 = __webpack_require__(8145);
|
|
@@ -16458,8 +17133,45 @@ class TerraPointSetGL extends CatalogueGL_js_1.CatalogueGL {
|
|
|
16458
17133
|
this._ready = true;
|
|
16459
17134
|
this._bufferInitialised = false;
|
|
16460
17135
|
}
|
|
17136
|
+
findNearestSourceIndex(inMouseHelper, inMatrix, viewMatrix, projectionMatrix) {
|
|
17137
|
+
if (inMouseHelper.xyz == null)
|
|
17138
|
+
return null;
|
|
17139
|
+
const canvas = this.getCanvas();
|
|
17140
|
+
const width = canvas.clientWidth;
|
|
17141
|
+
const height = canvas.clientHeight;
|
|
17142
|
+
if (!width || !height)
|
|
17143
|
+
return null;
|
|
17144
|
+
const modelView = gl_matrix_1.mat4.create();
|
|
17145
|
+
const mvp = gl_matrix_1.mat4.create();
|
|
17146
|
+
gl_matrix_1.mat4.multiply(modelView, viewMatrix, inMatrix);
|
|
17147
|
+
gl_matrix_1.mat4.multiply(mvp, projectionMatrix, modelView);
|
|
17148
|
+
const mousePoint = new Point_js_1.Point({
|
|
17149
|
+
x: inMouseHelper.xyz[0],
|
|
17150
|
+
y: inMouseHelper.xyz[1],
|
|
17151
|
+
z: inMouseHelper.xyz[2],
|
|
17152
|
+
}, CoordsType_js_1.CoordsType.CARTESIAN);
|
|
17153
|
+
const mouseScreen = this.projectPointToScreen(mousePoint, mvp, width, height);
|
|
17154
|
+
if (!mouseScreen)
|
|
17155
|
+
return null;
|
|
17156
|
+
let nearestIndex = null;
|
|
17157
|
+
let nearestDistancePx = Number.POSITIVE_INFINITY;
|
|
17158
|
+
for (let index = 0; index < this._sources.length; index += 1) {
|
|
17159
|
+
const source = this._sources[index];
|
|
17160
|
+
if (!source)
|
|
17161
|
+
continue;
|
|
17162
|
+
const sourceScreen = this.projectPointToScreen(source.point, mvp, width, height);
|
|
17163
|
+
if (!sourceScreen)
|
|
17164
|
+
continue;
|
|
17165
|
+
const distancePx = Math.hypot(sourceScreen[0] - mouseScreen[0], sourceScreen[1] - mouseScreen[1]);
|
|
17166
|
+
if (distancePx <= this.getHitRadiusPx(source) &&
|
|
17167
|
+
distancePx < nearestDistancePx) {
|
|
17168
|
+
nearestDistancePx = distancePx;
|
|
17169
|
+
nearestIndex = index;
|
|
17170
|
+
}
|
|
17171
|
+
}
|
|
17172
|
+
return nearestIndex;
|
|
17173
|
+
}
|
|
16461
17174
|
draw(inMatrix, inMouseHelper, viewMatrix, projectionMatrix) {
|
|
16462
|
-
this._oldMouseCoords = inMouseHelper?.xyz ?? null;
|
|
16463
17175
|
super.draw(inMatrix, inMouseHelper, viewMatrix, projectionMatrix);
|
|
16464
17176
|
}
|
|
16465
17177
|
}
|
|
@@ -16689,6 +17401,8 @@ class CatalogueShaderProgram {
|
|
|
16689
17401
|
this._webgl = webgl;
|
|
16690
17402
|
this.gl_uniforms = {
|
|
16691
17403
|
vertex_color: 'u_fragcolor',
|
|
17404
|
+
hover_color: 'u_hovercolor',
|
|
17405
|
+
selected_color: 'u_selectedcolor',
|
|
16692
17406
|
m_perspective: 'uPMatrix',
|
|
16693
17407
|
m_model_view: 'uMVMatrix'
|
|
16694
17408
|
};
|
|
@@ -16702,6 +17416,8 @@ class CatalogueShaderProgram {
|
|
|
16702
17416
|
pMatrix: null,
|
|
16703
17417
|
mvMatrix: null,
|
|
16704
17418
|
color: null,
|
|
17419
|
+
hoverColor: null,
|
|
17420
|
+
selectedColor: null,
|
|
16705
17421
|
position: -1,
|
|
16706
17422
|
hovered: -1,
|
|
16707
17423
|
pointSize: -1,
|
|
@@ -16751,6 +17467,8 @@ class CatalogueShaderProgram {
|
|
|
16751
17467
|
this.locations.pointSize = gl.getAttribLocation(this.shaderProgram, this.gl_attributes.point_size);
|
|
16752
17468
|
this.locations.brightness = gl.getAttribLocation(this.shaderProgram, this.gl_attributes.point_hue);
|
|
16753
17469
|
this.locations.color = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.vertex_color);
|
|
17470
|
+
this.locations.hoverColor = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.hover_color);
|
|
17471
|
+
this.locations.selectedColor = gl.getUniformLocation(this.shaderProgram, this.gl_uniforms.selected_color);
|
|
16754
17472
|
}
|
|
16755
17473
|
enableShaders(pMatrix, modelMatrix, viewMatrix) {
|
|
16756
17474
|
// const gl = global.gl as GL
|
|
@@ -17436,6 +18154,8 @@ class ShaderManager {
|
|
|
17436
18154
|
in float v_brightness;
|
|
17437
18155
|
|
|
17438
18156
|
uniform vec4 u_fragcolor;
|
|
18157
|
+
uniform vec4 u_hovercolor;
|
|
18158
|
+
uniform vec4 u_selectedcolor;
|
|
17439
18159
|
|
|
17440
18160
|
out vec4 fragColor;
|
|
17441
18161
|
|
|
@@ -17492,11 +18212,12 @@ class ShaderManager {
|
|
|
17492
18212
|
#endif
|
|
17493
18213
|
|
|
17494
18214
|
if (v_selected == 1.0){
|
|
17495
|
-
|
|
17496
|
-
fragColor = vec4(1.0, 0.0, 0.0, 1.0) * (alpha);
|
|
18215
|
+
fragColor = u_hovercolor * alpha;
|
|
17497
18216
|
} else if (v_selected == 2.0){
|
|
17498
|
-
//
|
|
17499
|
-
|
|
18217
|
+
// Persistent selection: keep the dataset colour as an outer ring
|
|
18218
|
+
// and use the hover colour for the fill. This remains visible for
|
|
18219
|
+
// both light and dark user-selected base colours.
|
|
18220
|
+
fragColor = (r > 0.72 ? u_fragcolor : u_hovercolor) * alpha;
|
|
17500
18221
|
}else{
|
|
17501
18222
|
if (r < 0.4) {
|
|
17502
18223
|
discard;
|
|
@@ -17903,6 +18624,7 @@ class XYZShaderProgram {
|
|
|
17903
18624
|
_shaderProgram;
|
|
17904
18625
|
_colorMapBlockIndex = null;
|
|
17905
18626
|
_colorMapBuffer = null;
|
|
18627
|
+
_opacity = 1;
|
|
17906
18628
|
_runtimeColorMap;
|
|
17907
18629
|
_colorMapVariableInfo = {
|
|
17908
18630
|
r_palette: { index: 0, offset: 0 },
|
|
@@ -17917,6 +18639,7 @@ class XYZShaderProgram {
|
|
|
17917
18639
|
vMatrix: null,
|
|
17918
18640
|
sampler: null,
|
|
17919
18641
|
colorMapIdx: null,
|
|
18642
|
+
opacity: null,
|
|
17920
18643
|
vertexPositionAttribute: -1,
|
|
17921
18644
|
textureCoordAttribute: -1,
|
|
17922
18645
|
};
|
|
@@ -17937,6 +18660,9 @@ class XYZShaderProgram {
|
|
|
17937
18660
|
enableProgram() {
|
|
17938
18661
|
this._webgl.useProgram(this.shaderProgram);
|
|
17939
18662
|
}
|
|
18663
|
+
setOpacity(opacity) {
|
|
18664
|
+
this._opacity = Math.min(1, Math.max(0, opacity));
|
|
18665
|
+
}
|
|
17940
18666
|
setRuntimeColorMap(colorMap) {
|
|
17941
18667
|
this._runtimeColorMap = colorMap;
|
|
17942
18668
|
}
|
|
@@ -17949,6 +18675,7 @@ class XYZShaderProgram {
|
|
|
17949
18675
|
this.locations.vMatrix = gl.getUniformLocation(program, 'uVMatrix');
|
|
17950
18676
|
this.locations.sampler = gl.getUniformLocation(program, 'uSampler');
|
|
17951
18677
|
this.locations.colorMapIdx = gl.getUniformLocation(program, 'cmapIdx');
|
|
18678
|
+
this.locations.opacity = gl.getUniformLocation(program, 'uOpacity');
|
|
17952
18679
|
this.locations.vertexPositionAttribute = gl.getAttribLocation(program, 'aVertexPosition');
|
|
17953
18680
|
this.locations.textureCoordAttribute = gl.getAttribLocation(program, 'aTextureCoord');
|
|
17954
18681
|
gl.uniformMatrix4fv(this.locations.pMatrix, false, pMatrix);
|
|
@@ -17956,6 +18683,7 @@ class XYZShaderProgram {
|
|
|
17956
18683
|
gl.uniformMatrix4fv(this.locations.mMatrix, false, mMatrix);
|
|
17957
18684
|
gl.uniform1i(this.locations.sampler, 0);
|
|
17958
18685
|
gl.uniform1i(this.locations.colorMapIdx, colorMapIdx);
|
|
18686
|
+
gl.uniform1f(this.locations.opacity, this._opacity);
|
|
17959
18687
|
if (colorMapIdx >= 2) {
|
|
17960
18688
|
this.uploadColorMap(colorMapIdx);
|
|
17961
18689
|
}
|
|
@@ -17978,6 +18706,7 @@ class XYZShaderProgram {
|
|
|
17978
18706
|
in vec2 vTextureCoord;
|
|
17979
18707
|
uniform sampler2D uSampler;
|
|
17980
18708
|
uniform int cmapIdx;
|
|
18709
|
+
uniform float uOpacity;
|
|
17981
18710
|
|
|
17982
18711
|
layout (std140) uniform colormap {
|
|
17983
18712
|
float r_palette[256];
|
|
@@ -17992,7 +18721,7 @@ class XYZShaderProgram {
|
|
|
17992
18721
|
|
|
17993
18722
|
if (cmapIdx == 1) {
|
|
17994
18723
|
float gray = 0.21 * color.r + 0.71 * color.g + 0.07 * color.b;
|
|
17995
|
-
outColor = vec4(vec3(gray), color.a);
|
|
18724
|
+
outColor = vec4(vec3(gray), color.a * uOpacity);
|
|
17996
18725
|
return;
|
|
17997
18726
|
}
|
|
17998
18727
|
|
|
@@ -18005,12 +18734,12 @@ class XYZShaderProgram {
|
|
|
18005
18734
|
r_palette[rIndex] / 256.0,
|
|
18006
18735
|
g_palette[gIndex] / 256.0,
|
|
18007
18736
|
b_palette[bIndex] / 256.0,
|
|
18008
|
-
color.a
|
|
18737
|
+
color.a * uOpacity
|
|
18009
18738
|
);
|
|
18010
18739
|
return;
|
|
18011
18740
|
}
|
|
18012
18741
|
|
|
18013
|
-
outColor = color;
|
|
18742
|
+
outColor = vec4(color.rgb, color.a * uOpacity);
|
|
18014
18743
|
}`);
|
|
18015
18744
|
gl.attachShader(this._shaderProgram, vertexShader);
|
|
18016
18745
|
gl.attachShader(this._shaderProgram, fragmentShader);
|
|
@@ -19212,7 +19941,6 @@ exports["default"] = STCSParser;
|
|
|
19212
19941
|
/***/ 7930
|
|
19213
19942
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
19214
19943
|
|
|
19215
|
-
var __webpack_unused_export__;
|
|
19216
19944
|
|
|
19217
19945
|
/*
|
|
19218
19946
|
* AstroViewer
|
|
@@ -19224,9 +19952,10 @@ var __webpack_unused_export__;
|
|
|
19224
19952
|
*
|
|
19225
19953
|
* See LICENSE.md, LICENSE-AGPL.md, and LICENSE-COMMERCIAL.md for details.
|
|
19226
19954
|
*/
|
|
19227
|
-
|
|
19955
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
19228
19956
|
exports.cartesianToSpherical = cartesianToSpherical;
|
|
19229
19957
|
exports.colorHex2RGB = colorHex2RGB;
|
|
19958
|
+
exports.interactionColorsFromHex = interactionColorsFromHex;
|
|
19230
19959
|
exports.degToRad = degToRad;
|
|
19231
19960
|
exports.radToDeg = radToDeg;
|
|
19232
19961
|
exports.sphericalToAstroDeg = sphericalToAstroDeg;
|
|
@@ -19234,6 +19963,8 @@ exports.sphericalToCartesian = sphericalToCartesian;
|
|
|
19234
19963
|
exports.astroDegToSpherical = astroDegToSpherical;
|
|
19235
19964
|
exports.raDegToHMS = raDegToHMS;
|
|
19236
19965
|
exports.decDegToDMS = decDegToDMS;
|
|
19966
|
+
exports.raHMSToDeg = raHMSToDeg;
|
|
19967
|
+
exports.decDMSToDeg = decDMSToDeg;
|
|
19237
19968
|
/**
|
|
19238
19969
|
* @author Fabrizio Giordano (Fab)
|
|
19239
19970
|
*/
|
|
@@ -19264,6 +19995,25 @@ function colorHex2RGB(hexColor) {
|
|
|
19264
19995
|
const rgb3 = (dec3 / 255).toFixed(2);
|
|
19265
19996
|
return [parseFloat(rgb1), parseFloat(rgb2), parseFloat(rgb3)];
|
|
19266
19997
|
}
|
|
19998
|
+
/**
|
|
19999
|
+
* Derive interaction colours from the object's normal colour.
|
|
20000
|
+
* Dark colours move towards white; light colours move towards black.
|
|
20001
|
+
* Selection uses the stronger contrast so selected > hover > normal.
|
|
20002
|
+
*/
|
|
20003
|
+
function interactionColorsFromHex(hexColor) {
|
|
20004
|
+
const base = colorHex2RGB(hexColor);
|
|
20005
|
+
const luminance = 0.2126 * base[0] + 0.7152 * base[1] + 0.0722 * base[2];
|
|
20006
|
+
const target = luminance < 0.55 ? 1.0 : 0.0;
|
|
20007
|
+
const mix = (amount) => [
|
|
20008
|
+
base[0] + (target - base[0]) * amount,
|
|
20009
|
+
base[1] + (target - base[1]) * amount,
|
|
20010
|
+
base[2] + (target - base[2]) * amount,
|
|
20011
|
+
];
|
|
20012
|
+
return {
|
|
20013
|
+
hover: mix(0.45),
|
|
20014
|
+
selected: mix(0.45),
|
|
20015
|
+
};
|
|
20016
|
+
}
|
|
19267
20017
|
function degToRad(degrees) {
|
|
19268
20018
|
return (degrees / 180) * Math.PI;
|
|
19269
20019
|
}
|
|
@@ -19310,6 +20060,13 @@ function decDegToDMS(decDeg) {
|
|
|
19310
20060
|
d = d * sign;
|
|
19311
20061
|
return { d, m, s };
|
|
19312
20062
|
}
|
|
20063
|
+
function raHMSToDeg(hms) {
|
|
20064
|
+
return 15 * (hms.h + hms.m / 60 + hms.s / 3600);
|
|
20065
|
+
}
|
|
20066
|
+
function decDMSToDeg(dms) {
|
|
20067
|
+
const sign = dms.d < 0 || Object.is(dms.d, -0) ? -1 : 1;
|
|
20068
|
+
return sign * (Math.abs(dms.d) + dms.m / 60 + dms.s / 3600);
|
|
20069
|
+
}
|
|
19313
20070
|
|
|
19314
20071
|
|
|
19315
20072
|
/***/ },
|