minerender 2.1.0-alpha.132 → 2.1.0-alpha.134

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.
Files changed (37) hide show
  1. package/dist/browser/esm/Materials.mjs +3 -2
  2. package/dist/browser/esm/Materials.mjs.map +1 -1
  3. package/dist/browser/esm/assets/Fonts.mjs +31 -4
  4. package/dist/browser/esm/assets/Fonts.mjs.map +1 -1
  5. package/dist/browser/esm/assets/_fonts/Unihex.mjs +166 -0
  6. package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -0
  7. package/dist/browser/esm/assets/source/HostedAssetSource.mjs +12 -1
  8. package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
  9. package/dist/browser/esm/assets/source/parser/AssetParsers.mjs +1 -0
  10. package/dist/browser/esm/assets/source/parser/AssetParsers.mjs.map +1 -1
  11. package/dist/browser/esm/cache/Caching.mjs +2 -0
  12. package/dist/browser/esm/cache/Caching.mjs.map +1 -1
  13. package/dist/browser/esm/env/browser/section.worker.mjs +5 -3
  14. package/dist/browser/esm/env/browser/section.worker.mjs.map +1 -1
  15. package/dist/browser/esm/gui/GuiText.mjs +4 -3
  16. package/dist/browser/esm/gui/GuiText.mjs.map +1 -1
  17. package/dist/browser/esm/index.browser.d.mts +25 -4
  18. package/dist/browser/esm/model/scene/ModelObject.mjs +4 -0
  19. package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
  20. package/dist/browser/esm/world/SectionGeometry.mjs +5 -3
  21. package/dist/browser/esm/world/SectionGeometry.mjs.map +1 -1
  22. package/dist/browser/esm/world/SectionMesh.mjs +4 -0
  23. package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
  24. package/dist/browser/esm/world/SectionModels.mjs +2 -2
  25. package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
  26. package/dist/browser/index.d.ts +25 -4
  27. package/dist/browser/index.js +263 -38
  28. package/dist/browser/index.js.map +1 -1
  29. package/dist/bundle.js +306 -38
  30. package/dist/bundle.js.map +1 -1
  31. package/dist/node/index.d.mts +25 -4
  32. package/dist/node/index.d.ts +25 -4
  33. package/dist/node/index.js +267 -38
  34. package/dist/node/index.js.map +1 -1
  35. package/dist/node/index.mjs +267 -38
  36. package/dist/node/index.mjs.map +1 -1
  37. package/package.json +1 -1
