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.
@@ -3545,6 +3545,9 @@ var init_InstanceReference = __esm({
3545
3545
  setMatrix(matrix) {
3546
3546
  this.activeInstanceable.setMatrixAt(this.index, matrix);
3547
3547
  }
3548
+ setVisible(visible) {
3549
+ this.activeInstanceable.setInstanceVisibleAt(this.index, visible);
3550
+ }
3548
3551
  setPositionRotationScale(position, rotation, scale) {
3549
3552
  this.activeInstanceable.setPositionRotationScaleAt(this.index, position, rotation, scale);
3550
3553
  }
@@ -3599,6 +3602,7 @@ var init_SceneObject = __esm({
3599
3602
  this._instanceCounter = 0;
3600
3603
  this.instanceReferences = /* @__PURE__ */ new Map();
3601
3604
  this.freeInstanceIndices = [];
3605
+ this.hiddenInstanceMatrices = /* @__PURE__ */ new Map();
3602
3606
  this.options = (0, import_ts_deepmerge3.default)({}, _SceneObject.DEFAULT_OPTIONS, options ?? {});
3603
3607
  console.log("SceneObject options", this.options);
3604
3608
  }
@@ -3801,6 +3805,7 @@ var init_SceneObject = __esm({
3801
3805
  removeInstanceAt(index) {
3802
3806
  if (!this.instanceReferences.has(index)) return;
3803
3807
  const mesh = this.instanceMesh;
3808
+ this.hiddenInstanceMatrices.delete(index);
3804
3809
  this.setMatrixAt(index, new Matrix44().makeScale(0, 0, 0));
3805
3810
  this.instanceReferences.delete(index);
3806
3811
  this.freeInstanceIndices.push(index);
@@ -3833,18 +3838,46 @@ var init_SceneObject = __esm({
3833
3838
  //<editor-fold desc="TRANSFORMATION">
3834
3839
  getMatrixAt(index, matrix = new Matrix44()) {
3835
3840
  if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
3841
+ const hidden = this.hiddenInstanceMatrices.get(index);
3842
+ if (hidden) {
3843
+ return matrix.copy(hidden);
3844
+ }
3836
3845
  this.instanceMesh.getMatrixAt(index, matrix);
3837
3846
  return matrix;
3838
3847
  }
3839
3848
  setMatrixAt(index, matrix) {
3840
3849
  if (!this.instanceReferences.has(index)) throw new MineRenderError("Instance is not active");
3841
3850
  const mesh = this.instanceMesh;
3842
- mesh.setMatrixAt(index, matrix);
3851
+ const hidden = this.hiddenInstanceMatrices.get(index);
3852
+ if (hidden) {
3853
+ hidden.copy(matrix);
3854
+ }
3855
+ mesh.setMatrixAt(index, hidden ? new Matrix44().makeScale(0, 0, 0) : matrix);
3843
3856
  mesh.instanceMatrix.needsUpdate = true;
3844
3857
  mesh.boundingBox = null;
3845
3858
  mesh.boundingSphere = null;
3846
3859
  this.notifyDirty();
3847
3860
  }
3861
+ setInstanceVisibleAt(index, visible) {
3862
+ if (!this.instanceReferences.has(index)) {
3863
+ throw new MineRenderError("Instance is not active");
3864
+ }
3865
+ const hidden = this.hiddenInstanceMatrices.get(index);
3866
+ if (visible) {
3867
+ if (!hidden) {
3868
+ return;
3869
+ }
3870
+ this.hiddenInstanceMatrices.delete(index);
3871
+ this.setMatrixAt(index, hidden);
3872
+ } else {
3873
+ if (hidden) {
3874
+ return;
3875
+ }
3876
+ const matrix = this.getMatrixAt(index);
3877
+ this.hiddenInstanceMatrices.set(index, matrix);
3878
+ this.setMatrixAt(index, matrix);
3879
+ }
3880
+ }
3848
3881
  setPositionRotationScaleAt(index, position, rotation, scale) {
3849
3882
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3850
3883
  const oldPosition = new Vector36();
@@ -3984,6 +4017,7 @@ var init_SceneObject = __esm({
3984
4017
  if (this._scene) this._scene.stats.instanceCount -= this.instanceReferences.size;
3985
4018
  this.instanceReferences.clear();
3986
4019
  this.freeInstanceIndices.length = 0;
4020
+ this.hiddenInstanceMatrices.clear();
3987
4021
  this._instanceCounter = 0;
3988
4022
  this.instanceMesh.count = 0;
3989
4023
  this.instanceMesh.dispose();
@@ -9193,6 +9227,21 @@ var BlockObject = class _BlockObject extends SceneObject {
9193
9227
  get blockEntities() {
9194
9228
  return this._entities;
9195
9229
  }
9230
+ /** Sets visibility for this block's model instances and block entities. */
9231
+ setVisible(visible) {
9232
+ this.visible = visible;
9233
+ for (const model of this._models) {
9234
+ if (isInstanceReference(model)) {
9235
+ model.setVisible(visible);
9236
+ } else {
9237
+ model.visible = visible;
9238
+ }
9239
+ }
9240
+ for (const entity of this._entities) {
9241
+ entity.visible = visible;
9242
+ }
9243
+ this.notifyDirty();
9244
+ }
9196
9245
  /**
9197
9246
  * Draws the block through the dataset's block-entity index. Returns false, leaving nothing behind,
9198
9247
  * when the block is not listed or one of its models cannot be loaded.
@@ -9226,6 +9275,7 @@ var BlockObject = class _BlockObject extends SceneObject {
9226
9275
  BlockEntities.matrix(resolved, this._entityPlacement);
9227
9276
  this._entities = created;
9228
9277
  this.placeEntities();
9278
+ this.setVisible(this.visible);
9229
9279
  return true;
9230
9280
  }
9231
9281
  placeEntities() {
@@ -9235,6 +9285,9 @@ var BlockObject = class _BlockObject extends SceneObject {
9235
9285
  }
9236
9286
  }
9237
9287
  get isOccluding() {
9288
+ if (!this.visible) {
9289
+ return false;
9290
+ }
9238
9291
  return this._models.some((model) => {
9239
9292
  const object = isInstanceReference(model) ? model.instanceable : model;
9240
9293
  return object.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
@@ -9290,6 +9343,9 @@ var BlockObject = class _BlockObject extends SceneObject {
9290
9343
  this._models = replacements;
9291
9344
  this._cullMask = worldMask;
9292
9345
  this.removeModels(previous.filter((model) => !replacements.includes(model)));
9346
+ if (!this.visible) {
9347
+ this.setVisible(false);
9348
+ }
9293
9349
  this.notifyDirty();
9294
9350
  }
9295
9351
  get state() {
@@ -9325,6 +9381,9 @@ var BlockObject = class _BlockObject extends SceneObject {
9325
9381
  this._isInstanced ||= isInstanceReference(replacement);
9326
9382
  this._instanceCounter = this._isInstanced ? 1 : 0;
9327
9383
  if (previous) this.removeModels([previous]);
9384
+ if (!this.visible) {
9385
+ this.setVisible(false);
9386
+ }
9328
9387
  this.notifyDirty();
9329
9388
  }
9330
9389
  nextInstance() {
@@ -9353,6 +9412,7 @@ var BlockObject = class _BlockObject extends SceneObject {
9353
9412
  this._models.push(await this.createVariant(blockStateVariant));
9354
9413
  }
9355
9414
  await this.updateFluid(this._fluidSampler);
9415
+ this.setVisible(this.visible);
9356
9416
  }
9357
9417
  async hasGeometry(variant) {
9358
9418
  const modelKey = AssetKey.parse("models", variant.model);
@@ -14142,6 +14202,16 @@ var MineRenderWorld = class {
14142
14202
  const chunk = Chunk.isAir(value) ? this.getChunkAt(pos) : this.getOrCreateChunkAt(pos);
14143
14203
  return chunk?.setBlockInChunkAt(chunk.worldPosToChunkPos(pos), value, pos, onBlocksChanged);
14144
14204
  }
14205
+ async setBlockVisibleAt(posOrX, yOrVisible, z, visible) {
14206
+ if (typeof posOrX === "number") {
14207
+ return this.setBlockVisibleAt(new Vector316(posOrX, yOrVisible, z), visible);
14208
+ }
14209
+ if (isTripleArray(posOrX)) {
14210
+ return this.setBlockVisibleAt(new Vector316(...posOrX), yOrVisible);
14211
+ }
14212
+ this.validatePosBounds(posOrX);
14213
+ await this.getChunkAt(posOrX)?.setBlockVisibleAt(posOrX, yOrVisible);
14214
+ }
14145
14215
  async placeMultiBlock(multiblock, useBatches = true, executor) {
14146
14216
  const changes = /* @__PURE__ */ new Map();
14147
14217
  try {
@@ -14257,12 +14327,14 @@ var MineRenderWorld = class {
14257
14327
  if (!chunk) continue;
14258
14328
  changed.add(chunk);
14259
14329
  const block = chunk.getBlockAt(pos);
14260
- if (!block) continue;
14330
+ if (!block || !chunk.isBlockVisibleAt(pos)) {
14331
+ continue;
14332
+ }
14261
14333
  if (block.object?.fluidKind) {
14262
14334
  await block.object.updateFluid((x, y, z) => {
14263
14335
  const neighbor = pos.clone().add(new Vector316(x, y, z));
14264
14336
  const section = this.getChunkAt(neighbor);
14265
- const object = section?.getBlockAt(neighbor)?.object;
14337
+ const object = section?.isBlockVisibleAt(neighbor) ? section.getBlockAt(neighbor)?.object : void 0;
14266
14338
  return {
14267
14339
  fluid: object?.fluidKind,
14268
14340
  level: object?.fluidLevel,
@@ -14449,6 +14521,7 @@ var Chunk = class _Chunk {
14449
14521
  this.data = new ChunkData();
14450
14522
  this.renderedBlocks = /* @__PURE__ */ new Map();
14451
14523
  this.sectionBlocks = /* @__PURE__ */ new Map();
14524
+ this.hiddenBlocks = /* @__PURE__ */ new Set();
14452
14525
  this.meshDirty = false;
14453
14526
  this.scene = scene;
14454
14527
  this.x = x;
@@ -14486,6 +14559,7 @@ var Chunk = class _Chunk {
14486
14559
  worldPos = this.chunkPosToWorldPos(pos);
14487
14560
  }
14488
14561
  const index = _Chunk.chunkPosToBlockIndex(pos);
14562
+ this.hiddenBlocks.delete(index);
14489
14563
  this.data.set(index, block);
14490
14564
  const readBlock = this.data.snapshot(index);
14491
14565
  this.renderedBlocks.get(index)?.object?.removeFromScene();
@@ -14527,9 +14601,31 @@ var Chunk = class _Chunk {
14527
14601
  await onBlocksChanged?.([worldPos]);
14528
14602
  }
14529
14603
  }
14604
+ async setBlockVisibleAt(pos, visible) {
14605
+ const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
14606
+ const block = this.renderedBlocks.get(index);
14607
+ if (!block || visible === !this.hiddenBlocks.has(index)) {
14608
+ return;
14609
+ }
14610
+ if (visible) {
14611
+ this.hiddenBlocks.delete(index);
14612
+ } else {
14613
+ this.hiddenBlocks.add(index);
14614
+ }
14615
+ block.object?.setVisible(visible);
14616
+ if (this.sectionBlocks.has(index)) {
14617
+ this.meshDirty = true;
14618
+ }
14619
+ this.scene.dirty = true;
14620
+ await this.onBlocksChanged?.([pos]);
14621
+ }
14622
+ isBlockVisibleAt(pos) {
14623
+ const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
14624
+ return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);
14625
+ }
14530
14626
  isOccludingAt(pos) {
14531
14627
  const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
14532
- return this.sectionBlocks.has(index) || (this.renderedBlocks.get(index)?.object?.isOccluding ?? false);
14628
+ return !this.hiddenBlocks.has(index) && (this.sectionBlocks.has(index) || (this.renderedBlocks.get(index)?.object?.isOccluding ?? false));
14533
14629
  }
14534
14630
  async setCullMaskAt(pos, mask) {
14535
14631
  const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
@@ -14545,7 +14641,10 @@ var Chunk = class _Chunk {
14545
14641
  }
14546
14642
  rebuildSectionMesh() {
14547
14643
  if (!this.meshDirty) return;
14548
- const next = this.sectionBlocks.size ? SectionMesh.build([...this.sectionBlocks.values()], this.sectionModels.maxAtlasSize) : void 0;
14644
+ const next = this.sectionBlocks.size ? SectionMesh.build(
14645
+ [...this.sectionBlocks.values()].filter((entry) => !this.hiddenBlocks.has(entry.index)),
14646
+ this.sectionModels.maxAtlasSize
14647
+ ) : void 0;
14549
14648
  this.sectionMesh?.dispose();
14550
14649
  this.sectionMesh = next;
14551
14650
  if (next) {
@@ -14565,6 +14664,7 @@ var Chunk = class _Chunk {
14565
14664
  this.sectionMesh = void 0;
14566
14665
  this.meshDirty = false;
14567
14666
  this.renderedBlocks.clear();
14667
+ this.hiddenBlocks.clear();
14568
14668
  this.data.clear();
14569
14669
  await onBlocksChanged?.(positions);
14570
14670
  }