vim-web 0.6.0-dev.6 → 0.6.0-dev.8

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/dist/vim-web.js CHANGED
@@ -45955,14 +45955,45 @@ class WebglAttribute {
45955
45955
  attribute.clearUpdateRanges();
45956
45956
  }
45957
45957
  }
45958
+ const LEVELS = 24;
45959
+ const PALETTE_SIZE = 128;
45960
+ function colorToIndex(r, g, b) {
45961
+ const ri = Math.round(r * LEVELS);
45962
+ const gi = Math.round(g * LEVELS);
45963
+ const bi = Math.round(b * LEVELS);
45964
+ return ri * 625 + gi * 25 + bi;
45965
+ }
45966
+ function buildPaletteTexture() {
45967
+ const data2 = new Uint8Array(PALETTE_SIZE * PALETTE_SIZE * 4);
45968
+ const total = (LEVELS + 1) * (LEVELS + 1) * (LEVELS + 1);
45969
+ for (let i = 0; i < total; i++) {
45970
+ const ri = Math.floor(i / 625);
45971
+ const gi = Math.floor(i % 625 / 25);
45972
+ const bi = i % 25;
45973
+ const offset = i * 4;
45974
+ data2[offset] = Math.round(ri / LEVELS * 255);
45975
+ data2[offset + 1] = Math.round(gi / LEVELS * 255);
45976
+ data2[offset + 2] = Math.round(bi / LEVELS * 255);
45977
+ data2[offset + 3] = 255;
45978
+ }
45979
+ return data2;
45980
+ }
45981
+ function buildColorIndices(g3d2, submeshCount) {
45982
+ const indices = new Uint16Array(submeshCount);
45983
+ for (let i = 0; i < submeshCount; i++) {
45984
+ const color = g3d2.getSubmeshColor(i);
45985
+ indices[i] = colorToIndex(color[0], color[1], color[2]);
45986
+ }
45987
+ return indices;
45988
+ }
45958
45989
  class WebglColorAttribute {
45959
- constructor(meshes, value, vim) {
45960
- __publicField(this, "vim");
45990
+ constructor(meshes, value) {
45961
45991
  __publicField(this, "_meshes");
45962
45992
  __publicField(this, "_value");
45993
+ /** Saved original colorIndex values per merged submesh (keyed by submesh identity) */
45994
+ __publicField(this, "_savedIndices", /* @__PURE__ */ new Map());
45963
45995
  this._meshes = meshes;
45964
45996
  this._value = value;
45965
- this.vim = vim;
45966
45997
  }
45967
45998
  updateMeshes(meshes) {
45968
45999
  this._meshes = meshes;
@@ -45986,78 +46017,65 @@ class WebglColorAttribute {
45986
46017
  }
45987
46018
  }
45988
46019
  /**
45989
- * Writes new color to the appropriate section of merged mesh color buffer.
45990
- * @param index index of the merged mesh instance
45991
- * @param color rgb representation of the color to apply
46020
+ * Merged meshes: change the per-vertex colorIndex to the override palette entry.
46021
+ * Saves original values on first override, restores on clear.
45992
46022
  */
45993
46023
  applyMergedColor(sub, color) {
45994
- if (!color) {
45995
- this.resetMergedColor(sub);
45996
- return;
45997
- }
46024
+ const geometry = sub.three.geometry;
46025
+ const attribute = geometry.getAttribute("colorIndex");
46026
+ if (!attribute) return;
45998
46027
  const start = sub.meshStart;
45999
46028
  const end = sub.meshEnd;
46000
- const colors = sub.three.geometry.getAttribute(
46001
- "color"
46002
- );
46003
- const indices = sub.three.geometry.index;
46004
- let c = 0;
46005
- const previous = new Float32Array((end - start) * 3);
46006
- for (let i = start; i < end; i++) {
46007
- const v = indices.getX(i);
46008
- previous[c++] = colors.getX(v);
46009
- previous[c++] = colors.getY(v);
46010
- previous[c++] = colors.getZ(v);
46011
- }
46012
- sub.saveColors(previous);
46013
- for (let i = start; i < end; i++) {
46014
- const v = indices.getX(i);
46015
- colors.setXYZ(v, color.r, color.g, color.b);
46016
- }
46017
- colors.needsUpdate = true;
46018
- colors.clearUpdateRanges();
46019
- }
46020
- resetMergedColor(sub) {
46021
- if (!this.vim) return;
46022
- const previous = sub.popColors();
46023
- if (previous === void 0) return;
46024
- const indices = sub.three.geometry.index;
46025
- const colors = sub.three.geometry.getAttribute(
46026
- "color"
46027
- );
46028
- let c = 0;
46029
- for (let i = sub.meshStart; i < sub.meshEnd; i++) {
46030
- const v = indices.getX(i);
46031
- colors.setXYZ(v, previous[c], previous[c + 1], previous[c + 2]);
46032
- c += 3;
46029
+ const indices = geometry.index;
46030
+ if (color) {
46031
+ if (!this._savedIndices.has(sub)) {
46032
+ const saved = new Uint16Array(end - start);
46033
+ for (let i = start; i < end; i++) {
46034
+ const v = indices.getX(i);
46035
+ saved[i - start] = attribute.getX(v);
46036
+ }
46037
+ this._savedIndices.set(sub, saved);
46038
+ }
46039
+ const palIdx = colorToIndex(color.r, color.g, color.b);
46040
+ for (let i = start; i < end; i++) {
46041
+ const v = indices.getX(i);
46042
+ attribute.setX(v, palIdx);
46043
+ }
46044
+ } else {
46045
+ const saved = this._savedIndices.get(sub);
46046
+ if (saved) {
46047
+ for (let i = start; i < end; i++) {
46048
+ const v = indices.getX(i);
46049
+ attribute.setX(v, saved[i - start]);
46050
+ }
46051
+ this._savedIndices.delete(sub);
46052
+ }
46033
46053
  }
46034
- colors.needsUpdate = true;
46035
- colors.clearUpdateRanges();
46054
+ attribute.needsUpdate = true;
46055
+ attribute.clearUpdateRanges();
46036
46056
  }
46037
46057
  /**
46038
- * Adds an instanceColor buffer to the instanced mesh and sets new color for given instance
46039
- * @param index index of the instanced instance
46040
- * @param color rgb representation of the color to apply
46058
+ * Instanced meshes: set per-instance palette index via instanceColorIndex attribute.
46059
+ * The `colored` flag (set separately) tells the shader to use this instead of per-vertex colorIndex.
46041
46060
  */
46042
46061
  applyInstancedColor(sub, color) {
46043
- const colors = this.getOrAddInstanceColorAttribute(
46044
- sub.three
46045
- );
46046
- if (color) {
46047
- colors.setXYZ(sub.index, color.r, color.g, color.b);
46048
- colors.needsUpdate = true;
46049
- colors.clearUpdateRanges();
46062
+ const mesh = sub.three;
46063
+ const geometry = mesh.geometry;
46064
+ let attribute = geometry.getAttribute("instanceColorIndex");
46065
+ if (!attribute || attribute.count < mesh.instanceMatrix.count) {
46066
+ const count = mesh.instanceMatrix.count;
46067
+ const array = new Float32Array(count);
46068
+ attribute = new InstancedBufferAttribute(array, 1);
46069
+ geometry.setAttribute("instanceColorIndex", attribute);
46050
46070
  }
46051
- }
46052
- getOrAddInstanceColorAttribute(mesh) {
46053
- if (mesh.instanceColor && mesh.instanceColor.count <= mesh.instanceMatrix.count) {
46054
- return mesh.instanceColor;
46071
+ if (color) {
46072
+ const palIdx = colorToIndex(color.r, color.g, color.b);
46073
+ attribute.setX(sub.index, palIdx);
46074
+ } else {
46075
+ attribute.setX(sub.index, 0);
46055
46076
  }
46056
- const count = mesh.instanceMatrix.count;
46057
- const colors = new Float32Array(count * 3);
46058
- const attribute = new InstancedBufferAttribute(colors, 3);
46059
- mesh.instanceColor = attribute;
46060
- return attribute;
46077
+ attribute.needsUpdate = true;
46078
+ attribute.clearUpdateRanges();
46061
46079
  }
46062
46080
  }
46063
46081
  let Element3D$1 = class Element3D {
@@ -46123,7 +46141,7 @@ let Element3D$1 = class Element3D {
46123
46141
  meshes,
46124
46142
  (v) => v ? 1 : 0
46125
46143
  );
46126
- this._colorAttribute = new WebglColorAttribute(meshes, void 0, vim);
46144
+ this._colorAttribute = new WebglColorAttribute(meshes, void 0);
46127
46145
  }
46128
46146
  /** @internal */
46129
46147
  get _vim() {
@@ -46317,7 +46335,7 @@ const _Marker = class _Marker {
46317
46335
  this._visibleAttribute = new WebglAttribute(true, "ignore", "ignore", array, (v) => v ? 0 : 1);
46318
46336
  this._focusedAttribute = new WebglAttribute(false, "focused", "focused", array, (v) => v ? 1 : 0);
46319
46337
  this._coloredAttribute = new WebglAttribute(false, "colored", "colored", array, (v) => v ? 1 : 0);
46320
- this._colorAttribute = new WebglColorAttribute(array, void 0, void 0);
46338
+ this._colorAttribute = new WebglColorAttribute(array, void 0);
46321
46339
  this.color = new Color(16718362);
46322
46340
  }
46323
46341
  /**
@@ -47537,19 +47555,19 @@ class StandardMaterial {
47537
47555
  __publicField(this, "_sectionStrokeWidth", 0.01);
47538
47556
  __publicField(this, "_sectionStrokeFalloff", 0.75);
47539
47557
  __publicField(this, "_sectionStrokeColor", new Color(16185078));
47540
- // Submesh color palette texture (shared, owned by Materials singleton)
47541
- __publicField(this, "_submeshColorTexture");
47558
+ // Color palette texture (shared, owned by Materials singleton)
47559
+ __publicField(this, "_colorPaletteTexture");
47542
47560
  this.three = material;
47543
47561
  this.patchShader(material);
47544
47562
  }
47545
47563
  /**
47546
- * Sets the submesh color texture for indexed color lookup.
47564
+ * Sets the color palette texture for indexed color lookup.
47547
47565
  * The texture is shared between opaque and transparent materials (created in Materials singleton).
47548
47566
  */
47549
- setSubmeshColorTexture(texture) {
47550
- this._submeshColorTexture = texture;
47567
+ setColorPaletteTexture(texture) {
47568
+ this._colorPaletteTexture = texture;
47551
47569
  if (this.uniforms) {
47552
- this.uniforms.submeshColorTexture.value = texture ?? null;
47570
+ this.uniforms.colorPaletteTexture.value = texture ?? null;
47553
47571
  }
47554
47572
  }
47555
47573
  get color() {
@@ -47611,7 +47629,7 @@ class StandardMaterial {
47611
47629
  this.uniforms.sectionStrokeWidth = { value: this._sectionStrokeWidth };
47612
47630
  this.uniforms.sectionStrokeFalloff = { value: this._sectionStrokeFalloff };
47613
47631
  this.uniforms.sectionStrokeColor = { value: this._sectionStrokeColor };
47614
- this.uniforms.submeshColorTexture = { value: this._submeshColorTexture ?? null };
47632
+ this.uniforms.colorPaletteTexture = { value: this._colorPaletteTexture ?? null };
47615
47633
  shader.vertexShader = shader.vertexShader.replace(
47616
47634
  "#include <color_pars_vertex>",
47617
47635
  `
@@ -47619,23 +47637,16 @@ class StandardMaterial {
47619
47637
 
47620
47638
  // COLORING
47621
47639
 
47622
- // attribute for color override
47623
- // merged meshes use it as vertex attribute
47624
- // instanced meshes use it as an instance attribute
47640
+ // Per-vertex color palette index
47641
+ attribute float colorIndex;
47642
+ // Per-instance palette override index (instanced meshes only)
47643
+ attribute float instanceColorIndex;
47644
+ // 1 = use instanceColorIndex, 0 = use per-vertex colorIndex
47625
47645
  attribute float colored;
47646
+ // 128×128 quantized color palette (25³ = 15,625 entries)
47647
+ uniform sampler2D colorPaletteTexture;
47626
47648
 
47627
- // There seems to be an issue where setting mehs.instanceColor
47628
- // doesn't properly set USE_INSTANCING_COLOR
47629
- // so we always use it as a fix
47630
- #ifndef USE_INSTANCING_COLOR
47631
- attribute vec3 instanceColor;
47632
- #endif
47633
-
47634
- // Submesh index for color palette lookup
47635
- attribute float submeshIndex;
47636
- uniform sampler2D submeshColorTexture; // 128×128 RGB texture (16384 colors max)
47637
-
47638
- // Passed to fragment to ignore phong model
47649
+ // Passed to fragment to control lighting model
47639
47650
  varying float vColored;
47640
47651
 
47641
47652
  // VISIBILITY
@@ -47653,18 +47664,13 @@ class StandardMaterial {
47653
47664
  `
47654
47665
  // COLORING
47655
47666
  vColored = colored;
47656
-
47657
- // Get color from texture palette using texelFetch (WebGL 2, faster)
47658
- int texSize = 128;
47659
- int x = int(submeshIndex) % texSize;
47660
- int y = int(submeshIndex) / texSize;
47661
- vColor.xyz = texelFetch(submeshColorTexture, ivec2(x, y), 0).rgb;
47662
-
47663
- // colored == 1 -> instance color
47664
- // colored == 0 -> submesh palette color
47667
+ int palIdx = int(colorIndex);
47665
47668
  #ifdef USE_INSTANCING
47666
- vColor.xyz = colored * instanceColor.xyz + (1.0f - colored) * vColor.xyz;
47669
+ if (colored > 0.5) palIdx = int(instanceColorIndex);
47667
47670
  #endif
47671
+ int x = palIdx % 128;
47672
+ int y = palIdx / 128;
47673
+ vColor.xyz = texelFetch(colorPaletteTexture, ivec2(x, y), 0).rgb;
47668
47674
 
47669
47675
  // VISIBILITY
47670
47676
  vIgnore = ignore;
@@ -54464,20 +54470,20 @@ class ModelMaterial {
54464
54470
  constructor(material, onUpdate) {
54465
54471
  __publicField(this, "three");
54466
54472
  __publicField(this, "_onUpdate");
54467
- // Submesh color palette texture (shared, owned by Materials singleton)
54468
- __publicField(this, "_submeshColorTexture");
54473
+ // Color palette texture (shared, owned by Materials singleton)
54474
+ __publicField(this, "_colorPaletteTexture");
54469
54475
  this.three = material ?? createModelMaterialShader();
54470
54476
  this._onUpdate = onUpdate;
54471
54477
  }
54472
54478
  /**
54473
- * Sets the submesh color texture for indexed color lookup.
54479
+ * Sets the color palette texture for indexed color lookup.
54474
54480
  * The texture is shared between materials (created in Materials singleton).
54475
54481
  */
54476
- setSubmeshColorTexture(texture) {
54482
+ setColorPaletteTexture(texture) {
54477
54483
  var _a3;
54478
- this._submeshColorTexture = texture;
54484
+ this._colorPaletteTexture = texture;
54479
54485
  if (this.three.uniforms) {
54480
- this.three.uniforms.submeshColorTexture.value = texture ?? null;
54486
+ this.three.uniforms.colorPaletteTexture.value = texture ?? null;
54481
54487
  }
54482
54488
  (_a3 = this._onUpdate) == null ? void 0 : _a3.call(this);
54483
54489
  }
@@ -54502,19 +54508,14 @@ function createModelTransparent(onUpdate) {
54502
54508
  function createModelMaterialShader(transparent = false) {
54503
54509
  return new ShaderMaterial({
54504
54510
  side: DoubleSide,
54505
- // Use GLSL ES 3.0 for WebGL 2
54506
54511
  glslVersion: GLSL3,
54507
- // Uniforms for texture-based color palette
54508
54512
  uniforms: {
54509
- submeshColorTexture: { value: null }
54513
+ colorPaletteTexture: { value: null }
54510
54514
  },
54511
- // Enable support for clipping planes.
54512
54515
  clipping: true,
54513
- // Transparency settings
54514
54516
  transparent,
54515
54517
  opacity: transparent ? 0.25 : 1,
54516
54518
  depthWrite: !transparent,
54517
- // Disable depth write for transparent materials
54518
54519
  vertexShader: (
54519
54520
  /* glsl */
54520
54521
  `
@@ -54523,29 +54524,16 @@ function createModelMaterialShader(transparent = false) {
54523
54524
  #include <clipping_planes_pars_vertex>
54524
54525
 
54525
54526
  // VISIBILITY
54526
- // Determines if an object or vertex should be visible.
54527
- // Used as an instance attribute for instanced meshes or as a vertex attribute for merged meshes.
54528
54527
  in float ignore;
54529
54528
 
54530
54529
  // COLORING
54531
- // Passes the color of the vertex or instance to the fragment shader.
54532
54530
  out vec3 vColor;
54533
54531
  out vec3 vViewPosition;
54534
54532
 
54535
- // Determines whether to use instance color (1 = instance, 0 = submesh).
54536
- // For merged meshes, this is used as a vertex attribute.
54537
- // For instanced meshes, this is used as an instance attribute.
54533
+ in float colorIndex;
54534
+ in float instanceColorIndex;
54538
54535
  in float colored;
54539
-
54540
- // Submesh index for color palette lookup
54541
- in float submeshIndex;
54542
- uniform sampler2D submeshColorTexture;
54543
-
54544
- // Fix for a known issue where setting mesh.instanceColor does not properly enable USE_INSTANCING_COLOR.
54545
- // This ensures that instance colors are always used when required.
54546
- #ifndef USE_INSTANCING_COLOR
54547
- in vec3 instanceColor;
54548
- #endif
54536
+ uniform sampler2D colorPaletteTexture;
54549
54537
 
54550
54538
  void main() {
54551
54539
  #include <begin_vertex>
@@ -54553,28 +54541,20 @@ function createModelMaterialShader(transparent = false) {
54553
54541
  #include <clipping_planes_vertex>
54554
54542
  #include <logdepthbuf_vertex>
54555
54543
 
54556
- // Place ignored vertices behind near plane to clip them.
54557
54544
  if (ignore > 0.5) {
54558
54545
  gl_Position = vec4(0.0, 0.0, -2.0, 1.0);
54559
54546
  return;
54560
54547
  }
54561
54548
 
54562
- // COLORING
54563
- // Get color from texture palette using texelFetch (WebGL 2, faster for indexed access)
54564
- int texSize = 128;
54565
- int colorIndex = int(submeshIndex);
54566
- int x = colorIndex % texSize;
54567
- int y = colorIndex / texSize;
54568
- vColor = texelFetch(submeshColorTexture, ivec2(x, y), 0).rgb;
54569
-
54570
- // Blend instance and submesh colors based on the colored attribute.
54571
- // colored == 1 -> use instance color.
54572
- // colored == 0 -> use submesh color from texture.
54549
+ // COLORING — unified palette lookup
54550
+ int palIdx = int(colorIndex);
54573
54551
  #ifdef USE_INSTANCING
54574
- vColor.xyz = colored * instanceColor.xyz + (1.0 - colored) * vColor.xyz;
54552
+ if (colored > 0.5) palIdx = int(instanceColorIndex);
54575
54553
  #endif
54554
+ int x = palIdx % 128;
54555
+ int y = palIdx / 128;
54556
+ vColor = texelFetch(colorPaletteTexture, ivec2(x, y), 0).rgb;
54576
54557
 
54577
- // Pass view position to fragment for screen-space derivatives
54578
54558
  vViewPosition = -mvPosition.xyz;
54579
54559
  }
54580
54560
  `
@@ -54586,7 +54566,6 @@ function createModelMaterialShader(transparent = false) {
54586
54566
  #include <logdepthbuf_pars_fragment>
54587
54567
  #include <clipping_planes_pars_fragment>
54588
54568
 
54589
- // Color and position for screen-space derivative lighting
54590
54569
  in vec3 vColor;
54591
54570
  in vec3 vViewPosition;
54592
54571
 
@@ -54600,13 +54579,11 @@ function createModelMaterialShader(transparent = false) {
54600
54579
  vec3 fdx = dFdx(vViewPosition);
54601
54580
  vec3 fdy = dFdy(vViewPosition);
54602
54581
  vec3 normal = normalize(cross(fdx, fdy));
54603
- // Pre-normalized light direction (sqrt(2), sqrt(3), sqrt(5)) / sqrt(10)
54604
54582
  const vec3 LIGHT_DIR = vec3(0.447214, 0.547723, 0.707107);
54605
54583
  float light = dot(normal, LIGHT_DIR);
54606
- light = 0.5 + (light * 0.5); // Remap to [0.5, 1.0]
54584
+ light = 0.5 + (light * 0.5);
54607
54585
  vec3 finalColor = vColor * light;
54608
54586
 
54609
- // Output final color
54610
54587
  fragColor = vec4(finalColor, ${transparent ? "0.25" : "1.0"});
54611
54588
  }
54612
54589
  `
@@ -54646,8 +54623,8 @@ const _Materials = class _Materials {
54646
54623
  __publicField(this, "_sectionStrokeFalloff", 0.75);
54647
54624
  __publicField(this, "_sectionStrokeColor", new Color(16185078));
54648
54625
  __publicField(this, "_onUpdate", new distExports$2.SignalDispatcher());
54649
- // Shared color palette texture for both opaque and transparent materials
54650
- __publicField(this, "_submeshColorTexture");
54626
+ // Shared color palette texture for all scene materials
54627
+ __publicField(this, "_colorPaletteTexture");
54651
54628
  this._opaque = opaque ?? createOpaque();
54652
54629
  this._transparent = transparent ?? createTransparent();
54653
54630
  const onUpdate = () => this._onUpdate.dispatch();
@@ -54785,55 +54762,34 @@ const _Materials = class _Materials {
54785
54762
  this._onUpdate.dispatch();
54786
54763
  }
54787
54764
  /**
54788
- * Sets the submesh color palette for both opaque and transparent materials.
54789
- * Creates a single shared DataTexture from the palette (128×128 RGBA, 16384 colors max).
54790
- * If palette is undefined, creates a white fallback texture.
54765
+ * Creates the fixed quantized color palette texture if it doesn't exist.
54766
+ * The palette is deterministic (25³ = 15,625 quantized colors in 128×128 texture)
54767
+ * and shared across all scene materials.
54791
54768
  */
54792
- setColorPalette(palette) {
54793
- if (this._submeshColorTexture) {
54794
- this._submeshColorTexture.dispose();
54795
- this._submeshColorTexture = void 0;
54796
- }
54797
- const textureSize = 128;
54798
- const textureData = new Uint8Array(textureSize * textureSize * 4);
54799
- if (palette && palette.length > 0) {
54800
- const colorCount = Math.min(palette.length / 3, textureSize * textureSize);
54801
- for (let i = 0; i < colorCount; i++) {
54802
- textureData[i * 4] = Math.round(palette[i * 3] * 255);
54803
- textureData[i * 4 + 1] = Math.round(palette[i * 3 + 1] * 255);
54804
- textureData[i * 4 + 2] = Math.round(palette[i * 3 + 2] * 255);
54805
- textureData[i * 4 + 3] = 255;
54806
- }
54807
- } else {
54808
- console.warn("[Color Optimization] Palette undefined, using white fallback texture");
54809
- for (let i = 0; i < textureSize * textureSize * 4; i += 4) {
54810
- textureData[i] = 255;
54811
- textureData[i + 1] = 255;
54812
- textureData[i + 2] = 255;
54813
- textureData[i + 3] = 255;
54814
- }
54815
- }
54816
- this._submeshColorTexture = new DataTexture(
54769
+ ensureColorPalette() {
54770
+ if (this._colorPaletteTexture) return;
54771
+ const textureData = buildPaletteTexture();
54772
+ this._colorPaletteTexture = new DataTexture(
54817
54773
  textureData,
54818
- textureSize,
54819
- textureSize,
54774
+ 128,
54775
+ 128,
54820
54776
  RGBAFormat,
54821
54777
  UnsignedByteType
54822
54778
  );
54823
- this._submeshColorTexture.needsUpdate = true;
54824
- this._submeshColorTexture.minFilter = NearestFilter;
54825
- this._submeshColorTexture.magFilter = NearestFilter;
54826
- this._opaque.setSubmeshColorTexture(this._submeshColorTexture);
54827
- this._transparent.setSubmeshColorTexture(this._submeshColorTexture);
54828
- this._modelOpaque.setSubmeshColorTexture(this._submeshColorTexture);
54829
- this._modelTransparent.setSubmeshColorTexture(this._submeshColorTexture);
54779
+ this._colorPaletteTexture.needsUpdate = true;
54780
+ this._colorPaletteTexture.minFilter = NearestFilter;
54781
+ this._colorPaletteTexture.magFilter = NearestFilter;
54782
+ this._opaque.setColorPaletteTexture(this._colorPaletteTexture);
54783
+ this._transparent.setColorPaletteTexture(this._colorPaletteTexture);
54784
+ this._modelOpaque.setColorPaletteTexture(this._colorPaletteTexture);
54785
+ this._modelTransparent.setColorPaletteTexture(this._colorPaletteTexture);
54830
54786
  this._onUpdate.dispatch();
54831
54787
  }
54832
54788
  /** dispose all materials. */
54833
54789
  dispose() {
54834
- if (this._submeshColorTexture) {
54835
- this._submeshColorTexture.dispose();
54836
- this._submeshColorTexture = void 0;
54790
+ if (this._colorPaletteTexture) {
54791
+ this._colorPaletteTexture.dispose();
54792
+ this._colorPaletteTexture = void 0;
54837
54793
  }
54838
54794
  this._opaque.dispose();
54839
54795
  this._transparent.dispose();
@@ -56895,7 +56851,7 @@ function isTransparencyModeValid(value) {
56895
56851
  );
56896
56852
  }
56897
56853
  function createGeometryFromMesh(g3d2, mesh, section) {
56898
- const colorPaletteIndex = createColorPaletteIndices(g3d2, mesh, section);
56854
+ const colorIndices = createColorIndices(g3d2, mesh, section);
56899
56855
  const positions = g3d2.positions.subarray(
56900
56856
  g3d2.getMeshVertexStart(mesh) * 3,
56901
56857
  g3d2.getMeshVertexEnd(mesh) * 3
@@ -56906,10 +56862,10 @@ function createGeometryFromMesh(g3d2, mesh, section) {
56906
56862
  return createGeometryFromArrays(
56907
56863
  positions,
56908
56864
  indices,
56909
- colorPaletteIndex
56865
+ colorIndices
56910
56866
  );
56911
56867
  }
56912
- function createColorPaletteIndices(g3d2, mesh, section) {
56868
+ function createColorIndices(g3d2, mesh, section) {
56913
56869
  const vertexCount = g3d2.getMeshVertexCount(mesh);
56914
56870
  const result = new Uint16Array(vertexCount);
56915
56871
  const subStart = g3d2.getMeshSubmeshStart(mesh, section);
@@ -56917,7 +56873,7 @@ function createColorPaletteIndices(g3d2, mesh, section) {
56917
56873
  for (let submesh = subStart; submesh < subEnd; submesh++) {
56918
56874
  const start = g3d2.getSubmeshIndexStart(submesh);
56919
56875
  const end = g3d2.getSubmeshIndexEnd(submesh);
56920
- const index2 = g3d2.submeshColor[submesh];
56876
+ const index2 = g3d2.colorIndices[submesh];
56921
56877
  for (let i = start; i < end; i++) {
56922
56878
  const vertexIndex = g3d2.indices[i];
56923
56879
  result[vertexIndex] = index2;
@@ -56925,14 +56881,14 @@ function createColorPaletteIndices(g3d2, mesh, section) {
56925
56881
  }
56926
56882
  return result;
56927
56883
  }
56928
- function createGeometryFromArrays(vertices, indices, colorPaletteIndex = void 0) {
56884
+ function createGeometryFromArrays(vertices, indices, colorIndices = void 0) {
56929
56885
  const geometry = new BufferGeometry();
56930
56886
  geometry.setAttribute("position", new BufferAttribute(vertices, 3));
56931
56887
  geometry.setIndex(new Uint32BufferAttribute(indices, 1));
56932
- if (colorPaletteIndex) {
56888
+ if (colorIndices) {
56933
56889
  geometry.setAttribute(
56934
- "submeshIndex",
56935
- new Uint16BufferAttribute(colorPaletteIndex, 1)
56890
+ "colorIndex",
56891
+ new Uint16BufferAttribute(colorIndices, 1)
56936
56892
  );
56937
56893
  }
56938
56894
  return geometry;
@@ -56986,8 +56942,7 @@ class InsertableGeometry {
56986
56942
  __publicField(this, "_computeBoundingBox", false);
56987
56943
  __publicField(this, "_indexAttribute");
56988
56944
  __publicField(this, "_vertexAttribute");
56989
- __publicField(this, "_submeshIndexAttribute");
56990
- // Color palette index for texture-based color lookup
56945
+ __publicField(this, "_colorIndexAttribute");
56991
56946
  __publicField(this, "_packedIdAttribute");
56992
56947
  __publicField(this, "_mapping");
56993
56948
  __publicField(this, "_vimIndex");
@@ -57006,7 +56961,7 @@ class InsertableGeometry {
57006
56961
  offsets.counts.vertices * distExports$1.G3d.POSITION_SIZE,
57007
56962
  distExports$1.G3d.POSITION_SIZE
57008
56963
  );
57009
- this._submeshIndexAttribute = new Uint16BufferAttribute(
56964
+ this._colorIndexAttribute = new Uint16BufferAttribute(
57010
56965
  offsets.counts.vertices,
57011
56966
  1
57012
56967
  );
@@ -57017,7 +56972,7 @@ class InsertableGeometry {
57017
56972
  this.geometry = new BufferGeometry();
57018
56973
  this.geometry.setIndex(this._indexAttribute);
57019
56974
  this.geometry.setAttribute("position", this._vertexAttribute);
57020
- this.geometry.setAttribute("submeshIndex", this._submeshIndexAttribute);
56975
+ this.geometry.setAttribute("colorIndex", this._colorIndexAttribute);
57021
56976
  this.geometry.setAttribute("packedId", this._packedIdAttribute);
57022
56977
  this.boundingBox = new Box3();
57023
56978
  this.boundingBox.makeEmpty();
@@ -57062,16 +57017,16 @@ class InsertableGeometry {
57062
57017
  submesh.instance = instanceNodes[g3dInstance];
57063
57018
  submesh.start = indexOffset + indexOut;
57064
57019
  const indices = this._indexAttribute.array;
57065
- const submeshIndices = this._submeshIndexAttribute.array;
57020
+ const colorIndices = this._colorIndexAttribute.array;
57066
57021
  const mergeOffset = instance * vertexCount;
57067
57022
  for (let sub = subStart; sub < subEnd; sub++) {
57068
57023
  const indexStart = g3d2.getSubmeshIndexStart(sub);
57069
57024
  const indexEnd = g3d2.getSubmeshIndexEnd(sub);
57070
- const colorIndex = g3d2.submeshColor[sub];
57025
+ const colorIndex = g3d2.colorIndices[sub];
57071
57026
  for (let index2 = indexStart; index2 < indexEnd; index2++) {
57072
57027
  const v = vertexOffset + mergeOffset + g3d2.indices[index2];
57073
57028
  indices[indexOffset + indexOut] = v;
57074
- submeshIndices[v] = colorIndex;
57029
+ colorIndices[v] = colorIndex;
57075
57030
  indexOut++;
57076
57031
  }
57077
57032
  }
@@ -57137,8 +57092,8 @@ class InsertableGeometry {
57137
57092
  const vSize = this._vertexAttribute.itemSize;
57138
57093
  this._vertexAttribute.addUpdateRange(vertexStart * vSize, (vertexEnd - vertexStart) * vSize);
57139
57094
  this._vertexAttribute.needsUpdate = true;
57140
- this._submeshIndexAttribute.addUpdateRange(vertexStart, vertexEnd - vertexStart);
57141
- this._submeshIndexAttribute.needsUpdate = true;
57095
+ this._colorIndexAttribute.addUpdateRange(vertexStart, vertexEnd - vertexStart);
57096
+ this._colorIndexAttribute.needsUpdate = true;
57142
57097
  this._packedIdAttribute.addUpdateRange(vertexStart, vertexEnd - vertexStart);
57143
57098
  this._packedIdAttribute.needsUpdate = true;
57144
57099
  if (this._computeBoundingBox) {
@@ -57151,7 +57106,6 @@ class InsertableSubmesh {
57151
57106
  constructor(mesh, index2) {
57152
57107
  __publicField(this, "mesh");
57153
57108
  __publicField(this, "index");
57154
- __publicField(this, "_colors");
57155
57109
  this.mesh = mesh;
57156
57110
  this.index = index2;
57157
57111
  }
@@ -57203,15 +57157,6 @@ class InsertableSubmesh {
57203
57157
  get object() {
57204
57158
  return this.mesh.vim.getElement(this.instance);
57205
57159
  }
57206
- saveColors(colors) {
57207
- if (this._colors) return;
57208
- this._colors = colors;
57209
- }
57210
- popColors() {
57211
- const result = this._colors;
57212
- this._colors = void 0;
57213
- return result;
57214
- }
57215
57160
  }
57216
57161
  class InsertableMesh {
57217
57162
  constructor(offsets, materials, transparent, mapping, vimIndex = 0) {
@@ -57528,57 +57473,6 @@ function requireLogging() {
57528
57473
  return logging;
57529
57474
  }
57530
57475
  var loggingExports = requireLogging();
57531
- const MAX_COLORS = 16384;
57532
- const QUANTIZATION_LEVELS = 25;
57533
- function buildColorPalette(mappedG3d, submeshColorCount) {
57534
- const uniqueColorsMap = /* @__PURE__ */ new Map();
57535
- const colorPaletteArray = [];
57536
- const submeshColor = new Uint16Array(submeshColorCount);
57537
- for (let i = 0; i < submeshColorCount; i++) {
57538
- const color = mappedG3d.getSubmeshColor(i);
57539
- const key = packColorKey(color[0], color[1], color[2]);
57540
- let colorIndex = uniqueColorsMap.get(key);
57541
- if (colorIndex === void 0) {
57542
- colorIndex = colorPaletteArray.length / 3;
57543
- uniqueColorsMap.set(key, colorIndex);
57544
- colorPaletteArray.push(color[0], color[1], color[2]);
57545
- }
57546
- submeshColor[i] = colorIndex;
57547
- }
57548
- let uniqueColorCount = uniqueColorsMap.size;
57549
- if (uniqueColorCount > MAX_COLORS) {
57550
- quantizeColors(mappedG3d.materialColors, QUANTIZATION_LEVELS);
57551
- uniqueColorsMap.clear();
57552
- colorPaletteArray.length = 0;
57553
- for (let i = 0; i < submeshColorCount; i++) {
57554
- const color = mappedG3d.getSubmeshColor(i);
57555
- const key = packColorKey(color[0], color[1], color[2]);
57556
- let colorIndex = uniqueColorsMap.get(key);
57557
- if (colorIndex === void 0) {
57558
- colorIndex = colorPaletteArray.length / 3;
57559
- uniqueColorsMap.set(key, colorIndex);
57560
- colorPaletteArray.push(color[0], color[1], color[2]);
57561
- }
57562
- submeshColor[i] = colorIndex;
57563
- }
57564
- uniqueColorCount = uniqueColorsMap.size;
57565
- }
57566
- if (uniqueColorCount <= MAX_COLORS) {
57567
- const palette = new Float32Array(colorPaletteArray);
57568
- return { palette, submeshColor, uniqueColorCount };
57569
- } else {
57570
- return { palette: void 0, submeshColor, uniqueColorCount };
57571
- }
57572
- }
57573
- function packColorKey(r, g, b) {
57574
- return (Math.round(r * 65535) * 65536 + Math.round(g * 65535)) * 65536 + Math.round(b * 65535);
57575
- }
57576
- function quantizeColors(colors, levels) {
57577
- const quantize = (value) => Math.round(value * levels) / levels;
57578
- for (let i = 0; i < colors.length; i++) {
57579
- colors[i] = quantize(colors[i]);
57580
- }
57581
- }
57582
57476
  function createMappedG3d(g3d2) {
57583
57477
  const mapped = g3d2;
57584
57478
  const map = /* @__PURE__ */ new Map();
@@ -57602,11 +57496,7 @@ function createMappedG3d(g3d2) {
57602
57496
  mapped._meshKeys = meshKeys;
57603
57497
  mapped._meshValues = meshValues;
57604
57498
  mapped._totalInstanceCount = totalCount;
57605
- const submeshColorCount = mapped.submeshMaterial.length;
57606
- const { palette, submeshColor, uniqueColorCount } = buildColorPalette(mapped, submeshColorCount);
57607
- mapped.colorPalette = palette;
57608
- mapped.submeshColor = submeshColor;
57609
- mapped.uniqueColorCount = uniqueColorCount;
57499
+ mapped.colorIndices = buildColorIndices(mapped, mapped.submeshMaterial.length);
57610
57500
  return mapped;
57611
57501
  }
57612
57502
  let LoadRequest$2 = class LoadRequest2 extends LoadRequest$3 {
@@ -57651,7 +57541,7 @@ let LoadRequest$2 = class LoadRequest2 extends LoadRequest$3 {
57651
57541
  const mapping = await ElementMapping.fromG3d(doc);
57652
57542
  const scene = new Scene2(fullSettings.matrix);
57653
57543
  const factory = new VimMeshFactory(mappedG3d, materials, scene, mapping, vimIndex);
57654
- Materials.getInstance().setColorPalette(mappedG3d.colorPalette);
57544
+ Materials.getInstance().ensureColorPalette();
57655
57545
  const header = await distExports$1.requestHeader(bfast2);
57656
57546
  const vim = new Vim$1(
57657
57547
  header,
@@ -57716,10 +57606,10 @@ class WebglViewer {
57716
57606
  this._camera,
57717
57607
  this.settings
57718
57608
  );
57609
+ this.selection = createSelection$1();
57719
57610
  this._inputs = createInputHandler(this);
57720
57611
  this._gizmos = new Gizmos(this._renderer, this._viewport, this, this._camera);
57721
57612
  this.materials.applySettings(this.settings.materials);
57722
- this.selection = createSelection$1();
57723
57613
  const size = this._renderer.three.getSize(new Vector2());
57724
57614
  const gpuPicker = new GpuPicker(
57725
57615
  this._renderer.three,
@@ -60311,11 +60201,13 @@ class SocketClient {
60311
60201
  */
60312
60202
  async _onOpen(_) {
60313
60203
  var _a3;
60204
+ console.log("WebSocket connection opened to ", this.url);
60314
60205
  clearTimeout(this._connectionTimeout);
60315
60206
  this.updateState({ status: "validating" });
60316
60207
  const issues = await this._validateConnection();
60317
60208
  if (issues !== void 0) {
60318
60209
  this._disconnect(issues);
60210
+ this._connectPromise.resolve(false);
60319
60211
  return;
60320
60212
  }
60321
60213
  this._logger.log("Connected to: ", (_a3 = this._socket) == null ? void 0 : _a3.url);