astro-viewer 3.13.1 → 3.14.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.
@@ -9493,12 +9493,19 @@ class CatalogueGL {
9493
9493
  if (this._catalogueShaderProgram.locations.color) {
9494
9494
  this._webgl.uniform4f(this._catalogueShaderProgram.locations.color, rgb[0], rgb[1], rgb[2], 1.0);
9495
9495
  }
9496
- const interactionColors = (0, Utils_js_1.interactionColorsFromHex)(this._shapeColor);
9496
+ // const interactionColors = interactionColorsFromHex(this._shapeColor);
9497
+ // Complementary RGB colour for catalogue interactions.
9498
+ // Keep the original catalogue colour unchanged.
9499
+ const complementaryColor = rgb.map((component) => 1.0 - component);
9497
9500
  if (this._catalogueShaderProgram.locations.hoverColor) {
9498
- this._webgl.uniform4f(this._catalogueShaderProgram.locations.hoverColor, ...interactionColors.hover, 1.0);
9501
+ this._webgl.uniform4f(this._catalogueShaderProgram.locations.hoverColor,
9502
+ // ...interactionColors.hover,
9503
+ ...complementaryColor, 1.0);
9499
9504
  }
9500
9505
  if (this._catalogueShaderProgram.locations.selectedColor) {
9501
- this._webgl.uniform4f(this._catalogueShaderProgram.locations.selectedColor, ...interactionColors.selected, 1.0);
9506
+ this._webgl.uniform4f(this._catalogueShaderProgram.locations.selectedColor,
9507
+ // ...interactionColors.selected,
9508
+ ...complementaryColor, 1.0);
9502
9509
  }
9503
9510
  // selected flags
9504
9511
  for (let s = 0; s < this.selectedIndexes.length; s++) {
@@ -11149,6 +11156,8 @@ class FootprintSetGL {
11149
11156
  hoveredIndexBuffer;
11150
11157
  selectedVertexPositionBuffer;
11151
11158
  selectedIndexBuffer;
11159
+ selectedFillBuffer;
11160
+ selectedFillVertices = new Float32Array(0);
11152
11161
  indexes;
11153
11162
  footprintPolygons = [];
11154
11163
  vertexCataloguePosition;
@@ -11204,6 +11213,7 @@ class FootprintSetGL {
11204
11213
  this.totSelectedPoints = 0;
11205
11214
  this.selectedIndexes = [];
11206
11215
  this.selectedElementIndexes = new Uint32Array();
11216
+ this.selectedFillVertices = new Float32Array();
11207
11217
  }
11208
11218
  initGLBuffers() {
11209
11219
  if (!this._webgl)
@@ -11214,6 +11224,7 @@ class FootprintSetGL {
11214
11224
  this.hoveredIndexBuffer = this._webgl.createBuffer();
11215
11225
  this.selectedVertexPositionBuffer = this._webgl.createBuffer();
11216
11226
  this.selectedIndexBuffer = this._webgl.createBuffer();
11227
+ this.selectedFillBuffer = this._webgl.createBuffer();
11217
11228
  }
11218
11229
  setIsVisible(visibility) {
11219
11230
  this._isVisible = visibility;
@@ -11391,9 +11402,11 @@ class FootprintSetGL {
11391
11402
  this.selectedVertexPosition = new Float32Array();
11392
11403
  this.selectedElementIndexes = new Uint32Array();
11393
11404
  this.nSlectedPrimitiveFlags = 0;
11405
+ this.selectedFillVertices = new Float32Array();
11394
11406
  return;
11395
11407
  }
11396
11408
  this.initSelectionBuffer();
11409
+ this.selectedFillVertices = this.buildSelectedFillVertices();
11397
11410
  }
11398
11411
  getFootprintsFromPointer(in_mouseHelper) {
11399
11412
  const pickedIndexes = this.checkClicking(in_mouseHelper);
@@ -11646,6 +11659,70 @@ class FootprintSetGL {
11646
11659
  }
11647
11660
  }
11648
11661
  }
11662
+ /** Triangulate selected simple rings in the same 2D projection used for picking.
11663
+ * A failed/degenerate ring is left unfilled; its outline remains visible.
11664
+ */
11665
+ buildSelectedFillVertices() {
11666
+ const vertices = [];
11667
+ const cross = (a, b, c) => (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
11668
+ for (const footprint of this._selectedFootprints) {
11669
+ const projected = footprint.selectionObj?.poly4selection;
11670
+ if (!projected)
11671
+ continue;
11672
+ footprint.polygons.forEach((ring, ringIndex) => {
11673
+ const coords = projected[ringIndex];
11674
+ if (!coords || coords.length !== ring.length || ring.length < 3)
11675
+ return;
11676
+ const indices = ring.map((_, i) => i);
11677
+ // STC-S normally omits the duplicated closing vertex; fromPolygons may not.
11678
+ if (indices.length > 3 &&
11679
+ Math.abs(coords[0].x - coords[indices[indices.length - 1]].x) < 1e-12 &&
11680
+ Math.abs(coords[0].y - coords[indices[indices.length - 1]].y) < 1e-12)
11681
+ indices.pop();
11682
+ if (indices.length < 3)
11683
+ return;
11684
+ const area = indices.reduce((sum, idx, i) => {
11685
+ const next = indices[(i + 1) % indices.length];
11686
+ return sum + coords[idx].x * coords[next].y - coords[next].x * coords[idx].y;
11687
+ }, 0);
11688
+ if (Math.abs(area) < 1e-14)
11689
+ return;
11690
+ const orientation = Math.sign(area);
11691
+ const triangles = [];
11692
+ let attempts = 0;
11693
+ while (indices.length > 3 && attempts++ < ring.length * ring.length) {
11694
+ let clipped = false;
11695
+ for (let i = 0; i < indices.length; i++) {
11696
+ const a = indices[(i + indices.length - 1) % indices.length];
11697
+ const b = indices[i];
11698
+ const c = indices[(i + 1) % indices.length];
11699
+ if (orientation * cross(coords[a], coords[b], coords[c]) <= 1e-14)
11700
+ continue;
11701
+ const contains = indices.some(idx => idx !== a && idx !== b && idx !== c &&
11702
+ orientation * cross(coords[a], coords[b], coords[idx]) >= -1e-14 &&
11703
+ orientation * cross(coords[b], coords[c], coords[idx]) >= -1e-14 &&
11704
+ orientation * cross(coords[c], coords[a], coords[idx]) >= -1e-14);
11705
+ if (contains)
11706
+ continue;
11707
+ triangles.push(a, b, c);
11708
+ indices.splice(i, 1);
11709
+ clipped = true;
11710
+ break;
11711
+ }
11712
+ if (!clipped)
11713
+ break;
11714
+ }
11715
+ if (indices.length !== 3)
11716
+ return;
11717
+ triangles.push(...indices);
11718
+ for (const idx of triangles) {
11719
+ const point = ring[idx];
11720
+ vertices.push(point.x, point.y, point.z);
11721
+ }
11722
+ });
11723
+ }
11724
+ return new Float32Array(vertices);
11725
+ }
11649
11726
  changeColor(color) {
11650
11727
  this._shapeColor = color;
11651
11728
  }
@@ -11662,11 +11739,6 @@ class FootprintSetGL {
11662
11739
  if (!this._webgl)
11663
11740
  return;
11664
11741
  this._footprintShaderProgram.enableShaders(pMatrix, in_mMatrix, vMatrix);
11665
- // this._footprintShaderProgram.enableShaders(
11666
- // computePerspectiveMatrixSingleton.pMatrix as Float32Array,
11667
- // in_mMatrix,
11668
- // vMatrix
11669
- // )
11670
11742
  if (in_mouseHelper != null && in_mouseHelper.xyz != this.oldMouseCoords) {
11671
11743
  this.checkSelection(in_mouseHelper);
11672
11744
  }
@@ -11689,6 +11761,31 @@ class FootprintSetGL {
11689
11761
  }
11690
11762
  if (this._selectedFootprints.length > 0) {
11691
11763
  const rgb = interactionColors.selected;
11764
+ if (this.selectedFillVertices.length > 0) {
11765
+ this._webgl.uniform4f(this._footprintShaderProgram.locations.color, rgb[0], rgb[1], rgb[2], 0.25);
11766
+ this._webgl.bindBuffer(this._webgl.ARRAY_BUFFER, this.selectedFillBuffer);
11767
+ this._webgl.bufferData(this._webgl.ARRAY_BUFFER, this.selectedFillVertices, this._webgl.DYNAMIC_DRAW);
11768
+ this._webgl.vertexAttribPointer(this._footprintShaderProgram.locations.position, FootprintSetGL.ELEM_SIZE, this._webgl.FLOAT, false, FootprintSetGL.BYTES_X_ELEM * FootprintSetGL.ELEM_SIZE, 0);
11769
+ this._webgl.enableVertexAttribArray(this._footprintShaderProgram.locations.position);
11770
+ // Keep translucent fills from writing depth and push them slightly
11771
+ // behind the outlines. Preserve the incoming GL state.
11772
+ const previousDepthMask = this._webgl.getParameter(this._webgl.DEPTH_WRITEMASK);
11773
+ const previousOffsetEnabled = this._webgl.isEnabled(this._webgl.POLYGON_OFFSET_FILL);
11774
+ const previousOffsetFactor = this._webgl.getParameter(this._webgl.POLYGON_OFFSET_FACTOR);
11775
+ const previousOffsetUnits = this._webgl.getParameter(this._webgl.POLYGON_OFFSET_UNITS);
11776
+ this._webgl.depthMask(false);
11777
+ this._webgl.enable(this._webgl.POLYGON_OFFSET_FILL);
11778
+ this._webgl.polygonOffset(1, 1);
11779
+ try {
11780
+ this._webgl.drawArrays(this._webgl.TRIANGLES, 0, this.selectedFillVertices.length / FootprintSetGL.ELEM_SIZE);
11781
+ }
11782
+ finally {
11783
+ this._webgl.depthMask(previousDepthMask);
11784
+ this._webgl.polygonOffset(previousOffsetFactor, previousOffsetUnits);
11785
+ if (!previousOffsetEnabled)
11786
+ this._webgl.disable(this._webgl.POLYGON_OFFSET_FILL);
11787
+ }
11788
+ }
11692
11789
  const alpha = 1.0;
11693
11790
  this._webgl.uniform4f(this._footprintShaderProgram.locations.color, rgb[0], rgb[1], rgb[2], alpha);
11694
11791
  this._webgl.uniform1f(this._footprintShaderProgram.locations.pointSize, 14.0); // <--- POINT_SIZE in LINE_LOOP is not applicable
@@ -18467,14 +18564,29 @@ class ShaderManager {
18467
18564
  alpha = 1.0 - smoothstep(1.0 - delta, 1.0 + delta, r);
18468
18565
  #endif
18469
18566
 
18470
- if (v_selected == 1.0){
18471
- fragColor = u_hovercolor * alpha;
18472
- } else if (v_selected == 2.0){
18473
- // Persistent selection: keep the dataset colour as an outer ring
18474
- // and use the hover colour for the fill. This remains visible for
18475
- // both light and dark user-selected base colours.
18567
+ if (v_selected == 1.0) {
18568
+ // Hover: original catalogue colour on the outer ring,
18569
+ // complementary colour in the centre.
18476
18570
  fragColor = (r > 0.72 ? u_fragcolor : u_hovercolor) * alpha;
18477
- }else{
18571
+
18572
+ } else if (v_selected == 2.0) {
18573
+ // Selected: same ring and fill, plus a contrasting centre dot.
18574
+ if (r < 0.09) {
18575
+ float luminance = dot(
18576
+ u_selectedcolor.rgb,
18577
+ vec3(0.2126, 0.7152, 0.0722)
18578
+ );
18579
+
18580
+ vec3 dotColor = luminance > 0.5
18581
+ ? vec3(0.0)
18582
+ : vec3(1.0);
18583
+
18584
+ fragColor = vec4(dotColor, 1.0) * alpha;
18585
+ } else {
18586
+ fragColor = (r > 0.72 ? u_fragcolor : u_selectedcolor) * alpha;
18587
+ }
18588
+
18589
+ } else {
18478
18590
  if (r < 0.4) {
18479
18591
  discard;
18480
18592
  }
@@ -20267,7 +20379,7 @@ function interactionColorsFromHex(hexColor) {
20267
20379
  ];
20268
20380
  return {
20269
20381
  hover: mix(0.45),
20270
- selected: mix(0.45),
20382
+ selected: mix(0.75),
20271
20383
  };
20272
20384
  }
20273
20385
  function degToRad(degrees) {