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.
- package/dist/browser/esm/Materials.mjs +3 -2
- package/dist/browser/esm/Materials.mjs.map +1 -1
- package/dist/browser/esm/assets/Fonts.mjs +31 -4
- package/dist/browser/esm/assets/Fonts.mjs.map +1 -1
- package/dist/browser/esm/assets/_fonts/Unihex.mjs +166 -0
- package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -0
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs +12 -1
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
- package/dist/browser/esm/assets/source/parser/AssetParsers.mjs +1 -0
- package/dist/browser/esm/assets/source/parser/AssetParsers.mjs.map +1 -1
- package/dist/browser/esm/cache/Caching.mjs +2 -0
- package/dist/browser/esm/cache/Caching.mjs.map +1 -1
- package/dist/browser/esm/env/browser/section.worker.mjs +5 -3
- package/dist/browser/esm/env/browser/section.worker.mjs.map +1 -1
- package/dist/browser/esm/gui/GuiText.mjs +4 -3
- package/dist/browser/esm/gui/GuiText.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +25 -4
- package/dist/browser/esm/model/scene/ModelObject.mjs +4 -0
- package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
- package/dist/browser/esm/world/SectionGeometry.mjs +5 -3
- package/dist/browser/esm/world/SectionGeometry.mjs.map +1 -1
- package/dist/browser/esm/world/SectionMesh.mjs +4 -0
- package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
- package/dist/browser/esm/world/SectionModels.mjs +2 -2
- package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
- package/dist/browser/index.d.ts +25 -4
- package/dist/browser/index.js +263 -38
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +306 -38
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +25 -4
- package/dist/node/index.d.ts +25 -4
- package/dist/node/index.js +267 -38
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +267 -38
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/browser/index.js
CHANGED
|
@@ -286,6 +286,7 @@ var init_Caching = __esm({
|
|
|
286
286
|
this.entityAnimationCache,
|
|
287
287
|
this.blockEntityIndexCache,
|
|
288
288
|
this.fontCache,
|
|
289
|
+
this.unihexCache,
|
|
289
290
|
this.bannerPatternCache,
|
|
290
291
|
this.mineRenderDataCache,
|
|
291
292
|
this.usernameUuidCache,
|
|
@@ -339,6 +340,7 @@ var init_Caching = __esm({
|
|
|
339
340
|
_Caching.entityTextureCache = _Caching.createAssetCache();
|
|
340
341
|
_Caching.entityAnimationCache = _Caching.createAssetCache();
|
|
341
342
|
_Caching.blockEntityIndexCache = _Caching.createAssetCache();
|
|
343
|
+
_Caching.unihexCache = _Caching.createAssetCache();
|
|
342
344
|
_Caching.fontCache = _Caching.createAssetCache();
|
|
343
345
|
_Caching.bannerPatternCache = _Caching.createAssetCache();
|
|
344
346
|
_Caching.mineRenderDataCache = _Caching.createAssetCache();
|
|
@@ -1055,6 +1057,7 @@ var init_Materials = __esm({
|
|
|
1055
1057
|
static createShadedCanvasMaterial(canvas, transparent = false, shade = false, boundUvs = false) {
|
|
1056
1058
|
const vertShader = `
|
|
1057
1059
|
uniform bool SHADE;
|
|
1060
|
+
attribute float shade;
|
|
1058
1061
|
|
|
1059
1062
|
// Keep MSAA edge pixels from sampling outside the face's atlas region.
|
|
1060
1063
|
#if __VERSION__ >= 300
|
|
@@ -1077,7 +1080,7 @@ var init_Materials = __esm({
|
|
|
1077
1080
|
void main()
|
|
1078
1081
|
{
|
|
1079
1082
|
|
|
1080
|
-
if (SHADE) {
|
|
1083
|
+
if (SHADE && shade > 0.5) {
|
|
1081
1084
|
|
|
1082
1085
|
#ifdef USE_INSTANCING
|
|
1083
1086
|
vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
|
|
@@ -1186,7 +1189,7 @@ var init_Materials = __esm({
|
|
|
1186
1189
|
side: transparent ? import_three5.DoubleSide : import_three5.FrontSide,
|
|
1187
1190
|
alphaTest: 0.5
|
|
1188
1191
|
});
|
|
1189
|
-
Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });
|
|
1192
|
+
Object.assign(material.defaultAttributeValues, { shade: [1], uvBounds: [0, 0, 1, 1] });
|
|
1190
1193
|
return material;
|
|
1191
1194
|
} catch (e) {
|
|
1192
1195
|
console.warn(e);
|
|
@@ -1351,6 +1354,7 @@ var init_AssetParsers = __esm({
|
|
|
1351
1354
|
AssetParser2["IMAGE"] = "image";
|
|
1352
1355
|
AssetParser2["LIST"] = "list";
|
|
1353
1356
|
AssetParser2["JSON"] = "json";
|
|
1357
|
+
AssetParser2["BINARY"] = "binary";
|
|
1354
1358
|
return AssetParser2;
|
|
1355
1359
|
})(AssetParser || {});
|
|
1356
1360
|
}
|
|
@@ -2821,7 +2825,7 @@ var init_parser = __esm({
|
|
|
2821
2825
|
});
|
|
2822
2826
|
|
|
2823
2827
|
// src/assets/source/HostedAssetSource.ts
|
|
2824
|
-
var p4, DEFAULT_OPTIONS, _HostedAssetSource, HostedAssetSource;
|
|
2828
|
+
var BINARY_TIMEOUT, p4, DEFAULT_OPTIONS, _HostedAssetSource, HostedAssetSource;
|
|
2825
2829
|
var init_HostedAssetSource = __esm({
|
|
2826
2830
|
"src/assets/source/HostedAssetSource.ts"() {
|
|
2827
2831
|
init_AssetSource();
|
|
@@ -2834,6 +2838,7 @@ var init_HostedAssetSource = __esm({
|
|
|
2834
2838
|
init_AssetLoader();
|
|
2835
2839
|
init_parser();
|
|
2836
2840
|
init_merge();
|
|
2841
|
+
BINARY_TIMEOUT = 6e4;
|
|
2837
2842
|
p4 = prefix("HostedAssetSource");
|
|
2838
2843
|
DEFAULT_OPTIONS = {
|
|
2839
2844
|
retryDefaults: true
|
|
@@ -2974,6 +2979,15 @@ var init_HostedAssetSource = __esm({
|
|
|
2974
2979
|
return response.data;
|
|
2975
2980
|
}
|
|
2976
2981
|
};
|
|
2982
|
+
_HostedAssetSource.BINARY = {
|
|
2983
|
+
config(request) {
|
|
2984
|
+
request.timeout = BINARY_TIMEOUT;
|
|
2985
|
+
request.responseType = "arraybuffer";
|
|
2986
|
+
},
|
|
2987
|
+
parse(response) {
|
|
2988
|
+
return { data: new Uint8Array(response.data) };
|
|
2989
|
+
}
|
|
2990
|
+
};
|
|
2977
2991
|
_HostedAssetSource.PARSER_MAP = /* @__PURE__ */ new Map([
|
|
2978
2992
|
["model" /* MODEL */, _HostedAssetSource.MODEL],
|
|
2979
2993
|
["blockstate" /* BLOCKSTATE */, _HostedAssetSource.BLOCKSTATE],
|
|
@@ -2981,7 +2995,8 @@ var init_HostedAssetSource = __esm({
|
|
|
2981
2995
|
["nbt" /* NBT */, _HostedAssetSource.NBT],
|
|
2982
2996
|
["image" /* IMAGE */, _HostedAssetSource.IMAGE],
|
|
2983
2997
|
["list" /* LIST */, _HostedAssetSource.LIST],
|
|
2984
|
-
["json" /* JSON */, _HostedAssetSource.JSON]
|
|
2998
|
+
["json" /* JSON */, _HostedAssetSource.JSON],
|
|
2999
|
+
["binary" /* BINARY */, _HostedAssetSource.BINARY]
|
|
2985
3000
|
]);
|
|
2986
3001
|
HostedAssetSource = _HostedAssetSource;
|
|
2987
3002
|
}
|
|
@@ -4762,6 +4777,178 @@ var init_Entities = __esm({
|
|
|
4762
4777
|
}
|
|
4763
4778
|
});
|
|
4764
4779
|
|
|
4780
|
+
// src/assets/_fonts/Unihex.ts
|
|
4781
|
+
var Unihex_exports = {};
|
|
4782
|
+
__export(Unihex_exports, {
|
|
4783
|
+
loadUnihex: () => loadUnihex
|
|
4784
|
+
});
|
|
4785
|
+
function readHex(text2, filename, glyphs) {
|
|
4786
|
+
const lines = text2.split("\n");
|
|
4787
|
+
if (lines[lines.length - 1] === "") lines.pop();
|
|
4788
|
+
lines.forEach((line, index) => {
|
|
4789
|
+
const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);
|
|
4790
|
+
if (!match || ![32, 64, 96, 128].includes(match[2].length)) {
|
|
4791
|
+
throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);
|
|
4792
|
+
}
|
|
4793
|
+
const codepoint = parseInt(match[1], 16);
|
|
4794
|
+
if (codepoint > 1114111) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);
|
|
4795
|
+
const bitWidth = match[2].length / 4;
|
|
4796
|
+
const rowLength = bitWidth / 4;
|
|
4797
|
+
const rows = new Uint32Array(GLYPH_HEIGHT);
|
|
4798
|
+
let mask = 0;
|
|
4799
|
+
for (let y = 0; y < GLYPH_HEIGHT; y++) {
|
|
4800
|
+
rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);
|
|
4801
|
+
mask |= rows[y];
|
|
4802
|
+
}
|
|
4803
|
+
let left = 0, right = bitWidth;
|
|
4804
|
+
if (mask) {
|
|
4805
|
+
while (!(mask >>> bitWidth - left - 1 & 1)) left++;
|
|
4806
|
+
right = bitWidth - 1;
|
|
4807
|
+
while (!(mask >>> bitWidth - right - 1 & 1)) right--;
|
|
4808
|
+
}
|
|
4809
|
+
glyphs.set(codepoint, { rows, bitWidth, left, right });
|
|
4810
|
+
});
|
|
4811
|
+
}
|
|
4812
|
+
async function parseUnihex(key) {
|
|
4813
|
+
try {
|
|
4814
|
+
const asset2 = await AssetLoader.get(key, "binary" /* BINARY */);
|
|
4815
|
+
if (!asset2) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);
|
|
4816
|
+
const records = /* @__PURE__ */ new Map();
|
|
4817
|
+
const reader = new import_zip2.ZipReader(new import_zip2.Uint8ArrayReader(asset2.data), { useWebWorkers: false, useCompressionStream: false });
|
|
4818
|
+
try {
|
|
4819
|
+
for (const entry of await reader.getEntries()) {
|
|
4820
|
+
if (!entry.directory && entry.filename.endsWith(".hex")) {
|
|
4821
|
+
readHex(await entry.getData(new import_zip2.TextWriter(), { checkSignature: true }), entry.filename, records);
|
|
4822
|
+
}
|
|
4823
|
+
}
|
|
4824
|
+
} finally {
|
|
4825
|
+
await reader.close();
|
|
4826
|
+
}
|
|
4827
|
+
const indices = new Int32Array(1114112).fill(-1);
|
|
4828
|
+
const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);
|
|
4829
|
+
let index = 0;
|
|
4830
|
+
for (const [codepoint, record] of records) {
|
|
4831
|
+
indices[codepoint] = index;
|
|
4832
|
+
rows.set(record.rows, index * GLYPH_HEIGHT);
|
|
4833
|
+
metrics.set([record.bitWidth, record.left, record.right], index * 3);
|
|
4834
|
+
index++;
|
|
4835
|
+
}
|
|
4836
|
+
return { indices, rows, metrics };
|
|
4837
|
+
} catch (error) {
|
|
4838
|
+
console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4839
|
+
return void 0;
|
|
4840
|
+
}
|
|
4841
|
+
}
|
|
4842
|
+
async function loadUnihex(provider, fontKey, characters) {
|
|
4843
|
+
const origin = new AssetKey(DEFAULT_NAMESPACE, "", void 0, void 0, "assets", "", fontKey.root);
|
|
4844
|
+
const key = AssetKey.parse("font", provider.hex_file, origin);
|
|
4845
|
+
key.assetType = void 0;
|
|
4846
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
4847
|
+
let overrides;
|
|
4848
|
+
try {
|
|
4849
|
+
overrides = (provider.size_overrides ?? []).map((override) => {
|
|
4850
|
+
const from = override.from.codePointAt(0), to = override.to.codePointAt(0);
|
|
4851
|
+
if ([...override.from].length !== 1 || [...override.to].length !== 1 || from >= to || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {
|
|
4852
|
+
throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);
|
|
4853
|
+
}
|
|
4854
|
+
return { ...override, from, to };
|
|
4855
|
+
});
|
|
4856
|
+
} catch (error) {
|
|
4857
|
+
console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4858
|
+
return glyphs;
|
|
4859
|
+
}
|
|
4860
|
+
const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
|
|
4861
|
+
if (!file) return glyphs;
|
|
4862
|
+
let atlas = atlases.get(provider);
|
|
4863
|
+
if (!atlas) {
|
|
4864
|
+
atlas = new UnihexAtlas();
|
|
4865
|
+
atlases.set(provider, atlas);
|
|
4866
|
+
}
|
|
4867
|
+
for (const character of characters) {
|
|
4868
|
+
const codepoint = character.codePointAt(0), index = file.indices[codepoint];
|
|
4869
|
+
if (index < 0) continue;
|
|
4870
|
+
const record = {
|
|
4871
|
+
rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),
|
|
4872
|
+
bitWidth: file.metrics[index * 3],
|
|
4873
|
+
left: file.metrics[index * 3 + 1],
|
|
4874
|
+
right: file.metrics[index * 3 + 2]
|
|
4875
|
+
};
|
|
4876
|
+
const override = overrides.find((range) => codepoint >= range.from && codepoint <= range.to);
|
|
4877
|
+
if (override) {
|
|
4878
|
+
record.left = override.left;
|
|
4879
|
+
record.right = override.right;
|
|
4880
|
+
}
|
|
4881
|
+
const width = record.right - record.left + 1;
|
|
4882
|
+
let rendered;
|
|
4883
|
+
const render = () => rendered ?? (rendered = atlas.draw(record));
|
|
4884
|
+
glyphs.set(character, {
|
|
4885
|
+
get image() {
|
|
4886
|
+
return render().image;
|
|
4887
|
+
},
|
|
4888
|
+
get x() {
|
|
4889
|
+
return render().x;
|
|
4890
|
+
},
|
|
4891
|
+
get y() {
|
|
4892
|
+
return render().y;
|
|
4893
|
+
},
|
|
4894
|
+
width,
|
|
4895
|
+
height: GLYPH_HEIGHT,
|
|
4896
|
+
scale: 0.5,
|
|
4897
|
+
ascent: 7,
|
|
4898
|
+
advance: Math.floor(width / 2) + 1,
|
|
4899
|
+
boldOffset: 0.5,
|
|
4900
|
+
shadowOffset: 0.5
|
|
4901
|
+
});
|
|
4902
|
+
}
|
|
4903
|
+
return glyphs;
|
|
4904
|
+
}
|
|
4905
|
+
var import_zip2, ATLAS_SIZE, GLYPH_HEIGHT, UnihexAtlas, atlases;
|
|
4906
|
+
var init_Unihex = __esm({
|
|
4907
|
+
"src/assets/_fonts/Unihex.ts"() {
|
|
4908
|
+
import_zip2 = require("@zip.js/zip.js");
|
|
4909
|
+
init_AssetKey();
|
|
4910
|
+
init_AssetLoader();
|
|
4911
|
+
init_Assets();
|
|
4912
|
+
init_Caching();
|
|
4913
|
+
init_AssetParsers();
|
|
4914
|
+
init_CanvasCompat();
|
|
4915
|
+
ATLAS_SIZE = 512;
|
|
4916
|
+
GLYPH_HEIGHT = 16;
|
|
4917
|
+
UnihexAtlas = class {
|
|
4918
|
+
constructor() {
|
|
4919
|
+
this.x = 0;
|
|
4920
|
+
this.y = 0;
|
|
4921
|
+
}
|
|
4922
|
+
draw(glyph) {
|
|
4923
|
+
const width = glyph.right - glyph.left + 1;
|
|
4924
|
+
if (this.image && this.x + width > this.image.width) {
|
|
4925
|
+
this.x = 0;
|
|
4926
|
+
this.y += GLYPH_HEIGHT;
|
|
4927
|
+
}
|
|
4928
|
+
if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {
|
|
4929
|
+
this.image = createCanvas(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);
|
|
4930
|
+
this.x = 0;
|
|
4931
|
+
this.y = 0;
|
|
4932
|
+
}
|
|
4933
|
+
const context = this.image.getContext("2d");
|
|
4934
|
+
const pixels = context.createImageData(width, GLYPH_HEIGHT);
|
|
4935
|
+
for (let y = 0; y < GLYPH_HEIGHT; y++) {
|
|
4936
|
+
for (let x = 0; x < width; x++) {
|
|
4937
|
+
const column = glyph.left + x;
|
|
4938
|
+
if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> glyph.bitWidth - column - 1 & 1)) continue;
|
|
4939
|
+
pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);
|
|
4940
|
+
}
|
|
4941
|
+
}
|
|
4942
|
+
const result = { image: this.image, x: this.x, y: this.y };
|
|
4943
|
+
context.putImageData(pixels, this.x, this.y);
|
|
4944
|
+
this.x += width;
|
|
4945
|
+
return result;
|
|
4946
|
+
}
|
|
4947
|
+
};
|
|
4948
|
+
atlases = /* @__PURE__ */ new WeakMap();
|
|
4949
|
+
}
|
|
4950
|
+
});
|
|
4951
|
+
|
|
4765
4952
|
// src/assets/Fonts.ts
|
|
4766
4953
|
var Fonts;
|
|
4767
4954
|
var init_Fonts = __esm({
|
|
@@ -4772,7 +4959,7 @@ var init_Fonts = __esm({
|
|
|
4772
4959
|
init_ModelTextures();
|
|
4773
4960
|
init_Caching();
|
|
4774
4961
|
Fonts = class {
|
|
4775
|
-
/** Combines font definitions in source-priority order.
|
|
4962
|
+
/** Combines font definitions in source-priority order. TrueType providers are skipped. */
|
|
4776
4963
|
static async get(key = "minecraft:default") {
|
|
4777
4964
|
const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
|
|
4778
4965
|
return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
|
|
@@ -4788,6 +4975,7 @@ var init_Fonts = __esm({
|
|
|
4788
4975
|
const stack = await AssetLoader.getAll(key, "json" /* JSON */);
|
|
4789
4976
|
if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
|
|
4790
4977
|
const glyphs = /* @__PURE__ */ new Map();
|
|
4978
|
+
const providers = [];
|
|
4791
4979
|
for (const asset2 of stack) {
|
|
4792
4980
|
for (const provider of asset2.providers) {
|
|
4793
4981
|
if (provider.filter?.uniform || provider.filter?.jp) continue;
|
|
@@ -4806,17 +4994,43 @@ var init_Fonts = __esm({
|
|
|
4806
4994
|
break;
|
|
4807
4995
|
case "reference":
|
|
4808
4996
|
case "minecraft:reference":
|
|
4809
|
-
|
|
4997
|
+
const reference = await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized]);
|
|
4998
|
+
if (reference.resolve) {
|
|
4999
|
+
providers.push(async (characters) => {
|
|
5000
|
+
await reference.resolve(characters);
|
|
5001
|
+
return reference.glyphs;
|
|
5002
|
+
});
|
|
5003
|
+
continue;
|
|
5004
|
+
}
|
|
5005
|
+
provided = reference.glyphs;
|
|
4810
5006
|
break;
|
|
5007
|
+
case "unihex":
|
|
5008
|
+
case "minecraft:unihex":
|
|
5009
|
+
providers.push(async (characters) => (await Promise.resolve().then(() => (init_Unihex(), Unihex_exports))).loadUnihex(provider, key, characters));
|
|
5010
|
+
continue;
|
|
4811
5011
|
default:
|
|
4812
5012
|
continue;
|
|
4813
5013
|
}
|
|
4814
|
-
for (const [character, glyph] of provided) {
|
|
5014
|
+
if (providers.every((provider2) => provider2 instanceof Map)) for (const [character, glyph] of provided) {
|
|
4815
5015
|
if (character !== "\0" && !glyphs.has(character)) glyphs.set(character, glyph);
|
|
4816
5016
|
}
|
|
5017
|
+
providers.push(provided);
|
|
5018
|
+
}
|
|
5019
|
+
}
|
|
5020
|
+
return { glyphs, resolve: providers.every((provider) => provider instanceof Map) ? void 0 : async (characters) => {
|
|
5021
|
+
const remaining = new Set([...characters].filter((character) => character !== "\0" && character !== "\n" && character !== "\r" && !glyphs.has(character)));
|
|
5022
|
+
for (const provider of providers) {
|
|
5023
|
+
if (!remaining.size) break;
|
|
5024
|
+
const provided = provider instanceof Map ? provider : await provider([...remaining].join(""));
|
|
5025
|
+
for (const character of remaining) {
|
|
5026
|
+
const glyph = provided.get(character);
|
|
5027
|
+
if (glyph) {
|
|
5028
|
+
glyphs.set(character, glyph);
|
|
5029
|
+
remaining.delete(character);
|
|
5030
|
+
}
|
|
5031
|
+
}
|
|
4817
5032
|
}
|
|
4818
|
-
}
|
|
4819
|
-
return { glyphs };
|
|
5033
|
+
} };
|
|
4820
5034
|
}
|
|
4821
5035
|
static async bitmap(provider, fontKey) {
|
|
4822
5036
|
const rows = provider.chars.map((row) => [...row]);
|
|
@@ -8023,6 +8237,7 @@ async function layoutGuiText(text2, options = {}) {
|
|
|
8023
8237
|
}
|
|
8024
8238
|
const font = await Fonts.get(options.font);
|
|
8025
8239
|
const runs = typeof text2 === "string" ? [{ text: text2 }] : text2;
|
|
8240
|
+
await font.resolve?.(runs.map((run) => run.text).join(""));
|
|
8026
8241
|
const glyphs = [], lineWidths = [];
|
|
8027
8242
|
let line = [], width = 0;
|
|
8028
8243
|
let trailingNewline = false;
|
|
@@ -8049,7 +8264,7 @@ async function layoutGuiText(text2, options = {}) {
|
|
|
8049
8264
|
continue;
|
|
8050
8265
|
}
|
|
8051
8266
|
const glyph = font.glyphs.get(character);
|
|
8052
|
-
const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
|
|
8267
|
+
const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);
|
|
8053
8268
|
line.push({ character, glyph, advance, style, x: 0, y: 0 });
|
|
8054
8269
|
width += advance;
|
|
8055
8270
|
while (width > maxWidth && line.length > 1) {
|
|
@@ -8077,7 +8292,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8077
8292
|
batches.push(batch);
|
|
8078
8293
|
}
|
|
8079
8294
|
const color2 = new import_three20.Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
8080
|
-
const offset = isShadow ? 1 : 0;
|
|
8295
|
+
const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
|
|
8081
8296
|
const top = glyph ? 7 - glyph.ascent : 0;
|
|
8082
8297
|
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
8083
8298
|
const width = glyph ? glyph.width * glyph.scale : 5;
|
|
@@ -8107,7 +8322,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8107
8322
|
for (let i = 0; i < 4; i++) batch.colors.push(color2.r, color2.g, color2.b);
|
|
8108
8323
|
batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
|
|
8109
8324
|
};
|
|
8110
|
-
for (const boldOffset of style.bold ? [0, 1] : [0]) {
|
|
8325
|
+
for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {
|
|
8111
8326
|
if (glyph) quad(0, top, width, top + height, boldOffset);
|
|
8112
8327
|
else {
|
|
8113
8328
|
quad(0, 0, 5, 1, boldOffset);
|
|
@@ -9878,6 +10093,10 @@ var init_ModelObject = __esm({
|
|
|
9878
10093
|
this.atlas.model.elements?.forEach((el) => {
|
|
9879
10094
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
9880
10095
|
this.geometries.add(elGeo);
|
|
10096
|
+
elGeo.setAttribute("shade", new import_three27.BufferAttribute(
|
|
10097
|
+
new Float32Array(elGeo.getAttribute("position").count).fill(!this.originalModel.itemId && el.shade === false ? 0 : 1),
|
|
10098
|
+
1
|
|
10099
|
+
));
|
|
9881
10100
|
if (this.options.cullMask) {
|
|
9882
10101
|
const indices = Array.from(elGeo.getIndex().array);
|
|
9883
10102
|
elGeo.setIndex(indices.filter((_, index) => {
|
|
@@ -17750,9 +17969,9 @@ function cached(map, key, load) {
|
|
|
17750
17969
|
function compactQuads(geometry, keep) {
|
|
17751
17970
|
const quads = keep.flatMap((kept, index) => kept ? [index] : []);
|
|
17752
17971
|
const compact = new import_three41.BufferGeometry();
|
|
17753
|
-
for (const [name, size] of Object.entries({ position: 3, normal: 3, uv: 2, uvBounds: 4, color: 3 })) {
|
|
17972
|
+
for (const [name, size] of Object.entries({ position: 3, normal: 3, uv: 2, uvBounds: 4, color: 3, shade: 1 })) {
|
|
17754
17973
|
const source2 = geometry.getAttribute(name);
|
|
17755
|
-
const defaults = name === "uvBounds" ? [0, 0, 1, 1] : name === "color" ? [1, 1, 1] : void 0;
|
|
17974
|
+
const defaults = name === "uvBounds" ? [0, 0, 1, 1] : name === "color" ? [1, 1, 1] : name === "shade" ? [1] : void 0;
|
|
17756
17975
|
const values = new Float32Array(quads.length * 4 * size);
|
|
17757
17976
|
for (let q = 0; q < quads.length; q++) {
|
|
17758
17977
|
for (let vertex = 0; vertex < 4; vertex++) {
|
|
@@ -19000,7 +19219,7 @@ var LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18];
|
|
|
19000
19219
|
|
|
19001
19220
|
// src/world/SectionGeometry.ts
|
|
19002
19221
|
function buildSectionGeometry(input) {
|
|
19003
|
-
const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
|
|
19222
|
+
const { count, indices, templates, cullMasks, templateData, atlases: atlases2, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
|
|
19004
19223
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
19005
19224
|
if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError("Section entry count exceeds its arrays");
|
|
19006
19225
|
if (biomeTints && biomeTints.length !== count * 3) throw new RangeError("Section biome tints must contain RGB for each placement");
|
|
@@ -19018,7 +19237,7 @@ function buildSectionGeometry(input) {
|
|
|
19018
19237
|
const cornerBrightness2 = ambientOcclusion ? new Float32Array(4) : void 0;
|
|
19019
19238
|
for (const template of templateData) {
|
|
19020
19239
|
const { quads } = template;
|
|
19021
|
-
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) {
|
|
19240
|
+
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) {
|
|
19022
19241
|
throw new RangeError("Section template arrays do not match its quad count");
|
|
19023
19242
|
}
|
|
19024
19243
|
}
|
|
@@ -19035,8 +19254,8 @@ function buildSectionGeometry(input) {
|
|
|
19035
19254
|
const locations = /* @__PURE__ */ new Map();
|
|
19036
19255
|
for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {
|
|
19037
19256
|
const firstPage = pages.length;
|
|
19038
|
-
for (const atlas of [...layerAtlases].sort((a, b) => Number(
|
|
19039
|
-
const { width, height, animated } =
|
|
19257
|
+
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))) {
|
|
19258
|
+
const { width, height, animated } = atlases2[atlas];
|
|
19040
19259
|
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
19041
19260
|
let selected = -1;
|
|
19042
19261
|
for (let i = firstPage; !animated && i < pages.length; i++) {
|
|
@@ -19079,7 +19298,7 @@ function buildSectionGeometry(input) {
|
|
|
19079
19298
|
});
|
|
19080
19299
|
if (!quads.sprites.length) continue;
|
|
19081
19300
|
if (!fluidPages.has(fluid)) {
|
|
19082
|
-
const { width, height } =
|
|
19301
|
+
const { width, height } = atlases2[data.atlas];
|
|
19083
19302
|
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
19084
19303
|
fluidPages.set(fluid, {
|
|
19085
19304
|
layer: 2,
|
|
@@ -19097,7 +19316,7 @@ function buildSectionGeometry(input) {
|
|
|
19097
19316
|
const tint = fluid === "water" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;
|
|
19098
19317
|
fluidPages.get(fluid).fluids.push({ quads, x, y, z, data, tint });
|
|
19099
19318
|
}
|
|
19100
|
-
pages.push(...[...fluidPages.values()].sort((a, b) => Number(
|
|
19319
|
+
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));
|
|
19101
19320
|
}
|
|
19102
19321
|
return pages.map((page) => {
|
|
19103
19322
|
let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);
|
|
@@ -19109,12 +19328,13 @@ function buildSectionGeometry(input) {
|
|
|
19109
19328
|
}
|
|
19110
19329
|
const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);
|
|
19111
19330
|
const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);
|
|
19331
|
+
const shade = new Float32Array(faces * 4).fill(1);
|
|
19112
19332
|
const outputIndices = new Uint32Array(faces * 6);
|
|
19113
19333
|
const blockIndices = new Uint16Array(faces);
|
|
19114
19334
|
let vertex = 0, indexOffset = 0;
|
|
19115
19335
|
for (const entry of page.entries) {
|
|
19116
19336
|
const template = templateData[templates[entry]];
|
|
19117
|
-
const atlas =
|
|
19337
|
+
const atlas = atlases2[template.atlas];
|
|
19118
19338
|
const placement = locations.get(template.atlas);
|
|
19119
19339
|
const mapU = (u) => (placement.x + u * atlas.width) / page.width;
|
|
19120
19340
|
const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
|
|
@@ -19138,6 +19358,7 @@ function buildSectionGeometry(input) {
|
|
|
19138
19358
|
normals[vertex * 3] = template.normals[source * 3];
|
|
19139
19359
|
normals[vertex * 3 + 1] = template.normals[source * 3 + 1];
|
|
19140
19360
|
normals[vertex * 3 + 2] = template.normals[source * 3 + 2];
|
|
19361
|
+
shade[vertex] = template.shade?.[source] ?? 1;
|
|
19141
19362
|
uvs[vertex * 2] = mapU(template.uvs[source * 2]);
|
|
19142
19363
|
uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);
|
|
19143
19364
|
uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);
|
|
@@ -19153,7 +19374,7 @@ function buildSectionGeometry(input) {
|
|
|
19153
19374
|
}
|
|
19154
19375
|
}
|
|
19155
19376
|
for (const { quads, x, y, z, data, tint } of page.fluids) {
|
|
19156
|
-
const atlas =
|
|
19377
|
+
const atlas = atlases2[data.atlas];
|
|
19157
19378
|
const placement = page.placements[0];
|
|
19158
19379
|
const mapU = (u) => (placement.x + u * atlas.width) / page.width;
|
|
19159
19380
|
const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
|
|
@@ -19190,11 +19411,11 @@ function buildSectionGeometry(input) {
|
|
|
19190
19411
|
indexOffset += 6;
|
|
19191
19412
|
}
|
|
19192
19413
|
}
|
|
19193
|
-
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };
|
|
19414
|
+
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, shade, indices: outputIndices, blockIndices };
|
|
19194
19415
|
});
|
|
19195
19416
|
}
|
|
19196
19417
|
function sectionGeometryTransferables(pages) {
|
|
19197
|
-
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]);
|
|
19418
|
+
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]);
|
|
19198
19419
|
}
|
|
19199
19420
|
|
|
19200
19421
|
// src/world/SectionWorker.ts
|
|
@@ -19254,7 +19475,7 @@ var templateCache = /* @__PURE__ */ new WeakMap();
|
|
|
19254
19475
|
var WATER_TINT = new import_three46.Color(4159204).toArray();
|
|
19255
19476
|
function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
19256
19477
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
19257
|
-
const
|
|
19478
|
+
const atlases2 = [];
|
|
19258
19479
|
const atlasIds = /* @__PURE__ */ new Map();
|
|
19259
19480
|
const templateIds = /* @__PURE__ */ new Map();
|
|
19260
19481
|
const input = {
|
|
@@ -19277,9 +19498,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19277
19498
|
if (id === void 0) {
|
|
19278
19499
|
let atlas = atlasIds.get(template.atlas);
|
|
19279
19500
|
if (atlas === void 0) {
|
|
19280
|
-
atlas =
|
|
19501
|
+
atlas = atlases2.length;
|
|
19281
19502
|
atlasIds.set(template.atlas, atlas);
|
|
19282
|
-
|
|
19503
|
+
atlases2.push(template.atlas);
|
|
19283
19504
|
input.atlases.push({ width: template.atlas.image.width, height: template.atlas.image.height, animated: template.atlas.hasAnimation });
|
|
19284
19505
|
}
|
|
19285
19506
|
let data = templateCache.get(template);
|
|
@@ -19297,6 +19518,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19297
19518
|
uvs: new Float32Array(quads * 8),
|
|
19298
19519
|
uvBounds: new Float32Array(quads * 16),
|
|
19299
19520
|
colors: new Float32Array(quads * 12),
|
|
19521
|
+
shade: new Float32Array(quads * 4),
|
|
19300
19522
|
indices: new Uint16Array(quads * 6),
|
|
19301
19523
|
cullFaces: new Uint8Array(template.cullFaces),
|
|
19302
19524
|
biomeTint: template.biomeTint ? new Uint8Array(template.biomeTint) : void 0,
|
|
@@ -19308,6 +19530,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19308
19530
|
const uv = template.geometry.getAttribute("uv");
|
|
19309
19531
|
const bounds = template.geometry.getAttribute("uvBounds");
|
|
19310
19532
|
const color2 = template.geometry.getAttribute("color");
|
|
19533
|
+
const shade = template.geometry.getAttribute("shade");
|
|
19311
19534
|
for (let vertex = 0; vertex < quads * 4; vertex++) {
|
|
19312
19535
|
data.positions.set([position.getX(vertex), position.getY(vertex), position.getZ(vertex)], vertex * 3);
|
|
19313
19536
|
data.normals.set([normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex)], vertex * 3);
|
|
@@ -19319,6 +19542,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19319
19542
|
bounds?.getW(vertex) ?? 1
|
|
19320
19543
|
], vertex * 4);
|
|
19321
19544
|
data.colors.set([color2?.getX(vertex) ?? 1, color2?.getY(vertex) ?? 1, color2?.getZ(vertex) ?? 1], vertex * 3);
|
|
19545
|
+
data.shade[vertex] = shade?.getX(vertex) ?? 1;
|
|
19322
19546
|
}
|
|
19323
19547
|
for (let i2 = 0; i2 < data.indices.length; i2++) data.indices[i2] = indices.getX(i2) - 4 * Math.floor(i2 / 6);
|
|
19324
19548
|
templateCache.set(template, data);
|
|
@@ -19338,9 +19562,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19338
19562
|
if (!atlas) continue;
|
|
19339
19563
|
let id = atlasIds.get(atlas);
|
|
19340
19564
|
if (id === void 0) {
|
|
19341
|
-
id =
|
|
19565
|
+
id = atlases2.length;
|
|
19342
19566
|
atlasIds.set(atlas, id);
|
|
19343
|
-
|
|
19567
|
+
atlases2.push(atlas);
|
|
19344
19568
|
input.atlases.push({ width: atlas.image.width, height: atlas.image.height, animated: atlas.hasAnimation });
|
|
19345
19569
|
}
|
|
19346
19570
|
input.fluids[kind] = {
|
|
@@ -19351,7 +19575,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19351
19575
|
};
|
|
19352
19576
|
}
|
|
19353
19577
|
}
|
|
19354
|
-
return { input, atlases };
|
|
19578
|
+
return { input, atlases: atlases2 };
|
|
19355
19579
|
}
|
|
19356
19580
|
var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
19357
19581
|
constructor() {
|
|
@@ -19366,23 +19590,23 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19366
19590
|
}
|
|
19367
19591
|
/** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
19368
19592
|
static build(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
19369
|
-
const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19370
|
-
return this.fromPages(buildSectionGeometry(input),
|
|
19593
|
+
const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19594
|
+
return this.fromPages(buildSectionGeometry(input), atlases2);
|
|
19371
19595
|
}
|
|
19372
19596
|
/** Builds section-local meshes in a browser worker when available, with synchronous fallback. */
|
|
19373
19597
|
static async buildAsync(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
19374
|
-
const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19598
|
+
const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19375
19599
|
const worker = SectionWorker.shared();
|
|
19376
19600
|
const pages = worker ? await worker.build(input).catch(() => buildSectionGeometry(input)) : buildSectionGeometry(input);
|
|
19377
|
-
return this.fromPages(pages,
|
|
19601
|
+
return this.fromPages(pages, atlases2);
|
|
19378
19602
|
}
|
|
19379
|
-
static fromPages(pages,
|
|
19603
|
+
static fromPages(pages, atlases2) {
|
|
19380
19604
|
const section = new _SectionMesh();
|
|
19381
19605
|
for (const page of pages) {
|
|
19382
19606
|
const canvas = createCanvas(page.width, page.height);
|
|
19383
19607
|
const context = canvas.getContext("2d");
|
|
19384
19608
|
for (const { atlas, x, y } of page.placements) {
|
|
19385
|
-
context.drawImage(
|
|
19609
|
+
context.drawImage(atlases2[atlas].image.canvas, x, y);
|
|
19386
19610
|
}
|
|
19387
19611
|
const geometry = new import_three46.BufferGeometry();
|
|
19388
19612
|
geometry.setAttribute("position", new import_three46.Float32BufferAttribute(page.positions.buffer, 3));
|
|
@@ -19390,10 +19614,11 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19390
19614
|
geometry.setAttribute("uv", new import_three46.Float32BufferAttribute(page.uvs.buffer, 2));
|
|
19391
19615
|
geometry.setAttribute("uvBounds", new import_three46.Float32BufferAttribute(page.uvBounds.buffer, 4));
|
|
19392
19616
|
geometry.setAttribute("color", new import_three46.Float32BufferAttribute(page.colors.buffer, 3));
|
|
19617
|
+
geometry.setAttribute("shade", new import_three46.Float32BufferAttribute(page.shade.buffer, 1));
|
|
19393
19618
|
geometry.setIndex(new import_three46.Uint32BufferAttribute(page.indices.buffer, 1));
|
|
19394
19619
|
geometry.computeBoundingBox();
|
|
19395
19620
|
geometry.computeBoundingSphere();
|
|
19396
|
-
const transparent = page.layer === 2 ?
|
|
19621
|
+
const transparent = page.layer === 2 ? atlases2[page.placements[0].atlas].hasTranslucency : page.layer === 1;
|
|
19397
19622
|
const material = Materials.createShadedCanvasMaterial(canvas, transparent, false, true);
|
|
19398
19623
|
material.side = import_three46.FrontSide;
|
|
19399
19624
|
if (page.layer === 2) {
|
|
@@ -19408,7 +19633,7 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19408
19633
|
section.blockIndices.set(mesh, page.blockIndices);
|
|
19409
19634
|
const unsubscribe = [];
|
|
19410
19635
|
for (const { atlas: id, x, y } of page.placements) {
|
|
19411
|
-
const atlas =
|
|
19636
|
+
const atlas = atlases2[id];
|
|
19412
19637
|
if (!atlas.hasAnimation) continue;
|
|
19413
19638
|
unsubscribe.push(atlas.subscribe(() => {
|
|
19414
19639
|
context.clearRect(x, y, atlas.image.width, atlas.image.height);
|