package/dist/bundle.js CHANGED
@@ -35632,6 +35632,7 @@ void main() {
35632
35632
  this.entityAnimationCache,
35633
35633
  this.blockEntityIndexCache,
35634
35634
  this.fontCache,
35635
+ this.unihexCache,
35635
35636
  this.bannerPatternCache,
35636
35637
  this.mineRenderDataCache,
35637
35638
  this.usernameUuidCache,
@@ -35685,6 +35686,7 @@ void main() {
35685
35686
  _Caching.entityTextureCache = _Caching.createAssetCache();
35686
35687
  _Caching.entityAnimationCache = _Caching.createAssetCache();
35687
35688
  _Caching.blockEntityIndexCache = _Caching.createAssetCache();
35689
+ _Caching.unihexCache = _Caching.createAssetCache();
35688
35690
  _Caching.fontCache = _Caching.createAssetCache();
35689
35691
  _Caching.bannerPatternCache = _Caching.createAssetCache();
35690
35692
  _Caching.mineRenderDataCache = _Caching.createAssetCache();
@@ -36796,6 +36798,7 @@ void main() {
36796
36798
  static createShadedCanvasMaterial(canvas, transparent = false, shade = false, boundUvs = false) {
36797
36799
  const vertShader = `
36798
36800
  uniform bool SHADE;
36801
+ attribute float shade;
36799
36802
 
36800
36803
  // Keep MSAA edge pixels from sampling outside the face's atlas region.
36801
36804
  #if __VERSION__ >= 300
@@ -36818,7 +36821,7 @@ void main() {
36818
36821
  void main()
36819
36822
  {
36820
36823
 
36821
- if (SHADE) {
36824
+ if (SHADE && shade > 0.5) {
36822
36825
 
36823
36826
  #ifdef USE_INSTANCING
36824
36827
  vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
@@ -36927,7 +36930,7 @@ void main() {
36927
36930
  side: transparent ? DoubleSide : FrontSide,
36928
36931
  alphaTest: 0.5
36929
36932
  });
36930
- Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });
36933
+ Object.assign(material.defaultAttributeValues, { shade: [1], uvBounds: [0, 0, 1, 1] });
36931
36934
  return material;
36932
36935
  } catch (e6) {
36933
36936
  console.warn(e6);
@@ -37098,6 +37101,7 @@ void main() {
37098
37101
  AssetParser2["IMAGE"] = "image";
37099
37102
  AssetParser2["LIST"] = "list";
37100
37103
  AssetParser2["JSON"] = "json";
37104
+ AssetParser2["BINARY"] = "binary";
37101
37105
  return AssetParser2;
37102
37106
  })(AssetParser || {});
37103
37107
  }
@@ -73063,7 +73067,7 @@ return ${compiler2.callType("value", tagType)}
73063
73067
  });
73064
73068
 
73065
73069
  // src/assets/source/HostedAssetSource.ts
73066
- var p7, DEFAULT_OPTIONS2, _HostedAssetSource, HostedAssetSource;
73070
+ var BINARY_TIMEOUT, p7, DEFAULT_OPTIONS2, _HostedAssetSource, HostedAssetSource;
73067
73071
  var init_HostedAssetSource = __esm({
73068
73072
  "src/assets/source/HostedAssetSource.ts"() {
73069
73073
  init_dirname();
@@ -73079,6 +73083,7 @@ return ${compiler2.callType("value", tagType)}
73079
73083
  init_AssetLoader();
73080
73084
  init_parser();
73081
73085
  init_merge();
73086
+ BINARY_TIMEOUT = 6e4;
73082
73087
  p7 = prefix("HostedAssetSource");
73083
73088
  DEFAULT_OPTIONS2 = {
73084
73089
  retryDefaults: true
@@ -73219,6 +73224,15 @@ return ${compiler2.callType("value", tagType)}
73219
73224
  return response.data;
73220
73225
  }
73221
73226
  };
73227
+ _HostedAssetSource.BINARY = {
73228
+ config(request) {
73229
+ request.timeout = BINARY_TIMEOUT;
73230
+ request.responseType = "arraybuffer";
73231
+ },
73232
+ parse(response) {
73233
+ return { data: new Uint8Array(response.data) };
73234
+ }
73235
+ };
73222
73236
  _HostedAssetSource.PARSER_MAP = /* @__PURE__ */ new Map([
73223
73237
  ["model" /* MODEL */, _HostedAssetSource.MODEL],
73224
73238
  ["blockstate" /* BLOCKSTATE */, _HostedAssetSource.BLOCKSTATE],
@@ -73226,7 +73240,8 @@ return ${compiler2.callType("value", tagType)}
73226
73240
  ["nbt" /* NBT */, _HostedAssetSource.NBT],
73227
73241
  ["image" /* IMAGE */, _HostedAssetSource.IMAGE],
73228
73242
  ["list" /* LIST */, _HostedAssetSource.LIST],
73229
- ["json" /* JSON */, _HostedAssetSource.JSON]
73243
+ ["json" /* JSON */, _HostedAssetSource.JSON],
73244
+ ["binary" /* BINARY */, _HostedAssetSource.BINARY]
73230
73245
  ]);
73231
73246
  HostedAssetSource = _HostedAssetSource;
73232
73247
  }
@@ -81841,7 +81856,7 @@ return ${compiler2.callType("value", tagType)}
81841
81856
  function readUint8Array(reader, offset, size, diskNumber) {
81842
81857
  return reader.readUint8Array(offset, size, diskNumber);
81843
81858
  }
81844
- var ERR_ITERATOR_COMPLETED_TOO_SOON, HTTP_HEADER_CONTENT_TYPE, DEFAULT_CHUNK_SIZE, PROPERTY_NAME_WRITABLE, Stream, Reader, BlobReader, BlobWriter, SplitDataReader, SplitDataWriter;
81859
+ var ERR_ITERATOR_COMPLETED_TOO_SOON, HTTP_HEADER_CONTENT_TYPE, DEFAULT_CHUNK_SIZE, PROPERTY_NAME_WRITABLE, Stream, Reader, BlobReader, BlobWriter, TextWriter, Uint8ArrayReader, SplitDataReader, SplitDataWriter;
81845
81860
  var init_io = __esm({
81846
81861
  "../../node_modules/@zip.js/zip.js/lib/core/io.js"() {
81847
81862
  init_dirname();
@@ -81924,6 +81939,46 @@ return ${compiler2.callType("value", tagType)}
81924
81939
  return this.blob;
81925
81940
  }
81926
81941
  };
81942
+ TextWriter = class extends BlobWriter {
81943
+ constructor(encoding) {
81944
+ super(encoding);
81945
+ Object.assign(this, {
81946
+ encoding,
81947
+ utf8: !encoding || encoding.toLowerCase() == "utf-8"
81948
+ });
81949
+ }
81950
+ async getData() {
81951
+ const {
81952
+ encoding,
81953
+ utf8
81954
+ } = this;
81955
+ const blob = await super.getData();
81956
+ if (blob.text && utf8) {
81957
+ return blob.text();
81958
+ } else {
81959
+ const reader = new FileReader();
81960
+ return new Promise((resolve, reject) => {
81961
+ Object.assign(reader, {
81962
+ onload: ({ target }) => resolve(target.result),
81963
+ onerror: () => reject(reader.error)
81964
+ });
81965
+ reader.readAsText(blob, encoding);
81966
+ });
81967
+ }
81968
+ }
81969
+ };
81970
+ Uint8ArrayReader = class extends Reader {
81971
+ constructor(array) {
81972
+ super();
81973
+ Object.assign(this, {
81974
+ array,
81975
+ size: array.length
81976
+ });
81977
+ }
81978
+ readUint8Array(index, length) {
81979
+ return this.array.slice(index, index + length);
81980
+ }
81981
+ };
81927
81982
  SplitDataReader = class extends Reader {
81928
81983
  constructor(readers) {
81929
81984
  super();
@@ -84682,6 +84737,181 @@ ${key}` : key;
84682
84737
  }
84683
84738
  });
84684
84739
 
84740
+ // src/assets/_fonts/Unihex.ts
84741
+ var Unihex_exports = {};
84742
+ __export(Unihex_exports, {
84743
+ loadUnihex: () => loadUnihex
84744
+ });
84745
+ function readHex(text2, filename, glyphs) {
84746
+ const lines = text2.split("\n");
84747
+ if (lines[lines.length - 1] === "") lines.pop();
84748
+ lines.forEach((line, index) => {
84749
+ const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);
84750
+ if (!match || ![32, 64, 96, 128].includes(match[2].length)) {
84751
+ throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);
84752
+ }
84753
+ const codepoint = parseInt(match[1], 16);
84754
+ if (codepoint > 1114111) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);
84755
+ const bitWidth = match[2].length / 4;
84756
+ const rowLength = bitWidth / 4;
84757
+ const rows = new Uint32Array(GLYPH_HEIGHT);
84758
+ let mask = 0;
84759
+ for (let y5 = 0; y5 < GLYPH_HEIGHT; y5++) {
84760
+ rows[y5] = parseInt(match[2].slice(y5 * rowLength, (y5 + 1) * rowLength), 16);
84761
+ mask |= rows[y5];
84762
+ }
84763
+ let left = 0, right = bitWidth;
84764
+ if (mask) {
84765
+ while (!(mask >>> bitWidth - left - 1 & 1)) left++;
84766
+ right = bitWidth - 1;
84767
+ while (!(mask >>> bitWidth - right - 1 & 1)) right--;
84768
+ }
84769
+ glyphs.set(codepoint, { rows, bitWidth, left, right });
84770
+ });
84771
+ }
84772
+ async function parseUnihex(key) {
84773
+ try {
84774
+ const asset2 = await AssetLoader.get(key, "binary" /* BINARY */);
84775
+ if (!asset2) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);
84776
+ const records = /* @__PURE__ */ new Map();
84777
+ const reader = new ZipReader(new Uint8ArrayReader(asset2.data), { useWebWorkers: false, useCompressionStream: false });
84778
+ try {
84779
+ for (const entry of await reader.getEntries()) {
84780
+ if (!entry.directory && entry.filename.endsWith(".hex")) {
84781
+ readHex(await entry.getData(new TextWriter(), { checkSignature: true }), entry.filename, records);
84782
+ }
84783
+ }
84784
+ } finally {
84785
+ await reader.close();
84786
+ }
84787
+ const indices = new Int32Array(1114112).fill(-1);
84788
+ const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);
84789
+ let index = 0;
84790
+ for (const [codepoint, record] of records) {
84791
+ indices[codepoint] = index;
84792
+ rows.set(record.rows, index * GLYPH_HEIGHT);
84793
+ metrics.set([record.bitWidth, record.left, record.right], index * 3);
84794
+ index++;
84795
+ }
84796
+ return { indices, rows, metrics };
84797
+ } catch (error2) {
84798
+ console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error2);
84799
+ return void 0;
84800
+ }
84801
+ }
84802
+ async function loadUnihex(provider, fontKey, characters) {
84803
+ const origin = new AssetKey(DEFAULT_NAMESPACE, "", void 0, void 0, "assets", "", fontKey.root);
84804
+ const key = AssetKey.parse("font", provider.hex_file, origin);
84805
+ key.assetType = void 0;
84806
+ const glyphs = /* @__PURE__ */ new Map();
84807
+ let overrides;
84808
+ try {
84809
+ overrides = (provider.size_overrides ?? []).map((override) => {
84810
+ const from = override.from.codePointAt(0), to = override.to.codePointAt(0);
84811
+ if ([...override.from].length !== 1 || [...override.to].length !== 1 || from >= to || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {
84812
+ throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);
84813
+ }
84814
+ return { ...override, from, to };
84815
+ });
84816
+ } catch (error2) {
84817
+ console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error2);
84818
+ return glyphs;
84819
+ }
84820
+ const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
84821
+ if (!file) return glyphs;
84822
+ let atlas = atlases.get(provider);
84823
+ if (!atlas) {
84824
+ atlas = new UnihexAtlas();
84825
+ atlases.set(provider, atlas);
84826
+ }
84827
+ for (const character of characters) {
84828
+ const codepoint = character.codePointAt(0), index = file.indices[codepoint];
84829
+ if (index < 0) continue;
84830
+ const record = {
84831
+ rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),
84832
+ bitWidth: file.metrics[index * 3],
84833
+ left: file.metrics[index * 3 + 1],
84834
+ right: file.metrics[index * 3 + 2]
84835
+ };
84836
+ const override = overrides.find((range) => codepoint >= range.from && codepoint <= range.to);
84837
+ if (override) {
84838
+ record.left = override.left;
84839
+ record.right = override.right;
84840
+ }
84841
+ const width = record.right - record.left + 1;
84842
+ let rendered;
84843
+ const render = () => rendered ?? (rendered = atlas.draw(record));
84844
+ glyphs.set(character, {
84845
+ get image() {
84846
+ return render().image;
84847
+ },
84848
+ get x() {
84849
+ return render().x;
84850
+ },
84851
+ get y() {
84852
+ return render().y;
84853
+ },
84854
+ width,
84855
+ height: GLYPH_HEIGHT,
84856
+ scale: 0.5,
84857
+ ascent: 7,
84858
+ advance: Math.floor(width / 2) + 1,
84859
+ boldOffset: 0.5,
84860
+ shadowOffset: 0.5
84861
+ });
84862
+ }
84863
+ return glyphs;
84864
+ }
84865
+ var ATLAS_SIZE, GLYPH_HEIGHT, UnihexAtlas, atlases;
84866
+ var init_Unihex = __esm({
84867
+ "src/assets/_fonts/Unihex.ts"() {
84868
+ init_dirname();
84869
+ init_buffer2();
84870
+ init_process2();
84871
+ init_zip();
84872
+ init_AssetKey();
84873
+ init_AssetLoader();
84874
+ init_Assets();
84875
+ init_Caching();
84876
+ init_AssetParsers();
84877
+ init_CanvasCompat();
84878
+ ATLAS_SIZE = 512;
84879
+ GLYPH_HEIGHT = 16;
84880
+ UnihexAtlas = class {
84881
+ constructor() {
84882
+ this.x = 0;
84883
+ this.y = 0;
84884
+ }
84885
+ draw(glyph) {
84886
+ const width = glyph.right - glyph.left + 1;
84887
+ if (this.image && this.x + width > this.image.width) {
84888
+ this.x = 0;
84889
+ this.y += GLYPH_HEIGHT;
84890
+ }
84891
+ if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {
84892
+ this.image = createCanvas(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);
84893
+ this.x = 0;
84894
+ this.y = 0;
84895
+ }
84896
+ const context = this.image.getContext("2d");
84897
+ const pixels = context.createImageData(width, GLYPH_HEIGHT);
84898
+ for (let y5 = 0; y5 < GLYPH_HEIGHT; y5++) {
84899
+ for (let x4 = 0; x4 < width; x4++) {
84900
+ const column = glyph.left + x4;
84901
+ if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y5] >>> glyph.bitWidth - column - 1 & 1)) continue;
84902
+ pixels.data.fill(255, (y5 * width + x4) * 4, (y5 * width + x4 + 1) * 4);
84903
+ }
84904
+ }
84905
+ const result = { image: this.image, x: this.x, y: this.y };
84906
+ context.putImageData(pixels, this.x, this.y);
84907
+ this.x += width;
84908
+ return result;
84909
+ }
84910
+ };
84911
+ atlases = /* @__PURE__ */ new WeakMap();
84912
+ }
84913
+ });
84914
+
84685
84915
  // src/assets/Fonts.ts
