minerender 2.1.0-alpha.132 → 2.1.0-alpha.133

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.
@@ -309,6 +309,9 @@ var init_Caching = __esm({
309
309
  static {
310
310
  this.blockEntityIndexCache = _Caching.createAssetCache();
311
311
  }
312
+ static {
313
+ this.unihexCache = _Caching.createAssetCache();
314
+ }
312
315
  static {
313
316
  this.fontCache = _Caching.createAssetCache();
314
317
  }
@@ -351,6 +354,7 @@ var init_Caching = __esm({
351
354
  this.entityAnimationCache,
352
355
  this.blockEntityIndexCache,
353
356
  this.fontCache,
357
+ this.unihexCache,
354
358
  this.bannerPatternCache,
355
359
  this.mineRenderDataCache,
356
360
  this.usernameUuidCache,
@@ -1408,6 +1412,7 @@ var init_AssetParsers = __esm({
1408
1412
  AssetParser2["IMAGE"] = "image";
1409
1413
  AssetParser2["LIST"] = "list";
1410
1414
  AssetParser2["JSON"] = "json";
1415
+ AssetParser2["BINARY"] = "binary";
1411
1416
  return AssetParser2;
1412
1417
  })(AssetParser || {});
1413
1418
  }
@@ -2878,7 +2883,7 @@ var init_parser = __esm({
2878
2883
  });
2879
2884
 
2880
2885
  // src/assets/source/HostedAssetSource.ts
2881
- var p3, DEFAULT_OPTIONS, HostedAssetSource;
2886
+ var BINARY_TIMEOUT, p3, DEFAULT_OPTIONS, HostedAssetSource;
2882
2887
  var init_HostedAssetSource = __esm({
2883
2888
  "src/assets/source/HostedAssetSource.ts"() {
2884
2889
  init_AssetSource();
@@ -2891,6 +2896,7 @@ var init_HostedAssetSource = __esm({
2891
2896
  init_AssetLoader();
2892
2897
  init_parser();
2893
2898
  init_merge();
2899
+ BINARY_TIMEOUT = 6e4;
2894
2900
  p3 = prefix("HostedAssetSource");
2895
2901
  DEFAULT_OPTIONS = {
2896
2902
  retryDefaults: true
@@ -2961,6 +2967,17 @@ var init_HostedAssetSource = __esm({
2961
2967
  }
2962
2968
  };
2963
2969
  }
2970
+ static {
2971
+ this.BINARY = {
2972
+ config(request) {
2973
+ request.timeout = BINARY_TIMEOUT;
2974
+ request.responseType = "arraybuffer";
2975
+ },
2976
+ parse(response) {
2977
+ return { data: new Uint8Array(response.data) };
2978
+ }
2979
+ };
2980
+ }
2964
2981
  static {
2965
2982
  this.PARSER_MAP = /* @__PURE__ */ new Map([
2966
2983
  ["model" /* MODEL */, _HostedAssetSource.MODEL],
@@ -2969,7 +2986,8 @@ var init_HostedAssetSource = __esm({
2969
2986
  ["nbt" /* NBT */, _HostedAssetSource.NBT],
2970
2987
  ["image" /* IMAGE */, _HostedAssetSource.IMAGE],
2971
2988
  ["list" /* LIST */, _HostedAssetSource.LIST],
2972
- ["json" /* JSON */, _HostedAssetSource.JSON]
2989
+ ["json" /* JSON */, _HostedAssetSource.JSON],
2990
+ ["binary" /* BINARY */, _HostedAssetSource.BINARY]
2973
2991
  ]);
2974
2992
  }
2975
2993
  /** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */
@@ -4855,6 +4873,178 @@ var init_Entities = __esm({
4855
4873
  }
4856
4874
  });
4857
4875
 
4876
+ // src/assets/_fonts/Unihex.ts
4877
+ var Unihex_exports = {};
4878
+ __export(Unihex_exports, {
4879
+ loadUnihex: () => loadUnihex
4880
+ });
4881
+ import { TextWriter, Uint8ArrayReader, ZipReader as ZipReader2 } from "@zip.js/zip.js";
4882
+ function readHex(text2, filename, glyphs) {
4883
+ const lines = text2.split("\n");
4884
+ if (lines[lines.length - 1] === "") lines.pop();
4885
+ lines.forEach((line, index) => {
4886
+ const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);
4887
+ if (!match || ![32, 64, 96, 128].includes(match[2].length)) {
4888
+ throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);
4889
+ }
4890
+ const codepoint = parseInt(match[1], 16);
4891
+ if (codepoint > 1114111) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);
4892
+ const bitWidth = match[2].length / 4;
4893
+ const rowLength = bitWidth / 4;
4894
+ const rows = new Uint32Array(GLYPH_HEIGHT);
4895
+ let mask = 0;
4896
+ for (let y = 0; y < GLYPH_HEIGHT; y++) {
4897
+ rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);
4898
+ mask |= rows[y];
4899
+ }
4900
+ let left = 0, right = bitWidth;
4901
+ if (mask) {
4902
+ while (!(mask >>> bitWidth - left - 1 & 1)) left++;
4903
+ right = bitWidth - 1;
4904
+ while (!(mask >>> bitWidth - right - 1 & 1)) right--;
4905
+ }
4906
+ glyphs.set(codepoint, { rows, bitWidth, left, right });
4907
+ });
4908
+ }
4909
+ async function parseUnihex(key) {
4910
+ try {
4911
+ const asset2 = await AssetLoader.get(key, "binary" /* BINARY */);
4912
+ if (!asset2) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);
4913
+ const records = /* @__PURE__ */ new Map();
4914
+ const reader = new ZipReader2(new Uint8ArrayReader(asset2.data), { useWebWorkers: false, useCompressionStream: false });
4915
+ try {
4916
+ for (const entry of await reader.getEntries()) {
4917
+ if (!entry.directory && entry.filename.endsWith(".hex")) {
4918
+ readHex(await entry.getData(new TextWriter(), { checkSignature: true }), entry.filename, records);
4919
+ }
4920
+ }
4921
+ } finally {
4922
+ await reader.close();
4923
+ }
4924
+ const indices = new Int32Array(1114112).fill(-1);
4925
+ const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);
4926
+ let index = 0;
4927
+ for (const [codepoint, record] of records) {
4928
+ indices[codepoint] = index;
4929
+ rows.set(record.rows, index * GLYPH_HEIGHT);
4930
+ metrics.set([record.bitWidth, record.left, record.right], index * 3);
4931
+ index++;
4932
+ }
4933
+ return { indices, rows, metrics };
4934
+ } catch (error) {
4935
+ console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
4936
+ return void 0;
4937
+ }
4938
+ }
4939
+ async function loadUnihex(provider, fontKey, characters) {
4940
+ const origin = new AssetKey(DEFAULT_NAMESPACE, "", void 0, void 0, "assets", "", fontKey.root);
4941
+ const key = AssetKey.parse("font", provider.hex_file, origin);
4942
+ key.assetType = void 0;
4943
+ const glyphs = /* @__PURE__ */ new Map();
4944
+ let overrides;
4945
+ try {
4946
+ overrides = (provider.size_overrides ?? []).map((override) => {
4947
+ const from = override.from.codePointAt(0), to = override.to.codePointAt(0);
4948
+ if ([...override.from].length !== 1 || [...override.to].length !== 1 || from >= to || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {
4949
+ throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);
4950
+ }
4951
+ return { ...override, from, to };
4952
+ });
4953
+ } catch (error) {
4954
+ console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
4955
+ return glyphs;
4956
+ }
4957
+ const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
4958
+ if (!file) return glyphs;
4959
+ let atlas = atlases.get(provider);
4960
+ if (!atlas) {
4961
+ atlas = new UnihexAtlas();
4962
+ atlases.set(provider, atlas);
4963
+ }
4964
+ for (const character of characters) {
4965
+ const codepoint = character.codePointAt(0), index = file.indices[codepoint];
4966
+ if (index < 0) continue;
4967
+ const record = {
4968
+ rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),
4969
+ bitWidth: file.metrics[index * 3],
4970
+ left: file.metrics[index * 3 + 1],
4971
+ right: file.metrics[index * 3 + 2]
4972
+ };
4973
+ const override = overrides.find((range) => codepoint >= range.from && codepoint <= range.to);
4974
+ if (override) {
4975
+ record.left = override.left;
4976
+ record.right = override.right;
4977
+ }
4978
+ const width = record.right - record.left + 1;
4979
+ let rendered;
4980
+ const render = () => rendered ??= atlas.draw(record);
4981
+ glyphs.set(character, {
4982
+ get image() {
4983
+ return render().image;
4984
+ },
4985
+ get x() {
4986
+ return render().x;
4987
+ },
4988
+ get y() {
4989
+ return render().y;
4990
+ },
4991
+ width,
4992
+ height: GLYPH_HEIGHT,
4993
+ scale: 0.5,
4994
+ ascent: 7,
4995
+ advance: Math.floor(width / 2) + 1,
4996
+ boldOffset: 0.5,
4997
+ shadowOffset: 0.5
4998
+ });
4999
+ }
5000
+ return glyphs;
5001
+ }
5002
+ var ATLAS_SIZE, GLYPH_HEIGHT, UnihexAtlas, atlases;
5003
+ var init_Unihex = __esm({
5004
+ "src/assets/_fonts/Unihex.ts"() {
5005
+ init_AssetKey();
5006
+ init_AssetLoader();
5007
+ init_Assets();
5008
+ init_Caching();
5009
+ init_AssetParsers();
5010
+ init_CanvasCompat();
5011
+ ATLAS_SIZE = 512;
5012
+ GLYPH_HEIGHT = 16;
5013
+ UnihexAtlas = class {
5014
+ constructor() {
5015
+ this.x = 0;
5016
+ this.y = 0;
5017
+ }
5018
+ draw(glyph) {
5019
+ const width = glyph.right - glyph.left + 1;
5020
+ if (this.image && this.x + width > this.image.width) {
5021
+ this.x = 0;
5022
+ this.y += GLYPH_HEIGHT;
5023
+ }
5024
+ if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {
5025
+ this.image = createCanvas2(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);
5026
+ this.x = 0;
5027
+ this.y = 0;
5028
+ }
5029
+ const context = this.image.getContext("2d");
5030
+ const pixels = context.createImageData(width, GLYPH_HEIGHT);
5031
+ for (let y = 0; y < GLYPH_HEIGHT; y++) {
5032
+ for (let x = 0; x < width; x++) {
5033
+ const column = glyph.left + x;
5034
+ if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> glyph.bitWidth - column - 1 & 1)) continue;
5035
+ pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);
5036
+ }
5037
+ }
5038
+ const result = { image: this.image, x: this.x, y: this.y };
5039
+ context.putImageData(pixels, this.x, this.y);
5040
+ this.x += width;
5041
+ return result;
5042
+ }
5043
+ };
5044
+ atlases = /* @__PURE__ */ new WeakMap();
5045
+ }
5046
+ });
5047
+
4858
5048
  // src/assets/Fonts.ts
