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.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,
|
|
@@ -1408,6 +1412,7 @@ var init_AssetParsers = __esm({
|
|
|
1408
1412
|
AssetParser2["IMAGE"] = "image";
|
|
1409
1413
|
AssetParser2["LIST"] = "list";
|
|
1410
1414
|
AssetParser2["JSON"] = "json";
|
|
1415
|
+
AssetParser2["BINARY"] = "binary";
|
|
1411
1416
|
return AssetParser2;
|
|
1412
1417
|
})(AssetParser || {});
|
|
1413
1418
|
}
|
|
@@ -2878,7 +2883,7 @@ var init_parser = __esm({
|
|
|
2878
2883
|
});
|
|
2879
2884
|
|
|
2880
2885
|
// src/assets/source/HostedAssetSource.ts
|
|
2881
|
-
var p3, DEFAULT_OPTIONS, HostedAssetSource;
|
|
2886
|
+
var BINARY_TIMEOUT, p3, DEFAULT_OPTIONS, HostedAssetSource;
|
|
2882
2887
|
var init_HostedAssetSource = __esm({
|
|
2883
2888
|
"src/assets/source/HostedAssetSource.ts"() {
|
|
2884
2889
|
init_AssetSource();
|
|
@@ -2891,6 +2896,7 @@ var init_HostedAssetSource = __esm({
|
|
|
2891
2896
|
init_AssetLoader();
|
|
2892
2897
|
init_parser();
|
|
2893
2898
|
init_merge();
|
|
2899
|
+
BINARY_TIMEOUT = 6e4;
|
|
2894
2900
|
p3 = prefix("HostedAssetSource");
|
|
2895
2901
|
DEFAULT_OPTIONS = {
|
|
2896
2902
|
retryDefaults: true
|
|
@@ -2961,6 +2967,17 @@ var init_HostedAssetSource = __esm({
|
|
|
2961
2967
|
}
|
|
2962
2968
|
};
|
|
2963
2969
|
}
|
|
2970
|
+
static {
|
|
2971
|
+
this.BINARY = {
|
|
2972
|
+
config(request) {
|
|
2973
|
+
request.timeout = BINARY_TIMEOUT;
|
|
2974
|
+
request.responseType = "arraybuffer";
|
|
2975
|
+
},
|
|
2976
|
+
parse(response) {
|
|
2977
|
+
return { data: new Uint8Array(response.data) };
|
|
2978
|
+
}
|
|
2979
|
+
};
|
|
2980
|
+
}
|
|
2964
2981
|
static {
|
|
2965
2982
|
this.PARSER_MAP = /* @__PURE__ */ new Map([
|
|
2966
2983
|
["model" /* MODEL */, _HostedAssetSource.MODEL],
|
|
@@ -2969,7 +2986,8 @@ var init_HostedAssetSource = __esm({
|
|
|
2969
2986
|
["nbt" /* NBT */, _HostedAssetSource.NBT],
|
|
2970
2987
|
["image" /* IMAGE */, _HostedAssetSource.IMAGE],
|
|
2971
2988
|
["list" /* LIST */, _HostedAssetSource.LIST],
|
|
2972
|
-
["json" /* JSON */, _HostedAssetSource.JSON]
|
|
2989
|
+
["json" /* JSON */, _HostedAssetSource.JSON],
|
|
2990
|
+
["binary" /* BINARY */, _HostedAssetSource.BINARY]
|
|
2973
2991
|
]);
|
|
2974
2992
|
}
|
|
2975
2993
|
/** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */
|
|
@@ -4855,6 +4873,178 @@ var init_Entities = __esm({
|
|
|
4855
4873
|
}
|
|
4856
4874
|
});
|
|
4857
4875
|
|
|
4876
|
+
// src/assets/_fonts/Unihex.ts
|
|
4877
|
+
var Unihex_exports = {};
|
|
4878
|
+
__export(Unihex_exports, {
|
|
4879
|
+
loadUnihex: () => loadUnihex
|
|
4880
|
+
});
|
|
4881
|
+
import { TextWriter, Uint8ArrayReader, ZipReader as ZipReader2 } from "@zip.js/zip.js";
|
|
4882
|
+
function readHex(text2, filename, glyphs) {
|
|
4883
|
+
const lines = text2.split("\n");
|
|
4884
|
+
if (lines[lines.length - 1] === "") lines.pop();
|
|
4885
|
+
lines.forEach((line, index) => {
|
|
4886
|
+
const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);
|
|
4887
|
+
if (!match || ![32, 64, 96, 128].includes(match[2].length)) {
|
|
4888
|
+
throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);
|
|
4889
|
+
}
|
|
4890
|
+
const codepoint = parseInt(match[1], 16);
|
|
4891
|
+
if (codepoint > 1114111) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);
|
|
4892
|
+
const bitWidth = match[2].length / 4;
|
|
4893
|
+
const rowLength = bitWidth / 4;
|
|
4894
|
+
const rows = new Uint32Array(GLYPH_HEIGHT);
|
|
4895
|
+
let mask = 0;
|
|
4896
|
+
for (let y = 0; y < GLYPH_HEIGHT; y++) {
|
|
4897
|
+
rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);
|
|
4898
|
+
mask |= rows[y];
|
|
4899
|
+
}
|
|
4900
|
+
let left = 0, right = bitWidth;
|
|
4901
|
+
if (mask) {
|
|
4902
|
+
while (!(mask >>> bitWidth - left - 1 & 1)) left++;
|
|
4903
|
+
right = bitWidth - 1;
|
|
4904
|
+
while (!(mask >>> bitWidth - right - 1 & 1)) right--;
|
|
4905
|
+
}
|
|
4906
|
+
glyphs.set(codepoint, { rows, bitWidth, left, right });
|
|
4907
|
+
});
|
|
4908
|
+
}
|
|
4909
|
+
async function parseUnihex(key) {
|
|
4910
|
+
try {
|
|
4911
|
+
const asset2 = await AssetLoader.get(key, "binary" /* BINARY */);
|
|
4912
|
+
if (!asset2) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);
|
|
4913
|
+
const records = /* @__PURE__ */ new Map();
|
|
4914
|
+
const reader = new ZipReader2(new Uint8ArrayReader(asset2.data), { useWebWorkers: false, useCompressionStream: false });
|
|
4915
|
+
try {
|
|
4916
|
+
for (const entry of await reader.getEntries()) {
|
|
4917
|
+
if (!entry.directory && entry.filename.endsWith(".hex")) {
|
|
4918
|
+
readHex(await entry.getData(new TextWriter(), { checkSignature: true }), entry.filename, records);
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
} finally {
|
|
4922
|
+
await reader.close();
|
|
4923
|
+
}
|
|
4924
|
+
const indices = new Int32Array(1114112).fill(-1);
|
|
4925
|
+
const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);
|
|
4926
|
+
let index = 0;
|
|
4927
|
+
for (const [codepoint, record] of records) {
|
|
4928
|
+
indices[codepoint] = index;
|
|
4929
|
+
rows.set(record.rows, index * GLYPH_HEIGHT);
|
|
4930
|
+
metrics.set([record.bitWidth, record.left, record.right], index * 3);
|
|
4931
|
+
index++;
|
|
4932
|
+
}
|
|
4933
|
+
return { indices, rows, metrics };
|
|
4934
|
+
} catch (error) {
|
|
4935
|
+
console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4936
|
+
return void 0;
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
async function loadUnihex(provider, fontKey, characters) {
|
|
4940
|
+
const origin = new AssetKey(DEFAULT_NAMESPACE, "", void 0, void 0, "assets", "", fontKey.root);
|
|
4941
|
+
const key = AssetKey.parse("font", provider.hex_file, origin);
|
|
4942
|
+
key.assetType = void 0;
|
|
4943
|
+
const glyphs = /* @__PURE__ */ new Map();
|
|
4944
|
+
let overrides;
|
|
4945
|
+
try {
|
|
4946
|
+
overrides = (provider.size_overrides ?? []).map((override) => {
|
|
4947
|
+
const from = override.from.codePointAt(0), to = override.to.codePointAt(0);
|
|
4948
|
+
if ([...override.from].length !== 1 || [...override.to].length !== 1 || from >= to || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {
|
|
4949
|
+
throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);
|
|
4950
|
+
}
|
|
4951
|
+
return { ...override, from, to };
|
|
4952
|
+
});
|
|
4953
|
+
} catch (error) {
|
|
4954
|
+
console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
4955
|
+
return glyphs;
|
|
4956
|
+
}
|
|
4957
|
+
const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
|
|
4958
|
+
if (!file) return glyphs;
|
|
4959
|
+
let atlas = atlases.get(provider);
|
|
4960
|
+
if (!atlas) {
|
|
4961
|
+
atlas = new UnihexAtlas();
|
|
4962
|
+
atlases.set(provider, atlas);
|
|
4963
|
+
}
|
|
4964
|
+
for (const character of characters) {
|
|
4965
|
+
const codepoint = character.codePointAt(0), index = file.indices[codepoint];
|
|
4966
|
+
if (index < 0) continue;
|
|
4967
|
+
const record = {
|
|
4968
|
+
rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),
|
|
4969
|
+
bitWidth: file.metrics[index * 3],
|
|
4970
|
+
left: file.metrics[index * 3 + 1],
|
|
4971
|
+
right: file.metrics[index * 3 + 2]
|
|
4972
|
+
};
|
|
4973
|
+
const override = overrides.find((range) => codepoint >= range.from && codepoint <= range.to);
|
|
4974
|
+
if (override) {
|
|
4975
|
+
record.left = override.left;
|
|
4976
|
+
record.right = override.right;
|
|
4977
|
+
}
|
|
4978
|
+
const width = record.right - record.left + 1;
|
|
4979
|
+
let rendered;
|
|
4980
|
+
const render = () => rendered ??= atlas.draw(record);
|
|
4981
|
+
glyphs.set(character, {
|
|
4982
|
+
get image() {
|
|
4983
|
+
return render().image;
|
|
4984
|
+
},
|
|
4985
|
+
get x() {
|
|
4986
|
+
return render().x;
|
|
4987
|
+
},
|
|
4988
|
+
get y() {
|
|
4989
|
+
return render().y;
|
|
4990
|
+
},
|
|
4991
|
+
width,
|
|
4992
|
+
height: GLYPH_HEIGHT,
|
|
4993
|
+
scale: 0.5,
|
|
4994
|
+
ascent: 7,
|
|
4995
|
+
advance: Math.floor(width / 2) + 1,
|
|
4996
|
+
boldOffset: 0.5,
|
|
4997
|
+
shadowOffset: 0.5
|
|
4998
|
+
});
|
|
4999
|
+
}
|
|
5000
|
+
return glyphs;
|
|
5001
|
+
}
|
|
5002
|
+
var ATLAS_SIZE, GLYPH_HEIGHT, UnihexAtlas, atlases;
|
|
5003
|
+
var init_Unihex = __esm({
|
|
5004
|
+
"src/assets/_fonts/Unihex.ts"() {
|
|
5005
|
+
init_AssetKey();
|
|
5006
|
+
init_AssetLoader();
|
|
5007
|
+
init_Assets();
|
|
5008
|
+
init_Caching();
|
|
5009
|
+
init_AssetParsers();
|
|
5010
|
+
init_CanvasCompat();
|
|
5011
|
+
ATLAS_SIZE = 512;
|
|
5012
|
+
GLYPH_HEIGHT = 16;
|
|
5013
|
+
UnihexAtlas = class {
|
|
5014
|
+
constructor() {
|
|
5015
|
+
this.x = 0;
|
|
5016
|
+
this.y = 0;
|
|
5017
|
+
}
|
|
5018
|
+
draw(glyph) {
|
|
5019
|
+
const width = glyph.right - glyph.left + 1;
|
|
5020
|
+
if (this.image && this.x + width > this.image.width) {
|
|
5021
|
+
this.x = 0;
|
|
5022
|
+
this.y += GLYPH_HEIGHT;
|
|
5023
|
+
}
|
|
5024
|
+
if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {
|
|
5025
|
+
this.image = createCanvas2(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);
|
|
5026
|
+
this.x = 0;
|
|
5027
|
+
this.y = 0;
|
|
5028
|
+
}
|
|
5029
|
+
const context = this.image.getContext("2d");
|
|
5030
|
+
const pixels = context.createImageData(width, GLYPH_HEIGHT);
|
|
5031
|
+
for (let y = 0; y < GLYPH_HEIGHT; y++) {
|
|
5032
|
+
for (let x = 0; x < width; x++) {
|
|
5033
|
+
const column = glyph.left + x;
|
|
5034
|
+
if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> glyph.bitWidth - column - 1 & 1)) continue;
|
|
5035
|
+
pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);
|
|
5036
|
+
}
|
|
5037
|
+
}
|
|
5038
|
+
const result = { image: this.image, x: this.x, y: this.y };
|
|
5039
|
+
context.putImageData(pixels, this.x, this.y);
|
|
5040
|
+
this.x += width;
|
|
5041
|
+
return result;
|
|
5042
|
+
}
|
|
5043
|
+
};
|
|
5044
|
+
atlases = /* @__PURE__ */ new WeakMap();
|
|
5045
|
+
}
|
|
5046
|
+
});
|
|
5047
|
+
|
|
4858
5048
|
// src/assets/Fonts.ts
|
|
4859
5049
|
var Fonts;
|
|
4860
5050
|
var init_Fonts = __esm({
|
|
@@ -4865,7 +5055,7 @@ var init_Fonts = __esm({
|
|
|
4865
5055
|
init_ModelTextures();
|
|
4866
5056
|
init_Caching();
|
|
4867
5057
|
Fonts = class {
|
|
4868
|
-
/** Combines font definitions in source-priority order.
|
|
5058
|
+
/** Combines font definitions in source-priority order. TrueType providers are skipped. */
|
|
4869
5059
|
static async get(key = "minecraft:default") {
|
|
4870
5060
|
const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
|
|
4871
5061
|
return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
|
|
@@ -4881,6 +5071,7 @@ var init_Fonts = __esm({
|
|
|
4881
5071
|
const stack = await AssetLoader.getAll(key, "json" /* JSON */);
|
|
4882
5072
|
if (stack.length === 0) throw new Error(`Could not load font ${key.toNamespacedString()}`);
|
|
4883
5073
|
const glyphs = /* @__PURE__ */ new Map();
|
|
5074
|
+
const providers = [];
|
|
4884
5075
|
for (const asset2 of stack) {
|
|
4885
5076
|
for (const provider of asset2.providers) {
|
|
4886
5077
|
if (provider.filter?.uniform || provider.filter?.jp) continue;
|
|
@@ -4899,17 +5090,43 @@ var init_Fonts = __esm({
|
|
|
4899
5090
|
break;
|
|
4900
5091
|
case "reference":
|
|
4901
5092
|
case "minecraft:reference":
|
|
4902
|
-
|
|
5093
|
+
const reference = await this.load(this.relatedKey("font", provider.id, key), [...parents, serialized]);
|
|
5094
|
+
if (reference.resolve) {
|
|
5095
|
+
providers.push(async (characters) => {
|
|
5096
|
+
await reference.resolve(characters);
|
|
5097
|
+
return reference.glyphs;
|
|
5098
|
+
});
|
|
5099
|
+
continue;
|
|
5100
|
+
}
|
|
5101
|
+
provided = reference.glyphs;
|
|
4903
5102
|
break;
|
|
5103
|
+
case "unihex":
|
|
5104
|
+
case "minecraft:unihex":
|
|
5105
|
+
providers.push(async (characters) => (await Promise.resolve().then(() => (init_Unihex(), Unihex_exports))).loadUnihex(provider, key, characters));
|
|
5106
|
+
continue;
|
|
4904
5107
|
default:
|
|
4905
5108
|
continue;
|
|
4906
5109
|
}
|
|
4907
|
-
for (const [character, glyph] of provided) {
|
|
5110
|
+
if (providers.every((provider2) => provider2 instanceof Map)) for (const [character, glyph] of provided) {
|
|
4908
5111
|
if (character !== "\0" && !glyphs.has(character)) glyphs.set(character, glyph);
|
|
4909
5112
|
}
|
|
5113
|
+
providers.push(provided);
|
|
5114
|
+
}
|
|
5115
|
+
}
|
|
5116
|
+
return { glyphs, resolve: providers.every((provider) => provider instanceof Map) ? void 0 : async (characters) => {
|
|
5117
|
+
const remaining = new Set([...characters].filter((character) => character !== "\0" && character !== "\n" && character !== "\r" && !glyphs.has(character)));
|
|
5118
|
+
for (const provider of providers) {
|
|
5119
|
+
if (!remaining.size) break;
|
|
5120
|
+
const provided = provider instanceof Map ? provider : await provider([...remaining].join(""));
|
|
5121
|
+
for (const character of remaining) {
|
|
5122
|
+
const glyph = provided.get(character);
|
|
5123
|
+
if (glyph) {
|
|
5124
|
+
glyphs.set(character, glyph);
|
|
5125
|
+
remaining.delete(character);
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
4910
5128
|
}
|
|
4911
|
-
}
|
|
4912
|
-
return { glyphs };
|
|
5129
|
+
} };
|
|
4913
5130
|
}
|
|
4914
5131
|
static async bitmap(provider, fontKey) {
|
|
4915
5132
|
const rows = provider.chars.map((row) => [...row]);
|
|
@@ -5003,6 +5220,13 @@ var init_EntityAnimation = __esm({
|
|
|
5003
5220
|
|
|
5004
5221
|
// src/entity/scene/EntityAnimationPlayer.ts
|
|
5005
5222
|
import { Euler as Euler3, Vector3 as Vector35 } from "three";
|
|
5223
|
+
function validateAnimationWeights(weights, count) {
|
|
5224
|
+
const values = Array.from(weights);
|
|
5225
|
+
if (values.length !== count || values.some((weight) => !Number.isFinite(weight) || weight < 0)) {
|
|
5226
|
+
throw new Error("Animation weights must match the clip count and contain only finite nonnegative numbers");
|
|
5227
|
+
}
|
|
5228
|
+
return values;
|
|
5229
|
+
}
|
|
5006
5230
|
var ZERO, EntityAnimationPlayer;
|
|
5007
5231
|
var init_EntityAnimationPlayer = __esm({
|
|
5008
5232
|
"src/entity/scene/EntityAnimationPlayer.ts"() {
|
|
@@ -5011,12 +5235,20 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5011
5235
|
EntityAnimationPlayer = class {
|
|
5012
5236
|
constructor() {
|
|
5013
5237
|
this.parts = [];
|
|
5238
|
+
this._animations = [];
|
|
5239
|
+
this._weights = [];
|
|
5240
|
+
this.loops = [];
|
|
5014
5241
|
this._time = 0;
|
|
5015
|
-
this.loop = false;
|
|
5016
5242
|
this.speed = 1;
|
|
5017
5243
|
}
|
|
5018
5244
|
get animation() {
|
|
5019
|
-
return this.
|
|
5245
|
+
return this._animations[0];
|
|
5246
|
+
}
|
|
5247
|
+
get animations() {
|
|
5248
|
+
return this._animations.slice();
|
|
5249
|
+
}
|
|
5250
|
+
get weights() {
|
|
5251
|
+
return this._weights.slice();
|
|
5020
5252
|
}
|
|
5021
5253
|
get time() {
|
|
5022
5254
|
return this._time;
|
|
@@ -5026,10 +5258,20 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5026
5258
|
* without them, the current pose is used. Stopping restores the pose from before playback.
|
|
5027
5259
|
*/
|
|
5028
5260
|
play(layers, animation, options = {}, poses) {
|
|
5261
|
+
this.playAnimations(layers, [animation], options, poses);
|
|
5262
|
+
}
|
|
5263
|
+
/**
|
|
5264
|
+
* Starts clips on matching parts with a shared clock. Weighted offsets add to the supplied baked poses
|
|
5265
|
+
* or, without poses, to each animated part's pose when playback starts.
|
|
5266
|
+
*/
|
|
5267
|
+
playAnimations(layers, animations, options = {}, poses) {
|
|
5268
|
+
const weights = validateAnimationWeights(options.weights ?? animations.map(() => 1), animations.length);
|
|
5029
5269
|
this.stop();
|
|
5030
|
-
this.
|
|
5270
|
+
this._animations = animations.slice();
|
|
5271
|
+
this._weights = weights;
|
|
5272
|
+
if (!animations.length) return;
|
|
5031
5273
|
this._time = options.time ?? 0;
|
|
5032
|
-
this.
|
|
5274
|
+
this.loops = animations.map((animation) => options.loop ?? animation.loop);
|
|
5033
5275
|
this.speed = options.speed ?? 1;
|
|
5034
5276
|
for (const layer of layers) {
|
|
5035
5277
|
const objects = [];
|
|
@@ -5038,7 +5280,8 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5038
5280
|
if (poses.has(object4)) objects.push(object4);
|
|
5039
5281
|
});
|
|
5040
5282
|
} else {
|
|
5041
|
-
|
|
5283
|
+
const bones = new Set(animations.flatMap((animation) => Object.keys(animation.bones)));
|
|
5284
|
+
for (const bone of bones) {
|
|
5042
5285
|
const object4 = layer.getObjectByName(`group:${bone}`);
|
|
5043
5286
|
if (object4) objects.push(object4);
|
|
5044
5287
|
}
|
|
@@ -5062,7 +5305,7 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5062
5305
|
}
|
|
5063
5306
|
/** Restores the poses from before playback. Returns whether an animation was active. */
|
|
5064
5307
|
stop() {
|
|
5065
|
-
if (!this.
|
|
5308
|
+
if (!this._animations.length) return false;
|
|
5066
5309
|
for (const part of this.parts) {
|
|
5067
5310
|
part.object.position.copy(part.position);
|
|
5068
5311
|
part.object.rotation.copy(part.rotation);
|
|
@@ -5074,12 +5317,14 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5074
5317
|
/** Forgets the animation without touching the parts, for parts that no longer exist. */
|
|
5075
5318
|
clear() {
|
|
5076
5319
|
this.parts = [];
|
|
5077
|
-
this.
|
|
5320
|
+
this._animations = [];
|
|
5321
|
+
this._weights = [];
|
|
5322
|
+
this.loops = [];
|
|
5078
5323
|
this._time = 0;
|
|
5079
5324
|
}
|
|
5080
5325
|
/** Applies the pose at an absolute playback time. Returns `false` when no clip is active. */
|
|
5081
5326
|
setTime(seconds) {
|
|
5082
|
-
if (!this.
|
|
5327
|
+
if (!this._animations.length) return false;
|
|
5083
5328
|
this._time = seconds;
|
|
5084
5329
|
this.apply();
|
|
5085
5330
|
return true;
|
|
@@ -5088,8 +5333,30 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
5088
5333
|
advance(deltaSeconds) {
|
|
5089
5334
|
return this.setTime(this._time + deltaSeconds * this.speed);
|
|
5090
5335
|
}
|
|
5336
|
+
/** Changes weights in clip order and reapplies the current time without restarting playback. */
|
|
5337
|
+
setWeights(weights) {
|
|
5338
|
+
if (!this._animations.length) return false;
|
|
5339
|
+
const validated = validateAnimationWeights(weights, this._animations.length);
|
|
5340
|
+
this._weights = validated;
|
|
5341
|
+
this.apply();
|
|
5342
|
+
return true;
|
|
5343
|
+
}
|
|
5091
5344
|
apply() {
|
|
5092
|
-
const pose =
|
|
5345
|
+
const pose = /* @__PURE__ */ Object.create(null);
|
|
5346
|
+
for (let i = 0; i < this._animations.length; i++) {
|
|
5347
|
+
const weight = this._weights[i];
|
|
5348
|
+
if (weight === 0) continue;
|
|
5349
|
+
const sampled = sampleEntityAnimation(this._animations[i], this._time, this.loops[i]);
|
|
5350
|
+
for (const [bone, channels] of Object.entries(sampled)) {
|
|
5351
|
+
const blended = pose[bone] ??= {};
|
|
5352
|
+
for (const channel of ENTITY_ANIMATION_CHANNELS) {
|
|
5353
|
+
const value = channels[channel];
|
|
5354
|
+
if (!value) continue;
|
|
5355
|
+
const target = blended[channel] ??= [0, 0, 0];
|
|
5356
|
+
for (let axis = 0; axis < 3; axis++) target[axis] += value[axis] * weight;
|
|
5357
|
+
}
|
|
5358
|
+
}
|
|
5359
|
+
}
|
|
5093
5360
|
for (const part of this.parts) {
|
|
5094
5361
|
const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone] ?? {};
|
|
5095
5362
|
part.object.position.set(part.basePosition.x + position[0], part.basePosition.y + position[1], part.basePosition.z + position[2]);
|
|
@@ -5713,7 +5980,7 @@ var init_EntityObject = __esm({
|
|
|
5713
5980
|
for (const geometry of this.geometries) geometry.dispose();
|
|
5714
5981
|
this.geometries.clear();
|
|
5715
5982
|
for (const dispose of this.disposeWireframes.splice(0)) dispose();
|
|
5716
|
-
for (const player of this.animationPlayers.splice(0)) player.clear();
|
|
5983
|
+
for (const { player } of this.animationPlayers.splice(0)) player.clear();
|
|
5717
5984
|
this.partPoses.clear();
|
|
5718
5985
|
super.disposeAndRemoveAllChildren();
|
|
5719
5986
|
}
|
|
@@ -5748,15 +6015,31 @@ var init_EntityObject = __esm({
|
|
|
5748
6015
|
//<editor-fold desc="ANIMATION">
|
|
5749
6016
|
/** The first active clip, until playback is stopped or the object is disposed. */
|
|
5750
6017
|
get animation() {
|
|
5751
|
-
return this.animationPlayers[0]?.animation;
|
|
6018
|
+
return this.animationPlayers[0]?.player.animation;
|
|
5752
6019
|
}
|
|
5753
|
-
/** Clips playing together,
|
|
6020
|
+
/** Clips playing together, in the order passed to {@link playAnimations}. */
|
|
5754
6021
|
get activeAnimations() {
|
|
5755
|
-
|
|
6022
|
+
const animations = [];
|
|
6023
|
+
for (const { player, indices } of this.animationPlayers) {
|
|
6024
|
+
player.animations.forEach((animation, i) => {
|
|
6025
|
+
animations[indices[i]] = animation;
|
|
6026
|
+
});
|
|
6027
|
+
}
|
|
6028
|
+
return animations;
|
|
6029
|
+
}
|
|
6030
|
+
/** Weights of the active clips, in the same order as {@link activeAnimations}. */
|
|
6031
|
+
get animationWeights() {
|
|
6032
|
+
const weights = [];
|
|
6033
|
+
for (const { player, indices } of this.animationPlayers) {
|
|
6034
|
+
player.weights.forEach((weight, i) => {
|
|
6035
|
+
weights[indices[i]] = weight;
|
|
6036
|
+
});
|
|
6037
|
+
}
|
|
6038
|
+
return weights;
|
|
5756
6039
|
}
|
|
5757
6040
|
/** Seconds since the animation started, before looping. */
|
|
5758
6041
|
get animationTime() {
|
|
5759
|
-
return this.animationPlayers[0]?.time ?? 0;
|
|
6042
|
+
return this.animationPlayers[0]?.player.time ?? 0;
|
|
5760
6043
|
}
|
|
5761
6044
|
/**
|
|
5762
6045
|
* Plays a clip from {@link Entities.getAnimations}, replacing all active clips.
|
|
@@ -5767,42 +6050,59 @@ var init_EntityObject = __esm({
|
|
|
5767
6050
|
playAnimation(animation, options) {
|
|
5768
6051
|
this.playAnimations([animation], options);
|
|
5769
6052
|
}
|
|
5770
|
-
/**
|
|
6053
|
+
/**
|
|
6054
|
+
* Plays clips with a shared clock, adding their weighted offsets within each geometry layer.
|
|
6055
|
+
* Weights default to 1 and are not normalized. Selected layers without their own clip follow `main`.
|
|
6056
|
+
*/
|
|
5771
6057
|
playAnimations(animations, options) {
|
|
5772
|
-
const
|
|
5773
|
-
const selections =
|
|
6058
|
+
const weights = validateAnimationWeights(options?.weights ?? animations.map(() => 1), animations.length);
|
|
6059
|
+
const selections = /* @__PURE__ */ new Map();
|
|
6060
|
+
animations.forEach((animation, index) => {
|
|
5774
6061
|
const layer = animation.layer ?? "main";
|
|
5775
|
-
if (targets.has(layer)) throw new Error(`Multiple animations target layer "${layer}"`);
|
|
5776
|
-
targets.add(layer);
|
|
5777
6062
|
const names = Object.keys(this.entityLayers).filter((name) => name.split("#")[0] === layer);
|
|
5778
6063
|
if (!names.length) throw new Error(`Entity ${this.entity.id} has no selected animation layer "${layer}"`);
|
|
5779
|
-
|
|
6064
|
+
let selection = selections.get(layer);
|
|
6065
|
+
if (!selection) selections.set(layer, selection = { animations: [], names, indices: [] });
|
|
6066
|
+
selection.animations.push(animation);
|
|
6067
|
+
selection.indices.push(index);
|
|
5780
6068
|
});
|
|
5781
|
-
const main = selections.
|
|
5782
|
-
if (main) main.names.push(...Object.keys(this.entityLayers).filter((name) => !
|
|
6069
|
+
const main = selections.get("main");
|
|
6070
|
+
if (main) main.names.push(...Object.keys(this.entityLayers).filter((name) => !selections.has(name.split("#")[0])));
|
|
5783
6071
|
this.createMeshes();
|
|
5784
6072
|
this.stopAnimation();
|
|
5785
|
-
for (const {
|
|
6073
|
+
for (const { animations: clips, names, indices } of selections.values()) {
|
|
5786
6074
|
const player = new EntityAnimationPlayer();
|
|
5787
|
-
player.
|
|
5788
|
-
|
|
6075
|
+
player.playAnimations(
|
|
6076
|
+
names.map((name) => this.getLayerGroup(name)),
|
|
6077
|
+
clips,
|
|
6078
|
+
{ ...options, weights: indices.map((index) => weights[index]) },
|
|
6079
|
+
this.partPoses
|
|
6080
|
+
);
|
|
6081
|
+
this.animationPlayers.push({ player, indices });
|
|
5789
6082
|
}
|
|
5790
6083
|
this.notifyDirty();
|
|
5791
6084
|
}
|
|
6085
|
+
/** Changes weights in active clip order, notifying the scene without restarting the shared clock. Has no effect without an animation. */
|
|
6086
|
+
setAnimationWeights(weights) {
|
|
6087
|
+
if (!this.animationPlayers.length) return;
|
|
6088
|
+
const values = validateAnimationWeights(weights, this.activeAnimations.length);
|
|
6089
|
+
for (const { player, indices } of this.animationPlayers) player.setWeights(indices.map((index) => values[index]));
|
|
6090
|
+
this.notifyDirty();
|
|
6091
|
+
}
|
|
5792
6092
|
/** Stops all clips and restores the poses from before playback. */
|
|
5793
6093
|
stopAnimation() {
|
|
5794
6094
|
const players = this.animationPlayers.splice(0);
|
|
5795
|
-
for (const player of players) player.stop();
|
|
6095
|
+
for (const { player } of players) player.stop();
|
|
5796
6096
|
if (players.length) this.notifyDirty();
|
|
5797
6097
|
}
|
|
5798
6098
|
/** Poses the object at an explicit time in seconds. Has no effect without an animation. */
|
|
5799
6099
|
setAnimationTime(seconds) {
|
|
5800
|
-
for (const player of this.animationPlayers) player.setTime(seconds);
|
|
6100
|
+
for (const { player } of this.animationPlayers) player.setTime(seconds);
|
|
5801
6101
|
if (this.animationPlayers.length) this.notifyDirty();
|
|
5802
6102
|
}
|
|
5803
6103
|
/** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
|
|
5804
6104
|
advanceAnimation(deltaSeconds) {
|
|
5805
|
-
for (const player of this.animationPlayers) player.advance(deltaSeconds);
|
|
6105
|
+
for (const { player } of this.animationPlayers) player.advance(deltaSeconds);
|
|
5806
6106
|
if (this.animationPlayers.length) this.notifyDirty();
|
|
5807
6107
|
}
|
|
5808
6108
|
//</editor-fold>
|
|
@@ -8064,6 +8364,7 @@ async function layoutGuiText(text2, options = {}) {
|
|
|
8064
8364
|
}
|
|
8065
8365
|
const font = await Fonts.get(options.font);
|
|
8066
8366
|
const runs = typeof text2 === "string" ? [{ text: text2 }] : text2;
|
|
8367
|
+
await font.resolve?.(runs.map((run) => run.text).join(""));
|
|
8067
8368
|
const glyphs = [], lineWidths = [];
|
|
8068
8369
|
let line = [], width = 0;
|
|
8069
8370
|
let trailingNewline = false;
|
|
@@ -8090,7 +8391,7 @@ async function layoutGuiText(text2, options = {}) {
|
|
|
8090
8391
|
continue;
|
|
8091
8392
|
}
|
|
8092
8393
|
const glyph = font.glyphs.get(character);
|
|
8093
|
-
const advance = (glyph?.advance ?? 6) + (style.bold ? 1 : 0);
|
|
8394
|
+
const advance = (glyph?.advance ?? 6) + (style.bold ? glyph?.boldOffset ?? 1 : 0);
|
|
8094
8395
|
line.push({ character, glyph, advance, style, x: 0, y: 0 });
|
|
8095
8396
|
width += advance;
|
|
8096
8397
|
while (width > maxWidth && line.length > 1) {
|
|
@@ -8118,7 +8419,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8118
8419
|
batches.push(batch);
|
|
8119
8420
|
}
|
|
8120
8421
|
const color2 = new Color8(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
8121
|
-
const offset = isShadow ? 1 : 0;
|
|
8422
|
+
const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
|
|
8122
8423
|
const top = glyph ? 7 - glyph.ascent : 0;
|
|
8123
8424
|
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
8124
8425
|
const width = glyph ? glyph.width * glyph.scale : 5;
|
|
@@ -8148,7 +8449,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8148
8449
|
for (let i = 0; i < 4; i++) batch.colors.push(color2.r, color2.g, color2.b);
|
|
8149
8450
|
batch.indices.push(base, base + 2, base + 1, base + 2, base + 3, base + 1);
|
|
8150
8451
|
};
|
|
8151
|
-
for (const boldOffset of style.bold ? [0, 1] : [0]) {
|
|
8452
|
+
for (const boldOffset of style.bold ? [0, glyph?.boldOffset ?? 1] : [0]) {
|
|
8152
8453
|
if (glyph) quad(0, top, width, top + height, boldOffset);
|
|
8153
8454
|
else {
|
|
8154
8455
|
quad(0, 0, 5, 1, boldOffset);
|
|
@@ -18771,7 +19072,7 @@ var LIGHT_SAMPLE_OFFSETS = [0, 1, -1, 324, -324, 18, -18];
|
|
|
18771
19072
|
|
|
18772
19073
|
// src/world/SectionGeometry.ts
|
|
18773
19074
|
function buildSectionGeometry(input) {
|
|
18774
|
-
const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
|
|
19075
|
+
const { count, indices, templates, cullMasks, templateData, atlases: atlases2, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion, biomeTints } = input;
|
|
18775
19076
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
18776
19077
|
if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError("Section entry count exceeds its arrays");
|
|
18777
19078
|
if (biomeTints && biomeTints.length !== count * 3) throw new RangeError("Section biome tints must contain RGB for each placement");
|
|
@@ -18806,8 +19107,8 @@ function buildSectionGeometry(input) {
|
|
|
18806
19107
|
const locations = /* @__PURE__ */ new Map();
|
|
18807
19108
|
for (const [layer, layerAtlases] of [...visibleAtlases].sort(([a], [b]) => a - b)) {
|
|
18808
19109
|
const firstPage = pages.length;
|
|
18809
|
-
for (const atlas of [...layerAtlases].sort((a, b) => Number(
|
|
18810
|
-
const { width, height, animated } =
|
|
19110
|
+
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))) {
|
|
19111
|
+
const { width, height, animated } = atlases2[atlas];
|
|
18811
19112
|
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
18812
19113
|
let selected = -1;
|
|
18813
19114
|
for (let i = firstPage; !animated && i < pages.length; i++) {
|
|
@@ -18850,7 +19151,7 @@ function buildSectionGeometry(input) {
|
|
|
18850
19151
|
});
|
|
18851
19152
|
if (!quads.sprites.length) continue;
|
|
18852
19153
|
if (!fluidPages.has(fluid)) {
|
|
18853
|
-
const { width, height } =
|
|
19154
|
+
const { width, height } = atlases2[data.atlas];
|
|
18854
19155
|
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
18855
19156
|
fluidPages.set(fluid, {
|
|
18856
19157
|
layer: 2,
|
|
@@ -18868,7 +19169,7 @@ function buildSectionGeometry(input) {
|
|
|
18868
19169
|
const tint = fluid === "water" && fluids.waterTints ? fluids.waterTints.subarray(tintIndex, tintIndex + 3) : data.tint;
|
|
18869
19170
|
fluidPages.get(fluid).fluids.push({ quads, x, y, z, data, tint });
|
|
18870
19171
|
}
|
|
18871
|
-
pages.push(...[...fluidPages.values()].sort((a, b) => Number(
|
|
19172
|
+
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));
|
|
18872
19173
|
}
|
|
18873
19174
|
return pages.map((page) => {
|
|
18874
19175
|
let faces = page.fluids.reduce((sum, fluid) => sum + fluid.quads.sprites.length, 0);
|
|
@@ -18885,7 +19186,7 @@ function buildSectionGeometry(input) {
|
|
|
18885
19186
|
let vertex = 0, indexOffset = 0;
|
|
18886
19187
|
for (const entry of page.entries) {
|
|
18887
19188
|
const template = templateData[templates[entry]];
|
|
18888
|
-
const atlas =
|
|
19189
|
+
const atlas = atlases2[template.atlas];
|
|
18889
19190
|
const placement = locations.get(template.atlas);
|
|
18890
19191
|
const mapU = (u) => (placement.x + u * atlas.width) / page.width;
|
|
18891
19192
|
const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
|
|
@@ -18924,7 +19225,7 @@ function buildSectionGeometry(input) {
|
|
|
18924
19225
|
}
|
|
18925
19226
|
}
|
|
18926
19227
|
for (const { quads, x, y, z, data, tint } of page.fluids) {
|
|
18927
|
-
const atlas =
|
|
19228
|
+
const atlas = atlases2[data.atlas];
|
|
18928
19229
|
const placement = page.placements[0];
|
|
18929
19230
|
const mapU = (u) => (placement.x + u * atlas.width) / page.width;
|
|
18930
19231
|
const mapV = (v) => 1 - (placement.y + (1 - v) * atlas.height) / page.height;
|
|
@@ -19026,7 +19327,7 @@ var templateCache = /* @__PURE__ */ new WeakMap();
|
|
|
19026
19327
|
var WATER_TINT = new Color12(4159204).toArray();
|
|
19027
19328
|
function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
19028
19329
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
19029
|
-
const
|
|
19330
|
+
const atlases2 = [];
|
|
19030
19331
|
const atlasIds = /* @__PURE__ */ new Map();
|
|
19031
19332
|
const templateIds = /* @__PURE__ */ new Map();
|
|
19032
19333
|
const input = {
|
|
@@ -19049,9 +19350,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19049
19350
|
if (id === void 0) {
|
|
19050
19351
|
let atlas = atlasIds.get(template.atlas);
|
|
19051
19352
|
if (atlas === void 0) {
|
|
19052
|
-
atlas =
|
|
19353
|
+
atlas = atlases2.length;
|
|
19053
19354
|
atlasIds.set(template.atlas, atlas);
|
|
19054
|
-
|
|
19355
|
+
atlases2.push(template.atlas);
|
|
19055
19356
|
input.atlases.push({ width: template.atlas.image.width, height: template.atlas.image.height, animated: template.atlas.hasAnimation });
|
|
19056
19357
|
}
|
|
19057
19358
|
let data = templateCache.get(template);
|
|
@@ -19110,9 +19411,9 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19110
19411
|
if (!atlas) continue;
|
|
19111
19412
|
let id = atlasIds.get(atlas);
|
|
19112
19413
|
if (id === void 0) {
|
|
19113
|
-
id =
|
|
19414
|
+
id = atlases2.length;
|
|
19114
19415
|
atlasIds.set(atlas, id);
|
|
19115
|
-
|
|
19416
|
+
atlases2.push(atlas);
|
|
19116
19417
|
input.atlases.push({ width: atlas.image.width, height: atlas.image.height, animated: atlas.hasAnimation });
|
|
19117
19418
|
}
|
|
19118
19419
|
input.fluids[kind] = {
|
|
@@ -19123,7 +19424,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19123
19424
|
};
|
|
19124
19425
|
}
|
|
19125
19426
|
}
|
|
19126
|
-
return { input, atlases };
|
|
19427
|
+
return { input, atlases: atlases2 };
|
|
19127
19428
|
}
|
|
19128
19429
|
var SectionMesh = class _SectionMesh extends Group3 {
|
|
19129
19430
|
constructor() {
|
|
@@ -19138,23 +19439,23 @@ var SectionMesh = class _SectionMesh extends Group3 {
|
|
|
19138
19439
|
}
|
|
19139
19440
|
/** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
19140
19441
|
static build(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
19141
|
-
const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19142
|
-
return this.fromPages(buildSectionGeometry(input),
|
|
19442
|
+
const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19443
|
+
return this.fromPages(buildSectionGeometry(input), atlases2);
|
|
19143
19444
|
}
|
|
19144
19445
|
/** Builds section-local meshes in a browser worker when available, with synchronous fallback. */
|
|
19145
19446
|
static async buildAsync(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
19146
|
-
const { input, atlases } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19447
|
+
const { input, atlases: atlases2 } = toInput(entries, maxAtlasSize, fluids, lighting);
|
|
19147
19448
|
const worker = SectionWorker.shared();
|
|
19148
19449
|
const pages = worker ? await worker.build(input).catch(() => buildSectionGeometry(input)) : buildSectionGeometry(input);
|
|
19149
|
-
return this.fromPages(pages,
|
|
19450
|
+
return this.fromPages(pages, atlases2);
|
|
19150
19451
|
}
|
|
19151
|
-
static fromPages(pages,
|
|
19452
|
+
static fromPages(pages, atlases2) {
|
|
19152
19453
|
const section = new _SectionMesh();
|
|
19153
19454
|
for (const page of pages) {
|
|
19154
19455
|
const canvas = createCanvas2(page.width, page.height);
|
|
19155
19456
|
const context = canvas.getContext("2d");
|
|
19156
19457
|
for (const { atlas, x, y } of page.placements) {
|
|
19157
|
-
context.drawImage(
|
|
19458
|
+
context.drawImage(atlases2[atlas].image.canvas, x, y);
|
|
19158
19459
|
}
|
|
19159
19460
|
const geometry = new BufferGeometry9();
|
|
19160
19461
|
geometry.setAttribute("position", new Float32BufferAttribute10(page.positions.buffer, 3));
|
|
@@ -19165,7 +19466,7 @@ var SectionMesh = class _SectionMesh extends Group3 {
|
|
|
19165
19466
|
geometry.setIndex(new Uint32BufferAttribute(page.indices.buffer, 1));
|
|
19166
19467
|
geometry.computeBoundingBox();
|
|
19167
19468
|
geometry.computeBoundingSphere();
|
|
19168
|
-
const transparent = page.layer === 2 ?
|
|
19469
|
+
const transparent = page.layer === 2 ? atlases2[page.placements[0].atlas].hasTranslucency : page.layer === 1;
|
|
19169
19470
|
const material = Materials.createShadedCanvasMaterial(canvas, transparent, false, true);
|
|
19170
19471
|
material.side = FrontSide4;
|
|
19171
19472
|
if (page.layer === 2) {
|
|
@@ -19180,7 +19481,7 @@ var SectionMesh = class _SectionMesh extends Group3 {
|
|
|
19180
19481
|
section.blockIndices.set(mesh, page.blockIndices);
|
|
19181
19482
|
const unsubscribe = [];
|
|
19182
19483
|
for (const { atlas: id, x, y } of page.placements) {
|
|
19183
|
-
const atlas =
|
|
19484
|
+
const atlas = atlases2[id];
|
|
19184
19485
|
if (!atlas.hasAnimation) continue;
|
|
19185
19486
|
unsubscribe.push(atlas.subscribe(() => {
|
|
19186
19487
|
context.clearRect(x, y, atlas.image.width, atlas.image.height);
|
|
@@ -20523,6 +20824,7 @@ export {
|
|
|
20523
20824
|
toRadians,
|
|
20524
20825
|
toTrianglesDrawMode,
|
|
20525
20826
|
trimCanvas,
|
|
20827
|
+
validateAnimationWeights,
|
|
20526
20828
|
yieldToEventLoop
|
|
20527
20829
|
};
|
|
20528
20830
|
//# sourceMappingURL=index.mjs.map
|