minerender 2.1.0-alpha.143 → 2.1.0-alpha.144

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
@@ -103237,6 +103237,7 @@ gl_FragDepth=readDepth(vUv);
103237
103237
  init_dirname();
103238
103238
  init_buffer2();
103239
103239
  init_process2();
103240
+ init_BlockObject();
103240
103241
  init_three_module();
103241
103242
  init_BlockStates();
103242
103243
  init_AssetKey();
@@ -103250,6 +103251,7 @@ gl_FragDepth=readDepth(vUv);
103250
103251
  init_util();
103251
103252
  init_AssetKey();
103252
103253
  init_BlockStates();
103254
+ init_BlockEntities();
103253
103255
  init_CubeFace();
103254
103256
 
103255
103257
  // src/world/SectionModels.ts
@@ -103350,6 +103352,10 @@ gl_FragDepth=readDepth(vUv);
103350
103352
  biomeTint: source ? [...templates.values()].some((template) => template.biomeTint?.some((value) => value === 1)) || void 0 : void 0
103351
103353
  };
103352
103354
  }
103355
+ /** Starts loading the state's models and atlases so a later `prepareState` with the same properties finds them loaded. */
103356
+ async preload(blockState3, properties = {}) {
103357
+ await this.state(blockState3, properties);
103358
+ }
103353
103359
  async state(blockState3, properties) {
103354
103360
  let states = this.states.get(blockState3);
103355
103361
  if (!states) this.states.set(blockState3, states = /* @__PURE__ */ new Map());
@@ -103372,22 +103378,24 @@ gl_FragDepth=readDepth(vUv);
103372
103378
  async prepare(blockState3, properties) {
103373
103379
  const state = { ...await BlockStateResolver.defaults(blockState3), ...properties };
103374
103380
  const groups = BlockStateResolver.matching(blockState3, state);
103375
- if (!groups.length) return void 0;
103381
+ if (!groups.length || groups.some((group) => Array.isArray(group) && !group.length)) return void 0;
103382
+ const variants = groups.flatMap((group) => Array.isArray(group) ? group : [group]);
103383
+ if (variants.some((variant) => !variant.model)) return void 0;
103384
+ const settled = await Promise.allSettled(variants.map(async (variant) => {
103385
+ const modelKey = AssetKey.parse("models", variant.model);
103386
+ modelKey.root = blockState3.key?.root;
103387
+ const model = await Models.getMerged(modelKey);
103388
+ if (!model?.elements?.length) return void 0;
103389
+ const atlas = await UVMapper.getAtlas(model);
103390
+ const rotation = BlockStateResolver.rotation(variant);
103391
+ if (!atlas || atlas.image.width > this.maxAtlasSize || atlas.image.height > this.maxAtlasSize) return void 0;
103392
+ return { model, atlas, rotation };
103393
+ }));
103376
103394
  const prepared = /* @__PURE__ */ new Map();
103377
- for (const group of groups) {
103378
- const choices = Array.isArray(group) ? group : [group];
103379
- if (!choices.length) return void 0;
103380
- for (const variant of choices) {
103381
- if (!variant.model) return void 0;
103382
- const modelKey = AssetKey.parse("models", variant.model);
103383
- modelKey.root = blockState3.key?.root;
103384
- const model = await Models.getMerged(modelKey);
103385
- if (!model?.elements?.length) return void 0;
103386
- const atlas = await UVMapper.getAtlas(model);
103387
- const rotation = BlockStateResolver.rotation(variant);
103388
- if (!atlas || atlas.image.width > this.maxAtlasSize || atlas.image.height > this.maxAtlasSize) return void 0;
103389
- prepared.set(variant, { model, atlas, rotation });
103390
- }
103395
+ for (const [i4, result] of settled.entries()) {
103396
+ if (result.status === "rejected") throw result.reason;
103397
+ if (!result.value) return void 0;
103398
+ prepared.set(variants[i4], result.value);
103391
103399
  }
103392
103400
  return { state, groups, choices: prepared };
103393
103401
  }
@@ -104080,15 +104088,18 @@ gl_FragDepth=readDepth(vUv);
104080
104088
  const key = AssetKey.parse("blockstates", block.type);
104081
104089
  keys.set(key.serialize(), key);
104082
104090
  }
104083
- await BlockStates.getAll(keys.values());
104091
+ const loaded = await BlockStates.getAll(keys.values());
104092
+ const states = new Map([...keys.keys()].map((key, i4) => [key, loaded[i4]]));
104084
104093
  if (!useBatches) {
104085
104094
  for (const block of multiblock.blocks) await place(block);
104086
104095
  return;
104087
104096
  }
104088
104097
  if (!executor) {
104089
104098
  const groups2 = /* @__PURE__ */ new Map();
104099
+ const distinct = /* @__PURE__ */ new Map();
104090
104100
  const position = new Vector3();
104091
104101
  for (const block of multiblock.blocks) {
104102
+ if (this.sectionModels && !Chunk.isAir(block)) distinct.set(ChunkData.paletteKey(block), block);
104092
104103
  const [x4, y5, z4] = block.position;
104093
104104
  this.validatePosBounds(position.set(x4, y5, z4));
104094
104105
  const cx = Math.floor(x4 / 16), cy = Math.floor(y5 / 16), cz = Math.floor(z4 / 16);
@@ -104099,6 +104110,16 @@ gl_FragDepth=readDepth(vUv);
104099
104110
  if (!group) groups2.set(chunk, group = []);
104100
104111
  group.push({ index: (y5 - cy * 16) * 256 + (z4 - cz * 16) * 16 + x4 - cx * 16, block });
104101
104112
  }
104113
+ if (this.sectionModels) {
104114
+ for (const block of distinct.values()) {
104115
+ const state = states.get(AssetKey.parse("blockstates", block.type).serialize());
104116
+ if (!state) continue;
104117
+ void (async () => {
104118
+ if (state.key && BlockEntities.entry(await BlockEntities.getIndex(state.key.root), state.key.toNamespacedString())) return;
104119
+ await this.sectionModels.preload(state, block.properties);
104120
+ })().catch(() => void 0);
104121
+ }
104122
+ }
104102
104123
  await this.placeChunkGroups(groups2, changes);
104103
104124
  return;
104104
104125
  }
@@ -105440,8 +105461,10 @@ gl_FragDepth=readDepth(vUv);
105440
105461
  if (rejected?.status === "rejected") throw rejected.reason;
105441
105462
  }
