minerender 2.1.0-alpha.131 → 2.1.0-alpha.133
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/entity/scene/EntityAnimationPlayer.mjs +62 -11
- package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs.map +1 -1
- package/dist/browser/esm/entity/scene/EntityObject.mjs +53 -20
- package/dist/browser/esm/entity/scene/EntityObject.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 +50 -10
- package/dist/browser/index.d.ts +50 -10
- package/dist/browser/index.js +357 -59
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +400 -59
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +50 -10
- package/dist/node/index.d.ts +50 -10
- package/dist/node/index.js +362 -59
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +361 -59
- 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,
|
|
@@ -1409,6 +1413,7 @@ var init_AssetParsers = __esm({
|
|
|
1409
1413
|
AssetParser2["IMAGE"] = "image";
|
|
1410
1414
|
AssetParser2["LIST"] = "list";
|
|
1411
1415
|
AssetParser2["JSON"] = "json";
|
|
1416
|
+
AssetParser2["BINARY"] = "binary";
|
|
1412
1417
|
return AssetParser2;
|
|
1413
1418
|
})(AssetParser || {});
|
|
1414
1419
|
}
|
|
@@ -2881,7 +2886,7 @@ var init_parser = __esm({
|
|
|
2881
2886
|
});
|
|
2882
2887
|
|
|
2883
2888
|
// src/assets/source/HostedAssetSource.ts
|
|
2884
|
-
var p3, DEFAULT_OPTIONS, HostedAssetSource;
|
|
2889
|
+
var BINARY_TIMEOUT, p3, DEFAULT_OPTIONS, HostedAssetSource;
|
|
2885
2890
|
var init_HostedAssetSource = __esm({
|
|
2886
2891
|
"src/assets/source/HostedAssetSource.ts"() {
|
|
2887
2892
|
init_AssetSource();
|
|
@@ -2894,6 +2899,7 @@ var init_HostedAssetSource = __esm({
|
|
|
2894
2899
|
init_AssetLoader();
|
|
2895
2900
|
init_parser();
|
|
2896
2901
|
init_merge();
|
|
2902
|
+
BINARY_TIMEOUT = 6e4;
|
|
2897
2903
|
p3 = prefix("HostedAssetSource");
|
|
2898
2904
|
DEFAULT_OPTIONS = {
|
|
2899
2905
|
retryDefaults: true
|
|
@@ -2964,6 +2970,17 @@ var init_HostedAssetSource = __esm({
|
|
|
2964
2970
|
}
|
|
2965
2971
|
};
|
|
2966
2972
|
}
|
|
2973
|
+
static {
|
|
2974
|
+
this.BINARY = {
|
|
2975
|
+
config(request) {
|
|
2976
|
+
request.timeout = BINARY_TIMEOUT;
|
|
2977
|
+
request.responseType = "arraybuffer";
|
|
2978
|
+
},
|
|
2979
|
+
parse(response) {
|
|
2980
|
+
return { data: new Uint8Array(response.data) };
|
|
2981
|
+
}
|
|
2982
|
+
};
|
|
2983
|
+
}
|
|
2967
2984
|
static {
|
|
2968
2985
|
this.PARSER_MAP = /* @__PURE__ */ new Map([
|
|
2969
2986
|
["model" /* MODEL */, _HostedAssetSource.MODEL],
|
|
@@ -2972,7 +2989,8 @@ var init_HostedAssetSource = __esm({
|
|
|
2972
2989
|
["nbt" /* NBT */, _HostedAssetSource.NBT],
|
|
2973
2990
|
["image" /* IMAGE */, _HostedAssetSource.IMAGE],
|
|
2974
2991
|
["list" /* LIST */, _HostedAssetSource.LIST],
|
|
2975
|
-
["json" /* JSON */, _HostedAssetSource.JSON]
|
|
2992
|
+
["json" /* JSON */, _HostedAssetSource.JSON],
|
|
2993
|
+
["binary" /* BINARY */, _HostedAssetSource.BINARY]
|
|
2976
2994
|
]);
|
|
2977
2995
|
}
|
|
2978
2996
|
/** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */
|
|
@@ -4858,6 +4876,178 @@ var init_Entities = __esm({
|
|
|
4858
4876
|
}
|
|
4859
4877
|
});
|
|
4860
4878
|
|
|
4879
|
+
// src/assets/_fonts/Unihex.ts
|
|
4880
|
+
var Unihex_exports = {};
|
|
4881
|
+
__export(Unihex_exports, {
|
|
4882
|
+
loadUnihex: () => loadUnihex
|
|
4883
|
+
});
|
|
4884
|
+
function readHex(text2, filename, glyphs) {
|
|
4885
|
+
const lines = text2.split("\n");
|
|
4886
|
+
if (lines[lines.length - 1] === "") lines.pop();
|
|
4887
|
+
lines.forEach((line, index) => {
|
|
4888
|
+
const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);
|
|
4889
|
+
if (!match || ![32, 64, 96, 128].includes(match[2].length)) {
|
|
4890
|
+
throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);
|
|
4891
|
+
}
|
|
4892
|
+
const codepoint = parseInt(match[1], 16);
|
|
4893
|
+
if (codepoint > 1114111) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);
|
|
4894
|
+
const bitWidth = match[2].length / 4;
|
|
4895
|
+
const rowLength = bitWidth / 4;
|
|
4896
|
+
const rows = new Uint32Array(GLYPH_HEIGHT);
|
|
4897
|
+
let mask = 0;
|
|
4898
|
+
for (let y = 0; y < GLYPH_HEIGHT; y++) {
|
|
4899
|
+
rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);
|
|
4900
|
+
mask |= rows[y];
|
|
4901
|
+
}
|
|
4902
|
+
let left = 0, right = bitWidth;
|
|
4903
|
+
if (mask) {
|
|
4904
|
+
while (!(mask >>> bitWidth - left - 1 & 1)) left++;
|
|
4905
|
+
right = bitWidth - 1;
|
|
4906
|
+
while (!(mask >>> bitWidth - right - 1 & 1)) right--;
|
|
4907
|
+
}
|
|
4908
|
+
glyphs.set(codepoint, { rows, bitWidth, left, right });
|
|
4909
|
+
});
|
|
4910
|
+
}
|
|
4911
|
+
async function parseUnihex(key) {
|
|
4912
|
+
try {
|
|
4913
|
+
const asset2 = await AssetLoader.get(key, "binary" /* BINARY */);
|
|
4914
|
+
if (!asset2) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);
|
|
4915
|
+
const records = /* @__PURE__ */ new Map();
|
|
4916
|
+
const reader = new import_zip2.ZipReader(new import_zip2.Uint8ArrayReader(asset2.data), { useWebWorkers: false, useCompressionStream: false });
|
|
4917
|
+
try {
|
|
4918
|
+
for (const entry of await reader.getEntries()) {
|
|
4919
|
+
if (!entry.directory && entry.filename.endsWith(".hex")) {
|
|
4920
|
+
readHex(await entry.getData(new import_zip2.TextWriter(), { checkSignature: true }), entry.filename, records);
|
|
4921
|
+
}
|
|
4922
|
+
}
|
|
4923
|
+
} finally {
|
|
4924
|
+
await reader.close();
|
|
4925
|
+
}
|
|
4926
|
+
const indices = new Int32Array(1114112).fill(-1);
|
|
4927
|
+
const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);
|
|
4928
|
+
let index = 0;
|
|
4929
|
+
for (const [codepoint, record] of records) {
|
|
4930
|
+
indices[codepoint] = index;
|
|
4931
|
+
rows.set(record.rows, index * GLYPH_HEIGHT);
|
|
4932
|
+
metrics.set([record.bitWidth, record.left, record.right], index * 3);
|
|
4933
|
+
index++;
|
|
4934
|
+
}
|
|
4935
|
+
return { indices, rows, metrics };
|
|
4936
|
+
} catch (error) {
|
|
4937
|
+
console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4938
|
+
return void 0;
|
|
4939
|
+
}
|
|
4940
|
+
}
|
|
4941
|
+
async function loadUnihex(provider, fontKey, characters) {
|
|
4942
|
+
const origin = new AssetKey(DEFAULT_NAMESPACE, "", void 0, void 0, "assets", "", fontKey.root);
|
|
4943
|
+
const key = AssetKey.parse("font", provider.hex_file, origin);
|
|
4944
|
+
key.assetType = void 0;
|
|
4945
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
4946
|
+
let overrides;
|
|
4947
|
+
try {
|
|
4948
|
+
overrides = (provider.size_overrides ?? []).map((override) => {
|
|
4949
|
+
const from = override.from.codePointAt(0), to = override.to.codePointAt(0);
|
|
4950
|
+
if ([...override.from].length !== 1 || [...override.to].length !== 1 || from >= to || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {
|
|
4951
|
+
throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);
|
|
4952
|
+
}
|
|
4953
|
+
return { ...override, from, to };
|
|
4954
|
+
});
|
|
4955
|
+
} catch (error) {
|
|
4956
|
+
console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4957
|
+
return glyphs;
|
|
4958
|
+
}
|
|
4959
|
+
const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
|
|
4960
|
+
if (!file) return glyphs;
|
|
4961
|
+
let atlas = atlases.get(provider);
|
|
4962
|
+
if (!atlas) {
|
|
4963
|
+
atlas = new UnihexAtlas();
|
|
4964
|
+
atlases.set(provider, atlas);
|
|
4965
|
+
}
|
|
4966
|
+
for (const character of characters) {
|
|
4967
|
+
const codepoint = character.codePointAt(0), index = file.indices[codepoint];
|
|
4968
|
+
if (index < 0) continue;
|
|
4969
|
+
const record = {
|
|
4970
|
+
rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),
|
|
4971
|
+
bitWidth: file.metrics[index * 3],
|
|
4972
|
+
left: file.metrics[index * 3 + 1],
|
|
4973
|
+
right: file.metrics[index * 3 + 2]
|
|
4974
|
+
};
|
|
4975
|
+
const override = overrides.find((range) => codepoint >= range.from && codepoint <= range.to);
|
|
4976
|
+
if (override) {
|
|
4977
|
+
record.left = override.left;
|
|
4978
|
+
record.right = override.right;
|
|
4979
|
+
}
|
|
4980
|
+
const width = record.right - record.left + 1;
|
|
4981
|
+
let rendered;
|
|
4982
|
+
const render = () => rendered ??= atlas.draw(record);
|
|
4983
|
+
glyphs.set(character, {
|
|
4984
|
+
get image() {
|
|
4985
|
+
return render().image;
|
|
4986
|
+
},
|
|
4987
|
+
get x() {
|
|
4988
|
+
return render().x;
|
|
4989
|
+
},
|
|
4990
|
+
get y() {
|
|
4991
|
+
return render().y;
|
|
4992
|
+
},
|
|
4993
|
+
width,
|
|
4994
|
+
height: GLYPH_HEIGHT,
|
|
4995
|
+
scale: 0.5,
|
|
4996
|
+
ascent: 7,
|
|
4997
|
+
advance: Math.floor(width / 2) + 1,
|
|
4998
|
+
boldOffset: 0.5,
|
|
4999
|
+
shadowOffset: 0.5
|
|
5000
|
+
});
|
|
5001
|
+
}
|
|
5002
|
+
return glyphs;
|
|
5003
|
+
}
|
|
5004
|
+
var import_zip2, ATLAS_SIZE, GLYPH_HEIGHT, UnihexAtlas, atlases;
|
|
5005
|
+
var init_Unihex = __esm({
|
|
5006
|
+
"src/assets/_fonts/Unihex.ts"() {
|
|
5007
|
+
import_zip2 = require("@zip.js/zip.js");
|
|
5008
|
+
init_AssetKey();
|
|
5009
|
+
init_AssetLoader();
|
|
5010
|
+
init_Assets();
|
|
5011
|
+
init_Caching();
|
|
5012
|
+
init_AssetParsers();
|
|
5013
|
+
init_CanvasCompat();
|
|
5014
|
+
ATLAS_SIZE = 512;
|
|
5015
|
+
GLYPH_HEIGHT = 16;
|
|
5016
|
+
UnihexAtlas = class {
|
|
5017
|
+
constructor() {
|
|
5018
|
+
this.x = 0;
|
|
5019
|
+
this.y = 0;
|
|
5020
|
+
}
|
|
5021
|
+
draw(glyph) {
|
|
5022
|
+
const width = glyph.right - glyph.left + 1;
|
|
5023
|
+
if (this.image && this.x + width > this.image.width) {
|
|
5024
|
+
this.x = 0;
|
|
5025
|
+
this.y += GLYPH_HEIGHT;
|
|
5026
|
+
}
|
|
5027
|
+
if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {
|
|
5028
|
+
this.image = createCanvas2(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);
|
|
5029
|
+
this.x = 0;
|
|
5030
|
+
this.y = 0;
|
|
5031
|
+
}
|
|
5032
|
+
const context = this.image.getContext("2d");
|
|
5033
|
+
const pixels = context.createImageData(width, GLYPH_HEIGHT);
|
|
5034
|
+
for (let y = 0; y < GLYPH_HEIGHT; y++) {
|
|
5035
|
+
for (let x = 0; x < width; x++) {
|
|
5036
|
+
const column = glyph.left + x;
|
|
5037
|
+
if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> glyph.bitWidth - column - 1 & 1)) continue;
|
|
5038
|
+
pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);
|
|
5039
|
+
}
|
|
5040
|
+
}
|
|
5041
|
+
const result = { image: this.image, x: this.x, y: this.y };
|
|
5042
|
+
context.putImageData(pixels, this.x, this.y);
|
|
5043
|
+
this.x += width;
|
|
5044
|
+
return result;
|
|
5045
|
+
}
|
|
5046
|
+
};
|
|
5047
|
+
atlases = /* @__PURE__ */ new WeakMap();
|
|
5048
|
+
}
|
|
5049
|
+
});
|
|
5050
|
+
|
|
4861
5051
|
// src/assets/Fonts.ts
|
|
4862
5052
|
var Fonts;
|
|
4863
5053
|
var init_Fonts = __esm({
|
|
@@ -4868,7 +5058,7 @@ var init_Fonts = __esm({
|
|
|
4868
5058
|
init_ModelTextures();
|
|
4869
5059
|
init_Caching();
|
|
4870
5060
|
Fonts = class {
|
|
4871
|
-
/** Combines font definitions in source-priority order.
|
|
5061
|
+
/** Combines font definitions in source-priority order. TrueType providers are skipped. */
|
|
4872
5062
|
static async get(key = "minecraft:default") {
|
|
4873
5063
|
const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
|
|
4874
5064
|
return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
|
|
@@ -4884,6 +5074,7 @@ var init_Fonts = __esm({
|
|
|
4884
5074
|
const stack = await AssetLoader.getAll(key, "json" /* JSON */);
|
|
4885
5075
|
if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
|
|
4886
5076
|
const glyphs = /* @__PURE__ */ new Map();
|
|
5077
|
+
const providers = [];
|
|
4887
5078
|
for (const asset2 of stack) {
|
|
4888
5079
|
for (const provider of asset2.providers) {
|
|
4889
5080
|
if (provider.filter?.uniform || provider.filter?.jp) continue;
|
|
@@ -4902,17 +5093,43 @@ var init_Fonts = __esm({
|
|
|
4902
5093
|
break;
|
|
4903
5094
|
case "reference":
|
|
4904
5095
|
case "minecraft:reference":
|
|
4905
|
-
|
|
5096
|
+
const reference = await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized]);
|
|
5097
|
+
if (reference.resolve) {
|
|
5098
|
+
providers.push(async (characters) => {
|
|
5099
|
+
await reference.resolve(characters);
|
|
5100
|
+
return reference.glyphs;
|
|
5101
|
+
});
|
|
5102
|
+
continue;
|
|
5103
|
+
}
|
|
5104
|
+
provided = reference.glyphs;
|
|
4906
5105
|
break;
|
|
5106
|
+
case "unihex":
|
|
5107
|
+
case "minecraft:unihex":
|
|
5108
|
+
providers.push(async (characters) => (await Promise.resolve().then(() => (init_Unihex(), Unihex_exports))).loadUnihex(provider, key, characters));
|
|
5109
|
+
continue;
|
|
4907
5110
|
default:
|
|
4908
5111
|
continue;
|
|
4909
5112
|
}
|
|
4910
|
-
for (const [character, glyph] of provided) {
|
|
5113
|
+
if (providers.every((provider2) => provider2 instanceof Map)) for (const [character, glyph] of provided) {
|
|
4911
5114
|
if (character !== "\0" && !glyphs.has(character)) glyphs.set(character, glyph);
|
|
4912
5115
|
}
|
|
5116
|
+
providers.push(provided);
|
|
5117
|
+
}
|
|
5118
|
+
}
|
|
5119
|
+
return { glyphs, resolve: providers.every((provider) => provider instanceof Map) ? void 0 : async (characters) => {
|
|
5120
|
+
const remaining = new Set([...characters].filter((character) => character !== "\0" && character !== "\n" && character !== "\r" && !glyphs.has(character)));
|
|
5121
|
+
for (const provider of providers) {
|
|
5122
|
+
if (!remaining.size) break;
|
|
5123
|
+
const provided = provider instanceof Map ? provider : await provider([...remaining].join(""));
|
|
5124
|
+
for (const character of remaining) {
|
|
5125
|
+
const glyph = provided.get(character);
|
|
5126
|
+
if (glyph) {
|
|
5127
|
+
glyphs.set(character, glyph);
|
|
5128
|
+
remaining.delete(character);
|
|
5129
|
+
}
|
|
5130
|
+
}
|
|
4913
5131
|
}
|
|
4914
|
-
}
|
|
4915
|
-
return { glyphs };
|
|
5132
|
+
} };
|
|
4916
5133
|
}
|
|
4917
5134
|
static async bitmap(provider, fontKey) {
|
|
4918
5135
|
const rows = provider.chars.map((row) => [...row]);
|
|
@@ -5005,6 +5222,13 @@ var init_EntityAnimation = __esm({
|
|
|
5005
5222
|
});
|
|
5006
5223
|
|
|
5007
5224
|
// src/entity/scene/EntityAnimationPlayer.ts
|
|
5225
|
+
function validateAnimationWeights(weights, count) {
|
|
5226
|
+
const values = Array.from(weights);
|
|
5227
|
+
if (values.length !== count || values.some((weight) => !Number.isFinite(weight) || weight < 0)) {
|
|
5228
|
+
throw new Error("Animation weights must match the clip count and contain only finite nonnegative numbers");
|
|
5229
|
+
}
|
|
5230
|
+
return values;
|
|
5231
|
+
}
|
|
5008
5232
|
var import_three11, ZERO, EntityAnimationPlayer;
|
|
5009
5233
|
var init_EntityAnimationPlayer = __esm({
|
|
5010
5234
|
"src/entity/scene/EntityAnimationPlayer.ts"() {
|
|
@@ -5014,12 +5238,20 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5014
5238
|
EntityAnimationPlayer = class {
|
|
5015
5239
|
constructor() {
|
|
5016
5240
|
this.parts = [];
|
|
5241
|
+
this._animations = [];
|
|
5242
|
+
this._weights = [];
|
|
5243
|
+
this.loops = [];
|
|
5017
5244
|
this._time = 0;
|
|
5018
|
-
this.loop = false;
|
|
5019
5245
|
this.speed = 1;
|
|
5020
5246
|
}
|
|
5021
5247
|
get animation() {
|
|
5022
|
-
return this.
|
|
5248
|
+
return this._animations[0];
|
|
5249
|
+
}
|
|
5250
|
+
get animations() {
|
|
5251
|
+
return this._animations.slice();
|
|
5252
|
+
}
|
|
5253
|
+
get weights() {
|
|
5254
|
+
return this._weights.slice();
|
|
5023
5255
|
}
|
|
5024
5256
|
get time() {
|
|
5025
5257
|
return this._time;
|
|
@@ -5029,10 +5261,20 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5029
5261
|
* without them, the current pose is used. Stopping restores the pose from before playback.
|
|
5030
5262
|
*/
|
|
5031
5263
|
play(layers, animation, options = {}, poses) {
|
|
5264
|
+
this.playAnimations(layers, [animation], options, poses);
|
|
5265
|
+
}
|
|
5266
|
+
/**
|
|
5267
|
+
* Starts clips on matching parts with a shared clock. Weighted offsets add to the supplied baked poses
|
|
5268
|
+
* or, without poses, to each animated part's pose when playback starts.
|
|
5269
|
+
*/
|
|
5270
|
+
playAnimations(layers, animations, options = {}, poses) {
|
|
5271
|
+
const weights = validateAnimationWeights(options.weights ?? animations.map(() => 1), animations.length);
|
|
5032
5272
|
this.stop();
|
|
5033
|
-
this.
|
|
5273
|
+
this._animations = animations.slice();
|
|
5274
|
+
this._weights = weights;
|
|
5275
|
+
if (!animations.length) return;
|
|
5034
5276
|
this._time = options.time ?? 0;
|
|
5035
|
-
this.
|
|
5277
|
+
this.loops = animations.map((animation) => options.loop ?? animation.loop);
|
|
5036
5278
|
this.speed = options.speed ?? 1;
|
|
5037
5279
|
for (const layer of layers) {
|
|
5038
5280
|
const objects = [];
|
|
@@ -5041,7 +5283,8 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5041
5283
|
if (poses.has(object4)) objects.push(object4);
|
|
5042
5284
|
});
|
|
5043
5285
|
} else {
|
|
5044
|
-
|
|
5286
|
+
const bones = new Set(animations.flatMap((animation) => Object.keys(animation.bones)));
|
|
5287
|
+
for (const bone of bones) {
|
|
5045
5288
|
const object4 = layer.getObjectByName(`group:${bone}`);
|
|
5046
5289
|
if (object4) objects.push(object4);
|
|
5047
5290
|
}
|
|
@@ -5065,7 +5308,7 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5065
5308
|
}
|
|
5066
5309
|
/** Restores the poses from before playback. Returns whether an animation was active. */
|
|
5067
5310
|
stop() {
|
|
5068
|
-
if (!this.
|
|
5311
|
+
if (!this._animations.length) return false;
|
|
5069
5312
|
for (const part of this.parts) {
|
|
5070
5313
|
part.object.position.copy(part.position);
|
|
5071
5314
|
part.object.rotation.copy(part.rotation);
|
|
@@ -5077,12 +5320,14 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5077
5320
|
/** Forgets the animation without touching the parts, for parts that no longer exist. */
|
|
5078
5321
|
clear() {
|
|
5079
5322
|
this.parts = [];
|
|
5080
|
-
this.
|
|
5323
|
+
this._animations = [];
|
|
5324
|
+
this._weights = [];
|
|
5325
|
+
this.loops = [];
|
|
5081
5326
|
this._time = 0;
|
|
5082
5327
|
}
|
|
5083
5328
|
/** Applies the pose at an absolute playback time. Returns `false` when no clip is active. */
|
|
5084
5329
|
setTime(seconds) {
|
|
5085
|
-
if (!this.
|
|
5330
|
+
if (!this._animations.length) return false;
|
|
5086
5331
|
this._time = seconds;
|
|
5087
5332
|
this.apply();
|
|
5088
5333
|
return true;
|
|
@@ -5091,8 +5336,30 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5091
5336
|
advance(deltaSeconds) {
|
|
5092
5337
|
return this.setTime(this._time + deltaSeconds * this.speed);
|
|
5093
5338
|
}
|
|
5339
|
+
/** Changes weights in clip order and reapplies the current time without restarting playback. */
|
|
5340
|
+
setWeights(weights) {
|
|
5341
|
+
if (!this._animations.length) return false;
|
|
5342
|
+
const validated = validateAnimationWeights(weights, this._animations.length);
|
|
5343
|
+
this._weights = validated;
|
|
5344
|
+
this.apply();
|
|
5345
|
+
return true;
|
|
5346
|
+
}
|
|
5094
5347
|
apply() {
|
|
5095
|
-
const pose =
|
|
5348
|
+
const pose = /* @__PURE__ */ Object.create(null);
|
|
5349
|
+
for (let i = 0; i < this._animations.length; i++) {
|
|
5350
|
+
const weight = this._weights[i];
|
|
5351
|
+
if (weight === 0) continue;
|
|
5352
|
+
const sampled = sampleEntityAnimation(this._animations[i], this._time, this.loops[i]);
|
|
5353
|
+
for (const [bone, channels] of Object.entries(sampled)) {
|
|
5354
|
+
const blended = pose[bone] ??= {};
|
|
5355
|
+
for (const channel of ENTITY_ANIMATION_CHANNELS) {
|
|
5356
|
+
const value = channels[channel];
|
|
5357
|
+
if (!value) continue;
|
|
5358
|
+
const target = blended[channel] ??= [0, 0, 0];
|
|
5359
|
+
for (let axis = 0; axis < 3; axis++) target[axis] += value[axis] * weight;
|
|
5360
|
+
}
|
|
5361
|
+
}
|
|
5362
|
+
}
|
|
5096
5363
|
for (const part of this.parts) {
|
|
5097
5364
|
const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone] ?? {};
|
|
5098
5365
|
part.object.position.set(part.basePosition.x + position[0], part.basePosition.y + position[1], part.basePosition.z + position[2]);
|
|
@@ -5716,7 +5983,7 @@ var init_EntityObject = __esm({
|
|
|
5716
5983
|
for (const geometry of this.geometries) geometry.dispose();
|
|
5717
5984
|
this.geometries.clear();
|
|
5718
5985
|
for (const dispose of this.disposeWireframes.splice(0)) dispose();
|
|
5719
|
-
for (const player of this.animationPlayers.splice(0)) player.clear();
|
|
5986
|
+
for (const { player } of this.animationPlayers.splice(0)) player.clear();
|
|
5720
5987
|
this.partPoses.clear();
|
|
5721
5988
|
super.disposeAndRemoveAllChildren();
|
|
5722
5989
|
}
|
|
@@ -5751,15 +6018,31 @@ var init_EntityObject = __esm({
|
|
|
5751
6018
|
//<editor-fold desc="ANIMATION">
|
|
5752
6019
|
/** The first active clip, until playback is stopped or the object is disposed. */
|
|
5753
6020
|
get animation() {
|
|
5754
|
-
return this.animationPlayers[0]?.animation;
|
|
6021
|
+
return this.animationPlayers[0]?.player.animation;
|
|
5755
6022
|
}
|
|
5756
|
-
/** Clips playing together,
|
|
6023
|
+
/** Clips playing together, in the order passed to {@link playAnimations}. */
|
|
5757
6024
|
get activeAnimations() {
|
|
5758
|
-
|
|
6025
|
+
const animations = [];
|
|
6026
|
+
for (const { player, indices } of this.animationPlayers) {
|
|
6027
|
+
player.animations.forEach((animation, i) => {
|
|
6028
|
+
animations[indices[i]] = animation;
|
|
6029
|
+
});
|
|
6030
|
+
}
|
|
6031
|
+
return animations;
|
|
6032
|
+
}
|
|
6033
|
+
/** Weights of the active clips, in the same order as {@link activeAnimations}. */
|
|
6034
|
+
get animationWeights() {
|
|
6035
|
+
const weights = [];
|
|
6036
|
+
for (const { player, indices } of this.animationPlayers) {
|
|
6037
|
+
player.weights.forEach((weight, i) => {
|
|
6038
|
+
weights[indices[i]] = weight;
|
|
6039
|
+
});
|
|
6040
|
+
}
|
|
6041
|
+
return weights;
|
|
5759
6042
|
}
|
|
5760
6043
|
/** Seconds since the animation started, before looping. */
|
|
5761
6044
|
get animationTime() {
|
|
5762
|
-
return this.animationPlayers[0]?.time ?? 0;
|
|
6045
|
+
return this.animationPlayers[0]?.player.time ?? 0;
|
|
5763
6046
|
}
|
|
5764
6047
|
/**
|
|
5765
6048
|
* Plays a clip from {@link Entities.getAnimations}, replacing all active clips.
|
|
@@ -5770,42 +6053,59 @@ var init_EntityObject = __esm({
|
|
|
5770
6053
|
playAnimation(animation, options) {
|
|
5771
6054
|
this.playAnimations([animation], options);
|
|
5772
6055
|
}
|
|
5773
|
-
/**
|
|
6056
|
+
/**
|
|
6057
|
+
* Plays clips with a shared clock, adding their weighted offsets within each geometry layer.
|
|
6058
|
+
* Weights default to 1 and are not normalized. Selected layers without their own clip follow `main`.
|
|
6059
|
+
*/
|
|
5774
6060
|
playAnimations(animations, options) {
|
|
5775
|
-
const
|
|
5776
|
-
const selections =
|
|
6061
|
+
const weights = validateAnimationWeights(options?.weights ?? animations.map(() => 1), animations.length);
|
|
6062
|
+
const selections = /* @__PURE__ */ new Map();
|
|
6063
|
+
animations.forEach((animation, index) => {
|
|
5777
6064
|
const layer = animation.layer ?? "main";
|
|
5778
|
-
if (targets.has(layer)) throw new Error(`Multiple animations target layer "${layer}"`);
|
|
5779
|
-
targets.add(layer);
|
|
5780
6065
|
const names = Object.keys(this.entityLayers).filter((name) => name.split("#")[0] === layer);
|
|
5781
6066
|
if (!names.length) throw new Error(`Entity ${this.entity.id} has no selected animation layer "${layer}"`);
|
|
5782
|
-
|
|
6067
|
+
let selection = selections.get(layer);
|
|
6068
|
+
if (!selection) selections.set(layer, selection = { animations: [], names, indices: [] });
|
|
6069
|
+
selection.animations.push(animation);
|
|
6070
|
+
selection.indices.push(index);
|
|
5783
6071
|
});
|
|
5784
|
-
const main = selections.
|
|
5785
|
-
if (main) main.names.push(...Object.keys(this.entityLayers).filter((name) => !
|
|
6072
|
+
const main = selections.get("main");
|
|
6073
|
+
if (main) main.names.push(...Object.keys(this.entityLayers).filter((name) => !selections.has(name.split("#")[0])));
|
|
5786
6074
|
this.createMeshes();
|
|
5787
6075
|
this.stopAnimation();
|
|
5788
|
-
for (const {
|
|
6076
|
+
for (const { animations: clips, names, indices } of selections.values()) {
|
|
5789
6077
|
const player = new EntityAnimationPlayer();
|
|
5790
|
-
player.
|
|
5791
|
-
|
|
6078
|
+
player.playAnimations(
|
|
6079
|
+
names.map((name) => this.getLayerGroup(name)),
|
|
6080
|
+
clips,
|
|
6081
|
+
{ ...options, weights: indices.map((index) => weights[index]) },
|
|
6082
|
+
this.partPoses
|
|
6083
|
+
);
|
|
6084
|
+
this.animationPlayers.push({ player, indices });
|
|
5792
6085
|
}
|
|
5793
6086
|
this.notifyDirty();
|
|
5794
6087
|
}
|
|
6088
|
+
/** Changes weights in active clip order, notifying the scene without restarting the shared clock. Has no effect without an animation. */
|
|
6089
|
+
setAnimationWeights(weights) {
|
|
6090
|
+
if (!this.animationPlayers.length) return;
|
|
6091
|
+
const values = validateAnimationWeights(weights, this.activeAnimations.length);
|
|
6092
|
+
for (const { player, indices } of this.animationPlayers) player.setWeights(indices.map((index) => values[index]));
|
|
6093
|
+
this.notifyDirty();
|
|
6094
|
+
}
|
|
5795
6095
|
/** Stops all clips and restores the poses from before playback. */
|
|
5796
6096
|
stopAnimation() {
|
|
5797
6097
|
const players = this.animationPlayers.splice(0);
|
|
5798
|
-
for (const player of players) player.stop();
|
|
6098
|
+
for (const { player } of players) player.stop();
|
|
5799
6099
|
if (players.length) this.notifyDirty();
|
|
5800
6100
|
}
|
|
5801
6101
|
/** Poses the object at an explicit time in seconds. Has no effect without an animation. */
|
|
5802
6102
|
setAnimationTime(seconds) {
|
|
5803
|
-
for (const player of this.animationPlayers) player.setTime(seconds);
|
|
6103
|
+
for (const { player } of this.animationPlayers) player.setTime(seconds);
|
|
5804
6104
|
if (this.animationPlayers.length) this.notifyDirty();
|
|
5805
6105
|
}
|
|
5806
6106
|
/** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
|
|
5807
6107
|
advanceAnimation(deltaSeconds) {
|
|
5808
|
-
for (const player of this.animationPlayers) player.advance(deltaSeconds);
|
|
6108
|
+
for (const { player } of this.animationPlayers) player.advance(deltaSeconds);
|
|
5809
6109
|
if (this.animationPlayers.length) this.notifyDirty();
|
|
5810
6110
|
}
|
|
5811
6111
|
//</editor-fold>
|
|
@@ -8038,6 +8338,7 @@ async function layoutGuiText(text2, options = {}) {
|
|
|
8038
8338
|
}
|
|
8039
8339
|
const font = await Fonts.get(options.font);
|
|
8040
8340
|
const runs = typeof text2 === "string" ? [{ text: text2 }] : text2;
|
|
8341
|
+
await font.resolve?.(runs.map((run) => run.text).join(""));
|
|
8041
8342
|
const glyphs = [], lineWidths = [];
|
|
8042
8343
|
let line = [], width = 0;
|
|
8043
8344
|
let trailingNewline = false;
|
|
@@ -8064,7 +8365,7 @@ async function layoutGuiText(text2, options = {}) {
|
|
|
8064
8365
|
continue;
|
|
8065
8366
|
}
|
|
8066
8367
|
const glyph = font.glyphs.get(character);
|
|
8067
|
-
const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
|
|
8368
|
+
const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);
|
|
8068
8369
|
line.push({ character, glyph, advance, style, x: 0, y: 0 });
|
|
8069
8370
|
width += advance;
|
|
8070
8371
|
while (width > maxWidth && line.length > 1) {
|
|
@@ -8092,7 +8393,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8092
8393
|
batches.push(batch);
|
|
8093
8394
|
}
|
|
8094
8395
|
const color2 = new import_three20.Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
8095
|
-
const offset = isShadow ? 1 : 0;
|
|
8396
|
+
const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
|
|
8096
8397
|
const top = glyph ? 7 - glyph.ascent : 0;
|
|
8097
8398
|
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
8098
8399
|
const width = glyph ? glyph.width * glyph.scale : 5;
|
|
@@ -8122,7 +8423,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8122
8423
|
for (let i = 0; i < 4; i++) batch.colors.push(color2.r, color2.g, color2.b);
|
|
8123
8424
|
batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
|
|
8124
8425
|
};
|
|
8125
|
-
for (const boldOffset of style.bold ? [0, 1] : [0]) {
|
|
8426
|
+
for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {
|
|
8126
8427
|
if (glyph) quad(0, top, width, top + height, boldOffset);
|
|
8127
8428
|
else {
|
|
8128
8429
|
quad(0, 0, 5, 1, boldOffset);
|
|
@@ -11399,6 +11700,7 @@ __export(index_node_exports, {
|
|
|
11399
11700
|
toRadians: () => toRadians,
|
|
11400
11701
|
toTrianglesDrawMode: () => toTrianglesDrawMode,
|
|
11401
11702
|
trimCanvas: () => trimCanvas,
|
|
11703
|
+
validateAnimationWeights: () => validateAnimationWeights,
|
|
11402
11704
|
yieldToEventLoop: () => yieldToEventLoop
|
|
11403
11705
|
});
|
|
11404
11706
|
module.exports = __toCommonJS(index_node_exports);
|
|
@@ -18937,7 +19239,7 @@ var LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18];
|
|
|
18937
19239
|
|
|
18938
19240
|
// src/world/SectionGeometry.ts
|
|
18939
19241
|
function buildSectionGeometry(input) {
|
|
18940
|
-
const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
|
|
19242
|
+
const { count, indices, templates, cullMasks, templateData, atlases: atlases2, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
|
|
18941
19243
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
18942
19244
|
if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError("Section entry count exceeds its arrays");
|
|
18943
19245
|
if (biomeTints && biomeTints.length !== count * 3) throw new RangeError("Section biome tints must contain RGB for each placement");
|
|
@@ -18972,8 +19274,8 @@ function buildSectionGeometry(input) {
|
|
|
18972
19274
|
const locations = /* @__PURE__ */ new Map();
|
|
18973
19275
|
for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {
|
|
18974
19276
|
const firstPage = pages.length;
|
|
18975
|
-
for (const atlas of [...layerAtlases].sort((a, b) => Number(
|
|
18976
|
-
const { width, height, animated } =
|
|
19277
|
+
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))) {
|
|
19278
|
+
const { width, height, animated } = atlases2[atlas];
|
|
18977
19279
|
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
18978
19280
|
let selected = -1;
|
|
18979
19281
|
for (let i = firstPage; !animated && i < pages.length; i++) {
|
|
@@ -19016,7 +19318,7 @@ function buildSectionGeometry(input) {
|
|
|
19016
19318
|
});
|
|
19017
19319
|
if (!quads.sprites.length) continue;
|
|
19018
19320
|
if (!fluidPages.has(fluid)) {
|
|
19019
|
-
const { width, height } =
|
|
19321
|
+
const { width, height } = atlases2[data.atlas];
|
|
19020
19322
|
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
19021
19323
|
fluidPages.set(fluid, {
|
|
19022
19324
|
layer: 2,
|
|
@@ -19034,7 +19336,7 @@ function buildSectionGeometry(input) {
|
|
|
19034
19336
|
const tint = fluid === "water" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;
|
|
19035
19337
|
fluidPages.get(fluid).fluids.push({ quads, x, y, z, data, tint });
|
|
19036
19338
|
}
|
|
19037
|
-
pages.push(...[...fluidPages.values()].sort((a, b) => Number(
|
|
19339
|
+
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));
|
|
19038
19340
|
}
|
|
19039
19341
|
return pages.map((page) => {
|
|
19040
19342
|
let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);
|
|
@@ -19051,7 +19353,7 @@ function buildSectionGeometry(input) {
|
|
|
19051
19353
|
let vertex = 0, indexOffset = 0;
|
|
19052
19354
|
for (const entry of page.entries) {
|
|
19053
19355
|
const template = templateData[templates[entry]];
|
|
19054
|
-
const atlas =
|
|
19356
|
+
const atlas = atlases2[template.atlas];
|
|
19055
19357
|
const placement = locations.get(template.atlas);
|
|
19056
19358
|
const mapU = (u) => (placement.x + u * atlas.width) / page.width;
|
|
19057
19359
|
const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
|
|
@@ -19090,7 +19392,7 @@ function buildSectionGeometry(input) {
|
|
|
19090
19392
|
}
|
|
19091
19393
|
}
|
|
19092
19394
|
for (const { quads, x, y, z, data, tint } of page.fluids) {
|
|
19093
|
-
const atlas =
|
|
19395
|
+
const atlas = atlases2[data.atlas];
|
|
19094
19396
|
const placement = page.placements[0];
|
|
19095
19397
|
const mapU = (u) => (placement.x + u * atlas.width) / page.width;
|
|
19096
19398
|
const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
|
|
@@ -19192,7 +19494,7 @@ var templateCache = /* @__PURE__ */ new WeakMap();
|
|
|
19192
19494
|
var WATER_TINT = new import_three46.Color(4159204).toArray();
|
|
19193
19495
|
function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
19194
19496
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
19195
|
-
const
|
|
19497
|
+
const atlases2 = [];
|
|
19196
19498
|
const atlasIds = /* @__PURE__ */ new Map();
|
|
19197
19499
|
const templateIds = /* @__PURE__ */ new Map();
|
|
19198
19500
|
const input = {
|
|
@@ -19215,9 +19517,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19215
19517
|
if (id === void 0) {
|
|
19216
19518
|
let atlas = atlasIds.get(template.atlas);
|
|
19217
19519
|
if (atlas === void 0) {
|
|
19218
|
-
atlas =
|
|
19520
|
+
atlas = atlases2.length;
|
|
19219
19521
|
atlasIds.set(template.atlas, atlas);
|
|
19220
|
-
|
|
19522
|
+
atlases2.push(template.atlas);
|
|
19221
19523
|
input.atlases.push({ width: template.atlas.image.width, height: template.atlas.image.height, animated: template.atlas.hasAnimation });
|
|
19222
19524
|
}
|
|
19223
19525
|
let data = templateCache.get(template);
|
|
@@ -19276,9 +19578,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19276
19578
|
if (!atlas) continue;
|
|
19277
19579
|
let id = atlasIds.get(atlas);
|
|
19278
19580
|
if (id === void 0) {
|
|
19279
|
-
id =
|
|
19581
|
+
id = atlases2.length;
|
|
19280
19582
|
atlasIds.set(atlas, id);
|
|
19281
|
-
|
|
19583
|
+
atlases2.push(atlas);
|
|
19282
19584
|
input.atlases.push({ width: atlas.image.width, height: atlas.image.height, animated: atlas.hasAnimation });
|
|
19283
19585
|
}
|
|
19284
19586
|
input.fluids[kind] = {
|
|
@@ -19289,7 +19591,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19289
19591
|
};
|
|
19290
19592
|
}
|
|
19291
19593
|
}
|
|
19292
|
-
return { input, atlases };
|
|
19594
|
+
return { input, atlases: atlases2 };
|
|
19293
19595
|
}
|
|
19294
19596
|
var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
19295
19597
|
constructor() {
|
|
@@ -19304,23 +19606,23 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19304
19606
|
}
|
|
19305
19607
|
/** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
19306
19608
|
static build(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
19307
|
-
const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19308
|
-
return this.fromPages(buildSectionGeometry(input),
|
|
19609
|
+
const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19610
|
+
return this.fromPages(buildSectionGeometry(input), atlases2);
|
|
19309
19611
|
}
|
|
19310
19612
|
/** Builds section-local meshes in a browser worker when available, with synchronous fallback. */
|
|
19311
19613
|
static async buildAsync(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
19312
|
-
const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19614
|
+
const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19313
19615
|
const worker = SectionWorker.shared();
|
|
19314
19616
|
const pages = worker ? await worker.build(input).catch(() => buildSectionGeometry(input)) : buildSectionGeometry(input);
|
|
19315
|
-
return this.fromPages(pages,
|
|
19617
|
+
return this.fromPages(pages, atlases2);
|
|
19316
19618
|
}
|
|
19317
|
-
static fromPages(pages,
|
|
19619
|
+
static fromPages(pages, atlases2) {
|
|
19318
19620
|
const section = new _SectionMesh();
|
|
19319
19621
|
for (const page of pages) {
|
|
19320
19622
|
const canvas = createCanvas2(page.width, page.height);
|
|
19321
19623
|
const context = canvas.getContext("2d");
|
|
19322
19624
|
for (const { atlas, x, y } of page.placements) {
|
|
19323
|
-
context.drawImage(
|
|
19625
|
+
context.drawImage(atlases2[atlas].image.canvas, x, y);
|
|
19324
19626
|
}
|
|
19325
19627
|
const geometry = new import_three46.BufferGeometry();
|
|
19326
19628
|
geometry.setAttribute("position", new import_three46.Float32BufferAttribute(page.positions.buffer, 3));
|
|
@@ -19331,7 +19633,7 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19331
19633
|
geometry.setIndex(new import_three46.Uint32BufferAttribute(page.indices.buffer, 1));
|
|
19332
19634
|
geometry.computeBoundingBox();
|
|
19333
19635
|
geometry.computeBoundingSphere();
|
|
19334
|
-
const transparent = page.layer === 2 ?
|
|
19636
|
+
const transparent = page.layer === 2 ? atlases2[page.placements[0].atlas].hasTranslucency : page.layer === 1;
|
|
19335
19637
|
const material = Materials.createShadedCanvasMaterial(canvas, transparent, false, true);
|
|
19336
19638
|
material.side = import_three46.FrontSide;
|
|
19337
19639
|
if (page.layer === 2) {
|
|
@@ -19346,7 +19648,7 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19346
19648
|
section.blockIndices.set(mesh, page.blockIndices);
|
|
19347
19649
|
const unsubscribe = [];
|
|
19348
19650
|
for (const { atlas: id, x, y } of page.placements) {
|
|
19349
|
-
const atlas =
|
|
19651
|
+
const atlas = atlases2[id];
|
|
19350
19652
|
if (!atlas.hasAnimation) continue;
|
|
19351
19653
|
unsubscribe.push(atlas.subscribe(() => {
|
|
19352
19654
|
context.clearRect(x, y, atlas.image.width, atlas.image.height);
|
|
@@ -20690,6 +20992,7 @@ var NodeRenderer = class _NodeRenderer extends Renderer {
|
|
|
20690
20992
|
toRadians,
|
|
20691
20993
|
toTrianglesDrawMode,
|
|
20692
20994
|
trimCanvas,
|
|
20995
|
+
validateAnimationWeights,
|
|
20693
20996
|
yieldToEventLoop
|
|
20694
20997
|
});
|
|
20695
20998
|
//# sourceMappingURL=index.js.map
|