4859
5049
  var Fonts;
4860
5050
  var init_Fonts = __esm({
@@ -4865,7 +5055,7 @@ var init_Fonts = __esm({
4865
5055
  init_ModelTextures();
4866
5056
  init_Caching();
4867
5057
  Fonts = class {
4868
- /** Combines font definitions in source-priority order. Unsupported Unihex and TrueType providers are skipped. */
5058
+ /** Combines font definitions in source-priority order. TrueType providers are skipped. */
4869
5059
  static async get(key = "minecraft:default") {
4870
5060
  const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
4871
5061
  return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
@@ -4881,6 +5071,7 @@ var init_Fonts = __esm({
4881
5071
  const stack = await AssetLoader.getAll(key, "json" /* JSON */);
4882
5072
  if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
4883
5073
  const glyphs = /* @__PURE__ */ new Map();
5074
+ const providers = [];
4884
5075
  for (const asset2 of stack) {
4885
5076
  for (const provider of asset2.providers) {
4886
5077
  if (provider.filter?.uniform || provider.filter?.jp) continue;
@@ -4899,17 +5090,43 @@ var init_Fonts = __esm({
4899
5090
  break;
4900
5091
  case "reference":
4901
5092
  case "minecraft:reference":
4902
- provided = (await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized])).glyphs;
5093
+ const reference = await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized]);
5094
+ if (reference.resolve) {
5095
+ providers.push(async (characters) => {
5096
+ await reference.resolve(characters);
5097
+ return reference.glyphs;
5098
+ });
5099
+ continue;
5100
+ }
5101
+ provided = reference.glyphs;
4903
5102
  break;
5103
+ case "unihex":
5104
+ case "minecraft:unihex":
5105
+ providers.push(async (characters) => (await Promise.resolve().then(() => (init_Unihex(), Unihex_exports))).loadUnihex(provider, key, characters));
5106
+ continue;
4904
5107
  default:
4905
5108
  continue;
4906
5109
  }
4907
- for (const [character, glyph] of provided) {
5110
+ if (providers.every((provider2) => provider2 instanceof Map)) for (const [character, glyph] of provided) {
4908
5111
  if (character !== "\0" && !glyphs.has(character)) glyphs.set(character, glyph);
4909
5112
  }
5113
+ providers.push(provided);
5114
+ }
5115
+ }
5116
+ return { glyphs, resolve: providers.every((provider) => provider instanceof Map) ? void 0 : async (characters) => {
5117
+ const remaining = new Set([...characters].filter((character) => character !== "\0" && character !== "\n" && character !== "\r" && !glyphs.has(character)));
5118
+ for (const provider of providers) {
5119
+ if (!remaining.size) break;
5120
+ const provided = provider instanceof Map ? provider : await provider([...remaining].join(""));
5121
+ for (const character of remaining) {
5122
+ const glyph = provided.get(character);
5123
+ if (glyph) {
5124
+ glyphs.set(character, glyph);
5125
+ remaining.delete(character);
5126
+ }
5127
+ }
4910
5128
  }
4911
- }
4912
- return { glyphs };
5129
+ } };
4913
5130
  }
4914
5131
  static async bitmap(provider, fontKey) {
4915
5132
  const rows = provider.chars.map((row) => [...row]);
@@ -8147,6 +8364,7 @@ async function layoutGuiText(text2, options = {}) {
8147
8364
  }
8148
8365
  const font = await Fonts.get(options.font);
8149
8366
  const runs = typeof text2 === "string" ? [{ text: text2 }] : text2;
8367
+ await font.resolve?.(runs.map((run) => run.text).join(""));
8150
8368
  const glyphs = [], lineWidths = [];
8151
8369
  let line = [], width = 0;
8152
8370
  let trailingNewline = false;
@@ -8173,7 +8391,7 @@ async function layoutGuiText(text2, options = {}) {
8173
8391
  continue;
8174
8392
  }
8175
8393
  const glyph = font.glyphs.get(character);
8176
- const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
8394
+ const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);
8177
8395
  line.push({ character, glyph, advance, style, x: 0, y: 0 });
8178
8396
  width += advance;
8179
8397
  while (width > maxWidth && line.length > 1) {
@@ -8201,7 +8419,7 @@ function createGuiTextGeometry(layout, shadow = true) {
8201
8419
  batches.push(batch);
8202
8420
  }
8203
8421
  const color2 = new Color8(isShadow ? (style.color & 16579836) >> 2 : style.color);
8204
- const offset = isShadow ? 1 : 0;
8422
+ const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
8205
8423
  const top = glyph ? 7 - glyph.ascent : 0;
8206
8424
  const height = glyph ? glyph.height * glyph.scale : 8;
8207
8425
  const width = glyph ? glyph.width * glyph.scale : 5;
@@ -8231,7 +8449,7 @@ function createGuiTextGeometry(layout, shadow = true) {
8231
8449
  for (let i = 0; i < 4; i++) batch.colors.push(color2.r, color2.g, color2.b);
8232
8450
  batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
8233
8451
  };
8234
- for (const boldOffset of style.bold ? [0, 1] : [0]) {
8452
+ for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {
8235
8453
  if (glyph) quad(0, top, width, top + height, boldOffset);
8236
8454
  else {
8237
8455
  quad(0, 0, 5, 1, boldOffset);
@@ -18854,7 +19072,7 @@ var LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18];
18854
19072
 
18855
19073
  // src/world/SectionGeometry.ts
18856
19074
  function buildSectionGeometry(input) {
18857
- const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
19075
+ const { count, indices, templates, cullMasks, templateData, atlases: atlases2, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
18858
19076
  if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
18859
19077
  if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError("Section entry count exceeds its arrays");
18860
19078
  if (biomeTints && biomeTints.length !== count * 3) throw new RangeError("Section biome tints must contain RGB for each placement");
@@ -18889,8 +19107,8 @@ function buildSectionGeometry(input) {
18889
19107
  const locations = /* @__PURE__ */ new Map();
18890
19108
  for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {
18891
19109
  const firstPage = pages.length;
18892
- for (const atlas of [...layerAtlases].sort((a, b) => Number(atlases[a].animated) - Number(atlases[b].animated) || (atlases[a].animated ? a - b : atlases[b].height - atlases[a].height))) {
18893
- const { width, height, animated } = atlases[atlas];
19110
+ for (const atlas of [...layerAtlases].sort((a, b) => Number(atlases2[a].animated) - Number(atlases2[b].animated) || (atlases2[a].animated ? a - b : atlases2[b].height - atlases2[a].height))) {
19111
+ const { width, height, animated } = atlases2[atlas];
18894
19112
  if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
18895
19113
  let selected = -1;
18896
19114
  for (let i = firstPage; !animated && i < pages.length; i++) {
@@ -18933,7 +19151,7 @@ function buildSectionGeometry(input) {
18933
19151
  });
18934
19152
  if (!quads.sprites.length) continue;
18935
19153
  if (!fluidPages.has(fluid)) {
18936
- const { width, height } = atlases[data.atlas];
19154
+ const { width, height } = atlases2[data.atlas];
18937
19155
  if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
18938
19156
  fluidPages.set(fluid, {
18939
19157
  layer: 2,
@@ -18951,7 +19169,7 @@ function buildSectionGeometry(input) {
18951
19169
  const tint = fluid === "water" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;
18952
19170
  fluidPages.get(fluid).fluids.push({ quads, x, y, z, data, tint });
18953
19171
  }
18954
- pages.push(...[...fluidPages.values()].sort((a, b) => Number(atlases[a.placements[0].atlas].animated) - Number(atlases[b.placements[0].atlas].animated) || a.placements[0].atlas - b.placements[0].atlas));
19172
+ pages.push(...[...fluidPages.values()].sort((a, b) => Number(atlases2[a.placements[0].atlas].animated) - Number(atlases2[b.placements[0].atlas].animated) || a.placements[0].atlas - b.placements[0].atlas));
18955
19173
  }
18956
19174
  return pages.map((page) => {
18957
19175
  let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);
@@ -18968,7 +19186,7 @@ function buildSectionGeometry(input) {
18968
19186
  let vertex = 0, indexOffset = 0;
18969
19187
  for (const entry of page.entries) {
18970
19188
  const template = templateData[templates[entry]];
18971
- const atlas = atlases[template.atlas];
19189
+ const atlas = atlases2[template.atlas];
18972
19190
  const placement = locations.get(template.atlas);
18973
19191
  const mapU = (u) => (placement.x + u * atlas.width) / page.width;
18974
19192
  const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
@@ -19007,7 +19225,7 @@ function buildSectionGeometry(input) {
19007
19225
  }
19008
19226
  }
19009
19227
  for (const { quads, x, y, z, data, tint } of page.fluids) {
19010
- const atlas = atlases[data.atlas];
19228
+ const atlas = atlases2[data.atlas];
19011
19229
  const placement = page.placements[0];
19012
19230
  const mapU = (u) => (placement.x + u * atlas.width) / page.width;
19013
19231
  const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
@@ -19109,7 +19327,7 @@ var templateCache = /* @__PURE__ */ new WeakMap();
19109
19327
  var WATER_TINT = new Color12(4159204).toArray();
19110
19328
  function toInput(entries, maxAtlasSize, fluids, lighting) {
19111
19329
  if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
19112
- const atlases = [];
19330
+ const atlases2 = [];
19113
19331
  const atlasIds = /* @__PURE__ */ new Map();
19114
19332
  const templateIds = /* @__PURE__ */ new Map();
19115
19333
  const input = {
@@ -19132,9 +19350,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
19132
19350
  if (id === void 0) {
19133
19351
  let atlas = atlasIds.get(template.atlas);
19134
19352
  if (atlas === void 0) {
19135
- atlas = atlases.length;
19353
+ atlas = atlases2.length;
19136
19354
  atlasIds.set(template.atlas, atlas);
19137
- atlases.push(template.atlas);
19355
+ atlases2.push(template.atlas);
19138
19356
  input.atlases.push({ width: template.atlas.image.width, height: template.atlas.image.height, animated: template.atlas.hasAnimation });
19139
19357
  }
19140
19358
  let data = templateCache.get(template);
@@ -19193,9 +19411,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
19193
19411
  if (!atlas) continue;
19194
19412
  let id = atlasIds.get(atlas);
19195
19413
  if (id === void 0) {
19196
- id = atlases.length;
19414
+ id = atlases2.length;
19197
19415
  atlasIds.set(atlas, id);
19198
- atlases.push(atlas);
19416
+ atlases2.push(atlas);
19199
19417
  input.atlases.push({ width: atlas.image.width, height: atlas.image.height, animated: atlas.hasAnimation });
19200
19418
  }
19201
19419
  input.fluids[kind] = {
@@ -19206,7 +19424,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
19206
19424
  };
19207
19425
  }
19208
19426
  }
19209
- return { input, atlases };
19427
+ return { input, atlases: atlases2 };
19210
19428
  }
19211
19429
  var SectionMesh = class _SectionMesh extends Group3 {
19212
19430
  constructor() {
@@ -19221,23 +19439,23 @@ var SectionMesh = class _SectionMesh extends Group3 {
19221
19439
  }
19222
19440
  /** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
19223
19441
  static build(entries, maxAtlasSize = 2048, fluids, lighting) {
19224
- const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
19225
- return this.fromPages(buildSectionGeometry(input), atlases);
19442
+ const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
19443
+ return this.fromPages(buildSectionGeometry(input), atlases2);
19226
19444
  }
19227
19445
  /** Builds section-local meshes in a browser worker when available, with synchronous fallback. */
19228
19446
  static async buildAsync(entries, maxAtlasSize = 2048, fluids, lighting) {
19229
- const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
19447
+ const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
19230
19448
  const worker = SectionWorker.shared();
19231
19449
  const pages = worker ? await worker.build(input).catch(() => buildSectionGeometry(input)) : buildSectionGeometry(input);
19232
- return this.fromPages(pages, atlases);
19450
+ return this.fromPages(pages, atlases2);
19233
19451
  }
19234
- static fromPages(pages, atlases) {
19452
+ static fromPages(pages, atlases2) {
19235
19453
  const section = new _SectionMesh();
19236
19454
  for (const page of pages) {
19237
19455
  const canvas = createCanvas2(page.width, page.height);
19238
19456
  const context = canvas.getContext("2d");
19239
19457
  for (const { atlas, x, y } of page.placements) {
19240
- context.drawImage(atlases[atlas].image.canvas, x, y);
19458
+ context.drawImage(atlases2[atlas].image.canvas, x, y);
19241
19459
  }
19242
19460
  const geometry = new BufferGeometry9();
19243
19461
  geometry.setAttribute("position", new Float32BufferAttribute10(page.positions.buffer, 3));
@@ -19248,7 +19466,7 @@ var SectionMesh = class _SectionMesh extends Group3 {
19248
19466
  geometry.setIndex(new Uint32BufferAttribute(page.indices.buffer, 1));
19249
19467
  geometry.computeBoundingBox();
19250
19468
  geometry.computeBoundingSphere();
19251
- const transparent = page.layer === 2 ? atlases[page.placements[0].atlas].hasTranslucency : page.layer === 1;
19469
+ const transparent = page.layer === 2 ? atlases2[page.placements[0].atlas].hasTranslucency : page.layer === 1;
19252
19470
  const material = Materials.createShadedCanvasMaterial(canvas, transparent, false, true);
19253
19471
  material.side = FrontSide4;
19254
19472
  if (page.layer === 2) {
@@ -19263,7 +19481,7 @@ var SectionMesh = class _SectionMesh extends Group3 {
19263
19481
  section.blockIndices.set(mesh, page.blockIndices);
19264
19482
  const unsubscribe = [];
19265
19483
  for (const { atlas: id, x, y } of page.placements) {
19266
- const atlas = atlases[id];
19484
+ const atlas = atlases2[id];
19267
19485
  if (!atlas.hasAnimation) continue;
19268
19486
  unsubscribe.push(atlas.subscribe(() => {
19269
19487
  context.clearRect(x, y, atlas.image.width, atlas.image.height);