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/node/index.mjs
CHANGED
|
@@ -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,
|
|
@@ -1112,6 +1116,7 @@ var init_Materials = __esm({
|
|
|
1112
1116
|
static createShadedCanvasMaterial(canvas, transparent = false, shade = false, boundUvs = false) {
|
|
1113
1117
|
const vertShader = `
|
|
1114
1118
|
uniform bool SHADE;
|
|
1119
|
+
attribute float shade;
|
|
1115
1120
|
|
|
1116
1121
|
// Keep MSAA edge pixels from sampling outside the face's atlas region.
|
|
1117
1122
|
#if __VERSION__ >= 300
|
|
@@ -1134,7 +1139,7 @@ var init_Materials = __esm({
|
|
|
1134
1139
|
void main()
|
|
1135
1140
|
{
|
|
1136
1141
|
|
|
1137
|
-
if (SHADE) {
|
|
1142
|
+
if (SHADE && shade > 0.5) {
|
|
1138
1143
|
|
|
1139
1144
|
#ifdef USE_INSTANCING
|
|
1140
1145
|
vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
|
|
@@ -1243,7 +1248,7 @@ var init_Materials = __esm({
|
|
|
1243
1248
|
side: transparent ? DoubleSide : FrontSide,
|
|
1244
1249
|
alphaTest: 0.5
|
|
1245
1250
|
});
|
|
1246
|
-
Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });
|
|
1251
|
+
Object.assign(material.defaultAttributeValues, { shade: [1], uvBounds: [0, 0, 1, 1] });
|
|
1247
1252
|
return material;
|
|
1248
1253
|
} catch (e) {
|
|
1249
1254
|
console.warn(e);
|
|
@@ -1408,6 +1413,7 @@ var init_AssetParsers = __esm({
|
|
|
1408
1413
|
AssetParser2["IMAGE"] = "image";
|
|
1409
1414
|
AssetParser2["LIST"] = "list";
|
|
1410
1415
|
AssetParser2["JSON"] = "json";
|
|
1416
|
+
AssetParser2["BINARY"] = "binary";
|
|
1411
1417
|
return AssetParser2;
|
|
1412
1418
|
})(AssetParser || {});
|
|
1413
1419
|
}
|
|
@@ -2878,7 +2884,7 @@ var init_parser = __esm({
|
|
|
2878
2884
|
});
|
|
2879
2885
|
|
|
2880
2886
|
// src/assets/source/HostedAssetSource.ts
|
|
2881
|
-
var p3, DEFAULT_OPTIONS, HostedAssetSource;
|
|
2887
|
+
var BINARY_TIMEOUT, p3, DEFAULT_OPTIONS, HostedAssetSource;
|
|
2882
2888
|
var init_HostedAssetSource = __esm({
|
|
2883
2889
|
"src/assets/source/HostedAssetSource.ts"() {
|
|
2884
2890
|
init_AssetSource();
|
|
@@ -2891,6 +2897,7 @@ var init_HostedAssetSource = __esm({
|
|
|
2891
2897
|
init_AssetLoader();
|
|
2892
2898
|
init_parser();
|
|
2893
2899
|
init_merge();
|
|
2900
|
+
BINARY_TIMEOUT = 6e4;
|
|
2894
2901
|
p3 = prefix("HostedAssetSource");
|
|
2895
2902
|
DEFAULT_OPTIONS = {
|
|
2896
2903
|
retryDefaults: true
|
|
@@ -2961,6 +2968,17 @@ var init_HostedAssetSource = __esm({
|
|
|
2961
2968
|
}
|
|
2962
2969
|
};
|
|
2963
2970
|
}
|
|
2971
|
+
static {
|
|
2972
|
+
this.BINARY = {
|
|
2973
|
+
config(request) {
|
|
2974
|
+
request.timeout = BINARY_TIMEOUT;
|
|
2975
|
+
request.responseType = "arraybuffer";
|
|
2976
|
+
},
|
|
2977
|
+
parse(response) {
|
|
2978
|
+
return { data: new Uint8Array(response.data) };
|
|
2979
|
+
}
|
|
2980
|
+
};
|
|
2981
|
+
}
|
|
2964
2982
|
static {
|
|
2965
2983
|
this.PARSER_MAP = /* @__PURE__ */ new Map([
|
|
2966
2984
|
["model" /* MODEL */, _HostedAssetSource.MODEL],
|
|
@@ -2969,7 +2987,8 @@ var init_HostedAssetSource = __esm({
|
|
|
2969
2987
|
["nbt" /* NBT */, _HostedAssetSource.NBT],
|
|
2970
2988
|
["image" /* IMAGE */, _HostedAssetSource.IMAGE],
|
|
2971
2989
|
["list" /* LIST */, _HostedAssetSource.LIST],
|
|
2972
|
-
["json" /* JSON */, _HostedAssetSource.JSON]
|
|
2990
|
+
["json" /* JSON */, _HostedAssetSource.JSON],
|
|
2991
|
+
["binary" /* BINARY */, _HostedAssetSource.BINARY]
|
|
2973
2992
|
]);
|
|
2974
2993
|
}
|
|
2975
2994
|
/** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */
|
|
@@ -4855,6 +4874,178 @@ var init_Entities = __esm({
|
|
|
4855
4874
|
}
|
|
4856
4875
|
});
|
|
4857
4876
|
|
|
4877
|
+
// src/assets/_fonts/Unihex.ts
|
|
4878
|
+
var Unihex_exports = {};
|
|
4879
|
+
__export(Unihex_exports, {
|
|
4880
|
+
loadUnihex: () => loadUnihex
|
|
4881
|
+
});
|
|
4882
|
+
import { TextWriter, Uint8ArrayReader, ZipReader as ZipReader2 } from "@zip.js/zip.js";
|
|
4883
|
+
function readHex(text2, filename, glyphs) {
|
|
4884
|
+
const lines = text2.split("\n");
|
|
4885
|
+
if (lines[lines.length - 1] === "") lines.pop();
|
|
4886
|
+
lines.forEach((line, index) => {
|
|
4887
|
+
const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);
|
|
4888
|
+
if (!match || ![32, 64, 96, 128].includes(match[2].length)) {
|
|
4889
|
+
throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);
|
|
4890
|
+
}
|
|
4891
|
+
const codepoint = parseInt(match[1], 16);
|
|
4892
|
+
if (codepoint > 1114111) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);
|
|
4893
|
+
const bitWidth = match[2].length / 4;
|
|
4894
|
+
const rowLength = bitWidth / 4;
|
|
4895
|
+
const rows = new Uint32Array(GLYPH_HEIGHT);
|
|
4896
|
+
let mask = 0;
|
|
4897
|
+
for (let y = 0; y < GLYPH_HEIGHT; y++) {
|
|
4898
|
+
rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);
|
|
4899
|
+
mask |= rows[y];
|
|
4900
|
+
}
|
|
4901
|
+
let left = 0, right = bitWidth;
|
|
4902
|
+
if (mask) {
|
|
4903
|
+
while (!(mask >>> bitWidth - left - 1 & 1)) left++;
|
|
4904
|
+
right = bitWidth - 1;
|
|
4905
|
+
while (!(mask >>> bitWidth - right - 1 & 1)) right--;
|
|
4906
|
+
}
|
|
4907
|
+
glyphs.set(codepoint, { rows, bitWidth, left, right });
|
|
4908
|
+
});
|
|
4909
|
+
}
|
|
4910
|
+
async function parseUnihex(key) {
|
|
4911
|
+
try {
|
|
4912
|
+
const asset2 = await AssetLoader.get(key, "binary" /* BINARY */);
|
|
4913
|
+
if (!asset2) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);
|
|
4914
|
+
const records = /* @__PURE__ */ new Map();
|
|
4915
|
+
const reader = new ZipReader2(new Uint8ArrayReader(asset2.data), { useWebWorkers: false, useCompressionStream: false });
|
|
4916
|
+
try {
|
|
4917
|
+
for (const entry of await reader.getEntries()) {
|
|
4918
|
+
if (!entry.directory && entry.filename.endsWith(".hex")) {
|
|
4919
|
+
readHex(await entry.getData(new TextWriter(), { checkSignature: true }), entry.filename, records);
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
} finally {
|
|
4923
|
+
await reader.close();
|
|
4924
|
+
}
|
|
4925
|
+
const indices = new Int32Array(1114112).fill(-1);
|
|
4926
|
+
const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);
|
|
4927
|
+
let index = 0;
|
|
4928
|
+
for (const [codepoint, record] of records) {
|
|
4929
|
+
indices[codepoint] = index;
|
|
4930
|
+
rows.set(record.rows, index * GLYPH_HEIGHT);
|
|
4931
|
+
metrics.set([record.bitWidth, record.left, record.right], index * 3);
|
|
4932
|
+
index++;
|
|
4933
|
+
}
|
|
4934
|
+
return { indices, rows, metrics };
|
|
4935
|
+
} catch (error) {
|
|
4936
|
+
console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4937
|
+
return void 0;
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4940
|
+
async function loadUnihex(provider, fontKey, characters) {
|
|
4941
|
+
const origin = new AssetKey(DEFAULT_NAMESPACE, "", void 0, void 0, "assets", "", fontKey.root);
|
|
4942
|
+
const key = AssetKey.parse("font", provider.hex_file, origin);
|
|
4943
|
+
key.assetType = void 0;
|
|
4944
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
4945
|
+
let overrides;
|
|
4946
|
+
try {
|
|
4947
|
+
overrides = (provider.size_overrides ?? []).map((override) => {
|
|
4948
|
+
const from = override.from.codePointAt(0), to = override.to.codePointAt(0);
|
|
4949
|
+
if ([...override.from].length !== 1 || [...override.to].length !== 1 || from >= to || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {
|
|
4950
|
+
throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);
|
|
4951
|
+
}
|
|
4952
|
+
return { ...override, from, to };
|
|
4953
|
+
});
|
|
4954
|
+
} catch (error) {
|
|
4955
|
+
console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4956
|
+
return glyphs;
|
|
4957
|
+
}
|
|
4958
|
+
const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
|
|
4959
|
+
if (!file) return glyphs;
|
|
4960
|
+
let atlas = atlases.get(provider);
|
|
4961
|
+
if (!atlas) {
|
|
4962
|
+
atlas = new UnihexAtlas();
|
|
4963
|
+
atlases.set(provider, atlas);
|
|
4964
|
+
}
|
|
4965
|
+
for (const character of characters) {
|
|
4966
|
+
const codepoint = character.codePointAt(0), index = file.indices[codepoint];
|
|
4967
|
+
if (index < 0) continue;
|
|
4968
|
+
const record = {
|
|
4969
|
+
rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),
|
|
4970
|
+
bitWidth: file.metrics[index * 3],
|
|
4971
|
+
left: file.metrics[index * 3 + 1],
|
|
4972
|
+
right: file.metrics[index * 3 + 2]
|
|
4973
|
+
};
|
|
4974
|
+
const override = overrides.find((range) => codepoint >= range.from && codepoint <= range.to);
|
|
4975
|
+
if (override) {
|
|
4976
|
+
record.left = override.left;
|
|
4977
|
+
record.right = override.right;
|
|
4978
|
+
}
|
|
4979
|
+
const width = record.right - record.left + 1;
|
|
4980
|
+
let rendered;
|
|
4981
|
+
const render = () => rendered ??= atlas.draw(record);
|
|
4982
|
+
glyphs.set(character, {
|
|
4983
|
+
get image() {
|
|
4984
|
+
return render().image;
|
|
4985
|
+
},
|
|
4986
|
+
get x() {
|
|
4987
|
+
return render().x;
|
|
4988
|
+
},
|
|
4989
|
+
get y() {
|
|
4990
|
+
return render().y;
|
|
4991
|
+
},
|
|
4992
|
+
width,
|
|
4993
|
+
height: GLYPH_HEIGHT,
|
|
4994
|
+
scale: 0.5,
|
|
4995
|
+
ascent: 7,
|
|
4996
|
+
advance: Math.floor(width / 2) + 1,
|
|
4997
|
+
boldOffset: 0.5,
|
|
4998
|
+
shadowOffset: 0.5
|
|
4999
|
+
});
|
|
5000
|
+
}
|
|
5001
|
+
return glyphs;
|
|
5002
|
+
}
|
|
5003
|
+
var ATLAS_SIZE, GLYPH_HEIGHT, UnihexAtlas, atlases;
|
|
5004
|
+
var init_Unihex = __esm({
|
|
5005
|
+
"src/assets/_fonts/Unihex.ts"() {
|
|
5006
|
+
init_AssetKey();
|
|
5007
|
+
init_AssetLoader();
|
|
5008
|
+
init_Assets();
|
|
5009
|
+
init_Caching();
|
|
5010
|
+
init_AssetParsers();
|
|
5011
|
+
init_CanvasCompat();
|
|
5012
|
+
ATLAS_SIZE = 512;
|
|
5013
|
+
GLYPH_HEIGHT = 16;
|
|
5014
|
+
UnihexAtlas = class {
|
|
5015
|
+
constructor() {
|
|
5016
|
+
this.x = 0;
|
|
5017
|
+
this.y = 0;
|
|
5018
|
+
}
|
|
5019
|
+
draw(glyph) {
|
|
5020
|
+
const width = glyph.right - glyph.left + 1;
|
|
5021
|
+
if (this.image && this.x + width > this.image.width) {
|
|
5022
|
+
this.x = 0;
|
|
5023
|
+
this.y += GLYPH_HEIGHT;
|
|
5024
|
+
}
|
|
5025
|
+
if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {
|
|
5026
|
+
this.image = createCanvas2(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);
|
|
5027
|
+
this.x = 0;
|
|
5028
|
+
this.y = 0;
|
|
5029
|
+
}
|
|
5030
|
+
const context = this.image.getContext("2d");
|
|
5031
|
+
const pixels = context.createImageData(width, GLYPH_HEIGHT);
|
|
5032
|
+
for (let y = 0; y < GLYPH_HEIGHT; y++) {
|
|
5033
|
+
for (let x = 0; x < width; x++) {
|
|
5034
|
+
const column = glyph.left + x;
|
|
5035
|
+
if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> glyph.bitWidth - column - 1 & 1)) continue;
|
|
5036
|
+
pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);
|
|
5037
|
+
}
|
|
5038
|
+
}
|
|
5039
|
+
const result = { image: this.image, x: this.x, y: this.y };
|
|
5040
|
+
context.putImageData(pixels, this.x, this.y);
|
|
5041
|
+
this.x += width;
|
|
5042
|
+
return result;
|
|
5043
|
+
}
|
|
5044
|
+
};
|
|
5045
|
+
atlases = /* @__PURE__ */ new WeakMap();
|
|
5046
|
+
}
|
|
5047
|
+
});
|
|
5048
|
+
|
|
4858
5049
|
// src/assets/Fonts.ts
|
|
4859
5050
|
var Fonts;
|
|
4860
5051
|
var init_Fonts = __esm({
|
|
@@ -4865,7 +5056,7 @@ var init_Fonts = __esm({
|
|
|
4865
5056
|
init_ModelTextures();
|
|
4866
5057
|
init_Caching();
|
|
4867
5058
|
Fonts = class {
|
|
4868
|
-
/** Combines font definitions in source-priority order.
|
|
5059
|
+
/** Combines font definitions in source-priority order. TrueType providers are skipped. */
|
|
4869
5060
|
static async get(key = "minecraft:default") {
|
|
4870
5061
|
const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
|
|
4871
5062
|
return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
|
|
@@ -4881,6 +5072,7 @@ var init_Fonts = __esm({
|
|
|
4881
5072
|
const stack = await AssetLoader.getAll(key, "json" /* JSON */);
|
|
4882
5073
|
if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
|
|
4883
5074
|
const glyphs = /* @__PURE__ */ new Map();
|
|
5075
|
+
const providers = [];
|
|
4884
5076
|
for (const asset2 of stack) {
|
|
4885
5077
|
for (const provider of asset2.providers) {
|
|
4886
5078
|
if (provider.filter?.uniform || provider.filter?.jp) continue;
|
|
@@ -4899,17 +5091,43 @@ var init_Fonts = __esm({
|
|
|
4899
5091
|
break;
|
|
4900
5092
|
case "reference":
|
|
4901
5093
|
case "minecraft:reference":
|
|
4902
|
-
|
|
5094
|
+
const reference = await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized]);
|
|
5095
|
+
if (reference.resolve) {
|
|
5096
|
+
providers.push(async (characters) => {
|
|
5097
|
+
await reference.resolve(characters);
|
|
5098
|
+
return reference.glyphs;
|
|
5099
|
+
});
|
|
5100
|
+
continue;
|
|
5101
|
+
}
|
|
5102
|
+
provided = reference.glyphs;
|
|
4903
5103
|
break;
|
|
5104
|
+
case "unihex":
|
|
5105
|
+
case "minecraft:unihex":
|
|
5106
|
+
providers.push(async (characters) => (await Promise.resolve().then(() => (init_Unihex(), Unihex_exports))).loadUnihex(provider, key, characters));
|
|
5107
|
+
continue;
|
|
4904
5108
|
default:
|
|
4905
5109
|
continue;
|
|
4906
5110
|
}
|
|
4907
|
-
for (const [character, glyph] of provided) {
|
|
5111
|
+
if (providers.every((provider2) => provider2 instanceof Map)) for (const [character, glyph] of provided) {
|
|
4908
5112
|
if (character !== "\0" && !glyphs.has(character)) glyphs.set(character, glyph);
|
|
4909
5113
|
}
|
|
5114
|
+
providers.push(provided);
|
|
5115
|
+
}
|
|
5116
|
+
}
|
|
5117
|
+
return { glyphs, resolve: providers.every((provider) => provider instanceof Map) ? void 0 : async (characters) => {
|
|
5118
|
+
const remaining = new Set([...characters].filter((character) => character !== "\0" && character !== "\n" && character !== "\r" && !glyphs.has(character)));
|
|
5119
|
+
for (const provider of providers) {
|
|
5120
|
+
if (!remaining.size) break;
|
|
5121
|
+
const provided = provider instanceof Map ? provider : await provider([...remaining].join(""));
|
|
5122
|
+
for (const character of remaining) {
|
|
5123
|
+
const glyph = provided.get(character);
|
|
5124
|
+
if (glyph) {
|
|
5125
|
+
glyphs.set(character, glyph);
|
|
5126
|
+
remaining.delete(character);
|
|
5127
|
+
}
|
|
5128
|
+
}
|
|
4910
5129
|
}
|
|
4911
|
-
}
|
|
4912
|
-
return { glyphs };
|
|
5130
|
+
} };
|
|
4913
5131
|
}
|
|
4914
5132
|
static async bitmap(provider, fontKey) {
|
|
4915
5133
|
const rows = provider.chars.map((row) => [...row]);
|
|
@@ -8147,6 +8365,7 @@ async function layoutGuiText(text2, options = {}) {
|
|
|
8147
8365
|
}
|
|
8148
8366
|
const font = await Fonts.get(options.font);
|
|
8149
8367
|
const runs = typeof text2 === "string" ? [{ text: text2 }] : text2;
|
|
8368
|
+
await font.resolve?.(runs.map((run) => run.text).join(""));
|
|
8150
8369
|
const glyphs = [], lineWidths = [];
|
|
8151
8370
|
let line = [], width = 0;
|
|
8152
8371
|
let trailingNewline = false;
|
|
@@ -8173,7 +8392,7 @@ async function layoutGuiText(text2, options = {}) {
|
|
|
8173
8392
|
continue;
|
|
8174
8393
|
}
|
|
8175
8394
|
const glyph = font.glyphs.get(character);
|
|
8176
|
-
const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
|
|
8395
|
+
const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);
|
|
8177
8396
|
line.push({ character, glyph, advance, style, x: 0, y: 0 });
|
|
8178
8397
|
width += advance;
|
|
8179
8398
|
while (width > maxWidth && line.length > 1) {
|
|
@@ -8201,7 +8420,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8201
8420
|
batches.push(batch);
|
|
8202
8421
|
}
|
|
8203
8422
|
const color2 = new Color8(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
8204
|
-
const offset = isShadow ? 1 : 0;
|
|
8423
|
+
const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
|
|
8205
8424
|
const top = glyph ? 7 - glyph.ascent : 0;
|
|
8206
8425
|
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
8207
8426
|
const width = glyph ? glyph.width * glyph.scale : 5;
|
|
@@ -8231,7 +8450,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8231
8450
|
for (let i = 0; i < 4; i++) batch.colors.push(color2.r, color2.g, color2.b);
|
|
8232
8451
|
batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
|
|
8233
8452
|
};
|
|
8234
|
-
for (const boldOffset of style.bold ? [0, 1] : [0]) {
|
|
8453
|
+
for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {
|
|
8235
8454
|
if (glyph) quad(0, top, width, top + height, boldOffset);
|
|
8236
8455
|
else {
|
|
8237
8456
|
quad(0, 0, 5, 1, boldOffset);
|
|
@@ -10011,6 +10230,10 @@ var init_ModelObject = __esm({
|
|
|
10011
10230
|
this.atlas.model.elements?.forEach((el) => {
|
|
10012
10231
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
10013
10232
|
this.geometries.add(elGeo);
|
|
10233
|
+
elGeo.setAttribute("shade", new BufferAttribute5(
|
|
10234
|
+
new Float32Array(elGeo.getAttribute("position").count).fill(!this.originalModel.itemId && el.shade === false ? 0 : 1),
|
|
10235
|
+
1
|
|
10236
|
+
));
|
|
10014
10237
|
if (this.options.cullMask) {
|
|
10015
10238
|
const indices = Array.from(elGeo.getIndex().array);
|
|
10016
10239
|
elGeo.setIndex(indices.filter((_, index) => {
|
|
@@ -17604,9 +17827,9 @@ function cached(map, key, load) {
|
|
|
17604
17827
|
function compactQuads(geometry, keep) {
|
|
17605
17828
|
const quads = keep.flatMap((kept, index) => kept ? [index] : []);
|
|
17606
17829
|
const compact = new BufferGeometry8();
|
|
17607
|
-
for (const [name, size] of Object.entries({ position: 3, normal: 3, uv: 2, uvBounds: 4, color: 3 })) {
|
|
17830
|
+
for (const [name, size] of Object.entries({ position: 3, normal: 3, uv: 2, uvBounds: 4, color: 3, shade: 1 })) {
|
|
17608
17831
|
const source2 = geometry.getAttribute(name);
|
|
17609
|
-
const defaults = name === "uvBounds" ? [0, 0, 1, 1] : name === "color" ? [1, 1, 1] : void 0;
|
|
17832
|
+
const defaults = name === "uvBounds" ? [0, 0, 1, 1] : name === "color" ? [1, 1, 1] : name === "shade" ? [1] : void 0;
|
|
17610
17833
|
const values = new Float32Array(quads.length * 4 * size);
|
|
17611
17834
|
for (let q = 0; q < quads.length; q++) {
|
|
17612
17835
|
for (let vertex = 0; vertex < 4; vertex++) {
|
|
@@ -18854,7 +19077,7 @@ var LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18];
|
|
|
18854
19077
|
|
|
18855
19078
|
// src/world/SectionGeometry.ts
|
|
18856
19079
|
function buildSectionGeometry(input) {
|
|
18857
|
-
const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
|
|
19080
|
+
const { count, indices, templates, cullMasks, templateData, atlases: atlases2, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
|
|
18858
19081
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
18859
19082
|
if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError("Section entry count exceeds its arrays");
|
|
18860
19083
|
if (biomeTints && biomeTints.length !== count * 3) throw new RangeError("Section biome tints must contain RGB for each placement");
|
|
@@ -18872,7 +19095,7 @@ function buildSectionGeometry(input) {
|
|
|
18872
19095
|
const cornerBrightness2 = ambientOcclusion ? new Float32Array(4) : void 0;
|
|
18873
19096
|
for (const template of templateData) {
|
|
18874
19097
|
const { quads } = template;
|
|
18875
|
-
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) {
|
|
19098
|
+
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) {
|
|
18876
19099
|
throw new RangeError("Section template arrays do not match its quad count");
|
|
18877
19100
|
}
|
|
18878
19101
|
}
|
|
@@ -18889,8 +19112,8 @@ function buildSectionGeometry(input) {
|
|
|
18889
19112
|
const locations = /* @__PURE__ */ new Map();
|
|
18890
19113
|
for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {
|
|
18891
19114
|
const firstPage = pages.length;
|
|
18892
|
-
for (const atlas of [...layerAtlases].sort((a, b) => Number(
|
|
18893
|
-
const { width, height, animated } =
|
|
19115
|
+
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))) {
|
|
19116
|
+
const { width, height, animated } = atlases2[atlas];
|
|
18894
19117
|
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
18895
19118
|
let selected = -1;
|
|
18896
19119
|
for (let i = firstPage; !animated && i < pages.length; i++) {
|
|
@@ -18933,7 +19156,7 @@ function buildSectionGeometry(input) {
|
|
|
18933
19156
|
});
|
|
18934
19157
|
if (!quads.sprites.length) continue;
|
|
18935
19158
|
if (!fluidPages.has(fluid)) {
|
|
18936
|
-
const { width, height } =
|
|
19159
|
+
const { width, height } = atlases2[data.atlas];
|
|
18937
19160
|
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
18938
19161
|
fluidPages.set(fluid, {
|
|
18939
19162
|
layer: 2,
|
|
@@ -18951,7 +19174,7 @@ function buildSectionGeometry(input) {
|
|
|
18951
19174
|
const tint = fluid === "water" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;
|
|
18952
19175
|
fluidPages.get(fluid).fluids.push({ quads, x, y, z, data, tint });
|
|
18953
19176
|
}
|
|
18954
|
-
pages.push(...[...fluidPages.values()].sort((a, b) => Number(
|
|
19177
|
+
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
19178
|
}
|
|
18956
19179
|
return pages.map((page) => {
|
|
18957
19180
|
let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);
|
|
@@ -18963,12 +19186,13 @@ function buildSectionGeometry(input) {
|
|
|
18963
19186
|
}
|
|
18964
19187
|
const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);
|
|
18965
19188
|
const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);
|
|
19189
|
+
const shade = new Float32Array(faces * 4).fill(1);
|
|
18966
19190
|
const outputIndices = new Uint32Array(faces * 6);
|
|
18967
19191
|
const blockIndices = new Uint16Array(faces);
|
|
18968
19192
|
let vertex = 0, indexOffset = 0;
|
|
18969
19193
|
for (const entry of page.entries) {
|
|
18970
19194
|
const template = templateData[templates[entry]];
|
|
18971
|
-
const atlas =
|
|
19195
|
+
const atlas = atlases2[template.atlas];
|
|
18972
19196
|
const placement = locations.get(template.atlas);
|
|
18973
19197
|
const mapU = (u) => (placement.x + u * atlas.width) / page.width;
|
|
18974
19198
|
const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
|
|
@@ -18992,6 +19216,7 @@ function buildSectionGeometry(input) {
|
|
|
18992
19216
|
normals[vertex * 3] = template.normals[source * 3];
|
|
18993
19217
|
normals[vertex * 3 + 1] = template.normals[source * 3 + 1];
|
|
18994
19218
|
normals[vertex * 3 + 2] = template.normals[source * 3 + 2];
|
|
19219
|
+
shade[vertex] = template.shade?.[source] ?? 1;
|
|
18995
19220
|
uvs[vertex * 2] = mapU(template.uvs[source * 2]);
|
|
18996
19221
|
uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);
|
|
18997
19222
|
uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);
|
|
@@ -19007,7 +19232,7 @@ function buildSectionGeometry(input) {
|
|
|
19007
19232
|
}
|
|
19008
19233
|
}
|
|
19009
19234
|
for (const { quads, x, y, z, data, tint } of page.fluids) {
|
|
19010
|
-
const atlas =
|
|
19235
|
+
const atlas = atlases2[data.atlas];
|
|
19011
19236
|
const placement = page.placements[0];
|
|
19012
19237
|
const mapU = (u) => (placement.x + u * atlas.width) / page.width;
|
|
19013
19238
|
const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
|
|
@@ -19044,11 +19269,11 @@ function buildSectionGeometry(input) {
|
|
|
19044
19269
|
indexOffset += 6;
|
|
19045
19270
|
}
|
|
19046
19271
|
}
|
|
19047
|
-
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };
|
|
19272
|
+
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, shade, indices: outputIndices, blockIndices };
|
|
19048
19273
|
});
|
|
19049
19274
|
}
|
|
19050
19275
|
function sectionGeometryTransferables(pages) {
|
|
19051
|
-
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]);
|
|
19276
|
+
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]);
|
|
19052
19277
|
}
|
|
19053
19278
|
|
|
19054
19279
|
// src/world/SectionWorker.ts
|
|
@@ -19109,7 +19334,7 @@ var templateCache = /* @__PURE__ */ new WeakMap();
|
|
|
19109
19334
|
var WATER_TINT = new Color12(4159204).toArray();
|
|
19110
19335
|
function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
19111
19336
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
19112
|
-
const
|
|
19337
|
+
const atlases2 = [];
|
|
19113
19338
|
const atlasIds = /* @__PURE__ */ new Map();
|
|
19114
19339
|
const templateIds = /* @__PURE__ */ new Map();
|
|
19115
19340
|
const input = {
|
|
@@ -19132,9 +19357,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19132
19357
|
if (id === void 0) {
|
|
19133
19358
|
let atlas = atlasIds.get(template.atlas);
|
|
19134
19359
|
if (atlas === void 0) {
|
|
19135
|
-
atlas =
|
|
19360
|
+
atlas = atlases2.length;
|
|
19136
19361
|
atlasIds.set(template.atlas, atlas);
|
|
19137
|
-
|
|
19362
|
+
atlases2.push(template.atlas);
|
|
19138
19363
|
input.atlases.push({ width: template.atlas.image.width, height: template.atlas.image.height, animated: template.atlas.hasAnimation });
|
|
19139
19364
|
}
|
|
19140
19365
|
let data = templateCache.get(template);
|
|
@@ -19152,6 +19377,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19152
19377
|
uvs: new Float32Array(quads * 8),
|
|
19153
19378
|
uvBounds: new Float32Array(quads * 16),
|
|
19154
19379
|
colors: new Float32Array(quads * 12),
|
|
19380
|
+
shade: new Float32Array(quads * 4),
|
|
19155
19381
|
indices: new Uint16Array(quads * 6),
|
|
19156
19382
|
cullFaces: new Uint8Array(template.cullFaces),
|
|
19157
19383
|
biomeTint: template.biomeTint ? new Uint8Array(template.biomeTint) : void 0,
|
|
@@ -19163,6 +19389,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19163
19389
|
const uv = template.geometry.getAttribute("uv");
|
|
19164
19390
|
const bounds = template.geometry.getAttribute("uvBounds");
|
|
19165
19391
|
const color2 = template.geometry.getAttribute("color");
|
|
19392
|
+
const shade = template.geometry.getAttribute("shade");
|
|
19166
19393
|
for (let vertex = 0; vertex < quads * 4; vertex++) {
|
|
19167
19394
|
data.positions.set([position.getX(vertex), position.getY(vertex), position.getZ(vertex)], vertex * 3);
|
|
19168
19395
|
data.normals.set([normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex)], vertex * 3);
|
|
@@ -19174,6 +19401,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19174
19401
|
bounds?.getW(vertex) ?? 1
|
|
19175
19402
|
], vertex * 4);
|
|
19176
19403
|
data.colors.set([color2?.getX(vertex) ?? 1, color2?.getY(vertex) ?? 1, color2?.getZ(vertex) ?? 1], vertex * 3);
|
|
19404
|
+
data.shade[vertex] = shade?.getX(vertex) ?? 1;
|
|
19177
19405
|
}
|
|
19178
19406
|
for (let i2 = 0; i2 < data.indices.length; i2++) data.indices[i2] = indices.getX(i2) - 4 * Math.floor(i2 / 6);
|
|
19179
19407
|
templateCache.set(template, data);
|
|
@@ -19193,9 +19421,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19193
19421
|
if (!atlas) continue;
|
|
19194
19422
|
let id = atlasIds.get(atlas);
|
|
19195
19423
|
if (id === void 0) {
|
|
19196
|
-
id =
|
|
19424
|
+
id = atlases2.length;
|
|
19197
19425
|
atlasIds.set(atlas, id);
|
|
19198
|
-
|
|
19426
|
+
atlases2.push(atlas);
|
|
19199
19427
|
input.atlases.push({ width: atlas.image.width, height: atlas.image.height, animated: atlas.hasAnimation });
|
|
19200
19428
|
}
|
|
19201
19429
|
input.fluids[kind] = {
|
|
@@ -19206,7 +19434,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19206
19434
|
};
|
|
19207
19435
|
}
|
|
19208
19436
|
}
|
|
19209
|
-
return { input, atlases };
|
|
19437
|
+
return { input, atlases: atlases2 };
|
|
19210
19438
|
}
|
|
19211
19439
|
var SectionMesh = class _SectionMesh extends Group3 {
|
|
19212
19440
|
constructor() {
|
|
@@ -19221,23 +19449,23 @@ var SectionMesh = class _SectionMesh extends Group3 {
|
|
|
19221
19449
|
}
|
|
19222
19450
|
/** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
19223
19451
|
static build(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
19224
|
-
const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19225
|
-
return this.fromPages(buildSectionGeometry(input),
|
|
19452
|
+
const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19453
|
+
return this.fromPages(buildSectionGeometry(input), atlases2);
|
|
19226
19454
|
}
|
|
19227
19455
|
/** Builds section-local meshes in a browser worker when available, with synchronous fallback. */
|
|
19228
19456
|
static async buildAsync(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
19229
|
-
const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19457
|
+
const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19230
19458
|
const worker = SectionWorker.shared();
|
|
19231
19459
|
const pages = worker ? await worker.build(input).catch(() => buildSectionGeometry(input)) : buildSectionGeometry(input);
|
|
19232
|
-
return this.fromPages(pages,
|
|
19460
|
+
return this.fromPages(pages, atlases2);
|
|
19233
19461
|
}
|
|
19234
|
-
static fromPages(pages,
|
|
19462
|
+
static fromPages(pages, atlases2) {
|
|
19235
19463
|
const section = new _SectionMesh();
|
|
19236
19464
|
for (const page of pages) {
|
|
19237
19465
|
const canvas = createCanvas2(page.width, page.height);
|
|
19238
19466
|
const context = canvas.getContext("2d");
|
|
19239
19467
|
for (const { atlas, x, y } of page.placements) {
|
|
19240
|
-
context.drawImage(
|
|
19468
|
+
context.drawImage(atlases2[atlas].image.canvas, x, y);
|
|
19241
19469
|
}
|
|
19242
19470
|
const geometry = new BufferGeometry9();
|
|
19243
19471
|
geometry.setAttribute("position", new Float32BufferAttribute10(page.positions.buffer, 3));
|
|
@@ -19245,10 +19473,11 @@ var SectionMesh = class _SectionMesh extends Group3 {
|
|
|
19245
19473
|
geometry.setAttribute("uv", new Float32BufferAttribute10(page.uvs.buffer, 2));
|
|
19246
19474
|
geometry.setAttribute("uvBounds", new Float32BufferAttribute10(page.uvBounds.buffer, 4));
|
|
19247
19475
|
geometry.setAttribute("color", new Float32BufferAttribute10(page.colors.buffer, 3));
|
|
19476
|
+
geometry.setAttribute("shade", new Float32BufferAttribute10(page.shade.buffer, 1));
|
|
19248
19477
|
geometry.setIndex(new Uint32BufferAttribute(page.indices.buffer, 1));
|
|
19249
19478
|
geometry.computeBoundingBox();
|
|
19250
19479
|
geometry.computeBoundingSphere();
|
|
19251
|
-
const transparent = page.layer === 2 ?
|
|
19480
|
+
const transparent = page.layer === 2 ? atlases2[page.placements[0].atlas].hasTranslucency : page.layer === 1;
|
|
19252
19481
|
const material = Materials.createShadedCanvasMaterial(canvas, transparent, false, true);
|
|
19253
19482
|
material.side = FrontSide4;
|
|
19254
19483
|
if (page.layer === 2) {
|
|
@@ -19263,7 +19492,7 @@ var SectionMesh = class _SectionMesh extends Group3 {
|
|
|
19263
19492
|
section.blockIndices.set(mesh, page.blockIndices);
|
|
19264
19493
|
const unsubscribe = [];
|
|
19265
19494
|
for (const { atlas: id, x, y } of page.placements) {
|
|
19266
|
-
const atlas =
|
|
19495
|
+
const atlas = atlases2[id];
|
|
19267
19496
|
if (!atlas.hasAnimation) continue;
|
|
19268
19497
|
unsubscribe.push(atlas.subscribe(() => {
|
|
19269
19498
|
context.clearRect(x, y, atlas.image.width, atlas.image.height);
|