minerender 2.1.0-alpha.61 → 2.1.0-alpha.63

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/bundle.js CHANGED
@@ -78923,11 +78923,11 @@ ${key}` : key;
78923
78923
  return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
78924
78924
  }
78925
78925
  /**
78926
- * Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
78926
+ * Native and sampled vanilla clips by name, or undefined when the model or selected version has none.
78927
78927
  */
78928
78928
  static async getAnimations(modelKey) {
78929
78929
  const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
78930
- const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json");
78930
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
78931
78931
  const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
78932
78932
  return file?.animations;
78933
78933
  }
@@ -78977,7 +78977,7 @@ ${key}` : key;
78977
78977
  let low = 0, high = keyframes.length;
78978
78978
  while (low < high) {
78979
78979
  const middle = low + high >>> 1;
78980
- if (time <= keyframes[middle].time) high = middle;
78980
+ if (time < keyframes[middle].time) high = middle;
78981
78981
  else low = middle + 1;
78982
78982
  }
78983
78983
  const a4 = Math.max(0, low - 1);
@@ -79025,6 +79025,7 @@ ${key}` : key;
79025
79025
  init_dirname();
79026
79026
  init_buffer2();
79027
79027
  init_process2();
79028
+ init_three_module();
79028
79029
  init_EntityAnimation();
79029
79030
  ZERO = [0, 0, 0];
79030
79031
  EntityAnimationPlayer = class {
@@ -79041,25 +79042,45 @@ ${key}` : key;
79041
79042
  return this._time;
79042
79043
  }
79043
79044
  /**
79044
- * Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
79045
- * bones without a matching part are skipped.
79045
+ * Starts an animation on matching named parts. Supplied baked poses are the baseline for offsets;
79046
+ * without them, the current pose is used. Stopping restores the pose from before playback.
79046
79047
  */
