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.js
CHANGED
|
@@ -310,6 +310,9 @@ var init_Caching = __esm({
|
|
|
310
310
|
static {
|
|
311
311
|
this.blockEntityIndexCache = _Caching.createAssetCache();
|
|
312
312
|
}
|
|
313
|
+
static {
|
|
314
|
+
this.unihexCache = _Caching.createAssetCache();
|
|
315
|
+
}
|
|
313
316
|
static {
|
|
314
317
|
this.fontCache = _Caching.createAssetCache();
|
|
315
318
|
}
|
|
@@ -352,6 +355,7 @@ var init_Caching = __esm({
|
|
|
352
355
|
this.entityAnimationCache,
|
|
353
356
|
this.blockEntityIndexCache,
|
|
354
357
|
this.fontCache,
|
|
358
|
+
this.unihexCache,
|
|
355
359
|
this.bannerPatternCache,
|
|
356
360
|
this.mineRenderDataCache,
|
|
357
361
|
this.usernameUuidCache,
|
|
@@ -1113,6 +1117,7 @@ var init_Materials = __esm({
|
|
|
1113
1117
|
static createShadedCanvasMaterial(canvas, transparent = false, shade = false, boundUvs = false) {
|
|
1114
1118
|
const vertShader = `
|
|
1115
1119
|
uniform bool SHADE;
|
|
1120
|
+
attribute float shade;
|
|
1116
1121
|
|
|
1117
1122
|
// Keep MSAA edge pixels from sampling outside the face's atlas region.
|
|
1118
1123
|
#if __VERSION__ >= 300
|
|
@@ -1135,7 +1140,7 @@ var init_Materials = __esm({
|
|
|
1135
1140
|
void main()
|
|
1136
1141
|
{
|
|
1137
1142
|
|
|
1138
|
-
if (SHADE) {
|
|
1143
|
+
if (SHADE && shade > 0.5) {
|
|
1139
1144
|
|
|
1140
1145
|
#ifdef USE_INSTANCING
|
|
1141
1146
|
vec3 N = vec3( modelMatrix * instanceMatrix * vec4(normal, 0.0) );
|
|
@@ -1244,7 +1249,7 @@ var init_Materials = __esm({
|
|
|
1244
1249
|
side: transparent ? import_three5.DoubleSide : import_three5.FrontSide,
|
|
1245
1250
|
alphaTest: 0.5
|
|
1246
1251
|
});
|
|
1247
|
-
Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });
|
|
1252
|
+
Object.assign(material.defaultAttributeValues, { shade: [1], uvBounds: [0, 0, 1, 1] });
|
|
1248
1253
|
return material;
|
|
1249
1254
|
} catch (e) {
|
|
1250
1255
|
console.warn(e);
|
|
@@ -1409,6 +1414,7 @@ var init_AssetParsers = __esm({
|
|
|
1409
1414
|
AssetParser2["IMAGE"] = "image";
|
|
1410
1415
|
AssetParser2["LIST"] = "list";
|
|
1411
1416
|
AssetParser2["JSON"] = "json";
|
|
1417
|
+
AssetParser2["BINARY"] = "binary";
|
|
1412
1418
|
return AssetParser2;
|
|
1413
1419
|
})(AssetParser || {});
|
|
1414
1420
|
}
|
|
@@ -2881,7 +2887,7 @@ var init_parser = __esm({
|
|
|
2881
2887
|
});
|
|
2882
2888
|
|
|
2883
2889
|
// src/assets/source/HostedAssetSource.ts
|
|
2884
|
-
var p3, DEFAULT_OPTIONS, HostedAssetSource;
|
|
2890
|
+
var BINARY_TIMEOUT, p3, DEFAULT_OPTIONS, HostedAssetSource;
|
|
2885
2891
|
var init_HostedAssetSource = __esm({
|
|
2886
2892
|
"src/assets/source/HostedAssetSource.ts"() {
|
|
2887
2893
|
init_AssetSource();
|
|
@@ -2894,6 +2900,7 @@ var init_HostedAssetSource = __esm({
|
|
|
2894
2900
|
init_AssetLoader();
|
|
2895
2901
|
init_parser();
|
|
2896
2902
|
init_merge();
|
|
2903
|
+
BINARY_TIMEOUT = 6e4;
|
|
2897
2904
|
p3 = prefix("HostedAssetSource");
|
|
2898
2905
|
DEFAULT_OPTIONS = {
|
|
2899
2906
|
retryDefaults: true
|
|
@@ -2964,6 +2971,17 @@ var init_HostedAssetSource = __esm({
|
|
|
2964
2971
|
}
|
|
2965
2972
|
};
|
|
2966
2973
|
}
|
|
2974
|
+
static {
|
|
2975
|
+
this.BINARY = {
|
|
2976
|
+
config(request) {
|
|
2977
|
+
request.timeout = BINARY_TIMEOUT;
|
|
2978
|
+
request.responseType = "arraybuffer";
|
|
2979
|
+
},
|
|
2980
|
+
parse(response) {
|
|
2981
|
+
return { data: new Uint8Array(response.data) };
|
|
2982
|
+
}
|
|
2983
|
+
};
|
|
2984
|
+
}
|
|
2967
2985
|
static {
|
|
2968
2986
|
this.PARSER_MAP = /* @__PURE__ */ new Map([
|
|
2969
2987
|
["model" /* MODEL */, _HostedAssetSource.MODEL],
|
|
@@ -2972,7 +2990,8 @@ var init_HostedAssetSource = __esm({
|
|
|
2972
2990
|
["nbt" /* NBT */, _HostedAssetSource.NBT],
|
|
2973
2991
|
["image" /* IMAGE */, _HostedAssetSource.IMAGE],
|
|
2974
2992
|
["list" /* LIST */, _HostedAssetSource.LIST],
|
|
2975
|
-
["json" /* JSON */, _HostedAssetSource.JSON]
|
|
2993
|
+
["json" /* JSON */, _HostedAssetSource.JSON],
|
|
2994
|
+
["binary" /* BINARY */, _HostedAssetSource.BINARY]
|
|
2976
2995
|
]);
|
|
2977
2996
|
}
|
|
2978
2997
|
/** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */
|
|
@@ -4858,6 +4877,178 @@ var init_Entities = __esm({
|
|
|
4858
4877
|
}
|
|
4859
4878
|
});
|
|
4860
4879
|
|
|
4880
|
+
// src/assets/_fonts/Unihex.ts
|
|
4881
|
+
var Unihex_exports = {};
|
|
4882
|
+
__export(Unihex_exports, {
|
|
4883
|
+
loadUnihex: () => loadUnihex
|
|
4884
|
+
});
|
|
4885
|
+
function readHex(text2, filename, glyphs) {
|
|
4886
|
+
const lines = text2.split("\n");
|
|
4887
|
+
if (lines[lines.length - 1] === "") lines.pop();
|
|
4888
|
+
lines.forEach((line, index) => {
|
|
4889
|
+
const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);
|
|
4890
|
+
if (!match || ![32, 64, 96, 128].includes(match[2].length)) {
|
|
4891
|
+
throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);
|
|
4892
|
+
}
|
|
4893
|
+
const codepoint = parseInt(match[1], 16);
|
|
4894
|
+
if (codepoint > 1114111) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);
|
|
4895
|
+
const bitWidth = match[2].length / 4;
|
|
4896
|
+
const rowLength = bitWidth / 4;
|
|
4897
|
+
const rows = new Uint32Array(GLYPH_HEIGHT);
|
|
4898
|
+
let mask = 0;
|
|
4899
|
+
for (let y = 0; y < GLYPH_HEIGHT; y++) {
|
|
4900
|
+
rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);
|
|
4901
|
+
mask |= rows[y];
|
|
4902
|
+
}
|
|
4903
|
+
let left = 0, right = bitWidth;
|
|
4904
|
+
if (mask) {
|
|
4905
|
+
while (!(mask >>> bitWidth - left - 1 & 1)) left++;
|
|
4906
|
+
right = bitWidth - 1;
|
|
4907
|
+
while (!(mask >>> bitWidth - right - 1 & 1)) right--;
|
|
4908
|
+
}
|
|
4909
|
+
glyphs.set(codepoint, { rows, bitWidth, left, right });
|
|
4910
|
+
});
|
|
4911
|
+
}
|
|
4912
|
+
async function parseUnihex(key) {
|
|
4913
|
+
try {
|
|
4914
|
+
const asset2 = await AssetLoader.get(key, "binary" /* BINARY */);
|
|
4915
|
+
if (!asset2) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);
|
|
4916
|
+
const records = /* @__PURE__ */ new Map();
|
|
4917
|
+
const reader = new import_zip2.ZipReader(new import_zip2.Uint8ArrayReader(asset2.data), { useWebWorkers: false, useCompressionStream: false });
|
|
4918
|
+
try {
|
|
4919
|
+
for (const entry of await reader.getEntries()) {
|
|
4920
|
+
if (!entry.directory && entry.filename.endsWith(".hex")) {
|
|
4921
|
+
readHex(await entry.getData(new import_zip2.TextWriter(), { checkSignature: true }), entry.filename, records);
|
|
4922
|
+
}
|
|
4923
|
+
}
|
|
4924
|
+
} finally {
|
|
4925
|
+
await reader.close();
|
|
4926
|
+
}
|
|
4927
|
+
const indices = new Int32Array(1114112).fill(-1);
|
|
4928
|
+
const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);
|
|
4929
|
+
let index = 0;
|
|
4930
|
+
for (const [codepoint, record] of records) {
|
|
4931
|
+
indices[codepoint] = index;
|
|
4932
|
+
rows.set(record.rows, index * GLYPH_HEIGHT);
|
|
4933
|
+
metrics.set([record.bitWidth, record.left, record.right], index * 3);
|
|
4934
|
+
index++;
|
|
4935
|
+
}
|
|
4936
|
+
return { indices, rows, metrics };
|
|
4937
|
+
} catch (error) {
|
|
4938
|
+
console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4939
|
+
return void 0;
|
|
4940
|
+
}
|
|
4941
|
+
}
|
|
4942
|
+
async function loadUnihex(provider, fontKey, characters) {
|
|
4943
|
+
const origin = new AssetKey(DEFAULT_NAMESPACE, "", void 0, void 0, "assets", "", fontKey.root);
|
|
4944
|
+
const key = AssetKey.parse("font", provider.hex_file, origin);
|
|
4945
|
+
key.assetType = void 0;
|
|
4946
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
4947
|
+
let overrides;
|
|
4948
|
+
try {
|
|
4949
|
+
overrides = (provider.size_overrides ?? []).map((override) => {
|
|
4950
|
+
const from = override.from.codePointAt(0), to = override.to.codePointAt(0);
|
|
4951
|
+
if ([...override.from].length !== 1 || [...override.to].length !== 1 || from >= to || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {
|
|
4952
|
+
throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);
|
|
4953
|
+
}
|
|
4954
|
+
return { ...override, from, to };
|
|
4955
|
+
});
|
|
4956
|
+
} catch (error) {
|
|
4957
|
+
console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4958
|
+
return glyphs;
|
|
4959
|
+
}
|
|
4960
|
+
const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
|
|
4961
|
+
if (!file) return glyphs;
|
|
4962
|
+
let atlas = atlases.get(provider);
|
|
4963
|
+
if (!atlas) {
|
|
4964
|
+
atlas = new UnihexAtlas();
|
|
4965
|
+
atlases.set(provider, atlas);
|
|
4966
|
+
}
|
|
4967
|
+
for (const character of characters) {
|
|
4968
|
+
const codepoint = character.codePointAt(0), index = file.indices[codepoint];
|
|
4969
|
+
if (index < 0) continue;
|
|
4970
|
+
const record = {
|
|
4971
|
+
rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),
|
|
4972
|
+
bitWidth: file.metrics[index * 3],
|
|
4973
|
+
left: file.metrics[index * 3 + 1],
|
|
4974
|
+
right: file.metrics[index * 3 + 2]
|
|
4975
|
+
};
|
|
4976
|
+
const override = overrides.find((range) => codepoint >= range.from && codepoint <= range.to);
|
|
4977
|
+
if (override) {
|
|
4978
|
+
record.left = override.left;
|
|
4979
|
+
record.right = override.right;
|
|
4980
|
+
}
|
|
4981
|
+
const width = record.right - record.left + 1;
|
|
4982
|
+
let rendered;
|
|
4983
|
+
const render = () => rendered ??= atlas.draw(record);
|
|
4984
|
+
glyphs.set(character, {
|
|
4985
|
+
get image() {
|
|
4986
|
+
return render().image;
|
|
4987
|
+
},
|
|
4988
|
+
get x() {
|
|
4989
|
+
return render().x;
|
|
4990
|
+
},
|
|
4991
|
+
get y() {
|
|
4992
|
+
return render().y;
|
|
4993
|
+
},
|
|
4994
|
+
width,
|
|
4995
|
+
height: GLYPH_HEIGHT,
|
|
4996
|
+
scale: 0.5,
|
|
4997
|
+
ascent: 7,
|
|
4998
|
+
advance: Math.floor(width / 2) + 1,
|
|
4999
|
+
boldOffset: 0.5,
|
|
5000
|
+
shadowOffset: 0.5
|
|
5001
|
+
});
|
|
5002
|
+
}
|
|
5003
|
+
return glyphs;
|
|
5004
|
+
}
|
|
5005
|
+
var import_zip2, ATLAS_SIZE, GLYPH_HEIGHT, UnihexAtlas, atlases;
|
|
5006
|
+
var init_Unihex = __esm({
|
|
5007
|
+
"src/assets/_fonts/Unihex.ts"() {
|
|
5008
|
+
import_zip2 = require("@zip.js/zip.js");
|
|
5009
|
+
init_AssetKey();
|
|
5010
|
+
init_AssetLoader();
|
|
5011
|
+
init_Assets();
|
|
5012
|
+
init_Caching();
|
|
5013
|
+
init_AssetParsers();
|
|
5014
|
+
init_CanvasCompat();
|
|
5015
|
+
ATLAS_SIZE = 512;
|
|
5016
|
+
GLYPH_HEIGHT = 16;
|
|
5017
|
+
UnihexAtlas = class {
|
|
5018
|
+
constructor() {
|
|
5019
|
+
this.x = 0;
|
|
5020
|
+
this.y = 0;
|
|
5021
|
+
}
|
|
5022
|
+
draw(glyph) {
|
|
5023
|
+
const width = glyph.right - glyph.left + 1;
|
|
5024
|
+
if (this.image && this.x + width > this.image.width) {
|
|
5025
|
+
this.x = 0;
|
|
5026
|
+
this.y += GLYPH_HEIGHT;
|
|
5027
|
+
}
|
|
5028
|
+
if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {
|
|
5029
|
+
this.image = createCanvas2(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);
|
|
5030
|
+
this.x = 0;
|
|
5031
|
+
this.y = 0;
|
|
5032
|
+
}
|
|
5033
|
+
const context = this.image.getContext("2d");
|
|
5034
|
+
const pixels = context.createImageData(width, GLYPH_HEIGHT);
|
|
5035
|
+
for (let y = 0; y < GLYPH_HEIGHT; y++) {
|
|
5036
|
+
for (let x = 0; x < width; x++) {
|
|
5037
|
+
const column = glyph.left + x;
|
|
5038
|
+
if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> glyph.bitWidth - column - 1 & 1)) continue;
|
|
5039
|
+
pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);
|
|
5040
|
+
}
|
|
5041
|
+
}
|
|
5042
|
+
const result = { image: this.image, x: this.x, y: this.y };
|
|
5043
|
+
context.putImageData(pixels, this.x, this.y);
|
|
5044
|
+
this.x += width;
|
|
5045
|
+
return result;
|
|
5046
|
+
}
|
|
5047
|
+
};
|
|
5048
|
+
atlases = /* @__PURE__ */ new WeakMap();
|
|
5049
|
+
}
|
|
5050
|
+
});
|
|
5051
|
+
|
|
4861
5052
|
// src/assets/Fonts.ts
|
|
4862
5053
|
var Fonts;
|
|
4863
5054
|
var init_Fonts = __esm({
|
|
@@ -4868,7 +5059,7 @@ var init_Fonts = __esm({
|
|
|
4868
5059
|
init_ModelTextures();
|
|
4869
5060
|
init_Caching();
|
|
4870
5061
|
Fonts = class {
|
|
4871
|
-
/** Combines font definitions in source-priority order.
|
|
5062
|
+
/** Combines font definitions in source-priority order. TrueType providers are skipped. */
|
|
4872
5063
|
static async get(key = "minecraft:default") {
|
|
4873
5064
|
const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
|
|
4874
5065
|
return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
|
|
@@ -4884,6 +5075,7 @@ var init_Fonts = __esm({
|
|
|
4884
5075
|
const stack = await AssetLoader.getAll(key, "json" /* JSON */);
|
|
4885
5076
|
if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
|
|
4886
5077
|
const glyphs = /* @__PURE__ */ new Map();
|
|
5078
|
+
const providers = [];
|
|
4887
5079
|
for (const asset2 of stack) {
|
|
4888
5080
|
for (const provider of asset2.providers) {
|
|
4889
5081
|
if (provider.filter?.uniform || provider.filter?.jp) continue;
|
|
@@ -4902,17 +5094,43 @@ var init_Fonts = __esm({
|
|
|
4902
5094
|
break;
|
|
4903
5095
|
case "reference":
|
|
4904
5096
|
case "minecraft:reference":
|
|
4905
|
-
|
|
5097
|
+
const reference = await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized]);
|
|
5098
|
+
if (reference.resolve) {
|
|
5099
|
+
providers.push(async (characters) => {
|
|
5100
|
+
await reference.resolve(characters);
|
|
5101
|
+
return reference.glyphs;
|
|
5102
|
+
});
|
|
5103
|
+
continue;
|
|
5104
|
+
}
|
|
5105
|
+
provided = reference.glyphs;
|
|
4906
5106
|
break;
|
|
5107
|
+
case "unihex":
|
|
5108
|
+
case "minecraft:unihex":
|
|
5109
|
+
providers.push(async (characters) => (await Promise.resolve().then(() => (init_Unihex(), Unihex_exports))).loadUnihex(provider, key, characters));
|
|
5110
|
+
continue;
|
|
4907
5111
|
default:
|
|
4908
5112
|
continue;
|
|
4909
5113
|
}
|
|
4910
|
-
for (const [character, glyph] of provided) {
|
|
5114
|
+
if (providers.every((provider2) => provider2 instanceof Map)) for (const [character, glyph] of provided) {
|
|
4911
5115
|
if (character !== "\0" && !glyphs.has(character)) glyphs.set(character, glyph);
|
|
4912
5116
|
}
|
|
5117
|
+
providers.push(provided);
|
|
5118
|
+
}
|
|
5119
|
+
}
|
|
5120
|
+
return { glyphs, resolve: providers.every((provider) => provider instanceof Map) ? void 0 : async (characters) => {
|
|
5121
|
+
const remaining = new Set([...characters].filter((character) => character !== "\0" && character !== "\n" && character !== "\r" && !glyphs.has(character)));
|
|
5122
|
+
for (const provider of providers) {
|
|
5123
|
+
if (!remaining.size) break;
|
|
5124
|
+
const provided = provider instanceof Map ? provider : await provider([...remaining].join(""));
|
|
5125
|
+
for (const character of remaining) {
|
|
5126
|
+
const glyph = provided.get(character);
|
|
5127
|
+
if (glyph) {
|
|
5128
|
+
glyphs.set(character, glyph);
|
|
5129
|
+
remaining.delete(character);
|
|
5130
|
+
}
|
|
5131
|
+
}
|
|
4913
5132
|
}
|
|
4914
|
-
}
|
|
4915
|
-
return { glyphs };
|
|
5133
|
+
} };
|
|
4916
5134
|
}
|
|
4917
5135
|
static async bitmap(provider, fontKey) {
|
|
4918
5136
|
const rows = provider.chars.map((row) => [...row]);
|
|
@@ -8121,6 +8339,7 @@ async function layoutGuiText(text2, options = {}) {
|
|
|
8121
8339
|
}
|
|
8122
8340
|
const font = await Fonts.get(options.font);
|
|
8123
8341
|
const runs = typeof text2 === "string" ? [{ text: text2 }] : text2;
|
|
8342
|
+
await font.resolve?.(runs.map((run) => run.text).join(""));
|
|
8124
8343
|
const glyphs = [], lineWidths = [];
|
|
8125
8344
|
let line = [], width = 0;
|
|
8126
8345
|
let trailingNewline = false;
|
|
@@ -8147,7 +8366,7 @@ async function layoutGuiText(text2, options = {}) {
|
|
|
8147
8366
|
continue;
|
|
8148
8367
|
}
|
|
8149
8368
|
const glyph = font.glyphs.get(character);
|
|
8150
|
-
const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
|
|
8369
|
+
const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);
|
|
8151
8370
|
line.push({ character, glyph, advance, style, x: 0, y: 0 });
|
|
8152
8371
|
width += advance;
|
|
8153
8372
|
while (width > maxWidth && line.length > 1) {
|
|
@@ -8175,7 +8394,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8175
8394
|
batches.push(batch);
|
|
8176
8395
|
}
|
|
8177
8396
|
const color2 = new import_three20.Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
8178
|
-
const offset = isShadow ? 1 : 0;
|
|
8397
|
+
const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
|
|
8179
8398
|
const top = glyph ? 7 - glyph.ascent : 0;
|
|
8180
8399
|
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
8181
8400
|
const width = glyph ? glyph.width * glyph.scale : 5;
|
|
@@ -8205,7 +8424,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8205
8424
|
for (let i = 0; i < 4; i++) batch.colors.push(color2.r, color2.g, color2.b);
|
|
8206
8425
|
batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
|
|
8207
8426
|
};
|
|
8208
|
-
for (const boldOffset of style.bold ? [0, 1] : [0]) {
|
|
8427
|
+
for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {
|
|
8209
8428
|
if (glyph) quad(0, top, width, top + height, boldOffset);
|
|
8210
8429
|
else {
|
|
8211
8430
|
quad(0, 0, 5, 1, boldOffset);
|
|
@@ -9979,6 +10198,10 @@ var init_ModelObject = __esm({
|
|
|
9979
10198
|
this.atlas.model.elements?.forEach((el) => {
|
|
9980
10199
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
9981
10200
|
this.geometries.add(elGeo);
|
|
10201
|
+
elGeo.setAttribute("shade", new import_three27.BufferAttribute(
|
|
10202
|
+
new Float32Array(elGeo.getAttribute("position").count).fill(!this.originalModel.itemId && el.shade === false ? 0 : 1),
|
|
10203
|
+
1
|
|
10204
|
+
));
|
|
9982
10205
|
if (this.options.cullMask) {
|
|
9983
10206
|
const indices = Array.from(elGeo.getIndex().array);
|
|
9984
10207
|
elGeo.setIndex(indices.filter((_, index) => {
|
|
@@ -17771,9 +17994,9 @@ function cached(map, key, load) {
|
|
|
17771
17994
|
function compactQuads(geometry, keep) {
|
|
17772
17995
|
const quads = keep.flatMap((kept, index) => kept ? [index] : []);
|
|
17773
17996
|
const compact = new import_three41.BufferGeometry();
|
|
17774
|
-
for (const [name, size] of Object.entries({ position: 3, normal: 3, uv: 2, uvBounds: 4, color: 3 })) {
|
|
17997
|
+
for (const [name, size] of Object.entries({ position: 3, normal: 3, uv: 2, uvBounds: 4, color: 3, shade: 1 })) {
|
|
17775
17998
|
const source2 = geometry.getAttribute(name);
|
|
17776
|
-
const defaults = name === "uvBounds" ? [0, 0, 1, 1] : name === "color" ? [1, 1, 1] : void 0;
|
|
17999
|
+
const defaults = name === "uvBounds" ? [0, 0, 1, 1] : name === "color" ? [1, 1, 1] : name === "shade" ? [1] : void 0;
|
|
17777
18000
|
const values = new Float32Array(quads.length * 4 * size);
|
|
17778
18001
|
for (let q = 0; q < quads.length; q++) {
|
|
17779
18002
|
for (let vertex = 0; vertex < 4; vertex++) {
|
|
@@ -19021,7 +19244,7 @@ var LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18];
|
|
|
19021
19244
|
|
|
19022
19245
|
// src/world/SectionGeometry.ts
|
|
19023
19246
|
function buildSectionGeometry(input) {
|
|
19024
|
-
const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
|
|
19247
|
+
const { count, indices, templates, cullMasks, templateData, atlases: atlases2, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
|
|
19025
19248
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
19026
19249
|
if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError("Section entry count exceeds its arrays");
|
|
19027
19250
|
if (biomeTints && biomeTints.length !== count * 3) throw new RangeError("Section biome tints must contain RGB for each placement");
|
|
@@ -19039,7 +19262,7 @@ function buildSectionGeometry(input) {
|
|
|
19039
19262
|
const cornerBrightness2 = ambientOcclusion ? new Float32Array(4) : void 0;
|
|
19040
19263
|
for (const template of templateData) {
|
|
19041
19264
|
const { quads } = template;
|
|
19042
|
-
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) {
|
|
19265
|
+
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) {
|
|
19043
19266
|
throw new RangeError("Section template arrays do not match its quad count");
|
|
19044
19267
|
}
|
|
19045
19268
|
}
|
|
@@ -19056,8 +19279,8 @@ function buildSectionGeometry(input) {
|
|
|
19056
19279
|
const locations = /* @__PURE__ */ new Map();
|
|
19057
19280
|
for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {
|
|
19058
19281
|
const firstPage = pages.length;
|
|
19059
|
-
for (const atlas of [...layerAtlases].sort((a, b) => Number(
|
|
19060
|
-
const { width, height, animated } =
|
|
19282
|
+
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))) {
|
|
19283
|
+
const { width, height, animated } = atlases2[atlas];
|
|
19061
19284
|
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
19062
19285
|
let selected = -1;
|
|
19063
19286
|
for (let i = firstPage; !animated && i < pages.length; i++) {
|
|
@@ -19100,7 +19323,7 @@ function buildSectionGeometry(input) {
|
|
|
19100
19323
|
});
|
|
19101
19324
|
if (!quads.sprites.length) continue;
|
|
19102
19325
|
if (!fluidPages.has(fluid)) {
|
|
19103
|
-
const { width, height } =
|
|
19326
|
+
const { width, height } = atlases2[data.atlas];
|
|
19104
19327
|
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
19105
19328
|
fluidPages.set(fluid, {
|
|
19106
19329
|
layer: 2,
|
|
@@ -19118,7 +19341,7 @@ function buildSectionGeometry(input) {
|
|
|
19118
19341
|
const tint = fluid === "water" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;
|
|
19119
19342
|
fluidPages.get(fluid).fluids.push({ quads, x, y, z, data, tint });
|
|
19120
19343
|
}
|
|
19121
|
-
pages.push(...[...fluidPages.values()].sort((a, b) => Number(
|
|
19344
|
+
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));
|
|
19122
19345
|
}
|
|
19123
19346
|
return pages.map((page) => {
|
|
19124
19347
|
let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);
|
|
@@ -19130,12 +19353,13 @@ function buildSectionGeometry(input) {
|
|
|
19130
19353
|
}
|
|
19131
19354
|
const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);
|
|
19132
19355
|
const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);
|
|
19356
|
+
const shade = new Float32Array(faces * 4).fill(1);
|
|
19133
19357
|
const outputIndices = new Uint32Array(faces * 6);
|
|
19134
19358
|
const blockIndices = new Uint16Array(faces);
|
|
19135
19359
|
let vertex = 0, indexOffset = 0;
|
|
19136
19360
|
for (const entry of page.entries) {
|
|
19137
19361
|
const template = templateData[templates[entry]];
|
|
19138
|
-
const atlas =
|
|
19362
|
+
const atlas = atlases2[template.atlas];
|
|
19139
19363
|
const placement = locations.get(template.atlas);
|
|
19140
19364
|
const mapU = (u) => (placement.x + u * atlas.width) / page.width;
|
|
19141
19365
|
const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
|
|
@@ -19159,6 +19383,7 @@ function buildSectionGeometry(input) {
|
|
|
19159
19383
|
normals[vertex * 3] = template.normals[source * 3];
|
|
19160
19384
|
normals[vertex * 3 + 1] = template.normals[source * 3 + 1];
|
|
19161
19385
|
normals[vertex * 3 + 2] = template.normals[source * 3 + 2];
|
|
19386
|
+
shade[vertex] = template.shade?.[source] ?? 1;
|
|
19162
19387
|
uvs[vertex * 2] = mapU(template.uvs[source * 2]);
|
|
19163
19388
|
uvs[vertex * 2 + 1] = mapV(template.uvs[source * 2 + 1]);
|
|
19164
19389
|
uvBounds[vertex * 4] = mapU(template.uvBounds[source * 4]);
|
|
@@ -19174,7 +19399,7 @@ function buildSectionGeometry(input) {
|
|
|
19174
19399
|
}
|
|
19175
19400
|
}
|
|
19176
19401
|
for (const { quads, x, y, z, data, tint } of page.fluids) {
|
|
19177
|
-
const atlas =
|
|
19402
|
+
const atlas = atlases2[data.atlas];
|
|
19178
19403
|
const placement = page.placements[0];
|
|
19179
19404
|
const mapU = (u) => (placement.x + u * atlas.width) / page.width;
|
|
19180
19405
|
const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
|
|
@@ -19211,11 +19436,11 @@ function buildSectionGeometry(input) {
|
|
|
19211
19436
|
indexOffset += 6;
|
|
19212
19437
|
}
|
|
19213
19438
|
}
|
|
19214
|
-
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };
|
|
19439
|
+
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, shade, indices: outputIndices, blockIndices };
|
|
19215
19440
|
});
|
|
19216
19441
|
}
|
|
19217
19442
|
function sectionGeometryTransferables(pages) {
|
|
19218
|
-
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]);
|
|
19443
|
+
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]);
|
|
19219
19444
|
}
|
|
19220
19445
|
|
|
19221
19446
|
// src/world/SectionWorker.ts
|
|
@@ -19276,7 +19501,7 @@ var templateCache = /* @__PURE__ */ new WeakMap();
|
|
|
19276
19501
|
var WATER_TINT = new import_three46.Color(4159204).toArray();
|
|
19277
19502
|
function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
19278
19503
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
19279
|
-
const
|
|
19504
|
+
const atlases2 = [];
|
|
19280
19505
|
const atlasIds = /* @__PURE__ */ new Map();
|
|
19281
19506
|
const templateIds = /* @__PURE__ */ new Map();
|
|
19282
19507
|
const input = {
|
|
@@ -19299,9 +19524,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19299
19524
|
if (id === void 0) {
|
|
19300
19525
|
let atlas = atlasIds.get(template.atlas);
|
|
19301
19526
|
if (atlas === void 0) {
|
|
19302
|
-
atlas =
|
|
19527
|
+
atlas = atlases2.length;
|
|
19303
19528
|
atlasIds.set(template.atlas, atlas);
|
|
19304
|
-
|
|
19529
|
+
atlases2.push(template.atlas);
|
|
19305
19530
|
input.atlases.push({ width: template.atlas.image.width, height: template.atlas.image.height, animated: template.atlas.hasAnimation });
|
|
19306
19531
|
}
|
|
19307
19532
|
let data = templateCache.get(template);
|
|
@@ -19319,6 +19544,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19319
19544
|
uvs: new Float32Array(quads * 8),
|
|
19320
19545
|
uvBounds: new Float32Array(quads * 16),
|
|
19321
19546
|
colors: new Float32Array(quads * 12),
|
|
19547
|
+
shade: new Float32Array(quads * 4),
|
|
19322
19548
|
indices: new Uint16Array(quads * 6),
|
|
19323
19549
|
cullFaces: new Uint8Array(template.cullFaces),
|
|
19324
19550
|
biomeTint: template.biomeTint ? new Uint8Array(template.biomeTint) : void 0,
|
|
@@ -19330,6 +19556,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19330
19556
|
const uv = template.geometry.getAttribute("uv");
|
|
19331
19557
|
const bounds = template.geometry.getAttribute("uvBounds");
|
|
19332
19558
|
const color2 = template.geometry.getAttribute("color");
|
|
19559
|
+
const shade = template.geometry.getAttribute("shade");
|
|
19333
19560
|
for (let vertex = 0; vertex < quads * 4; vertex++) {
|
|
19334
19561
|
data.positions.set([position.getX(vertex), position.getY(vertex), position.getZ(vertex)], vertex * 3);
|
|
19335
19562
|
data.normals.set([normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex)], vertex * 3);
|
|
@@ -19341,6 +19568,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19341
19568
|
bounds?.getW(vertex) ?? 1
|
|
19342
19569
|
], vertex * 4);
|
|
19343
19570
|
data.colors.set([color2?.getX(vertex) ?? 1, color2?.getY(vertex) ?? 1, color2?.getZ(vertex) ?? 1], vertex * 3);
|
|
19571
|
+
data.shade[vertex] = shade?.getX(vertex) ?? 1;
|
|
19344
19572
|
}
|
|
19345
19573
|
for (let i2 = 0; i2 < data.indices.length; i2++) data.indices[i2] = indices.getX(i2) - 4 * Math.floor(i2 / 6);
|
|
19346
19574
|
templateCache.set(template, data);
|
|
@@ -19360,9 +19588,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19360
19588
|
if (!atlas) continue;
|
|
19361
19589
|
let id = atlasIds.get(atlas);
|
|
19362
19590
|
if (id === void 0) {
|
|
19363
|
-
id =
|
|
19591
|
+
id = atlases2.length;
|
|
19364
19592
|
atlasIds.set(atlas, id);
|
|
19365
|
-
|
|
19593
|
+
atlases2.push(atlas);
|
|
19366
19594
|
input.atlases.push({ width: atlas.image.width, height: atlas.image.height, animated: atlas.hasAnimation });
|
|
19367
19595
|
}
|
|
19368
19596
|
input.fluids[kind] = {
|
|
@@ -19373,7 +19601,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19373
19601
|
};
|
|
19374
19602
|
}
|
|
19375
19603
|
}
|
|
19376
|
-
return { input, atlases };
|
|
19604
|
+
return { input, atlases: atlases2 };
|
|
19377
19605
|
}
|
|
19378
19606
|
var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
19379
19607
|
constructor() {
|
|
@@ -19388,23 +19616,23 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19388
19616
|
}
|
|
19389
19617
|
/** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
19390
19618
|
static build(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
19391
|
-
const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19392
|
-
return this.fromPages(buildSectionGeometry(input),
|
|
19619
|
+
const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19620
|
+
return this.fromPages(buildSectionGeometry(input), atlases2);
|
|
19393
19621
|
}
|
|
19394
19622
|
/** Builds section-local meshes in a browser worker when available, with synchronous fallback. */
|
|
19395
19623
|
static async buildAsync(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
19396
|
-
const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19624
|
+
const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19397
19625
|
const worker = SectionWorker.shared();
|
|
19398
19626
|
const pages = worker ? await worker.build(input).catch(() => buildSectionGeometry(input)) : buildSectionGeometry(input);
|
|
19399
|
-
return this.fromPages(pages,
|
|
19627
|
+
return this.fromPages(pages, atlases2);
|
|
19400
19628
|
}
|
|
19401
|
-
static fromPages(pages,
|
|
19629
|
+
static fromPages(pages, atlases2) {
|
|
19402
19630
|
const section = new _SectionMesh();
|
|
19403
19631
|
for (const page of pages) {
|
|
19404
19632
|
const canvas = createCanvas2(page.width, page.height);
|
|
19405
19633
|
const context = canvas.getContext("2d");
|
|
19406
19634
|
for (const { atlas, x, y } of page.placements) {
|
|
19407
|
-
context.drawImage(
|
|
19635
|
+
context.drawImage(atlases2[atlas].image.canvas, x, y);
|
|
19408
19636
|
}
|
|
19409
19637
|
const geometry = new import_three46.BufferGeometry();
|
|
19410
19638
|
geometry.setAttribute("position", new import_three46.Float32BufferAttribute(page.positions.buffer, 3));
|
|
@@ -19412,10 +19640,11 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19412
19640
|
geometry.setAttribute("uv", new import_three46.Float32BufferAttribute(page.uvs.buffer, 2));
|
|
19413
19641
|
geometry.setAttribute("uvBounds", new import_three46.Float32BufferAttribute(page.uvBounds.buffer, 4));
|
|
19414
19642
|
geometry.setAttribute("color", new import_three46.Float32BufferAttribute(page.colors.buffer, 3));
|
|
19643
|
+
geometry.setAttribute("shade", new import_three46.Float32BufferAttribute(page.shade.buffer, 1));
|
|
19415
19644
|
geometry.setIndex(new import_three46.Uint32BufferAttribute(page.indices.buffer, 1));
|
|
19416
19645
|
geometry.computeBoundingBox();
|
|
19417
19646
|
geometry.computeBoundingSphere();
|
|
19418
|
-
const transparent = page.layer === 2 ?
|
|
19647
|
+
const transparent = page.layer === 2 ? atlases2[page.placements[0].atlas].hasTranslucency : page.layer === 1;
|
|
19419
19648
|
const material = Materials.createShadedCanvasMaterial(canvas, transparent, false, true);
|
|
19420
19649
|
material.side = import_three46.FrontSide;
|
|
19421
19650
|
if (page.layer === 2) {
|
|
@@ -19430,7 +19659,7 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19430
19659
|
section.blockIndices.set(mesh, page.blockIndices);
|
|
19431
19660
|
const unsubscribe = [];
|
|
19432
19661
|
for (const { atlas: id, x, y } of page.placements) {
|
|
19433
|
-
const atlas =
|
|
19662
|
+
const atlas = atlases2[id];
|
|
19434
19663
|
if (!atlas.hasAnimation) continue;
|
|
19435
19664
|
unsubscribe.push(atlas.subscribe(() => {
|
|
19436
19665
|
context.clearRect(x, y, atlas.image.width, atlas.image.height);
|