105442
105463
  const positions = [];
105443
- let failed = false, failure;
105444
- for (const { index, key, block } of placements) {
105464
+ const jobs = /* @__PURE__ */ new Map();
105465
+ let failureOrder = Infinity, failure;
105466
+ for (const [order, { index, key, block }] of placements.entries()) {
105467
+ jobs.delete(index);
105445
105468
  this.hiddenBlocks.delete(index);
105446
105469
  this.data.assign(index, this.data.intern(block), block?.nbt);
105447
105470
  const readBlock = this.data.snapshot(index);
@@ -105457,7 +105480,6 @@ gl_FragDepth=readDepth(vUv);
105457
105480
  this.z * 16 + Math.floor(index / 16) % 16
105458
105481
  );
105459
105482
  positions.push(worldPos);
105460
- let object4;
105461
105483
  try {
105462
105484
  if (!readBlock) continue;
105463
105485
  const resolved = resolutions.get(key);
@@ -105479,7 +105501,7 @@ gl_FragDepth=readDepth(vUv);
105479
105501
  this.sectionBlocks.set(index, templates.map((template) => ({ index, template, cullMask: 0, biomeTint: context?.tint })));
105480
105502
  this.meshDirty = true;
105481
105503
  } else {
105482
- object4 = await this.scene.addBlock(blockState3, {
105504
+ jobs.set(index, { order, readBlock, blockState: blockState3, position: MineRenderWorld.worldToScenePosition(worldPos), options: {
105483
105505
  mergeMeshes: true,
105484
105506
  instanceMeshes: true,
105485
105507
  maxInstanceCount: 2e3,
@@ -105487,13 +105509,12 @@ gl_FragDepth=readDepth(vUv);
105487
105509
  variantPosition,
105488
105510
  biome: context?.biome,
105489
105511
  biomePosition: this.biomePosition(index, blockState3, stored)
105490
- });
105491
- object4.setPosition(MineRenderWorld.worldToScenePosition(worldPos));
105512
+ } });
105513
+ continue;
105492
105514
  }
105493
105515
  this.renderedBlocks.set(index, { get block() {
105494
105516
  return readBlock();
105495
- }, object: object4 });
105496
- if (object4) this.objectBlocks.add(index);
105517
+ }, object: void 0 });
105497
105518
  } catch (error2) {
105498
105519
  if (preserveDataOnFailure && readBlock) {
105499
105520
  this.renderedBlocks.set(index, { get block() {
@@ -105501,12 +105522,35 @@ gl_FragDepth=readDepth(vUv);
105501
105522
  }, object: void 0 });
105502
105523
  } else this.data.assign(index, 0);
105503
105524
  this.fluidCells[index] = 0;
105504
- object4?.removeFromScene();
105505
- if (!failed) failure = error2;
105506
- failed = true;
105525
+ if (order < failureOrder) {
105526
+ failureOrder = order;
105527
+ failure = error2;
105528
+ }
105507
105529
  }
