minerender 2.1.0-alpha.62 → 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.
@@ -3459,6 +3459,9 @@ var init_InstanceReference = __esm({
3459
3459
  setMatrix(matrix) {
3460
3460
  this.activeInstanceable.setMatrixAt(this.index, matrix);
3461
3461
  }
3462
+ setVisible(visible) {
3463
+ this.activeInstanceable.setInstanceVisibleAt(this.index, visible);
3464
+ }
3462
3465
  setPositionRotationScale(position, rotation, scale) {
3463
3466
  this.activeInstanceable.setPositionRotationScaleAt(this.index, position, rotation, scale);
3464
3467
  }
@@ -3513,6 +3516,7 @@ var init_SceneObject = __esm({
3513
3516
  this._instanceCounter = 0;
3514
3517
  this.instanceReferences = /* @__PURE__ */ new Map();
3515
3518
  this.freeInstanceIndices = [];
3519
+ this.hiddenInstanceMatrices = /* @__PURE__ */ new Map();
3516
3520
  this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
3517
3521
  console.log("SceneObject options", this.options);
3518
3522
  }
@@ -3707,6 +3711,7 @@ var init_SceneObject = __esm({
3707
3711
  removeInstanceAt(index) {
3708
3712
  if (!this.instanceReferences.has(index)) return;
3709
3713
  const mesh = this.instanceMesh;
3714
+ this.hiddenInstanceMatrices.delete(index);
3710
3715
  this.setMatrixAt(index, new Matrix44().makeScale(0, 0, 0));
3711
3716
  this.instanceReferences.delete(index);
3712
3717
  this.freeInstanceIndices.push(index);
@@ -3739,18 +3744,46 @@ var init_SceneObject = __esm({
3739
3744
  //<editor-fold desc="TRANSFORMATION">
3740
3745
  getMatrixAt(index, matrix = new Matrix44()) {
3741
3746
  if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
3747
+ const hidden = this.hiddenInstanceMatrices.get(index);
3748
+ if (hidden) {
3749
+ return matrix.copy(hidden);
3750
+ }
3742
3751
  this.instanceMesh.getMatrixAt(index, matrix);
3743
3752
  return matrix;
3744
3753
  }
3745
3754
  setMatrixAt(index, matrix) {
3746
3755
  if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
3747
3756
  const mesh = this.instanceMesh;
3748
- mesh.setMatrixAt(index, matrix);
3757
+ const hidden = this.hiddenInstanceMatrices.get(index);
3758
+ if (hidden) {
3759
+ hidden.copy(matrix);
3760
+ }
3761
+ mesh.setMatrixAt(index, hidden ? new Matrix44().makeScale(0, 0, 0) : matrix);
3749
3762
  mesh.instanceMatrix.needsUpdate = true;
3750
3763
  mesh.boundingBox = null;
3751
3764
  mesh.boundingSphere = null;
3752
3765
  this.notifyDirty();
3753
3766
  }
3767
+ setInstanceVisibleAt(index, visible) {
3768
+ if (!this.instanceReferences.has(index)) {
3769
+ throw new MineRenderError("Instance is not active");
3770
+ }
3771
+ const hidden = this.hiddenInstanceMatrices.get(index);
3772
+ if (visible) {
3773
+ if (!hidden) {
3774
+ return;
3775
+ }
3776
+ this.hiddenInstanceMatrices.delete(index);
3777
+ this.setMatrixAt(index, hidden);
3778
+ } else {
3779
+ if (hidden) {
3780
+ return;
3781
+ }
3782
+ const matrix = this.getMatrixAt(index);
3783
+ this.hiddenInstanceMatrices.set(index, matrix);
3784
+ this.setMatrixAt(index, matrix);
3785
+ }
3786
+ }
3754
3787
  setPositionRotationScaleAt(index, position, rotation, scale) {
3755
3788
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3756
3789
  const oldPosition = new Vector36();
@@ -3890,6 +3923,7 @@ var init_SceneObject = __esm({
3890
3923
  if (this._scene) this._scene.stats.instanceCount -= this.instanceReferences.size;
3891
3924
  this.instanceReferences.clear();
3892
3925
  this.freeInstanceIndices.length = 0;
3926
+ this.hiddenInstanceMatrices.clear();
3893
3927
  this._instanceCounter = 0;
3894
3928
  this.instanceMesh.count = 0;
3895
3929
  this.instanceMesh.dispose();
@@ -9137,6 +9171,21 @@ var _BlockObject = class _BlockObject extends SceneObject {
9137
9171
  get blockEntities() {
9138
9172
  return this._entities;
9139
9173
  }
9174
+ /** Sets visibility for this block's model instances and block entities. */
9175
+ setVisible(visible) {
9176
+ this.visible = visible;
9177
+ for (const model of this._models) {
9178
+ if (isInstanceReference(model)) {
9179
+ model.setVisible(visible);
9180
+ } else {
9181
+ model.visible = visible;
9182
+ }
9183
+ }
9184
+ for (const entity of this._entities) {
9185
+ entity.visible = visible;
9186
+ }
9187
+ this.notifyDirty();
9188
+ }
9140
9189
  /**
9141
9190
  * Draws the block through the dataset's block-entity index. Returns false, leaving nothing behind,
9142
9191
  * when the block is not listed or one of its models cannot be loaded.
@@ -9170,6 +9219,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
9170
9219
  BlockEntities.matrix(resolved, this._entityPlacement);
9171
9220
  this._entities = created;
9172
9221
  this.placeEntities();
9222
+ this.setVisible(this.visible);
9173
9223
  return true;
9174
9224
  }
9175
9225
  placeEntities() {
@@ -9179,6 +9229,9 @@ var _BlockObject = class _BlockObject extends SceneObject {
9179
9229
  }
9180
9230
  }
9181
9231
  get isOccluding() {
9232
+ if (!this.visible) {
9233
+ return false;
9234
+ }
9182
9235
  return this._models.some((model) => {
9183
9236
  const object = isInstanceReference(model) ? model.instanceable : model;
9184
9237
  return object.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
@@ -9234,6 +9287,9 @@ var _BlockObject = class _BlockObject extends SceneObject {
9234
9287
  this._models = replacements;
9235
9288
  this._cullMask = worldMask;
9236
9289
  this.removeModels(previous.filter((model) => !replacements.includes(model)));
9290
+ if (!this.visible) {
9291
+ this.setVisible(false);
9292
+ }
9237
9293
  this.notifyDirty();
9238
9294
  }
9239
9295
  get state() {
@@ -9269,6 +9325,9 @@ var _BlockObject = class _BlockObject extends SceneObject {
9269
9325
  this._isInstanced || (this._isInstanced = isInstanceReference(replacement));
9270
9326
  this._instanceCounter = this._isInstanced ? 1 : 0;
9271
9327
  if (previous) this.removeModels([previous]);
9328
+ if (!this.visible) {
9329
+ this.setVisible(false);
9330
+ }
9272
9331
  this.notifyDirty();
9273
9332
  }
9274
9333
  nextInstance() {
@@ -9297,6 +9356,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
9297
9356
  this._models.push(await this.createVariant(blockStateVariant));
9298
9357
  }
9299
9358
  await this.updateFluid(this._fluidSampler);
9359
+ this.setVisible(this.visible);
9300
9360
  }
9301
9361
  async hasGeometry(variant) {
9302
9362
  const modelKey = AssetKey.parse("models", variant.model);
@@ -14088,6 +14148,16 @@ var MineRenderWorld = class {
14088
14148
  const chunk = Chunk.isAir(value) ? this.getChunkAt(pos) : this.getOrCreateChunkAt(pos);
14089
14149
  return chunk?.setBlockInChunkAt(chunk.worldPosToChunkPos(pos), value, pos, onBlocksChanged);
14090
14150
  }
14151
+ async setBlockVisibleAt(posOrX, yOrVisible, z, visible) {
14152
+ if (typeof posOrX === "number") {
14153
+ return this.setBlockVisibleAt(new Vector316(posOrX, yOrVisible, z), visible);
14154
+ }
14155
+ if (isTripleArray(posOrX)) {
14156
+ return this.setBlockVisibleAt(new Vector316(...posOrX), yOrVisible);
14157
+ }
14158
+ this.validatePosBounds(posOrX);
14159
+ await this.getChunkAt(posOrX)?.setBlockVisibleAt(posOrX, yOrVisible);
14160
+ }
14091
14161
  async placeMultiBlock(multiblock, useBatches = true, executor) {
14092
14162
  const changes = /* @__PURE__ */ new Map();
14093
14163
  try {
@@ -14203,12 +14273,14 @@ var MineRenderWorld = class {
14203
14273
  if (!chunk) continue;
14204
14274
  changed.add(chunk);
14205
14275
  const block = chunk.getBlockAt(pos);
14206
- if (!block) continue;
14276
+ if (!block || !chunk.isBlockVisibleAt(pos)) {
14277
+ continue;
14278
+ }
14207
14279
  if (block.object?.fluidKind) {
14208
14280
  await block.object.updateFluid((x, y, z) => {
14209
14281
  const neighbor = pos.clone().add(new Vector316(x, y, z));
14210
14282
  const section = this.getChunkAt(neighbor);
14211
- const object = section?.getBlockAt(neighbor)?.object;
14283
+ const object = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
14212
14284
  return {
14213
14285
  fluid: object?.fluidKind,
14214
14286
  level: object?.fluidLevel,
@@ -14395,6 +14467,7 @@ var Chunk = class _Chunk {
14395
14467
  this.data = new ChunkData();
14396
14468
  this.renderedBlocks = /* @__PURE__ */ new Map();
14397
14469
  this.sectionBlocks = /* @__PURE__ */ new Map();
14470
+ this.hiddenBlocks = /* @__PURE__ */ new Set();
14398
14471
  this.meshDirty = false;
14399
14472
  this.scene = scene;
14400
14473
  this.x = x;
@@ -14432,6 +14505,7 @@ var Chunk = class _Chunk {
14432
14505
  worldPos = this.chunkPosToWorldPos(pos);
14433
14506
  }
14434
14507
  const index = _Chunk.chunkPosToBlockIndex(pos);
14508
+ this.hiddenBlocks.delete(index);
14435
14509
  this.data.set(index, block);
14436
14510
  const readBlock = this.data.snapshot(index);
14437
14511
  this.renderedBlocks.get(index)?.object?.removeFromScene();
@@ -14473,9 +14547,31 @@ var Chunk = class _Chunk {
14473
14547
  await onBlocksChanged?.([worldPos]);
14474
14548
  }
14475
14549
  }
14550
+ async setBlockVisibleAt(pos, visible) {
14551
+ const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
14552
+ const block = this.renderedBlocks.get(index);
14553
+ if (!block || visible === !this.hiddenBlocks.has(index)) {
14554
+ return;
14555
+ }
14556
+ if (visible) {
14557
+ this.hiddenBlocks.delete(index);
14558
+ } else {
14559
+ this.hiddenBlocks.add(index);
14560
+ }
14561
+ block.object?.setVisible(visible);
14562
+ if (this.sectionBlocks.has(index)) {
14563
+ this.meshDirty = true;
14564
+ }
14565
+ this.scene.dirty = true;
14566
+ await this.onBlocksChanged?.([pos]);
14567
+ }
14568
+ isBlockVisibleAt(pos) {
14569
+ const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
14570
+ return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);
14571
+ }
14476
14572
  isOccludingAt(pos) {
14477
14573
  const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
14478
- return this.sectionBlocks.has(index) || (this.renderedBlocks.get(index)?.object?.isOccluding ?? false);
14574
+ return !this.hiddenBlocks.has(index) && (this.sectionBlocks.has(index) || (this.renderedBlocks.get(index)?.object?.isOccluding ?? false));
14479
14575
  }
14480
14576
  async setCullMaskAt(pos, mask) {
14481
14577
  const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
@@ -14491,7 +14587,10 @@ var Chunk = class _Chunk {
14491
14587
  }
14492
14588
  rebuildSectionMesh() {
14493
14589
  if (!this.meshDirty) return;
14494
- const next = this.sectionBlocks.size ? SectionMesh.build([...this.sectionBlocks.values()], this.sectionModels.maxAtlasSize) : void 0;
14590
+ const next = this.sectionBlocks.size ? SectionMesh.build(
14591
+ [...this.sectionBlocks.values()].filter((entry) => !this.hiddenBlocks.has(entry.index)),
14592
+ this.sectionModels.maxAtlasSize
14593
+ ) : void 0;
14495
14594
  this.sectionMesh?.dispose();
14496
14595
  this.sectionMesh = next;
14497
14596
  if (next) {
@@ -14511,6 +14610,7 @@ var Chunk = class _Chunk {
14511
14610
  this.sectionMesh = void 0;
14512
14611
  this.meshDirty = false;
14513
14612
  this.renderedBlocks.clear();
14613
+ this.hiddenBlocks.clear();
14514
14614
  this.data.clear();
14515
14615
  await onBlocksChanged?.(positions);
14516
14616
  }