79047
- play(layers, animation, options = {}) {
79048
+ play(layers, animation, options = {}, poses) {
79048
79049
  this.stop();
79049
79050
  this._animation = animation;
79050
79051
  this._time = options.time ?? 0;
79051
79052
  this.loop = options.loop ?? animation.loop;
79052
79053
  this.speed = options.speed ?? 1;
79053
79054
  for (const layer of layers) {
79054
- for (const bone of Object.keys(animation.bones)) {
79055
- const object = layer.getObjectByName(`group:${bone}`);
79056
- if (!object) continue;
79057
- this.parts.push({ bone, object, position: object.position.clone(), rotation: object.rotation.clone(), scale: object.scale.clone() });
79055
+ const objects = [];
79056
+ if (poses) {
79057
+ layer.traverse((object) => {
79058
+ if (poses.has(object)) objects.push(object);
79059
+ });
79060
+ } else {
79061
+ for (const bone of Object.keys(animation.bones)) {
79062
+ const object = layer.getObjectByName(`group:${bone}`);
79063
+ if (object) objects.push(object);
79064
+ }
79065
+ }
79066
+ for (const object of objects) {
79067
+ const bone = object.name.slice("group:".length);
79068
+ const pose = poses?.get(object);
79069
+ this.parts.push({
79070
+ bone,
79071
+ object,
79072
+ position: object.position.clone(),
79073
+ rotation: object.rotation.clone(),
79074
+ scale: object.scale.clone(),
79075
+ basePosition: pose ? new Vector3(...pose.offset) : object.position.clone(),
79076
+ baseRotation: pose ? new Euler(...pose.rotation, "ZYX") : object.rotation.clone(),
79077
+ baseScale: pose ? new Vector3(...pose.scale ?? [1, 1, 1]) : object.scale.clone()
79078
+ });
79058
79079
  }
79059
79080
  }
79060
79081
  this.apply();
79061
79082
  }
79062
- /** Restores the default poses. Returns whether an animation was active. */
79083
+ /** Restores the poses from before playback. Returns whether an animation was active. */
79063
79084
  stop() {
79064
79085
  if (!this._animation) return false;
79065
79086
  for (const part of this.parts) {
@@ -79088,10 +79109,10 @@ ${key}` : key;
79088
79109
  apply() {
79089
79110
  const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
79090
79111
  for (const part of this.parts) {
79091
- const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone];
79092
- part.object.position.set(part.position.x + position[0], part.position.y + position[1], part.position.z + position[2]);
79093
- part.object.rotation.set(part.rotation.x + rotation[0], part.rotation.y + rotation[1], part.rotation.z + rotation[2], part.rotation.order);
79094
- part.object.scale.set(part.scale.x + scale[0], part.scale.y + scale[1], part.scale.z + scale[2]);
79112
+ const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone] ?? {};
79113
+ part.object.position.set(part.basePosition.x + position[0], part.basePosition.y + position[1], part.basePosition.z + position[2]);
79114
+ part.object.rotation.set(part.baseRotation.x + rotation[0], part.baseRotation.y + rotation[1], part.baseRotation.z + rotation[2], part.baseRotation.order);
79115
+ part.object.scale.set(part.baseScale.x + scale[0], part.baseScale.y + scale[1], part.baseScale.z + scale[2]);
79095
79116
  }
79096
79117
  }
79097
79118
  };
@@ -79134,6 +79155,9 @@ ${key}` : key;
79134
79155
  setMatrix(matrix) {
79135
79156
  this.activeInstanceable.setMatrixAt(this.index, matrix);
79136
79157
  }
79158
+ setVisible(visible) {
79159
+ this.activeInstanceable.setInstanceVisibleAt(this.index, visible);
79160
+ }
79137
79161
  setPositionRotationScale(position, rotation, scale) {
79138
79162
  this.activeInstanceable.setPositionRotationScaleAt(this.index, position, rotation, scale);
79139
79163
  }
@@ -79191,6 +79215,7 @@ ${key}` : key;
79191
79215
  this._instanceCounter = 0;
79192
79216
  this.instanceReferences = /* @__PURE__ */ new Map();
79193
79217
  this.freeInstanceIndices = [];
79218
+ this.hiddenInstanceMatrices = /* @__PURE__ */ new Map();
79194
79219
  this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
79195
79220
  console.log("SceneObject options", this.options);
79196
79221
  }
@@ -79385,6 +79410,7 @@ ${key}` : key;
79385
79410
  removeInstanceAt(index) {
79386
79411
  if (!this.instanceReferences.has(index)) return;
79387
79412
  const mesh = this.instanceMesh;
79413
+ this.hiddenInstanceMatrices.delete(index);
79388
79414
  this.setMatrixAt(index, new Matrix4().makeScale(0, 0, 0));
79389
79415
  this.instanceReferences.delete(index);
79390
79416
  this.freeInstanceIndices.push(index);
@@ -79417,18 +79443,46 @@ ${key}` : key;
79417
79443
  //<editor-fold desc="TRANSFORMATION">
79418
79444
  getMatrixAt(index, matrix = new Matrix4()) {
79419
79445
  if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
79446
+ const hidden = this.hiddenInstanceMatrices.get(index);
79447
+ if (hidden) {
79448
+ return matrix.copy(hidden);
79449
+ }
79420
79450
  this.instanceMesh.getMatrixAt(index, matrix);
79421
79451
  return matrix;
79422
79452
  }
79423
79453
  setMatrixAt(index, matrix) {
79424
79454
  if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
79425
79455
  const mesh = this.instanceMesh;
79426
- mesh.setMatrixAt(index, matrix);
79456
+ const hidden = this.hiddenInstanceMatrices.get(index);
79457
+ if (hidden) {
79458
+ hidden.copy(matrix);
79459
+ }
79460
+ mesh.setMatrixAt(index, hidden ? new Matrix4().makeScale(0, 0, 0) : matrix);
79427
79461
  mesh.instanceMatrix.needsUpdate = true;
79428
79462
  mesh.boundingBox = null;
79429
79463
  mesh.boundingSphere = null;
79430
79464
  this.notifyDirty();
79431
79465
  }
79466
+ setInstanceVisibleAt(index, visible) {
79467
+ if (!this.instanceReferences.has(index)) {
79468
+ throw new MineRenderError("Instance is not active");
79469
+ }
79470
+ const hidden = this.hiddenInstanceMatrices.get(index);
79471
+ if (visible) {
79472
+ if (!hidden) {
79473
+ return;
79474
+ }
79475
+ this.hiddenInstanceMatrices.delete(index);
79476
+ this.setMatrixAt(index, hidden);
79477
+ } else {
79478
+ if (hidden) {
79479
+ return;
79480
+ }
79481
+ const matrix = this.getMatrixAt(index);
79482
+ this.hiddenInstanceMatrices.set(index, matrix);
79483
+ this.setMatrixAt(index, matrix);
79484
+ }
79485
+ }
79432
79486
  setPositionRotationScaleAt(index, position, rotation, scale) {
79433
79487
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
79434
79488
  const oldPosition = new Vector3();
@@ -79568,6 +79622,7 @@ ${key}` : key;
79568
79622
  if (this._scene) this._scene.stats.instanceCount -= this.instanceReferences.size;
79569
79623
  this.instanceReferences.clear();
79570
79624
  this.freeInstanceIndices.length = 0;
79625
+ this.hiddenInstanceMatrices.clear();
79571
79626
  this._instanceCounter = 0;
79572
79627
  this.instanceMesh.count = 0;
79573
79628
  this.instanceMesh.dispose();
@@ -79634,7 +79689,8 @@ ${key}` : key;
79634
79689
  this.scrollMaterials = [];
79635
79690
  /** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
79636
79691
  this.age = 0;
79637
- this.animationPlayer = new EntityAnimationPlayer();
79692
+ this.animationPlayers = [];
79693
+ this.partPoses = /* @__PURE__ */ new Map();
79638
79694
  this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
79639
79695
  this.addEventListener("added", () => this.updateScrollSubscription());
79640
79696
  this.addEventListener("removed", () => this.updateScrollSubscription());
@@ -79651,7 +79707,8 @@ ${key}` : key;
79651
79707
  for (const geometry of this.geometries) geometry.dispose();
79652
79708
  this.geometries.clear();
79653
79709
  for (const dispose of this.disposeWireframes.splice(0)) dispose();
79654
- this.animationPlayer.clear();
79710
+ for (const player of this.animationPlayers.splice(0)) player.clear();
79711
+ this.partPoses.clear();
79655
79712
  super.disposeAndRemoveAllChildren();
79656
79713
  }
79657
79714
  clearScrollMaterials() {
@@ -79683,36 +79740,61 @@ ${key}` : key;
79683
79740
  this.notifyDirty();
79684
79741
  }
79685
79742
  //<editor-fold desc="ANIMATION">
79686
- /** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
79743
+ /** The first active clip, until playback is stopped or the object is disposed. */
79687
79744
  get animation() {
79688
- return this.animationPlayer.animation;
79745
+ return this.animationPlayers[0]?.animation;
79746
+ }
79747
+ /** Clips playing together, each targeting a separate geometry layer. */
79748
+ get activeAnimations() {
79749
+ return this.animationPlayers.map((player) => player.animation);
79689
79750
  }
79690
79751
  /** Seconds since the animation started, before looping. */
79691
79752
  get animationTime() {
79692
- return this.animationPlayer.time;
79753
+ return this.animationPlayers[0]?.time ?? 0;
79693
79754
  }
79694
79755
  /**
79695
- * Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
79696
- * Parts of every layer are matched by name and their current pose is the default the offsets add to.
79756
+ * Plays a clip from {@link Entities.getAnimations}, replacing all active clips.
79757
+ * Offsets apply to the baked pose in the clip's layer (`main` by default), including repeated draws of that layer.
79697
79758
  * The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
79698
79759
  */
79699
79760
  playAnimation(animation, options) {
79761
+ this.playAnimations([animation], options);
79762
+ }
79763
+ /** Plays one clip per selected geometry layer, with a shared clock and no blending between clips. */
79764
+ playAnimations(animations, options) {
79765
+ const targets = /* @__PURE__ */ new Set();
79766
+ const selections = animations.map((animation) => {
79767
+ const layer = animation.layer ?? "main";
79768
+ if (targets.has(layer)) throw new Error(`Multiple animations target layer "${layer}"`);
79769
+ targets.add(layer);
79770
+ const names = Object.keys(this.entityLayers).filter((name2) => name2.split("#")[0] === layer);
79771
+ if (!names.length) throw new Error(`Entity ${this.entity.id} has no selected animation layer "${layer}"`);
79772
+ return { animation, names };
79773
+ });
79700
79774
  this.createMeshes();
79701
- const layers = Object.keys(this.entityLayers).map((name2) => this.getLayerGroup(name2)).filter((layer) => !!layer);
79702
- this.animationPlayer.play(layers, animation, options);
79775
+ this.stopAnimation();
79776
+ for (const { animation, names } of selections) {
79777
+ const player = new EntityAnimationPlayer();
79778
+ player.play(names.map((name2) => this.getLayerGroup(name2)), animation, options, this.partPoses);
79779
+ this.animationPlayers.push(player);
79780
+ }
79703
79781
  this.notifyDirty();
79704
79782
  }
79705
- /** Stops the animation and restores the default pose. */
79783
+ /** Stops all clips and restores the poses from before playback. */
79706
79784
  stopAnimation() {
79707
- if (this.animationPlayer.stop()) this.notifyDirty();
79785
+ const players = this.animationPlayers.splice(0);
79786
+ for (const player of players) player.stop();
79787
+ if (players.length) this.notifyDirty();
79708
79788
  }
79709
79789
  /** Poses the object at an explicit time in seconds. Has no effect without an animation. */
79710
79790
  setAnimationTime(seconds) {
79711
- if (this.animationPlayer.setTime(seconds)) this.notifyDirty();
79791
+ for (const player of this.animationPlayers) player.setTime(seconds);
79792
+ if (this.animationPlayers.length) this.notifyDirty();
79712
79793
  }
79713
79794
  /** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
79714
79795
  advanceAnimation(deltaSeconds) {
79715
- if (this.animationPlayer.advance(deltaSeconds)) this.notifyDirty();
79796
+ for (const player of this.animationPlayers) player.advance(deltaSeconds);
79797
+ if (this.animationPlayers.length) this.notifyDirty();
79716
79798
  }
79717
79799
  //</editor-fold>
79718
79800
  getLayerGroup(name2) {
@@ -79772,6 +79854,7 @@ ${key}` : key;
79772
79854
  anchor.position.fromArray(part.pose.offset);
79773
79855
  anchor.rotation.set(...part.pose.rotation, "ZYX");
79774
79856
  anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
79857
+ this.partPoses.set(anchor, part.pose);
79775
79858
  parent.add(anchor);
79776
79859
  const size = part.texture ?? textureSize;
79777
79860
  for (const cube of part.cubes) {
@@ -87990,6 +88073,21 @@ property list uchar int vertex_index
87990
88073
  get blockEntities() {
87991
88074
  return this._entities;
87992
88075
  }
88076
+ /** Sets visibility for this block's model instances and block entities. */
88077
+ setVisible(visible) {
88078
+ this.visible = visible;
88079
+ for (const model of this._models) {
88080
+ if (isInstanceReference(model)) {
88081
+ model.setVisible(visible);
88082
+ } else {
88083
+ model.visible = visible;
88084
+ }
88085
+ }
88086
+ for (const entity of this._entities) {
88087
+ entity.visible = visible;
88088
+ }
88089
+ this.notifyDirty();
88090
+ }
87993
88091
  /**
87994
88092
  * Draws the block through the dataset's block-entity index. Returns false, leaving nothing behind,
87995
88093
  * when the block is not listed or one of its models cannot be loaded.
@@ -88023,6 +88121,7 @@ property list uchar int vertex_index
88023
88121
  BlockEntities.matrix(resolved, this._entityPlacement);
88024
88122
  this._entities = created;
88025
88123
  this.placeEntities();
88124
+ this.setVisible(this.visible);
88026
88125
  return true;
88027
88126
  }
88028
88127
  placeEntities() {
@@ -88032,6 +88131,9 @@ property list uchar int vertex_index
88032
88131
  }
88033
88132
  }
88034
88133
  get isOccluding() {
88134
+ if (!this.visible) {
88135
+ return false;
88136
+ }
88035
88137
  return this._models.some((model) => {
88036
88138
  const object = isInstanceReference(model) ? model.instanceable : model;
88037
88139
  return object.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
@@ -88087,6 +88189,9 @@ property list uchar int vertex_index
88087
88189
  this._models = replacements;
88088
88190
  this._cullMask = worldMask;
88089
88191
  this.removeModels(previous.filter((model) => !replacements.includes(model)));
88192
+ if (!this.visible) {
88193
+ this.setVisible(false);
88194
+ }
88090
88195
  this.notifyDirty();
88091
88196
  }
88092
88197
  get state() {
@@ -88122,6 +88227,9 @@ property list uchar int vertex_index
88122
88227
  this._isInstanced || (this._isInstanced = isInstanceReference(replacement));
88123
88228
  this._instanceCounter = this._isInstanced ? 1 : 0;
88124
88229
  if (previous) this.removeModels([previous]);
88230
+ if (!this.visible) {
88231
+ this.setVisible(false);
88232
+ }
88125
88233
  this.notifyDirty();
88126
88234
  }
88127
88235
  nextInstance() {
@@ -88150,6 +88258,7 @@ property list uchar int vertex_index
88150
88258
  this._models.push(await this.createVariant(blockStateVariant));
88151
88259
  }
88152
88260
  await this.updateFluid(this._fluidSampler);
88261
+ this.setVisible(this.visible);
88153
88262
  }
88154
88263
  async hasGeometry(variant) {
88155
88264
  const modelKey = AssetKey.parse("models", variant.model);
@@ -94810,6 +94919,16 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
94810
94919
  const chunk = Chunk.isAir(value) ? this.getChunkAt(pos) : this.getOrCreateChunkAt(pos);
94811
94920
  return chunk?.setBlockInChunkAt(chunk.worldPosToChunkPos(pos), value, pos, onBlocksChanged);
94812
94921
  }
94922
+ async setBlockVisibleAt(posOrX, yOrVisible, z4, visible) {
94923
+ if (typeof posOrX === "number") {
94924
+ return this.setBlockVisibleAt(new Vector3(posOrX, yOrVisible, z4), visible);
94925
+ }
94926
+ if (isTripleArray(posOrX)) {
94927
+ return this.setBlockVisibleAt(new Vector3(...posOrX), yOrVisible);
94928
+ }
94929
+ this.validatePosBounds(posOrX);
94930
+ await this.getChunkAt(posOrX)?.setBlockVisibleAt(posOrX, yOrVisible);
94931
+ }
94813
94932
  async placeMultiBlock(multiblock, useBatches = true, executor) {
94814
94933
  const changes = /* @__PURE__ */ new Map();
94815
94934
  try {
@@ -94925,12 +95044,14 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
94925
95044
  if (!chunk) continue;
94926
95045
  changed.add(chunk);
94927
95046
  const block = chunk.getBlockAt(pos);
94928
- if (!block) continue;
95047
+ if (!block || !chunk.isBlockVisibleAt(pos)) {
95048
+ continue;
95049
+ }
94929
95050
  if (block.object?.fluidKind) {
94930
95051
  await block.object.updateFluid((x4, y5, z4) => {
94931
95052
  const neighbor = pos.clone().add(new Vector3(x4, y5, z4));
94932
95053
  const section = this.getChunkAt(neighbor);
94933
- const object = section?.getBlockAt(neighbor)?.object;
95054
+ const object = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
94934
95055
  return {
94935
95056
  fluid: object?.fluidKind,
94936
95057
  level: object?.fluidLevel,
@@ -95120,6 +95241,7 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
95120
95241
  this.data = new ChunkData();
95121
95242
  this.renderedBlocks = /* @__PURE__ */ new Map();
95122
95243
  this.sectionBlocks = /* @__PURE__ */ new Map();
95244
+ this.hiddenBlocks = /* @__PURE__ */ new Set();
95123
95245
  this.meshDirty = false;
95124
95246
  this.scene = scene;
95125
95247
  this.x = x4;
@@ -95157,6 +95279,7 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
95157
95279
  worldPos = this.chunkPosToWorldPos(pos);
95158
95280
  }
95159
95281
  const index = _Chunk.chunkPosToBlockIndex(pos);
95282
+ this.hiddenBlocks.delete(index);
95160
95283
  this.data.set(index, block);
95161
95284
  const readBlock = this.data.snapshot(index);
95162
95285
  this.renderedBlocks.get(index)?.object?.removeFromScene();
@@ -95198,9 +95321,31 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
95198
95321
  await onBlocksChanged?.([worldPos]);
95199
95322
  }
95200
95323
  }
95324
+ async setBlockVisibleAt(pos, visible) {
95325
+ const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
95326
+ const block = this.renderedBlocks.get(index);
95327
+ if (!block || visible === !this.hiddenBlocks.has(index)) {
95328
+ return;
95329
+ }
95330
+ if (visible) {
95331
+ this.hiddenBlocks.delete(index);
95332
+ } else {
95333
+ this.hiddenBlocks.add(index);
95334
+ }
95335
+ block.object?.setVisible(visible);
95336
+ if (this.sectionBlocks.has(index)) {
95337
+ this.meshDirty = true;
95338
+ }
95339
+ this.scene.dirty = true;
95340
+ await this.onBlocksChanged?.([pos]);
95341
+ }
95342
+ isBlockVisibleAt(pos) {
95343
+ const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
95344
+ return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);
95345
+ }
95201
95346
  isOccludingAt(pos) {
95202
95347
  const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
95203
- return this.sectionBlocks.has(index) || (this.renderedBlocks.get(index)?.object?.isOccluding ?? false);
95348
+ return !this.hiddenBlocks.has(index) && (this.sectionBlocks.has(index) || (this.renderedBlocks.get(index)?.object?.isOccluding ?? false));
95204
95349
  }
95205
95350
  async setCullMaskAt(pos, mask) {
95206
95351
  const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
@@ -95216,7 +95361,10 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
95216
95361
  }
95217
95362
  rebuildSectionMesh() {
95218
95363
  if (!this.meshDirty) return;
95219
- const next = this.sectionBlocks.size ? SectionMesh.build([...this.sectionBlocks.values()], this.sectionModels.maxAtlasSize) : void 0;
95364
+ const next = this.sectionBlocks.size ? SectionMesh.build(
95365
+ [...this.sectionBlocks.values()].filter((entry) => !this.hiddenBlocks.has(entry.index)),
95366
+ this.sectionModels.maxAtlasSize
95367
+ ) : void 0;
95220
95368
  this.sectionMesh?.dispose();
95221
95369
  this.sectionMesh = next;
95222
95370
  if (next) {
@@ -95236,6 +95384,7 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
95236
95384
  this.sectionMesh = void 0;
95237
95385
  this.meshDirty = false;
95238
95386
  this.renderedBlocks.clear();
95387
+ this.hiddenBlocks.clear();
95239
95388
  this.data.clear();
95240
95389
  await onBlocksChanged?.(positions);
95241
95390
  }