105508
105530
  }
105509
- if (failed) throw failure;
105531
+ const pending = [...jobs];
105532
+ const objects = await Promise.allSettled(pending.map(([, job]) => this.createBlockObject(job.blockState, job.position, job.options)));
105533
+ for (const [i4, [index, { order, readBlock }]] of pending.entries()) {
105534
+ const result = objects[i4];
105535
+ if (result.status === "fulfilled") {
105536
+ this.renderedBlocks.set(index, { get block() {
105537
+ return readBlock();
105538
+ }, object: result.value });
105539
+ this.objectBlocks.add(index);
105540
+ } else {
105541
+ if (preserveDataOnFailure) {
105542
+ this.renderedBlocks.set(index, { get block() {
105543
+ return readBlock();
105544
+ }, object: void 0 });
105545
+ } else this.data.assign(index, 0);
105546
+ this.fluidCells[index] = 0;
105547
+ if (order < failureOrder) {
105548
+ failureOrder = order;
105549
+ failure = result.reason;
105550
+ }
105551
+ }
105552
+ }
105553
+ if (failureOrder < Infinity) throw failure;
105510
105554
  return positions;
105511
105555
  }
105512
105556
  /** Replaces every cell from parsed section data. The caller refreshes neighbor culling. */
@@ -105577,37 +105621,42 @@ gl_FragDepth=readDepth(vUv);
105577
105621
  failed = true;
105578
105622
  }
105579
105623
  }
105580
- for (const { index, blockState: blockState3, biome } of perBlocks) {
105581
- let object4;
105582
- try {
105583
- object4 = await this.scene.addBlock(blockState3, {
105584
- mergeMeshes: true,
105585
- instanceMeshes: true,
105586
- maxInstanceCount: 2e3,
105587
- initialState: this.data.stateAt(this.data.idAt(index)).properties,
105588
- variantPosition: this.positionAt(index),
105589
- biome,
105590
- biomePosition: this.biomePosition(index, blockState3, this.data.stateAt(this.data.idAt(index)))
105591
- });
105592
- object4.setPosition(new Vector3(
105593
- this.x * 256 + index % 16 * 16,
105594
- this.y * 256 + Math.floor(index / 256) * 16,
105595
- this.z * 256 + Math.floor(index / 16) % 16 * 16
105596
- ));
105597
- this.renderedBlocks.get(index).object = object4;
105624
+ const objects = await Promise.allSettled(perBlocks.map(({ index, blockState: blockState3, biome }) => this.createBlockObject(blockState3, new Vector3(
105625
+ this.x * 256 + index % 16 * 16,
105626
+ this.y * 256 + Math.floor(index / 256) * 16,
105627
+ this.z * 256 + Math.floor(index / 16) % 16 * 16
105628
+ ), {
105629
+ mergeMeshes: true,
105630
+ instanceMeshes: true,
105631
+ maxInstanceCount: 2e3,
105632
+ initialState: this.data.stateAt(this.data.idAt(index)).properties,
105633
+ variantPosition: this.positionAt(index),
105634
+ biome,
105635
+ biomePosition: this.biomePosition(index, blockState3, this.data.stateAt(this.data.idAt(index)))
105636
+ })));
105637
+ for (const [i4, { index }] of perBlocks.entries()) {
105638
+ const result = objects[i4];
105639
+ if (result.status === "fulfilled") {
105640
+ this.renderedBlocks.get(index).object = result.value;
105598
105641
  this.objectBlocks.add(index);
105599
- } catch (error2) {
105642
+ } else {
105600
105643
  this.data.assign(index, 0);
105601
105644
  this.fluidCells[index] = 0;
105602
105645
  this.renderedBlocks.delete(index);
105603
105646
  this.objectBlocks.delete(index);
105604
- object4?.removeFromScene();
105605
- if (!failed) failure = error2;
105647
+ if (!failed) failure = result.reason;
105606
105648
  failed = true;
105607
105649
  }
105608
105650
  }
105609
105651
  if (failed) throw failure;
105610
105652
  }
105653
+ createBlockObject(blockState3, position, options) {
105654
+ return this.scene.addSceneObject(blockState3, () => {
105655
+ const object4 = new BlockObject(blockState3, options);
105656
+ object4.position.copy(position);
105657
+ return object4;
105658
+ }, options);
105659
+ }
105611
105660
  positionAt(index) {
105612
105661
  return [this.x * 16 + index % 16, this.y * 16 + Math.floor(index / 256), this.z * 16 + Math.floor(index / 16) % 16];
105613
105662
  }