minerender 2.1.0-alpha.88 → 2.1.0-alpha.89

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
@@ -21996,8 +21996,8 @@ var MineRender = (() => {
21996
21996
  }
21997
21997
  }
21998
21998
  }
21999
- function vertexAttribPointer(index, size, type, normalized, stride, offset, integer2) {
22000
- if (integer2 === true) {
21999
+ function vertexAttribPointer(index, size, type, normalized, stride, offset, integer3) {
22000
+ if (integer3 === true) {
22001
22001
  gl.vertexAttribIPointer(index, size, type, stride, offset);
22002
22002
  } else {
22003
22003
  gl.vertexAttribPointer(index, size, type, normalized, stride, offset);
@@ -22024,7 +22024,7 @@ var MineRender = (() => {
22024
22024
  const buffer2 = attribute.buffer;
22025
22025
  const type = attribute.type;
22026
22026
  const bytesPerElement = attribute.bytesPerElement;
22027
- const integer2 = type === gl.INT || type === gl.UNSIGNED_INT || geometryAttribute.gpuType === IntType;
22027
+ const integer3 = type === gl.INT || type === gl.UNSIGNED_INT || geometryAttribute.gpuType === IntType;
22028
22028
  if (geometryAttribute.isInterleavedBufferAttribute) {
22029
22029
  const data = geometryAttribute.data;
22030
22030
  const stride = data.stride;
@@ -22050,7 +22050,7 @@ var MineRender = (() => {
22050
22050
  normalized,
22051
22051
  stride * bytesPerElement,
22052
22052
  (offset + size / programAttribute.locationSize * i4) * bytesPerElement,
22053
- integer2
22053
+ integer3
22054
22054
  );
22055
22055
  }
22056
22056
  } else {
@@ -22075,7 +22075,7 @@ var MineRender = (() => {
22075
22075
  normalized,
22076
22076
  size * bytesPerElement,
22077
22077
  size / programAttribute.locationSize * i4 * bytesPerElement,
22078
- integer2
22078
+ integer3
22079
22079
  );
22080
22080
  }
22081
22081
  }
@@ -106592,6 +106592,7 @@ ${shader.fragmentShader}`.replace(
106592
106592
  SkinTextures: () => SkinTextures,
106593
106593
  Skins: () => Skins,
106594
106594
  SpecialItems: () => SpecialItems,
106595
+ SpongeSchematicParser: () => SpongeSchematicParser,
106595
106596
  StructureParser: () => StructureParser,
106596
106597
  TextureAtlas: () => TextureAtlas,
106597
106598
  TextureLoader: () => TextureLoader2,
@@ -111367,46 +111368,46 @@ property list uchar int vertex_index
111367
111368
  }
111368
111369
  var BlockStateResolver = class {
111369
111370
  /** Loads vanilla property defaults, falling back to preview values inferred from the blockstate file. */
111370
- static async defaults(blockState) {
111371
- const defaults = blockState.key ? await BlockStates.getDefaultState(blockState.key) : void 0;
111371
+ static async defaults(blockState2) {
111372
+ const defaults = blockState2.key ? await BlockStates.getDefaultState(blockState2.key) : void 0;
111372
111373
  const state = {};
111373
111374
  if (defaults && Object.keys(defaults).length > 0) {
111374
111375
  for (const key in defaults) state[key] = defaults[key].default;
111375
- } else if (blockState.variants) {
111376
- const variant = Object.keys(blockState.variants)[0];
111376
+ } else if (blockState2.variants) {
111377
+ const variant = Object.keys(blockState2.variants)[0];
111377
111378
  if (variant) {
111378
111379
  for (const property of variant.split(",")) {
111379
111380
  const [key, value] = property.split("=");
111380
111381
  state[key] = value;
111381
111382
  }
111382
111383
  }
111383
- } else if (blockState.multipart) {
111384
- const condition = blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
111384
+ } else if (blockState2.multipart) {
111385
+ const condition = blockState2.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
111385
111386
  for (const [key, value] of Object.entries(condition ?? {})) state[key] = value.split("|")[0];
111386
111387
  }
111387
111388
  return state;
111388
111389
  }
111389
111390
  /** Selects matching models. Supply `choose` to control selection within each alternatives array. */
111390
- static select(blockState, state, choose = this.choose) {
111391
- return this.matching(blockState, state).map(choose);
111391
+ static select(blockState2, state, choose = this.choose) {
111392
+ return this.matching(blockState2, state).map(choose);
111392
111393
  }
111393
111394
  /** Returns matching model groups before choosing weighted alternatives. */
111394
- static matching(blockState, state) {
111395
+ static matching(blockState2, state) {
111395
111396
  const out = [];
111396
- if (blockState.variants) {
111397
- if (Object.keys(blockState.variants).length === 1 && "" in blockState.variants) {
111398
- out.push(blockState.variants[""]);
111397
+ if (blockState2.variants) {
111398
+ if (Object.keys(blockState2.variants).length === 1 && "" in blockState2.variants) {
111399
+ out.push(blockState2.variants[""]);
111399
111400
  } else {
111400
- for (const variantKey in blockState.variants) {
111401
+ for (const variantKey in blockState2.variants) {
111401
111402
  const matches = variantKey.split(",").every((property) => {
111402
111403
  const [key, value] = property.split("=");
111403
111404
  return `${state[key]}` === `${value}`;
111404
111405
  });
111405
- if (matches) out.push(blockState.variants[variantKey]);
111406
+ if (matches) out.push(blockState2.variants[variantKey]);
111406
111407
  }
111407
111408
  }
111408
- } else if (blockState.multipart) {
111409
- for (const part of blockState.multipart) {
111409
+ } else if (blockState2.multipart) {
111410
+ for (const part of blockState2.multipart) {
111410
111411
  if (part.apply && (!part.when || matchesCondition(part.when, state))) {
111411
111412
  out.push(part.apply);
111412
111413
  }
@@ -111545,9 +111546,9 @@ property list uchar int vertex_index
111545
111546
  init_FluidGeometry();
111546
111547
  init_Entities();
111547
111548
  var _BlockObject = class _BlockObject extends SceneObject {
111548
- constructor(blockState, options) {
111549
+ constructor(blockState2, options) {
111549
111550
  super(options);
111550
- this.blockState = blockState;
111551
+ this.blockState = blockState2;
111551
111552
  this.isBlockObject = true;
111552
111553
  this._previousState = {};
111553
111554
  this._state = {};
@@ -113742,6 +113743,160 @@ property list uchar int vertex_index
113742
113743
  throw new MineRenderError(`Schematic ${name2} must be a compound list`);
113743
113744
  }
113744
113745
 
113746
+ // src/model/multiblock/SpongeSchematicParser.ts
113747
+ init_dirname();
113748
+ init_buffer2();
113749
+ init_process2();
113750
+ init_MineRenderError();
113751
+ var SpongeSchematicParser = class {
113752
+ /**
113753
+ * Parses decoded NBT with a local block palette, omitting air blocks.
113754
+ * Applies Offset to block and entity positions; size remains the source dimensions.
113755
+ * Biomes and metadata are not imported, and DataVersion does not trigger migration.
113756
+ */
113757
+ static async parse(nbt) {
113758
+ const tags = nbt.value.Schematic === void 0 ? nbt.value : compound(nbt.value.Schematic, "Schematic");
113759
+ const version3 = integer2(tags.Version, "Version");
113760
+ if (version3 !== 2 && version3 !== 3) {
113761
+ throw new MineRenderError(`Unsupported Sponge schematic version ${version3}; expected 2 or 3`);
113762
+ }
113763
+ const dataVersion = integer2(tags.DataVersion, "DataVersion");
113764
+ const size = ["Width", "Height", "Length"].map((name2) => {
113765
+ const tag = tags[name2];
113766
+ if (tag?.type !== "short" || !Number.isInteger(tag.value) || tag.value < -32768 || tag.value > 65535 || tag.value === 0) {
113767
+ throw new MineRenderError(`Sponge schematic ${name2} must be a positive unsigned short`);
113768
+ }
113769
+ return tag.value & 65535;
113770
+ });
113771
+ const offset = tags.Offset === void 0 ? [0, 0, 0] : intPosition(tags.Offset, "Offset");
113772
+ const blocks = [];
113773
+ const container = version3 === 2 ? tags : tags.Blocks === void 0 ? void 0 : compound(tags.Blocks, "Blocks");
113774
+ if (container) {
113775
+ const paletteTag = container.Palette;
113776
+ if (!paletteTag) throw new MineRenderError("Sponge schematic requires a local Palette; global block IDs are not supported");
113777
+ const palette = /* @__PURE__ */ new Map();
113778
+ const paletteMax = version3 === 2 && tags.PaletteMax !== void 0 ? integer2(tags.PaletteMax, "PaletteMax") : void 0;
113779
+ if (paletteMax !== void 0 && paletteMax <= 0) throw new MineRenderError("Sponge schematic PaletteMax must be positive");
113780
+ for (const [state, tag] of Object.entries(compound(paletteTag, "Palette"))) {
113781
+ const id = integer2(tag, "Palette index");
113782
+ if (id < 0 || palette.has(id) || paletteMax !== void 0 && id >= paletteMax) {
113783
+ throw new MineRenderError(`Invalid or duplicate Sponge schematic palette index ${id}`);
113784
+ }
113785
+ palette.set(id, blockState(state));
113786
+ }
113787
+ const [width, height, length] = size;
113788
+ const volume = width * height * length;
113789
+ const data = container[version3 === 2 ? "BlockData" : "Data"];
113790
+ if (data?.type !== "byteArray" || !Array.isArray(data.value) || data.value.length < volume) {
113791
+ throw new MineRenderError(`Sponge schematic block data must contain ${volume} varints`);
113792
+ }
113793
+ const blockEntities = /* @__PURE__ */ new Map();
113794
+ for (const entity of compoundList2(container, "BlockEntities")) {
113795
+ const pos = intPosition(entity.Pos, "BlockEntities Pos");
113796
+ if (pos.some((value2, axis) => value2 < 0 || value2 >= size[axis])) {
113797
+ throw new MineRenderError("Sponge schematic block entity position is outside its dimensions");
113798
+ }
113799
+ const index = pos[0] + pos[2] * width + pos[1] * width * length;
113800
+ if (blockEntities.has(index)) throw new MineRenderError(`Duplicate Sponge schematic block entity at index ${index}`);
113801
+ const value = entityData(entity, version3);
113802
+ for (const [axis, name2] of ["x", "y", "z"].entries()) {
113803
+ value[name2] = { type: "int", value: pos[axis] + offset[axis] };
113804
+ }
113805
+ blockEntities.set(index, { type: "compound", value });
113806
+ }
113807
+ let cursor = 0;
113808
+ for (let index = 0; index < volume; index++) {
113809
+ let id = 0;
113810
+ for (let shift = 0; ; shift += 7) {
113811
+ const byte = data.value[cursor++];
113812
+ if (!Number.isInteger(byte) || byte < -128 || byte > 255) {
113813
+ throw new MineRenderError(`Invalid or truncated Sponge schematic varint at index ${index}`);
113814
+ }
113815
+ const unsigned = byte & 255;
113816
+ if (shift === 28 && unsigned > 7) {
113817
+ throw new MineRenderError(`Sponge schematic varint exceeds a nonnegative int at index ${index}`);
113818
+ }
113819
+ id += (unsigned & 127) * 2 ** shift;
113820
+ if ((unsigned & 128) === 0) break;
113821
+ }
113822
+ const state = palette.get(id);
113823
+ if (!state) throw new MineRenderError(`Sponge schematic palette index ${id} does not exist`);
113824
+ if (["minecraft:air", "minecraft:cave_air", "minecraft:void_air"].includes(state.type)) continue;
113825
+ blocks.push({
113826
+ type: state.type,
113827
+ properties: { ...state.properties },
113828
+ position: [
113829
+ index % width + offset[0],
113830
+ Math.floor(index / (width * length)) + offset[1],
113831
+ Math.floor(index / width) % length + offset[2]
113832
+ ],
113833
+ nbt: blockEntities.get(index)
113834
+ });
113835
+ }
113836
+ if (cursor !== data.value.length) throw new MineRenderError("Sponge schematic block data has trailing bytes");
113837
+ }
113838
+ const entities = compoundList2(tags, "Entities").map((entity) => {
113839
+ const pos = entity.Pos;
113840
+ if (pos?.type !== "list" || pos.value.type !== "double" || pos.value.value.length !== 3 || !pos.value.value.every(Number.isFinite)) {
113841
+ throw new MineRenderError("Sponge schematic entity Pos must contain three doubles");
113842
+ }
113843
+ const position = pos.value.value.map((value2, axis) => value2 + offset[axis]);
113844
+ const value = entityData(entity, version3);
113845
+ value.Pos = { type: "list", value: { type: "double", value: [...position] } };
113846
+ return { position, nbt: { type: "compound", value } };
113847
+ });
113848
+ return { size, blocks, entities, dataVersion };
113849
+ }
113850
+ };
113851
+ function integer2(tag, name2) {
113852
+ if (tag?.type !== "int" || !Number.isInteger(tag.value) || tag.value < -2147483648 || tag.value > 2147483647) {
113853
+ throw new MineRenderError(`Sponge schematic ${name2} must be an int`);
113854
+ }
113855
+ return tag.value;
113856
+ }
113857
+ function compound(tag, name2) {
113858
+ if (tag?.type !== "compound" || !tag.value || typeof tag.value !== "object" || Array.isArray(tag.value)) {
113859
+ throw new MineRenderError(`Sponge schematic ${name2} must be a compound`);
113860
+ }
113861
+ return tag.value;
113862
+ }
113863
+ function intPosition(tag, name2) {
113864
+ if (tag?.type !== "intArray" || !Array.isArray(tag.value) || tag.value.length !== 3 || !tag.value.every((value) => Number.isInteger(value) && value >= -2147483648 && value <= 2147483647)) {
113865
+ throw new MineRenderError(`Sponge schematic ${name2} must contain three ints`);
113866
+ }
113867
+ return [...tag.value];
113868
+ }
113869
+ function compoundList2(tags, name2) {
113870
+ const tag = tags[name2];
113871
+ if (tag === void 0) return [];
113872
+ if (tag.type === "list" && Array.isArray(tag.value.value)) {
113873
+ if (tag.value.value.length === 0) return [];
113874
+ if (tag.value.type === "compound") return tag.value.value;
113875
+ }
113876
+ throw new MineRenderError(`Sponge schematic ${name2} must be a compound list`);
113877
+ }
113878
+ function blockState(state) {
113879
+ const match = /^((?:[a-z0-9_.-]+:)?[a-z0-9_./-]+)(?:\[([^\[\]]*)\])?$/.exec(state);
113880
+ if (!match) throw new MineRenderError(`Invalid Sponge schematic block state ${state}`);
113881
+ const properties = {};
113882
+ if (match[2]) {
113883
+ for (const entry of match[2].split(",")) {
113884
+ const pair = /^([a-z0-9_]+)=([^\s=,\[\]]+)$/.exec(entry);
113885
+ if (!pair || Object.prototype.hasOwnProperty.call(properties, pair[1])) throw new MineRenderError(`Invalid Sponge schematic block state ${state}`);
113886
+ Object.defineProperty(properties, pair[1], { value: pair[2], enumerable: true, writable: true, configurable: true });
113887
+ }
113888
+ }
113889
+ return { type: match[1].includes(":") ? match[1] : `minecraft:${match[1]}`, properties };
113890
+ }
113891
+ function entityData(entity, version3) {
113892
+ const id = entity.Id;
113893
+ if (id?.type !== "string" || !id.value) throw new MineRenderError("Sponge schematic entity Id must be a nonempty string");
113894
+ const { Id, Pos, ...extra } = entity;
113895
+ const value = version3 === 2 ? extra : entity.Data === void 0 ? {} : { ...compound(entity.Data, "entity Data") };
113896
+ value.id = { type: "string", value: id.value.includes(":") ? id.value : `minecraft:${id.value}` };
113897
+ return value;
113898
+ }
113899
+
113745
113900
  // src/model/multiblock/StructureParser.ts
113746
113901
  init_dirname();
113747
113902
  init_buffer2();
@@ -115001,8 +115156,8 @@ property list uchar int vertex_index
115001
115156
  * Set `options.initialState` to choose block properties such as `facing` or `axis`.
115002
115157
  * Use the returned object's `setPosition` method to move all of its model parts.
115003
115158
  */
115004
- async addBlock(blockState, options, parent = this) {
115005
- return this.addSceneObject(blockState, () => new BlockObject(blockState, options), options, parent);
115159
+ async addBlock(blockState2, options, parent = this) {
115160
+ return this.addSceneObject(blockState2, () => new BlockObject(blockState2, options), options, parent);
115006
115161
  }
115007
115162
  /**
115008
115163
  * Loads a skin and adds an initialized player model.
@@ -119255,18 +119410,18 @@ gl_FragDepth=readDepth(vUv);
119255
119410
  if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("maxAtlasSize must be a positive integer");
119256
119411
  }
119257
119412
  /** Returns a cube template, or `undefined` when the block requires an individual render object. */
119258
- async get(blockState, properties = {}) {
119259
- if (!blockState.variants || blockState.multipart) return void 0;
119260
- let states = this.states.get(blockState);
119261
- if (!states) this.states.set(blockState, states = /* @__PURE__ */ new Map());
119413
+ async get(blockState2, properties = {}) {
119414
+ if (!blockState2.variants || blockState2.multipart) return void 0;
119415
+ let states = this.states.get(blockState2);
119416
+ if (!states) this.states.set(blockState2, states = /* @__PURE__ */ new Map());
119262
119417
  const key = JSON.stringify(Object.entries(properties).sort(([a4], [b4]) => a4.localeCompare(b4)));
119263
- const prepared = await cached(states, key, () => this.prepare(blockState, properties));
119418
+ const prepared = await cached(states, key, () => this.prepare(blockState2, properties));
119264
119419
  if (!prepared) return void 0;
119265
119420
  return prepared.templates.get(BlockStateResolver.choose(prepared.variants));
119266
119421
  }
119267
- async prepare(blockState, properties) {
119268
- const state = { ...await BlockStateResolver.defaults(blockState), ...properties };
119269
- const groups = BlockStateResolver.matching(blockState, state);
119422
+ async prepare(blockState2, properties) {
119423
+ const state = { ...await BlockStateResolver.defaults(blockState2), ...properties };
119424
+ const groups = BlockStateResolver.matching(blockState2, state);
119270
119425
  if (groups.length !== 1) return void 0;
119271
119426
  const variants = groups[0];
119272
119427
  const choices = Array.isArray(variants) ? variants : [variants];
@@ -119278,7 +119433,7 @@ gl_FragDepth=readDepth(vUv);
119278
119433
  const atlas = await UVMapper.getAtlas(model);
119279
119434
  const rotation = BlockStateResolver.rotation(variant);
119280
119435
  if (!atlas || atlas.hasAnimation || !ModelCulling.isOpaqueFullCube(atlas) || atlas.image.width > this.maxAtlasSize || atlas.image.height > this.maxAtlasSize || ModelCulling.toLocalMask(63, rotation) !== 63) return void 0;
119281
- const tints = await BlockTints.get(blockState.key, state, model);
119436
+ const tints = await BlockTints.get(blockState2.key, state, model);
119282
119437
  let models = this.models.get(model);
119283
119438
  if (!models) this.models.set(model, models = /* @__PURE__ */ new Map());
119284
119439
  const key = JSON.stringify([rotation.x, rotation.y, rotation.z, variant.uvlock, tints]);
@@ -119993,10 +120148,10 @@ gl_FragDepth=readDepth(vUv);
119993
120148
  if (resolutions.has(key)) continue;
119994
120149
  const stored = { type: block.type, properties: block.properties ? { ...block.properties } : void 0 };
119995
120150
  const resolved = (async () => {
119996
- const blockState = await BlockStates.get(AssetKey.parse("blockstates", stored.type));
119997
- const perBlock = !blockState || !this.sectionModels || !!getFluidKind(blockState.key, stored.properties) || !!(blockState.key && BlockEntities.entry(await BlockEntities.getIndex(blockState.key.root), blockState.key.toNamespacedString()));
119998
- if (!perBlock) await this.sectionModels.get(blockState, stored.properties);
119999
- return { blockState, perBlock };
120151
+ const blockState2 = await BlockStates.get(AssetKey.parse("blockstates", stored.type));
120152
+ const perBlock = !blockState2 || !this.sectionModels || !!getFluidKind(blockState2.key, stored.properties) || !!(blockState2.key && BlockEntities.entry(await BlockEntities.getIndex(blockState2.key.root), blockState2.key.toNamespacedString()));
120153
+ if (!perBlock) await this.sectionModels.get(blockState2, stored.properties);
120154
+ return { blockState: blockState2, perBlock };
120000
120155
  })();
120001
120156
  resolutions.set(key, resolved);
120002
120157
  void resolved.catch(() => void 0);
@@ -120021,17 +120176,17 @@ gl_FragDepth=readDepth(vUv);
120021
120176
  if (!readBlock) continue;
120022
120177
  const stored = readBlock();
120023
120178
  const key = ChunkData.paletteKey(stored);
120024
- const { blockState, perBlock } = await resolutions.get(key);
120025
- if (!blockState) {
120179
+ const { blockState: blockState2, perBlock } = await resolutions.get(key);
120180
+ if (!blockState2) {
120026
120181
  this.data.set(index, void 0);
120027
120182
  continue;
120028
120183
  }
120029
- const template = perBlock ? void 0 : await this.sectionModels.get(blockState, stored.properties);
120184
+ const template = perBlock ? void 0 : await this.sectionModels.get(blockState2, stored.properties);
120030
120185
  if (template) {
120031
120186
  this.sectionBlocks.set(index, { index, template, cullMask: 0 });
120032
120187
  this.meshDirty = true;
120033
120188
  } else {
120034
- object3 = await this.scene.addBlock(blockState, {
120189
+ object3 = await this.scene.addBlock(blockState2, {
120035
120190
  mergeMeshes: true,
120036
120191
  instanceMeshes: true,
120037
120192
  maxInstanceCount: 2e3,