84686
84916
  var Fonts;
84687
84917
  var init_Fonts = __esm({
@@ -84695,7 +84925,7 @@ ${key}` : key;
84695
84925
  init_ModelTextures();
84696
84926
  init_Caching();
84697
84927
  Fonts = class {
84698
- /** Combines font definitions in source-priority order. Unsupported Unihex and TrueType providers are skipped. */
84928
+ /** Combines font definitions in source-priority order. TrueType providers are skipped. */
84699
84929
  static async get(key = "minecraft:default") {
84700
84930
  const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
84701
84931
  return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
@@ -84711,6 +84941,7 @@ ${key}` : key;
84711
84941
  const stack = await AssetLoader.getAll(key, "json" /* JSON */);
84712
84942
  if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
84713
84943
  const glyphs = /* @__PURE__ */ new Map();
84944
+ const providers = [];
84714
84945
  for (const asset2 of stack) {
84715
84946
  for (const provider of asset2.providers) {
84716
84947
  if (provider.filter?.uniform || provider.filter?.jp) continue;
@@ -84729,17 +84960,43 @@ ${key}` : key;
84729
84960
  break;
84730
84961
  case "reference":
84731
84962
  case "minecraft:reference":
84732
- provided = (await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized])).glyphs;
84963
+ const reference = await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized]);
84964
+ if (reference.resolve) {
84965
+ providers.push(async (characters) => {
84966
+ await reference.resolve(characters);
84967
+ return reference.glyphs;
84968
+ });
84969
+ continue;
84970
+ }
84971
+ provided = reference.glyphs;
84733
84972
  break;
84973
+ case "unihex":
84974
+ case "minecraft:unihex":
84975
+ providers.push(async (characters) => (await Promise.resolve().then(() => (init_Unihex(), Unihex_exports))).loadUnihex(provider, key, characters));
84976
+ continue;
84734
84977
  default:
84735
84978
  continue;
84736
84979
  }
84737
- for (const [character, glyph] of provided) {
84980
+ if (providers.every((provider2) => provider2 instanceof Map)) for (const [character, glyph] of provided) {
84738
84981
  if (character !== "\0" && !glyphs.has(character)) glyphs.set(character, glyph);
84739
84982
  }
84983
+ providers.push(provided);
84740
84984
  }
84741
84985
  }
84742
- return { glyphs };
84986
+ return { glyphs, resolve: providers.every((provider) => provider instanceof Map) ? void 0 : async (characters) => {
84987
+ const remaining = new Set([...characters].filter((character) => character !== "\0" && character !== "\n" && character !== "\r" && !glyphs.has(character)));
84988
+ for (const provider of providers) {
84989
+ if (!remaining.size) break;
84990
+ const provided = provider instanceof Map ? provider : await provider([...remaining].join(""));
84991
+ for (const character of remaining) {
84992
+ const glyph = provided.get(character);
84993
+ if (glyph) {
84994
+ glyphs.set(character, glyph);
84995
+ remaining.delete(character);
84996
+ }
84997
+ }
84998
+ }
84999
+ } };
84743
85000
  }
84744
85001
  static async bitmap(provider, fontKey) {
84745
85002
  const rows = provider.chars.map((row) => [...row]);
@@ -87964,6 +88221,7 @@ ${key}` : key;
87964
88221
  }
87965
88222
  const font = await Fonts.get(options.font);
87966
88223
  const runs = typeof text2 === "string" ? [{ text: text2 }] : text2;
88224
+ await font.resolve?.(runs.map((run) => run.text).join(""));
87967
88225
  const glyphs = [], lineWidths = [];
87968
88226
  let line = [], width = 0;
87969
88227
  let trailingNewline = false;
@@ -87990,7 +88248,7 @@ ${key}` : key;
87990
88248
  continue;
87991
88249
  }
87992
88250
  const glyph = font.glyphs.get(character);
87993
- const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
88251
+ const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);
87994
88252
  line.push({ character, glyph, advance, style, x: 0, y: 0 });
87995
88253
  width += advance;
87996
88254
  while (width > maxWidth && line.length > 1) {
@@ -88018,7 +88276,7 @@ ${key}` : key;
88018
88276
  batches.push(batch);
88019
88277
  }
88020
88278
  const color3 = new Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
88021
- const offset = isShadow ? 1 : 0;
88279
+ const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
88022
88280
  const top = glyph ? 7 - glyph.ascent : 0;
88023
88281
  const height = glyph ? glyph.height * glyph.scale : 8;
88024
88282
  const width = glyph ? glyph.width * glyph.scale : 5;
@@ -88048,7 +88306,7 @@ ${key}` : key;
88048
88306
  for (let i4 = 0; i4 < 4; i4++) batch.colors.push(color3.r, color3.g, color3.b);
88049
88307
  batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
88050
88308
  };
88051
- for (const boldOffset of style.bold ? [0, 1] : [0]) {
88309
+ for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {
88052
88310
  if (glyph) quad(0, top, width, top + height, boldOffset);
88053
88311
  else {
88054
88312
  quad(0, 0, 5, 1, boldOffset);
@@ -92586,6 +92844,10 @@ ${shader.fragmentShader}`.replace(
92586
92844
  this.atlas.model.elements?.forEach((el) => {
92587
92845
  const elGeo = this._getBoxGeometryFromElement(el).clone();
92588
92846
  this.geometries.add(elGeo);
92847
+ elGeo.setAttribute("shade", new BufferAttribute(
92848
+ new Float32Array(elGeo.getAttribute("position").count).fill(!this.originalModel.itemId && el.shade === false ? 0 : 1),
92849
+ 1
92850
+ ));
92589
92851
  if (this.options.cullMask) {
92590
92852
  const indices = Array.from(elGeo.getIndex().array);
92591
92853
  elGeo.setIndex(indices.filter((_4, index) => {
@@ -102878,9 +103140,9 @@ gl_FragDepth=readDepth(vUv);
102878
103140
  function compactQuads(geometry, keep) {
102879
103141
  const quads = keep.flatMap((kept, index) => kept ? [index] : []);
102880
103142
  const compact = new BufferGeometry();
102881
- for (const [name2, size] of Object.entries({ position: 3, normal: 3, uv: 2, uvBounds: 4, color: 3 })) {
103143
+ for (const [name2, size] of Object.entries({ position: 3, normal: 3, uv: 2, uvBounds: 4, color: 3, shade: 1 })) {
102882
103144
  const source2 = geometry.getAttribute(name2);
102883
- const defaults = name2 === "uvBounds" ? [0, 0, 1, 1] : name2 === "color" ? [1, 1, 1] : void 0;
103145
+ const defaults = name2 === "uvBounds" ? [0, 0, 1, 1] : name2 === "color" ? [1, 1, 1] : name2 === "shade" ? [1] : void 0;
102884
103146
  const values = new Float32Array(quads.length * 4 * size);
102885
103147
  for (let q3 = 0; q3 < quads.length; q3++) {
102886
103148
  for (let vertex2 = 0; vertex2 < 4; vertex2++) {
@@ -104158,7 +104420,7 @@ gl_FragDepth=readDepth(vUv);
104158
104420
 
104159
104421
  // src/world/SectionGeometry.ts
104160
104422
  function buildSectionGeometry(input) {
104161
- const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
104423
+ const { count, indices, templates, cullMasks, templateData, atlases: atlases2, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
104162
104424
  if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
104163
104425
  if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError("Section entry count exceeds its arrays");
104164
104426
  if (biomeTints && biomeTints.length !== count * 3) throw new RangeError("Section biome tints must contain RGB for each placement");
@@ -104176,7 +104438,7 @@ gl_FragDepth=readDepth(vUv);
104176
104438
  const cornerBrightness2 = ambientOcclusion ? new Float32Array(4) : void 0;
104177
104439
  for (const template of templateData) {
104178
104440
  const { quads } = template;
104179
- if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 || template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 || template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads || template.biomeTint && template.biomeTint.length !== quads) {
104441
+ if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 || template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 || template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads || template.shade && template.shade.length !== quads * 4 || template.biomeTint && template.biomeTint.length !== quads) {
104180
104442
  throw new RangeError("Section template arrays do not match its quad count");
104181
104443
  }
104182
104444
  }
@@ -104193,8 +104455,8 @@ gl_FragDepth=readDepth(vUv);
104193
104455
  const locations = /* @__PURE__ */ new Map();
104194
104456
  for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a4], [b4]) => a4 - b4)) {
104195
104457
  const firstPage = pages.length;
104196
- for (const atlas of [...layerAtlases].sort((a4, b4) => Number(atlases[a4].animated) - Number(atlases[b4].animated) || (atlases[a4].animated ? a4 - b4 : atlases[b4].height - atlases[a4].height))) {
104197
- const { width, height, animated } = atlases[atlas];
104458
+ for (const atlas of [...layerAtlases].sort((a4, b4) => Number(atlases2[a4].animated) - Number(atlases2[b4].animated) || (atlases2[a4].animated ? a4 - b4 : atlases2[b4].height - atlases2[a4].height))) {
104459
+ const { width, height, animated } = atlases2[atlas];
104198
104460
  if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
104199
104461
  let selected = -1;
104200
104462
  for (let i4 = firstPage; !animated && i4 < pages.length; i4++) {
@@ -104237,7 +104499,7 @@ gl_FragDepth=readDepth(vUv);
104237
104499
  });
104238
104500
  if (!quads.sprites.length) continue;
104239
104501
  if (!fluidPages.has(fluid)) {
104240
- const { width, height } = atlases[data.atlas];
104502
+ const { width, height } = atlases2[data.atlas];
104241
104503
  if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
104242
104504
  fluidPages.set(fluid, {
104243
104505
  layer: 2,
@@ -104255,7 +104517,7 @@ gl_FragDepth=readDepth(vUv);
104255
104517
  const tint = fluid === "water" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;
104256
104518
  fluidPages.get(fluid).fluids.push({ quads, x: x4, y: y5, z: z4, data, tint });
104257
104519
  }
104258
- pages.push(...[...fluidPages.values()].sort((a4, b4) => Number(atlases[a4.placements[0].atlas].animated) - Number(atlases[b4.placements[0].atlas].animated) || a4.placements[0].atlas - b4.placements[0].atlas));
104520
+ pages.push(...[...fluidPages.values()].sort((a4, b4) => Number(atlases2[a4.placements[0].atlas].animated) - Number(atlases2[b4.placements[0].atlas].animated) || a4.placements[0].atlas - b4.placements[0].atlas));
104259
104521
  }
104260
104522
  return pages.map((page) => {
104261
104523
  let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);
@@ -104267,12 +104529,13 @@ gl_FragDepth=readDepth(vUv);
104267
104529
  }
104268
104530
  const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);
104269
104531
  const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);
104532
+ const shade = new Float32Array(faces * 4).fill(1);
104270
104533
  const outputIndices = new Uint32Array(faces * 6);
104271
104534
  const blockIndices = new Uint16Array(faces);
104272
104535
  let vertex2 = 0, indexOffset = 0;
104273
104536
  for (const entry of page.entries) {
104274
104537
  const template = templateData[templates[entry]];
104275
- const atlas = atlases[template.atlas];
104538
+ const atlas = atlases2[template.atlas];
104276
104539
  const placement = locations.get(template.atlas);
104277
104540
  const mapU = (u4) => (placement.x + u4 * atlas.width) / page.width;
104278
104541
  const mapV = (v5) => 1 - (placement.y + (1 - v5) * atlas.height) / page.height;
@@ -104296,6 +104559,7 @@ gl_FragDepth=readDepth(vUv);
104296
104559
  normals[vertex2 * 3] = template.normals[source * 3];
104297
104560
  normals[vertex2 * 3 + 1] = template.normals[source * 3 + 1];
104298
104561
  normals[vertex2 * 3 + 2] = template.normals[source * 3 + 2];
104562
+ shade[vertex2] = template.shade?.[source] ?? 1;
104299
104563
  uvs[vertex2 * 2] = mapU(template.uvs[source * 2]);
104300
104564
  uvs[vertex2 * 2 + 1] = mapV(template.uvs[source * 2 + 1]);
104301
104565
  uvBounds[vertex2 * 4] = mapU(template.uvBounds[source * 4]);
@@ -104311,7 +104575,7 @@ gl_FragDepth=readDepth(vUv);
104311
104575
  }
104312
104576
  }
104313
104577
  for (const { quads, x: x4, y: y5, z: z4, data, tint } of page.fluids) {
104314
- const atlas = atlases[data.atlas];
104578
+ const atlas = atlases2[data.atlas];
104315
104579
  const placement = page.placements[0];
104316
104580
  const mapU = (u4) => (placement.x + u4 * atlas.width) / page.width;
104317
104581
  const mapV = (v5) => 1 - (placement.y + (1 - v5) * atlas.height) / page.height;
@@ -104348,11 +104612,11 @@ gl_FragDepth=readDepth(vUv);
104348
104612
  indexOffset += 6;
104349
104613
  }
104350
104614
  }
104351
- return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };
104615
+ return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, shade, indices: outputIndices, blockIndices };
104352
104616
  });
104353
104617
  }
104354
104618
  function sectionGeometryTransferables(pages) {
104355
- return pages.flatMap((page) => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.indices.buffer, page.blockIndices.buffer]);
104619
+ return pages.flatMap((page) => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.shade.buffer, page.indices.buffer, page.blockIndices.buffer]);
104356
104620
  }
104357
104621
 
104358
104622
  // src/world/SectionWorker.ts
@@ -104415,7 +104679,7 @@ gl_FragDepth=readDepth(vUv);
104415
104679
  var WATER_TINT = new Color(4159204).toArray();
104416
104680
  function toInput(entries, maxAtlasSize, fluids, lighting) {
104417
104681
  if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
104418
- const atlases = [];
104682
+ const atlases2 = [];
104419
104683
  const atlasIds = /* @__PURE__ */ new Map();
104420
104684
  const templateIds = /* @__PURE__ */ new Map();
104421
104685
  const input = {
@@ -104438,9 +104702,9 @@ gl_FragDepth=readDepth(vUv);
104438
104702
  if (id === void 0) {
104439
104703
  let atlas = atlasIds.get(template.atlas);
104440
104704
  if (atlas === void 0) {
104441
- atlas = atlases.length;
104705
+ atlas = atlases2.length;
104442
104706
  atlasIds.set(template.atlas, atlas);
104443
- atlases.push(template.atlas);
104707
+ atlases2.push(template.atlas);
104444
104708
  input.atlases.push({ width: template.atlas.image.width, height: template.atlas.image.height, animated: template.atlas.hasAnimation });
104445
104709
  }
104446
104710
  let data = templateCache.get(template);
@@ -104458,6 +104722,7 @@ gl_FragDepth=readDepth(vUv);
104458
104722
  uvs: new Float32Array(quads * 8),
104459
104723
  uvBounds: new Float32Array(quads * 16),
104460
104724
  colors: new Float32Array(quads * 12),
104725
+ shade: new Float32Array(quads * 4),
104461
104726
  indices: new Uint16Array(quads * 6),
104462
104727
  cullFaces: new Uint8Array(template.cullFaces),
104463
104728
  biomeTint: template.biomeTint ? new Uint8Array(template.biomeTint) : void 0,
@@ -104469,6 +104734,7 @@ gl_FragDepth=readDepth(vUv);
104469
104734
  const uv = template.geometry.getAttribute("uv");
104470
104735
  const bounds = template.geometry.getAttribute("uvBounds");
104471
104736
  const color3 = template.geometry.getAttribute("color");
104737
+ const shade = template.geometry.getAttribute("shade");
104472
104738
  for (let vertex2 = 0; vertex2 < quads * 4; vertex2++) {
104473
104739
  data.positions.set([position.getX(vertex2), position.getY(vertex2), position.getZ(vertex2)], vertex2 * 3);
104474
104740
  data.normals.set([normal.getX(vertex2), normal.getY(vertex2), normal.getZ(vertex2)], vertex2 * 3);
@@ -104480,6 +104746,7 @@ gl_FragDepth=readDepth(vUv);
104480
104746
  bounds?.getW(vertex2) ?? 1
104481
104747
  ], vertex2 * 4);
104482
104748
  data.colors.set([color3?.getX(vertex2) ?? 1, color3?.getY(vertex2) ?? 1, color3?.getZ(vertex2) ?? 1], vertex2 * 3);
104749
+ data.shade[vertex2] = shade?.getX(vertex2) ?? 1;
104483
104750
  }
104484
104751
  for (let i5 = 0; i5 < data.indices.length; i5++) data.indices[i5] = indices.getX(i5) - 4 * Math.floor(i5 / 6);
104485
104752
  templateCache.set(template, data);
@@ -104499,9 +104766,9 @@ gl_FragDepth=readDepth(vUv);
104499
104766
  if (!atlas) continue;
104500
104767
  let id = atlasIds.get(atlas);
104501
104768
  if (id === void 0) {
104502
- id = atlases.length;
104769
+ id = atlases2.length;
104503
104770
  atlasIds.set(atlas, id);
104504
- atlases.push(atlas);
104771
+ atlases2.push(atlas);
104505
104772
  input.atlases.push({ width: atlas.image.width, height: atlas.image.height, animated: atlas.hasAnimation });
104506
104773
  }
104507
104774
  input.fluids[kind] = {
@@ -104512,7 +104779,7 @@ gl_FragDepth=readDepth(vUv);
104512
104779
  };
104513
104780
  }
104514
104781
  }
104515
- return { input, atlases };
104782
+ return { input, atlases: atlases2 };
104516
104783
  }
104517
104784
  var SectionMesh = class _SectionMesh extends Group {
104518
104785
  constructor() {
@@ -104527,23 +104794,23 @@ gl_FragDepth=readDepth(vUv);
104527
104794
  }
104528
104795
  /** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
104529
104796
  static build(entries, maxAtlasSize = 2048, fluids, lighting) {
104530
- const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
104531
- return this.fromPages(buildSectionGeometry(input), atlases);
104797
+ const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
104798
+ return this.fromPages(buildSectionGeometry(input), atlases2);
104532
104799
  }
104533
104800
  /** Builds section-local meshes in a browser worker when available, with synchronous fallback. */
104534
104801
  static async buildAsync(entries, maxAtlasSize = 2048, fluids, lighting) {
104535
- const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
104802
+ const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
104536
104803
  const worker = SectionWorker.shared();
104537
104804
  const pages = worker ? await worker.build(input).catch(() => buildSectionGeometry(input)) : buildSectionGeometry(input);
104538
- return this.fromPages(pages, atlases);
104805
+ return this.fromPages(pages, atlases2);
104539
104806
  }
104540
- static fromPages(pages, atlases) {
104807
+ static fromPages(pages, atlases2) {
104541
104808
  const section = new _SectionMesh();
104542
104809
  for (const page of pages) {
104543
104810
  const canvas = createCanvas(page.width, page.height);
104544
104811
  const context = canvas.getContext("2d");
104545
104812
  for (const { atlas, x: x4, y: y5 } of page.placements) {
104546
- context.drawImage(atlases[atlas].image.canvas, x4, y5);
104813
+ context.drawImage(atlases2[atlas].image.canvas, x4, y5);
104547
104814
  }
104548
104815
  const geometry = new BufferGeometry();
104549
104816
  geometry.setAttribute("position", new Float32BufferAttribute(page.positions.buffer, 3));
@@ -104551,10 +104818,11 @@ gl_FragDepth=readDepth(vUv);
104551
104818
  geometry.setAttribute("uv", new Float32BufferAttribute(page.uvs.buffer, 2));
104552
104819
  geometry.setAttribute("uvBounds", new Float32BufferAttribute(page.uvBounds.buffer, 4));
104553
104820
  geometry.setAttribute("color", new Float32BufferAttribute(page.colors.buffer, 3));
104821
+ geometry.setAttribute("shade", new Float32BufferAttribute(page.shade.buffer, 1));
104554
104822
  geometry.setIndex(new Uint32BufferAttribute(page.indices.buffer, 1));
104555
104823
  geometry.computeBoundingBox();
104556
104824
  geometry.computeBoundingSphere();
104557
- const transparent = page.layer === 2 ? atlases[page.placements[0].atlas].hasTranslucency : page.layer === 1;
104825
+ const transparent = page.layer === 2 ? atlases2[page.placements[0].atlas].hasTranslucency : page.layer === 1;
104558
104826
  const material = Materials.createShadedCanvasMaterial(canvas, transparent, false, true);
104559
104827
  material.side = FrontSide;
104560
104828
  if (page.layer === 2) {
@@ -104569,7 +104837,7 @@ gl_FragDepth=readDepth(vUv);
104569
104837
  section.blockIndices.set(mesh, page.blockIndices);
104570
104838
  const unsubscribe = [];
104571
104839
  for (const { atlas: id, x: x4, y: y5 } of page.placements) {
104572
- const atlas = atlases[id];
104840
+ const atlas = atlases2[id];
104573
104841
  if (!atlas.hasAnimation) continue;
104574
104842
  unsubscribe.push(atlas.subscribe(() => {
104575
104843
  context.clearRect(x4, y5, atlas.image.width, atlas.image.height);