vim-web 0.6.0-dev.5 → 0.6.0-dev.7

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.
@@ -45971,14 +45971,45 @@ void main() {
45971
45971
  attribute.clearUpdateRanges();
45972
45972
  }
45973
45973
  }
45974
+ const LEVELS = 24;
45975
+ const PALETTE_SIZE = 128;
45976
+ function colorToIndex(r, g, b) {
45977
+ const ri = Math.round(r * LEVELS);
45978
+ const gi = Math.round(g * LEVELS);
45979
+ const bi = Math.round(b * LEVELS);
45980
+ return ri * 625 + gi * 25 + bi;
45981
+ }
45982
+ function buildPaletteTexture() {
45983
+ const data2 = new Uint8Array(PALETTE_SIZE * PALETTE_SIZE * 4);
45984
+ const total = (LEVELS + 1) * (LEVELS + 1) * (LEVELS + 1);
45985
+ for (let i2 = 0; i2 < total; i2++) {
45986
+ const ri = Math.floor(i2 / 625);
45987
+ const gi = Math.floor(i2 % 625 / 25);
45988
+ const bi = i2 % 25;
45989
+ const offset = i2 * 4;
45990
+ data2[offset] = Math.round(ri / LEVELS * 255);
45991
+ data2[offset + 1] = Math.round(gi / LEVELS * 255);
45992
+ data2[offset + 2] = Math.round(bi / LEVELS * 255);
45993
+ data2[offset + 3] = 255;
45994
+ }
45995
+ return data2;
45996
+ }
45997
+ function buildColorIndices(g3d2, submeshCount) {
45998
+ const indices = new Uint16Array(submeshCount);
45999
+ for (let i2 = 0; i2 < submeshCount; i2++) {
46000
+ const color = g3d2.getSubmeshColor(i2);
46001
+ indices[i2] = colorToIndex(color[0], color[1], color[2]);
46002
+ }
46003
+ return indices;
46004
+ }
45974
46005
  class WebglColorAttribute {
45975
- constructor(meshes, value, vim) {
45976
- __publicField(this, "vim");
46006
+ constructor(meshes, value) {
45977
46007
  __publicField(this, "_meshes");
45978
46008
  __publicField(this, "_value");
46009
+ /** Saved original colorIndex values per merged submesh (keyed by submesh identity) */
46010
+ __publicField(this, "_savedIndices", /* @__PURE__ */ new Map());
45979
46011
  this._meshes = meshes;
45980
46012
  this._value = value;
45981
- this.vim = vim;
45982
46013
  }
45983
46014
  updateMeshes(meshes) {
45984
46015
  this._meshes = meshes;
@@ -46002,78 +46033,65 @@ void main() {
46002
46033
  }
46003
46034
  }
46004
46035
  /**
46005
- * Writes new color to the appropriate section of merged mesh color buffer.
46006
- * @param index index of the merged mesh instance
46007
- * @param color rgb representation of the color to apply
46036
+ * Merged meshes: change the per-vertex colorIndex to the override palette entry.
46037
+ * Saves original values on first override, restores on clear.
46008
46038
  */
46009
46039
  applyMergedColor(sub, color) {
46010
- if (!color) {
46011
- this.resetMergedColor(sub);
46012
- return;
46013
- }
46040
+ const geometry = sub.three.geometry;
46041
+ const attribute = geometry.getAttribute("colorIndex");
46042
+ if (!attribute) return;
46014
46043
  const start = sub.meshStart;
46015
46044
  const end = sub.meshEnd;
46016
- const colors = sub.three.geometry.getAttribute(
46017
- "color"
46018
- );
46019
- const indices = sub.three.geometry.index;
46020
- let c = 0;
46021
- const previous = new Float32Array((end - start) * 3);
46022
- for (let i2 = start; i2 < end; i2++) {
46023
- const v = indices.getX(i2);
46024
- previous[c++] = colors.getX(v);
46025
- previous[c++] = colors.getY(v);
46026
- previous[c++] = colors.getZ(v);
46027
- }
46028
- sub.saveColors(previous);
46029
- for (let i2 = start; i2 < end; i2++) {
46030
- const v = indices.getX(i2);
46031
- colors.setXYZ(v, color.r, color.g, color.b);
46032
- }
46033
- colors.needsUpdate = true;
46034
- colors.clearUpdateRanges();
46035
- }
46036
- resetMergedColor(sub) {
46037
- if (!this.vim) return;
46038
- const previous = sub.popColors();
46039
- if (previous === void 0) return;
46040
- const indices = sub.three.geometry.index;
46041
- const colors = sub.three.geometry.getAttribute(
46042
- "color"
46043
- );
46044
- let c = 0;
46045
- for (let i2 = sub.meshStart; i2 < sub.meshEnd; i2++) {
46046
- const v = indices.getX(i2);
46047
- colors.setXYZ(v, previous[c], previous[c + 1], previous[c + 2]);
46048
- c += 3;
46045
+ const indices = geometry.index;
46046
+ if (color) {
46047
+ if (!this._savedIndices.has(sub)) {
46048
+ const saved = new Uint16Array(end - start);
46049
+ for (let i2 = start; i2 < end; i2++) {
46050
+ const v = indices.getX(i2);
46051
+ saved[i2 - start] = attribute.getX(v);
46052
+ }
46053
+ this._savedIndices.set(sub, saved);
46054
+ }
46055
+ const palIdx = colorToIndex(color.r, color.g, color.b);
46056
+ for (let i2 = start; i2 < end; i2++) {
46057
+ const v = indices.getX(i2);
46058
+ attribute.setX(v, palIdx);
46059
+ }
46060
+ } else {
46061
+ const saved = this._savedIndices.get(sub);
46062
+ if (saved) {
46063
+ for (let i2 = start; i2 < end; i2++) {
46064
+ const v = indices.getX(i2);
46065
+ attribute.setX(v, saved[i2 - start]);
46066
+ }
46067
+ this._savedIndices.delete(sub);
46068
+ }
46049
46069
  }
46050
- colors.needsUpdate = true;
46051
- colors.clearUpdateRanges();
46070
+ attribute.needsUpdate = true;
46071
+ attribute.clearUpdateRanges();
46052
46072
  }
46053
46073
  /**
46054
- * Adds an instanceColor buffer to the instanced mesh and sets new color for given instance
46055
- * @param index index of the instanced instance
46056
- * @param color rgb representation of the color to apply
46074
+ * Instanced meshes: set per-instance palette index via instanceColorIndex attribute.
46075
+ * The `colored` flag (set separately) tells the shader to use this instead of per-vertex colorIndex.
46057
46076
  */
46058
46077
  applyInstancedColor(sub, color) {
46059
- const colors = this.getOrAddInstanceColorAttribute(
46060
- sub.three
46061
- );
46062
- if (color) {
46063
- colors.setXYZ(sub.index, color.r, color.g, color.b);
46064
- colors.needsUpdate = true;
46065
- colors.clearUpdateRanges();
46078
+ const mesh = sub.three;
46079
+ const geometry = mesh.geometry;
46080
+ let attribute = geometry.getAttribute("instanceColorIndex");
46081
+ if (!attribute || attribute.count < mesh.instanceMatrix.count) {
46082
+ const count = mesh.instanceMatrix.count;
46083
+ const array = new Float32Array(count);
46084
+ attribute = new InstancedBufferAttribute(array, 1);
46085
+ geometry.setAttribute("instanceColorIndex", attribute);
46066
46086
  }
46067
- }
46068
- getOrAddInstanceColorAttribute(mesh) {
46069
- if (mesh.instanceColor && mesh.instanceColor.count <= mesh.instanceMatrix.count) {
46070
- return mesh.instanceColor;
46087
+ if (color) {
46088
+ const palIdx = colorToIndex(color.r, color.g, color.b);
46089
+ attribute.setX(sub.index, palIdx);
46090
+ } else {
46091
+ attribute.setX(sub.index, 0);
46071
46092
  }
46072
- const count = mesh.instanceMatrix.count;
46073
- const colors = new Float32Array(count * 3);
46074
- const attribute = new InstancedBufferAttribute(colors, 3);
46075
- mesh.instanceColor = attribute;
46076
- return attribute;
46093
+ attribute.needsUpdate = true;
46094
+ attribute.clearUpdateRanges();
46077
46095
  }
46078
46096
  }
46079
46097
  let Element3D$1 = class Element3D {
@@ -46139,7 +46157,7 @@ void main() {
46139
46157
  meshes,
46140
46158
  (v) => v ? 1 : 0
46141
46159
  );
46142
- this._colorAttribute = new WebglColorAttribute(meshes, void 0, vim);
46160
+ this._colorAttribute = new WebglColorAttribute(meshes, void 0);
46143
46161
  }
46144
46162
  /** @internal */
46145
46163
  get _vim() {
@@ -46333,7 +46351,7 @@ void main() {
46333
46351
  this._visibleAttribute = new WebglAttribute(true, "ignore", "ignore", array, (v) => v ? 0 : 1);
46334
46352
  this._focusedAttribute = new WebglAttribute(false, "focused", "focused", array, (v) => v ? 1 : 0);
46335
46353
  this._coloredAttribute = new WebglAttribute(false, "colored", "colored", array, (v) => v ? 1 : 0);
46336
- this._colorAttribute = new WebglColorAttribute(array, void 0, void 0);
46354
+ this._colorAttribute = new WebglColorAttribute(array, void 0);
46337
46355
  this.color = new Color(16718362);
46338
46356
  }
46339
46357
  /**
@@ -47553,19 +47571,19 @@ void main() {
47553
47571
  __publicField(this, "_sectionStrokeWidth", 0.01);
47554
47572
  __publicField(this, "_sectionStrokeFalloff", 0.75);
47555
47573
  __publicField(this, "_sectionStrokeColor", new Color(16185078));
47556
- // Submesh color palette texture (shared, owned by Materials singleton)
47557
- __publicField(this, "_submeshColorTexture");
47574
+ // Color palette texture (shared, owned by Materials singleton)
47575
+ __publicField(this, "_colorPaletteTexture");
47558
47576
  this.three = material;
47559
47577
  this.patchShader(material);
47560
47578
  }
47561
47579
  /**
47562
- * Sets the submesh color texture for indexed color lookup.
47580
+ * Sets the color palette texture for indexed color lookup.
47563
47581
  * The texture is shared between opaque and transparent materials (created in Materials singleton).
47564
47582
  */
47565
- setSubmeshColorTexture(texture) {
47566
- this._submeshColorTexture = texture;
47583
+ setColorPaletteTexture(texture) {
47584
+ this._colorPaletteTexture = texture;
47567
47585
  if (this.uniforms) {
47568
- this.uniforms.submeshColorTexture.value = texture ?? null;
47586
+ this.uniforms.colorPaletteTexture.value = texture ?? null;
47569
47587
  }
47570
47588
  }
47571
47589
  get color() {
@@ -47627,7 +47645,7 @@ void main() {
47627
47645
  this.uniforms.sectionStrokeWidth = { value: this._sectionStrokeWidth };
47628
47646
  this.uniforms.sectionStrokeFalloff = { value: this._sectionStrokeFalloff };
47629
47647
  this.uniforms.sectionStrokeColor = { value: this._sectionStrokeColor };
47630
- this.uniforms.submeshColorTexture = { value: this._submeshColorTexture ?? null };
47648
+ this.uniforms.colorPaletteTexture = { value: this._colorPaletteTexture ?? null };
47631
47649
  shader.vertexShader = shader.vertexShader.replace(
47632
47650
  "#include <color_pars_vertex>",
47633
47651
  `
@@ -47635,23 +47653,16 @@ void main() {
47635
47653
 
47636
47654
  // COLORING
47637
47655
 
47638
- // attribute for color override
47639
- // merged meshes use it as vertex attribute
47640
- // instanced meshes use it as an instance attribute
47656
+ // Per-vertex color palette index
47657
+ attribute float colorIndex;
47658
+ // Per-instance palette override index (instanced meshes only)
47659
+ attribute float instanceColorIndex;
47660
+ // 1 = use instanceColorIndex, 0 = use per-vertex colorIndex
47641
47661
  attribute float colored;
47662
+ // 128×128 quantized color palette (25³ = 15,625 entries)
47663
+ uniform sampler2D colorPaletteTexture;
47642
47664
 
47643
- // There seems to be an issue where setting mehs.instanceColor
47644
- // doesn't properly set USE_INSTANCING_COLOR
47645
- // so we always use it as a fix
47646
- #ifndef USE_INSTANCING_COLOR
47647
- attribute vec3 instanceColor;
47648
- #endif
47649
-
47650
- // Submesh index for color palette lookup
47651
- attribute float submeshIndex;
47652
- uniform sampler2D submeshColorTexture; // 128×128 RGB texture (16384 colors max)
47653
-
47654
- // Passed to fragment to ignore phong model
47665
+ // Passed to fragment to control lighting model
47655
47666
  varying float vColored;
47656
47667
 
47657
47668
  // VISIBILITY
@@ -47669,18 +47680,13 @@ void main() {
47669
47680
  `
47670
47681
  // COLORING
47671
47682
  vColored = colored;
47672
-
47673
- // Get color from texture palette using texelFetch (WebGL 2, faster)
47674
- int texSize = 128;
47675
- int x = int(submeshIndex) % texSize;
47676
- int y = int(submeshIndex) / texSize;
47677
- vColor.xyz = texelFetch(submeshColorTexture, ivec2(x, y), 0).rgb;
47678
-
47679
- // colored == 1 -> instance color
47680
- // colored == 0 -> submesh palette color
47683
+ int palIdx = int(colorIndex);
47681
47684
  #ifdef USE_INSTANCING
47682
- vColor.xyz = colored * instanceColor.xyz + (1.0f - colored) * vColor.xyz;
47685
+ if (colored > 0.5) palIdx = int(instanceColorIndex);
47683
47686
  #endif
47687
+ int x = palIdx % 128;
47688
+ int y = palIdx / 128;
47689
+ vColor.xyz = texelFetch(colorPaletteTexture, ivec2(x, y), 0).rgb;
47684
47690
 
47685
47691
  // VISIBILITY
47686
47692
  vIgnore = ignore;
@@ -54480,20 +54486,20 @@ void main() {
54480
54486
  constructor(material, onUpdate) {
54481
54487
  __publicField(this, "three");
54482
54488
  __publicField(this, "_onUpdate");
54483
- // Submesh color palette texture (shared, owned by Materials singleton)
54484
- __publicField(this, "_submeshColorTexture");
54489
+ // Color palette texture (shared, owned by Materials singleton)
54490
+ __publicField(this, "_colorPaletteTexture");
54485
54491
  this.three = material ?? createModelMaterialShader();
54486
54492
  this._onUpdate = onUpdate;
54487
54493
  }
54488
54494
  /**
54489
- * Sets the submesh color texture for indexed color lookup.
54495
+ * Sets the color palette texture for indexed color lookup.
54490
54496
  * The texture is shared between materials (created in Materials singleton).
54491
54497
  */
54492
- setSubmeshColorTexture(texture) {
54498
+ setColorPaletteTexture(texture) {
54493
54499
  var _a3;
54494
- this._submeshColorTexture = texture;
54500
+ this._colorPaletteTexture = texture;
54495
54501
  if (this.three.uniforms) {
54496
- this.three.uniforms.submeshColorTexture.value = texture ?? null;
54502
+ this.three.uniforms.colorPaletteTexture.value = texture ?? null;
54497
54503
  }
54498
54504
  (_a3 = this._onUpdate) == null ? void 0 : _a3.call(this);
54499
54505
  }
@@ -54518,19 +54524,14 @@ void main() {
54518
54524
  function createModelMaterialShader(transparent = false) {
54519
54525
  return new ShaderMaterial({
54520
54526
  side: DoubleSide,
54521
- // Use GLSL ES 3.0 for WebGL 2
54522
54527
  glslVersion: GLSL3,
54523
- // Uniforms for texture-based color palette
54524
54528
  uniforms: {
54525
- submeshColorTexture: { value: null }
54529
+ colorPaletteTexture: { value: null }
54526
54530
  },
54527
- // Enable support for clipping planes.
54528
54531
  clipping: true,
54529
- // Transparency settings
54530
54532
  transparent,
54531
54533
  opacity: transparent ? 0.25 : 1,
54532
54534
  depthWrite: !transparent,
54533
- // Disable depth write for transparent materials
54534
54535
  vertexShader: (
54535
54536
  /* glsl */
54536
54537
  `
@@ -54539,29 +54540,16 @@ void main() {
54539
54540
  #include <clipping_planes_pars_vertex>
54540
54541
 
54541
54542
  // VISIBILITY
54542
- // Determines if an object or vertex should be visible.
54543
- // Used as an instance attribute for instanced meshes or as a vertex attribute for merged meshes.
54544
54543
  in float ignore;
54545
54544
 
54546
54545
  // COLORING
54547
- // Passes the color of the vertex or instance to the fragment shader.
54548
54546
  out vec3 vColor;
54549
54547
  out vec3 vViewPosition;
54550
54548
 
54551
- // Determines whether to use instance color (1 = instance, 0 = submesh).
54552
- // For merged meshes, this is used as a vertex attribute.
54553
- // For instanced meshes, this is used as an instance attribute.
54549
+ in float colorIndex;
54550
+ in float instanceColorIndex;
54554
54551
  in float colored;
54555
-
54556
- // Submesh index for color palette lookup
54557
- in float submeshIndex;
54558
- uniform sampler2D submeshColorTexture;
54559
-
54560
- // Fix for a known issue where setting mesh.instanceColor does not properly enable USE_INSTANCING_COLOR.
54561
- // This ensures that instance colors are always used when required.
54562
- #ifndef USE_INSTANCING_COLOR
54563
- in vec3 instanceColor;
54564
- #endif
54552
+ uniform sampler2D colorPaletteTexture;
54565
54553
 
54566
54554
  void main() {
54567
54555
  #include <begin_vertex>
@@ -54569,28 +54557,20 @@ void main() {
54569
54557
  #include <clipping_planes_vertex>
54570
54558
  #include <logdepthbuf_vertex>
54571
54559
 
54572
- // Place ignored vertices behind near plane to clip them.
54573
54560
  if (ignore > 0.5) {
54574
54561
  gl_Position = vec4(0.0, 0.0, -2.0, 1.0);
54575
54562
  return;
54576
54563
  }
54577
54564
 
54578
- // COLORING
54579
- // Get color from texture palette using texelFetch (WebGL 2, faster for indexed access)
54580
- int texSize = 128;
54581
- int colorIndex = int(submeshIndex);
54582
- int x = colorIndex % texSize;
54583
- int y = colorIndex / texSize;
54584
- vColor = texelFetch(submeshColorTexture, ivec2(x, y), 0).rgb;
54585
-
54586
- // Blend instance and submesh colors based on the colored attribute.
54587
- // colored == 1 -> use instance color.
54588
- // colored == 0 -> use submesh color from texture.
54565
+ // COLORING — unified palette lookup
54566
+ int palIdx = int(colorIndex);
54589
54567
  #ifdef USE_INSTANCING
54590
- vColor.xyz = colored * instanceColor.xyz + (1.0 - colored) * vColor.xyz;
54568
+ if (colored > 0.5) palIdx = int(instanceColorIndex);
54591
54569
  #endif
54570
+ int x = palIdx % 128;
54571
+ int y = palIdx / 128;
54572
+ vColor = texelFetch(colorPaletteTexture, ivec2(x, y), 0).rgb;
54592
54573
 
54593
- // Pass view position to fragment for screen-space derivatives
54594
54574
  vViewPosition = -mvPosition.xyz;
54595
54575
  }
54596
54576
  `
@@ -54602,7 +54582,6 @@ void main() {
54602
54582
  #include <logdepthbuf_pars_fragment>
54603
54583
  #include <clipping_planes_pars_fragment>
54604
54584
 
54605
- // Color and position for screen-space derivative lighting
54606
54585
  in vec3 vColor;
54607
54586
  in vec3 vViewPosition;
54608
54587
 
@@ -54616,13 +54595,11 @@ void main() {
54616
54595
  vec3 fdx = dFdx(vViewPosition);
54617
54596
  vec3 fdy = dFdy(vViewPosition);
54618
54597
  vec3 normal = normalize(cross(fdx, fdy));
54619
- // Pre-normalized light direction (sqrt(2), sqrt(3), sqrt(5)) / sqrt(10)
54620
54598
  const vec3 LIGHT_DIR = vec3(0.447214, 0.547723, 0.707107);
54621
54599
  float light = dot(normal, LIGHT_DIR);
54622
- light = 0.5 + (light * 0.5); // Remap to [0.5, 1.0]
54600
+ light = 0.5 + (light * 0.5);
54623
54601
  vec3 finalColor = vColor * light;
54624
54602
 
54625
- // Output final color
54626
54603
  fragColor = vec4(finalColor, ${transparent ? "0.25" : "1.0"});
54627
54604
  }
54628
54605
  `
@@ -54662,8 +54639,8 @@ void main() {
54662
54639
  __publicField(this, "_sectionStrokeFalloff", 0.75);
54663
54640
  __publicField(this, "_sectionStrokeColor", new Color(16185078));
54664
54641
  __publicField(this, "_onUpdate", new distExports$2.SignalDispatcher());
54665
- // Shared color palette texture for both opaque and transparent materials
54666
- __publicField(this, "_submeshColorTexture");
54642
+ // Shared color palette texture for all scene materials
54643
+ __publicField(this, "_colorPaletteTexture");
54667
54644
  this._opaque = opaque ?? createOpaque();
54668
54645
  this._transparent = transparent ?? createTransparent();
54669
54646
  const onUpdate = () => this._onUpdate.dispatch();
@@ -54801,55 +54778,34 @@ void main() {
54801
54778
  this._onUpdate.dispatch();
54802
54779
  }
54803
54780
  /**
54804
- * Sets the submesh color palette for both opaque and transparent materials.
54805
- * Creates a single shared DataTexture from the palette (128×128 RGBA, 16384 colors max).
54806
- * If palette is undefined, creates a white fallback texture.
54781
+ * Creates the fixed quantized color palette texture if it doesn't exist.
54782
+ * The palette is deterministic (25³ = 15,625 quantized colors in 128×128 texture)
54783
+ * and shared across all scene materials.
54807
54784
  */
54808
- setColorPalette(palette) {
54809
- if (this._submeshColorTexture) {
54810
- this._submeshColorTexture.dispose();
54811
- this._submeshColorTexture = void 0;
54812
- }
54813
- const textureSize = 128;
54814
- const textureData = new Uint8Array(textureSize * textureSize * 4);
54815
- if (palette && palette.length > 0) {
54816
- const colorCount = Math.min(palette.length / 3, textureSize * textureSize);
54817
- for (let i2 = 0; i2 < colorCount; i2++) {
54818
- textureData[i2 * 4] = Math.round(palette[i2 * 3] * 255);
54819
- textureData[i2 * 4 + 1] = Math.round(palette[i2 * 3 + 1] * 255);
54820
- textureData[i2 * 4 + 2] = Math.round(palette[i2 * 3 + 2] * 255);
54821
- textureData[i2 * 4 + 3] = 255;
54822
- }
54823
- } else {
54824
- console.warn("[Color Optimization] Palette undefined, using white fallback texture");
54825
- for (let i2 = 0; i2 < textureSize * textureSize * 4; i2 += 4) {
54826
- textureData[i2] = 255;
54827
- textureData[i2 + 1] = 255;
54828
- textureData[i2 + 2] = 255;
54829
- textureData[i2 + 3] = 255;
54830
- }
54831
- }
54832
- this._submeshColorTexture = new DataTexture(
54785
+ ensureColorPalette() {
54786
+ if (this._colorPaletteTexture) return;
54787
+ const textureData = buildPaletteTexture();
54788
+ this._colorPaletteTexture = new DataTexture(
54833
54789
  textureData,
54834
- textureSize,
54835
- textureSize,
54790
+ 128,
54791
+ 128,
54836
54792
  RGBAFormat,
54837
54793
  UnsignedByteType
54838
54794
  );
54839
- this._submeshColorTexture.needsUpdate = true;
54840
- this._submeshColorTexture.minFilter = NearestFilter;
54841
- this._submeshColorTexture.magFilter = NearestFilter;
54842
- this._opaque.setSubmeshColorTexture(this._submeshColorTexture);
54843
- this._transparent.setSubmeshColorTexture(this._submeshColorTexture);
54844
- this._modelOpaque.setSubmeshColorTexture(this._submeshColorTexture);
54845
- this._modelTransparent.setSubmeshColorTexture(this._submeshColorTexture);
54795
+ this._colorPaletteTexture.needsUpdate = true;
54796
+ this._colorPaletteTexture.minFilter = NearestFilter;
54797
+ this._colorPaletteTexture.magFilter = NearestFilter;
54798
+ this._opaque.setColorPaletteTexture(this._colorPaletteTexture);
54799
+ this._transparent.setColorPaletteTexture(this._colorPaletteTexture);
54800
+ this._modelOpaque.setColorPaletteTexture(this._colorPaletteTexture);
54801
+ this._modelTransparent.setColorPaletteTexture(this._colorPaletteTexture);
54846
54802
  this._onUpdate.dispatch();
54847
54803
  }
54848
54804
  /** dispose all materials. */
54849
54805
  dispose() {
54850
- if (this._submeshColorTexture) {
54851
- this._submeshColorTexture.dispose();
54852
- this._submeshColorTexture = void 0;
54806
+ if (this._colorPaletteTexture) {
54807
+ this._colorPaletteTexture.dispose();
54808
+ this._colorPaletteTexture = void 0;
54853
54809
  }
54854
54810
  this._opaque.dispose();
54855
54811
  this._transparent.dispose();
@@ -56911,7 +56867,7 @@ void main() {
56911
56867
  );
56912
56868
  }
56913
56869
  function createGeometryFromMesh(g3d2, mesh, section) {
56914
- const colorPaletteIndex = createColorPaletteIndices(g3d2, mesh, section);
56870
+ const colorIndices = createColorIndices(g3d2, mesh, section);
56915
56871
  const positions = g3d2.positions.subarray(
56916
56872
  g3d2.getMeshVertexStart(mesh) * 3,
56917
56873
  g3d2.getMeshVertexEnd(mesh) * 3
@@ -56922,10 +56878,10 @@ void main() {
56922
56878
  return createGeometryFromArrays(
56923
56879
  positions,
56924
56880
  indices,
56925
- colorPaletteIndex
56881
+ colorIndices
56926
56882
  );
56927
56883
  }
56928
- function createColorPaletteIndices(g3d2, mesh, section) {
56884
+ function createColorIndices(g3d2, mesh, section) {
56929
56885
  const vertexCount = g3d2.getMeshVertexCount(mesh);
56930
56886
  const result = new Uint16Array(vertexCount);
56931
56887
  const subStart = g3d2.getMeshSubmeshStart(mesh, section);
@@ -56933,7 +56889,7 @@ void main() {
56933
56889
  for (let submesh = subStart; submesh < subEnd; submesh++) {
56934
56890
  const start = g3d2.getSubmeshIndexStart(submesh);
56935
56891
  const end = g3d2.getSubmeshIndexEnd(submesh);
56936
- const index2 = g3d2.submeshColor[submesh];
56892
+ const index2 = g3d2.colorIndices[submesh];
56937
56893
  for (let i2 = start; i2 < end; i2++) {
56938
56894
  const vertexIndex = g3d2.indices[i2];
56939
56895
  result[vertexIndex] = index2;
@@ -56941,14 +56897,14 @@ void main() {
56941
56897
  }
56942
56898
  return result;
56943
56899
  }
56944
- function createGeometryFromArrays(vertices, indices, colorPaletteIndex = void 0) {
56900
+ function createGeometryFromArrays(vertices, indices, colorIndices = void 0) {
56945
56901
  const geometry = new BufferGeometry();
56946
56902
  geometry.setAttribute("position", new BufferAttribute(vertices, 3));
56947
56903
  geometry.setIndex(new Uint32BufferAttribute(indices, 1));
56948
- if (colorPaletteIndex) {
56904
+ if (colorIndices) {
56949
56905
  geometry.setAttribute(
56950
- "submeshIndex",
56951
- new Uint16BufferAttribute(colorPaletteIndex, 1)
56906
+ "colorIndex",
56907
+ new Uint16BufferAttribute(colorIndices, 1)
56952
56908
  );
56953
56909
  }
56954
56910
  return geometry;
@@ -57002,8 +56958,7 @@ void main() {
57002
56958
  __publicField(this, "_computeBoundingBox", false);
57003
56959
  __publicField(this, "_indexAttribute");
57004
56960
  __publicField(this, "_vertexAttribute");
57005
- __publicField(this, "_submeshIndexAttribute");
57006
- // Color palette index for texture-based color lookup
56961
+ __publicField(this, "_colorIndexAttribute");
57007
56962
  __publicField(this, "_packedIdAttribute");
57008
56963
  __publicField(this, "_mapping");
57009
56964
  __publicField(this, "_vimIndex");
@@ -57022,7 +56977,7 @@ void main() {
57022
56977
  offsets.counts.vertices * distExports$1.G3d.POSITION_SIZE,
57023
56978
  distExports$1.G3d.POSITION_SIZE
57024
56979
  );
57025
- this._submeshIndexAttribute = new Uint16BufferAttribute(
56980
+ this._colorIndexAttribute = new Uint16BufferAttribute(
57026
56981
  offsets.counts.vertices,
57027
56982
  1
57028
56983
  );
@@ -57033,7 +56988,7 @@ void main() {
57033
56988
  this.geometry = new BufferGeometry();
57034
56989
  this.geometry.setIndex(this._indexAttribute);
57035
56990
  this.geometry.setAttribute("position", this._vertexAttribute);
57036
- this.geometry.setAttribute("submeshIndex", this._submeshIndexAttribute);
56991
+ this.geometry.setAttribute("colorIndex", this._colorIndexAttribute);
57037
56992
  this.geometry.setAttribute("packedId", this._packedIdAttribute);
57038
56993
  this.boundingBox = new Box3();
57039
56994
  this.boundingBox.makeEmpty();
@@ -57078,16 +57033,16 @@ void main() {
57078
57033
  submesh.instance = instanceNodes[g3dInstance];
57079
57034
  submesh.start = indexOffset + indexOut;
57080
57035
  const indices = this._indexAttribute.array;
57081
- const submeshIndices = this._submeshIndexAttribute.array;
57036
+ const colorIndices = this._colorIndexAttribute.array;
57082
57037
  const mergeOffset = instance * vertexCount;
57083
57038
  for (let sub = subStart; sub < subEnd; sub++) {
57084
57039
  const indexStart = g3d2.getSubmeshIndexStart(sub);
57085
57040
  const indexEnd = g3d2.getSubmeshIndexEnd(sub);
57086
- const colorIndex = g3d2.submeshColor[sub];
57041
+ const colorIndex = g3d2.colorIndices[sub];
57087
57042
  for (let index2 = indexStart; index2 < indexEnd; index2++) {
57088
57043
  const v = vertexOffset + mergeOffset + g3d2.indices[index2];
57089
57044
  indices[indexOffset + indexOut] = v;
57090
- submeshIndices[v] = colorIndex;
57045
+ colorIndices[v] = colorIndex;
57091
57046
  indexOut++;
57092
57047
  }
57093
57048
  }
@@ -57153,8 +57108,8 @@ void main() {
57153
57108
  const vSize = this._vertexAttribute.itemSize;
57154
57109
  this._vertexAttribute.addUpdateRange(vertexStart * vSize, (vertexEnd - vertexStart) * vSize);
57155
57110
  this._vertexAttribute.needsUpdate = true;
57156
- this._submeshIndexAttribute.addUpdateRange(vertexStart, vertexEnd - vertexStart);
57157
- this._submeshIndexAttribute.needsUpdate = true;
57111
+ this._colorIndexAttribute.addUpdateRange(vertexStart, vertexEnd - vertexStart);
57112
+ this._colorIndexAttribute.needsUpdate = true;
57158
57113
  this._packedIdAttribute.addUpdateRange(vertexStart, vertexEnd - vertexStart);
57159
57114
  this._packedIdAttribute.needsUpdate = true;
57160
57115
  if (this._computeBoundingBox) {
@@ -57167,7 +57122,6 @@ void main() {
57167
57122
  constructor(mesh, index2) {
57168
57123
  __publicField(this, "mesh");
57169
57124
  __publicField(this, "index");
57170
- __publicField(this, "_colors");
57171
57125
  this.mesh = mesh;
57172
57126
  this.index = index2;
57173
57127
  }
@@ -57219,15 +57173,6 @@ void main() {
57219
57173
  get object() {
57220
57174
  return this.mesh.vim.getElement(this.instance);
57221
57175
  }
57222
- saveColors(colors) {
57223
- if (this._colors) return;
57224
- this._colors = colors;
57225
- }
57226
- popColors() {
57227
- const result = this._colors;
57228
- this._colors = void 0;
57229
- return result;
57230
- }
57231
57176
  }
57232
57177
  class InsertableMesh {
57233
57178
  constructor(offsets, materials, transparent, mapping, vimIndex = 0) {
@@ -57544,57 +57489,6 @@ void main() {
57544
57489
  return logging;
57545
57490
  }
57546
57491
  var loggingExports = requireLogging();
57547
- const MAX_COLORS = 16384;
57548
- const QUANTIZATION_LEVELS = 25;
57549
- function buildColorPalette(mappedG3d, submeshColorCount) {
57550
- const uniqueColorsMap = /* @__PURE__ */ new Map();
57551
- const colorPaletteArray = [];
57552
- const submeshColor = new Uint16Array(submeshColorCount);
57553
- for (let i2 = 0; i2 < submeshColorCount; i2++) {
57554
- const color = mappedG3d.getSubmeshColor(i2);
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[i2] = colorIndex;
57563
- }
57564
- let uniqueColorCount = uniqueColorsMap.size;
57565
- if (uniqueColorCount > MAX_COLORS) {
57566
- quantizeColors(mappedG3d.materialColors, QUANTIZATION_LEVELS);
57567
- uniqueColorsMap.clear();
57568
- colorPaletteArray.length = 0;
57569
- for (let i2 = 0; i2 < submeshColorCount; i2++) {
57570
- const color = mappedG3d.getSubmeshColor(i2);
57571
- const key = packColorKey(color[0], color[1], color[2]);
57572
- let colorIndex = uniqueColorsMap.get(key);
57573
- if (colorIndex === void 0) {
57574
- colorIndex = colorPaletteArray.length / 3;
57575
- uniqueColorsMap.set(key, colorIndex);
57576
- colorPaletteArray.push(color[0], color[1], color[2]);
57577
- }
57578
- submeshColor[i2] = colorIndex;
57579
- }
57580
- uniqueColorCount = uniqueColorsMap.size;
57581
- }
57582
- if (uniqueColorCount <= MAX_COLORS) {
57583
- const palette = new Float32Array(colorPaletteArray);
57584
- return { palette, submeshColor, uniqueColorCount };
57585
- } else {
57586
- return { palette: void 0, submeshColor, uniqueColorCount };
57587
- }
57588
- }
57589
- function packColorKey(r, g, b) {
57590
- return (Math.round(r * 65535) * 65536 + Math.round(g * 65535)) * 65536 + Math.round(b * 65535);
57591
- }
57592
- function quantizeColors(colors, levels) {
57593
- const quantize = (value) => Math.round(value * levels) / levels;
57594
- for (let i2 = 0; i2 < colors.length; i2++) {
57595
- colors[i2] = quantize(colors[i2]);
57596
- }
57597
- }
57598
57492
  function createMappedG3d(g3d2) {
57599
57493
  const mapped = g3d2;
57600
57494
  const map = /* @__PURE__ */ new Map();
@@ -57618,11 +57512,7 @@ void main() {
57618
57512
  mapped._meshKeys = meshKeys;
57619
57513
  mapped._meshValues = meshValues;
57620
57514
  mapped._totalInstanceCount = totalCount;
57621
- const submeshColorCount = mapped.submeshMaterial.length;
57622
- const { palette, submeshColor, uniqueColorCount } = buildColorPalette(mapped, submeshColorCount);
57623
- mapped.colorPalette = palette;
57624
- mapped.submeshColor = submeshColor;
57625
- mapped.uniqueColorCount = uniqueColorCount;
57515
+ mapped.colorIndices = buildColorIndices(mapped, mapped.submeshMaterial.length);
57626
57516
  return mapped;
57627
57517
  }
57628
57518
  let LoadRequest$2 = class LoadRequest extends LoadRequest$3 {
@@ -57667,7 +57557,7 @@ void main() {
57667
57557
  const mapping = await ElementMapping.fromG3d(doc);
57668
57558
  const scene = new Scene(fullSettings.matrix);
57669
57559
  const factory = new VimMeshFactory(mappedG3d, materials, scene, mapping, vimIndex);
57670
- Materials.getInstance().setColorPalette(mappedG3d.colorPalette);
57560
+ Materials.getInstance().ensureColorPalette();
57671
57561
  const header = await distExports$1.requestHeader(bfast2);
57672
57562
  const vim = new Vim$1(
57673
57563
  header,
@@ -73665,6 +73555,29 @@ Averrage Date/Second ${avgDataRatePS} kb
73665
73555
  }
73666
73556
  return clone;
73667
73557
  }
73558
+ function createState(initial) {
73559
+ return new MutableState(initial);
73560
+ }
73561
+ class MutableState {
73562
+ constructor(initial) {
73563
+ __publicField(this, "_value");
73564
+ __publicField(this, "_onChange", new distExports.SimpleEventDispatcher());
73565
+ this._value = initial;
73566
+ }
73567
+ get() {
73568
+ return this._value;
73569
+ }
73570
+ set(value) {
73571
+ if (value === this._value) return;
73572
+ this._value = value;
73573
+ this._onChange.dispatch(value);
73574
+ }
73575
+ confirm() {
73576
+ }
73577
+ get onChange() {
73578
+ return this._onChange.asEvent();
73579
+ }
73580
+ }
73668
73581
  function useRefresher() {
73669
73582
  const [refresh, setRefresh] = React2.useState(false);
73670
73583
  return {
@@ -76384,7 +76297,8 @@ Averrage Date/Second ${avgDataRatePS} kb
76384
76297
  Settings: index$6,
76385
76298
  Ultra: index$4,
76386
76299
  Webgl: index$5,
76387
- createContainer
76300
+ createContainer,
76301
+ createState
76388
76302
  }, Symbol.toStringTag, { value: "Module" }));
76389
76303
  exports.Core = index$7;
76390
76304
  exports.React = index;