minerender 2.1.0-beta.7 → 2.1.0-beta.8
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/README.md +10 -1
- package/dist/browser/esm/armor/Armor.mjs +84 -0
- package/dist/browser/esm/armor/Armor.mjs.map +1 -0
- package/dist/browser/esm/armor/index.mjs +3 -0
- package/dist/browser/esm/armor/index.mjs.map +1 -0
- package/dist/browser/esm/assets/BlockEntities.mjs +2 -0
- package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
- package/dist/browser/esm/assets/Entities.mjs +39 -11
- package/dist/browser/esm/assets/Entities.mjs.map +1 -1
- package/dist/browser/esm/assets/MineRenderData.mjs +8 -17
- package/dist/browser/esm/assets/MineRenderData.mjs.map +1 -1
- package/dist/browser/esm/assets/ModelTextures.mjs +13 -7
- package/dist/browser/esm/assets/ModelTextures.mjs.map +1 -1
- package/dist/browser/esm/assets/_versions/DatasetVersions.mjs +22 -0
- package/dist/browser/esm/assets/_versions/DatasetVersions.mjs.map +1 -0
- package/dist/browser/esm/cache/Caching.mjs +8 -0
- package/dist/browser/esm/cache/Caching.mjs.map +1 -1
- package/dist/browser/esm/entity/scene/EntityObject.mjs +31 -5
- package/dist/browser/esm/entity/scene/EntityObject.mjs.map +1 -1
- package/dist/browser/esm/env/browser/BrowserEnv.mjs +11 -4
- package/dist/browser/esm/env/browser/BrowserEnv.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +129 -13
- package/dist/browser/esm/index.browser.mjs.map +1 -1
- package/dist/browser/esm/index.mjs +1 -0
- package/dist/browser/esm/index.mjs.map +1 -1
- package/dist/browser/esm/model/ItemGlint.mjs +7 -6
- package/dist/browser/esm/model/ItemGlint.mjs.map +1 -1
- package/dist/browser/esm/model/block/scene/BlockObject.mjs +16 -5
- package/dist/browser/esm/model/block/scene/BlockObject.mjs.map +1 -1
- package/dist/browser/esm/scene/SceneDocument.mjs +35 -5
- package/dist/browser/esm/scene/SceneDocument.mjs.map +1 -1
- package/dist/browser/esm/scene/SceneDocumentLoader.mjs +14 -3
- package/dist/browser/esm/scene/SceneDocumentLoader.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinGeometries.mjs +4 -1
- package/dist/browser/esm/skin/SkinGeometries.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinPart.mjs +2 -0
- package/dist/browser/esm/skin/SkinPart.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinTextureCoordinates.mjs +11 -1
- package/dist/browser/esm/skin/SkinTextureCoordinates.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinTextures.mjs +1 -1
- package/dist/browser/esm/skin/SkinTextures.mjs.map +1 -1
- package/dist/browser/esm/skin/scene/SkinObject.mjs +119 -7
- package/dist/browser/esm/skin/scene/SkinObject.mjs.map +1 -1
- package/dist/browser/esm/texture/PalettedTextures.mjs +46 -0
- package/dist/browser/esm/texture/PalettedTextures.mjs.map +1 -0
- package/dist/browser/esm/texture/index.mjs +1 -0
- package/dist/browser/esm/texture/index.mjs.map +1 -1
- package/dist/browser/esm/util/util.mjs +0 -2
- package/dist/browser/esm/util/util.mjs.map +1 -1
- package/dist/browser/esm/world/Chunk.mjs +62 -33
- package/dist/browser/esm/world/Chunk.mjs.map +1 -1
- package/dist/browser/esm/world/MineRenderWorld.mjs +98 -13
- package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
- package/dist/browser/esm/world/SectionMesh.mjs +65 -9
- package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
- package/dist/browser/esm/world/SectionModels.mjs +21 -15
- package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
- package/dist/browser/esm/world/SectionWorker.mjs +8 -2
- package/dist/browser/esm/world/SectionWorker.mjs.map +1 -1
- package/dist/browser/esm/world/WorldStreamer.mjs +109 -15
- package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
- package/dist/browser/index.d.ts +129 -13
- package/dist/browser/index.js +1592 -894
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +1330 -619
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +117 -12
- package/dist/node/index.d.ts +117 -12
- package/dist/node/index.js +1505 -793
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +1303 -593
- package/dist/node/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/node/index.js
CHANGED
|
@@ -184,8 +184,6 @@ async function sleep(timeout) {
|
|
|
184
184
|
});
|
|
185
185
|
}
|
|
186
186
|
function yieldToEventLoop() {
|
|
187
|
-
const scheduler = globalThis.scheduler;
|
|
188
|
-
if (scheduler?.yield) return scheduler.yield();
|
|
189
187
|
return new Promise((resolve) => {
|
|
190
188
|
if (typeof MessageChannel !== "undefined") {
|
|
191
189
|
const channel = new MessageChannel();
|
|
@@ -243,6 +241,10 @@ var init_Caching = __esm({
|
|
|
243
241
|
import_loading_cache = require("@inventivetalent/loading-cache");
|
|
244
242
|
import_time = require("@inventivetalent/time");
|
|
245
243
|
Caching = class _Caching {
|
|
244
|
+
static {
|
|
245
|
+
/** Cached in place of a missing asset. The caches drop `undefined` results, which would request the asset again. */
|
|
246
|
+
this.MISSING = false;
|
|
247
|
+
}
|
|
246
248
|
static {
|
|
247
249
|
this._generation = 0;
|
|
248
250
|
}
|
|
@@ -310,6 +312,9 @@ var init_Caching = __esm({
|
|
|
310
312
|
static {
|
|
311
313
|
this.blockEntityIndexCache = _Caching.createAssetCache();
|
|
312
314
|
}
|
|
315
|
+
static {
|
|
316
|
+
this.entityDatasetVersionCache = _Caching.createAssetCache();
|
|
317
|
+
}
|
|
313
318
|
static {
|
|
314
319
|
this.unihexCache = _Caching.createAssetCache();
|
|
315
320
|
}
|
|
@@ -319,6 +324,12 @@ var init_Caching = __esm({
|
|
|
319
324
|
static {
|
|
320
325
|
this.bannerPatternCache = _Caching.createAssetCache();
|
|
321
326
|
}
|
|
327
|
+
static {
|
|
328
|
+
this.equipmentCache = _Caching.createAssetCache();
|
|
329
|
+
}
|
|
330
|
+
static {
|
|
331
|
+
this.trimCache = _Caching.createAssetCache();
|
|
332
|
+
}
|
|
322
333
|
static {
|
|
323
334
|
this.mineRenderDataCache = _Caching.createAssetCache();
|
|
324
335
|
}
|
|
@@ -354,9 +365,12 @@ var init_Caching = __esm({
|
|
|
354
365
|
this.entityTextureCache,
|
|
355
366
|
this.entityAnimationCache,
|
|
356
367
|
this.blockEntityIndexCache,
|
|
368
|
+
this.entityDatasetVersionCache,
|
|
357
369
|
this.fontCache,
|
|
358
370
|
this.unihexCache,
|
|
359
371
|
this.bannerPatternCache,
|
|
372
|
+
this.equipmentCache,
|
|
373
|
+
this.trimCache,
|
|
360
374
|
this.mineRenderDataCache,
|
|
361
375
|
this.usernameUuidCache,
|
|
362
376
|
this.biomeCache
|
|
@@ -2404,15 +2418,21 @@ var init_ModelTextures = __esm({
|
|
|
2404
2418
|
key.extension += ".mcmeta";
|
|
2405
2419
|
}
|
|
2406
2420
|
const keyStr = key.serialize();
|
|
2407
|
-
|
|
2408
|
-
return this.PERSISTENT_META_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2421
|
+
const meta = await Caching.textureMetaCache.get(keyStr, (k) => {
|
|
2422
|
+
return this.PERSISTENT_META_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), async (k1) => {
|
|
2423
|
+
if (AssetLoader.persistentScope === "") {
|
|
2424
|
+
const path = key.getFullPath();
|
|
2425
|
+
const slash = path.lastIndexOf("/");
|
|
2426
|
+
const listKey = new AssetKey(key.namespace, `${path.slice(0, slash + 1)}_list`, "textures", void 0, "assets", ".json", key.root);
|
|
2427
|
+
const list2 = await Caching.listAssetCache.get(listKey.serialize(), () => AssetLoader.get(listKey, "list" /* LIST */)).catch(() => void 0);
|
|
2428
|
+
if (list2 && !list2.files.includes(`${path.slice(slash + 1)}${key.extension}`)) return Caching.MISSING;
|
|
2429
|
+
}
|
|
2430
|
+
const asset2 = await AssetLoader.get(key, "meta" /* META */);
|
|
2431
|
+
if (asset2) asset2.key = key;
|
|
2432
|
+
return asset2 ?? Caching.MISSING;
|
|
2414
2433
|
});
|
|
2415
2434
|
});
|
|
2435
|
+
return meta === Caching.MISSING ? void 0 : meta;
|
|
2416
2436
|
}
|
|
2417
2437
|
/** Clears persisted texture metadata. Use {@link Caching.clear} to discard in-memory textures and metadata. */
|
|
2418
2438
|
static async clearCache() {
|
|
@@ -3332,23 +3352,303 @@ var init_MinecraftCubeTexture = __esm({
|
|
|
3332
3352
|
}
|
|
3333
3353
|
});
|
|
3334
3354
|
|
|
3355
|
+
// src/assets/_versions/DatasetVersions.ts
|
|
3356
|
+
var parseRelease, compare2, nearestRelease;
|
|
3357
|
+
var init_DatasetVersions = __esm({
|
|
3358
|
+
"src/assets/_versions/DatasetVersions.ts"() {
|
|
3359
|
+
parseRelease = (value) => /^\d+\.\d+(?:\.\d+)?$/.test(value) ? value.split(".").map(Number) : void 0;
|
|
3360
|
+
compare2 = (left, right) => {
|
|
3361
|
+
for (let i = 0; i < 3; i++) {
|
|
3362
|
+
const difference = (left[i] ?? 0) - (right[i] ?? 0);
|
|
3363
|
+
if (difference) return difference;
|
|
3364
|
+
}
|
|
3365
|
+
return 0;
|
|
3366
|
+
};
|
|
3367
|
+
nearestRelease = (requestedVersion, published) => {
|
|
3368
|
+
const requested = parseRelease(requestedVersion);
|
|
3369
|
+
if (!requested) return void 0;
|
|
3370
|
+
const versions = published.map((name) => ({ name, number: parseRelease(name) })).filter((entry) => !!entry.number).sort((left, right) => compare2(left.number, right.number));
|
|
3371
|
+
const sameLine = versions.filter((entry) => entry.number[0] === requested[0] && entry.number[1] === requested[1]);
|
|
3372
|
+
const selected = sameLine.sort((left, right) => Math.abs((left.number[2] ?? 0) - (requested[2] ?? 0)) - Math.abs((right.number[2] ?? 0) - (requested[2] ?? 0)) || compare2(left.number, right.number))[0] ?? versions.filter((entry) => compare2(entry.number, requested) <= 0).pop() ?? versions[0];
|
|
3373
|
+
return selected?.name;
|
|
3374
|
+
};
|
|
3375
|
+
}
|
|
3376
|
+
});
|
|
3377
|
+
|
|
3378
|
+
// src/error/MineRenderError.ts
|
|
3379
|
+
var MineRenderError;
|
|
3380
|
+
var init_MineRenderError = __esm({
|
|
3381
|
+
"src/error/MineRenderError.ts"() {
|
|
3382
|
+
MineRenderError = class _MineRenderError extends Error {
|
|
3383
|
+
constructor(msg) {
|
|
3384
|
+
super(msg);
|
|
3385
|
+
Object.setPrototypeOf(this, _MineRenderError.prototype);
|
|
3386
|
+
}
|
|
3387
|
+
get name() {
|
|
3388
|
+
return "MineRenderError";
|
|
3389
|
+
}
|
|
3390
|
+
};
|
|
3391
|
+
}
|
|
3392
|
+
});
|
|
3393
|
+
|
|
3394
|
+
// src/assets/Entities.ts
|
|
3395
|
+
var Entities;
|
|
3396
|
+
var init_Entities = __esm({
|
|
3397
|
+
"src/assets/Entities.ts"() {
|
|
3398
|
+
init_AssetKey();
|
|
3399
|
+
init_DatasetVersions();
|
|
3400
|
+
init_AssetLoader();
|
|
3401
|
+
init_source();
|
|
3402
|
+
init_Caching();
|
|
3403
|
+
init_AssetDefaults();
|
|
3404
|
+
init_MineRenderError();
|
|
3405
|
+
init_ModelTextures();
|
|
3406
|
+
Entities = class {
|
|
3407
|
+
/**
|
|
3408
|
+
* Resolves `root` (default: the active version). Uses the exact dataset when published or when the
|
|
3409
|
+
* version is not a release; otherwise selects the nearest published release, like {@link MineRenderData.resolve}.
|
|
3410
|
+
* Textures keep the requested root.
|
|
3411
|
+
*/
|
|
3412
|
+
static async getDatasetRoot(root) {
|
|
3413
|
+
const requestRoot = (root ?? AssetLoader.ROOT).replace(/\/+$/, "");
|
|
3414
|
+
const requestedVersion = requestRoot.slice(requestRoot.lastIndexOf("/") + 1);
|
|
3415
|
+
const base = requestRoot.slice(0, requestRoot.lastIndexOf("/"));
|
|
3416
|
+
const selected = await Caching.entityDatasetVersionCache.get(root ?? `sources:${AssetLoader.ROOT}`, async () => {
|
|
3417
|
+
const key = new AssetKey("entity-models", "version", void 0, void 0, void 0, ".json", root);
|
|
3418
|
+
key.rootType = void 0;
|
|
3419
|
+
if (!parseRelease(requestedVersion) || await AssetLoader.get(key, "json" /* JSON */) !== void 0) return requestedVersion;
|
|
3420
|
+
const indexKey = new AssetKey("entity-models", "versions", void 0, void 0, void 0, ".json", base);
|
|
3421
|
+
indexKey.rootType = void 0;
|
|
3422
|
+
const index = await AssetLoader.get(indexKey, "json" /* JSON */);
|
|
3423
|
+
if (index === void 0) return requestedVersion;
|
|
3424
|
+
if (!index || typeof index !== "object" || Array.isArray(index) || !Array.isArray(index.versions) || !index.versions.every((entry) => entry && typeof entry === "object" && !Array.isArray(entry) && typeof entry.name === "string")) {
|
|
3425
|
+
throw new MineRenderError(`Invalid entity model version index at ${base}/entity-models/versions.json`);
|
|
3426
|
+
}
|
|
3427
|
+
return nearestRelease(requestedVersion, index.versions.map((entry) => entry.name)) ?? requestedVersion;
|
|
3428
|
+
});
|
|
3429
|
+
return selected === requestedVersion ? root : `${base}/${selected}`;
|
|
3430
|
+
}
|
|
3431
|
+
/** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */
|
|
3432
|
+
static async getEntityList() {
|
|
3433
|
+
const root = await this.getDatasetRoot();
|
|
3434
|
+
const collect = async (path) => {
|
|
3435
|
+
const prefix2 = path ? `${path}/` : "";
|
|
3436
|
+
const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json", root);
|
|
3437
|
+
const list2 = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
|
|
3438
|
+
if (!list2) return [];
|
|
3439
|
+
const files = list2.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
|
|
3440
|
+
const children = await Promise.all(list2.directories.map((directory) => collect(`${prefix2}${directory}`)));
|
|
3441
|
+
return [...files, ...children.flat()];
|
|
3442
|
+
};
|
|
3443
|
+
return collect("");
|
|
3444
|
+
}
|
|
3445
|
+
/** @internal */
|
|
3446
|
+
static async getModelFile(modelKey) {
|
|
3447
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
3448
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", await this.getDatasetRoot(isAssetKey(modelKey) ? modelKey.root : void 0));
|
|
3449
|
+
return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
3450
|
+
}
|
|
3451
|
+
/** Returns selectable geometry-layer names, or an empty list when the model is missing. */
|
|
3452
|
+
static async getLayerList(modelKey) {
|
|
3453
|
+
return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
|
|
3454
|
+
}
|
|
3455
|
+
/** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
|
|
3456
|
+
static async getPassList(modelKey) {
|
|
3457
|
+
return (await this.getModelFile(modelKey))?.passes ?? [];
|
|
3458
|
+
}
|
|
3459
|
+
/**
|
|
3460
|
+
* Loads the layers and textures to pass to {@link MineRenderScene.addEntity}.
|
|
3461
|
+
* By default, selects `main`, unconditional passes, and passes enabled by `options.when`.
|
|
3462
|
+
*
|
|
3463
|
+
* @param modelKey - Dataset model, such as `new BasicAssetKey("minecraft", "zombie")`.
|
|
3464
|
+
* @param textureKey - Texture override for the first selected layer.
|
|
3465
|
+
* @param options - Layer selection, conditional passes, and per-layer texture overrides.
|
|
3466
|
+
* @returns The selected model, or `undefined` when its dataset file is missing.
|
|
3467
|
+
*/
|
|
3468
|
+
static async getEntity(modelKey, textureKey, options) {
|
|
3469
|
+
const model = await this.getModelFile(modelKey);
|
|
3470
|
+
if (!model) return void 0;
|
|
3471
|
+
const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
|
|
3472
|
+
const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
|
|
3473
|
+
if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
|
|
3474
|
+
draws.push(...passes);
|
|
3475
|
+
const names = [];
|
|
3476
|
+
const selected = draws.map((pass) => {
|
|
3477
|
+
const layer = model.layers[pass.layer];
|
|
3478
|
+
if (!layer) {
|
|
3479
|
+
throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
|
|
3480
|
+
}
|
|
3481
|
+
let name = pass.layer;
|
|
3482
|
+
for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;
|
|
3483
|
+
names.push(name);
|
|
3484
|
+
return { name, layer, pass };
|
|
3485
|
+
});
|
|
3486
|
+
const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {
|
|
3487
|
+
const override = options?.textures?.[name] ?? (index === 0 ? textureKey : void 0);
|
|
3488
|
+
const textureLocation = pass.textureLocation ?? layer.textureLocation;
|
|
3489
|
+
let texture;
|
|
3490
|
+
if (override) {
|
|
3491
|
+
const path = isAssetKey(override) ? override.getFullPath() : override.path;
|
|
3492
|
+
texture = isAssetKey(override) && override.assetType === "textures" && path.startsWith("entity/") ? override : new AssetKey(override.namespace, path, "textures", "entity", "assets", ".png", isAssetKey(override) ? override.root : void 0);
|
|
3493
|
+
} else if (textureLocation !== void 0) {
|
|
3494
|
+
texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
3495
|
+
if (isAssetKey(modelKey)) texture.root = modelKey.root;
|
|
3496
|
+
} else {
|
|
3497
|
+
texture = await this.resolveTexture(modelKey);
|
|
3498
|
+
}
|
|
3499
|
+
const render = pass.render ?? layer.render;
|
|
3500
|
+
return [name, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
|
|
3501
|
+
})));
|
|
3502
|
+
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
3503
|
+
}
|
|
3504
|
+
/**
|
|
3505
|
+
* Native and sampled vanilla clips by name, or undefined when the model or selected version has none.
|
|
3506
|
+
*/
|
|
3507
|
+
static async getAnimations(modelKey) {
|
|
3508
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
3509
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json", await this.getDatasetRoot(isAssetKey(modelKey) ? modelKey.root : void 0));
|
|
3510
|
+
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
3511
|
+
return file?.animations;
|
|
3512
|
+
}
|
|
3513
|
+
/** Finds a fallback texture using the model path, its directory, and vanilla variant data. */
|
|
3514
|
+
static async resolveTexture(modelKey) {
|
|
3515
|
+
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
3516
|
+
const root = isAssetKey(modelKey) ? modelKey.root : void 0;
|
|
3517
|
+
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", root);
|
|
3518
|
+
const texture = await Caching.entityTextureCache.get(key.serialize(), async () => {
|
|
3519
|
+
const name = path.split("/").pop();
|
|
3520
|
+
for (const candidate of [path, `${path}/${name}`]) {
|
|
3521
|
+
const texture3 = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png", root);
|
|
3522
|
+
if (await ModelTextures.get(texture3)) return texture3;
|
|
3523
|
+
}
|
|
3524
|
+
const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json", root);
|
|
3525
|
+
const list2 = await AssetLoader.get(listKey, "list" /* LIST */);
|
|
3526
|
+
const files = list2?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
|
|
3527
|
+
const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
|
|
3528
|
+
if (!file) return Caching.MISSING;
|
|
3529
|
+
const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json", root);
|
|
3530
|
+
const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
|
|
3531
|
+
const assets = variant?.assets;
|
|
3532
|
+
const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
|
|
3533
|
+
if (typeof textureId !== "string") return Caching.MISSING;
|
|
3534
|
+
const texture2 = AssetKey.parse("textures", textureId);
|
|
3535
|
+
texture2.root = root;
|
|
3536
|
+
return texture2;
|
|
3537
|
+
});
|
|
3538
|
+
return texture === Caching.MISSING ? void 0 : texture;
|
|
3539
|
+
}
|
|
3540
|
+
/** @deprecated Use getEntityList(); block entities share the entity dataset. */
|
|
3541
|
+
static getBlockList() {
|
|
3542
|
+
return this.getEntityList();
|
|
3543
|
+
}
|
|
3544
|
+
/** @deprecated Use getEntity(); block entities share the entity dataset. */
|
|
3545
|
+
static getBlock(modelKey, textureKey, options) {
|
|
3546
|
+
return this.getEntity(modelKey, textureKey, options);
|
|
3547
|
+
}
|
|
3548
|
+
};
|
|
3549
|
+
}
|
|
3550
|
+
});
|
|
3551
|
+
|
|
3552
|
+
// src/armor/Armor.ts
|
|
3553
|
+
var Armor_exports = {};
|
|
3554
|
+
__export(Armor_exports, {
|
|
3555
|
+
Armor: () => Armor
|
|
3556
|
+
});
|
|
3557
|
+
var ARMOR_TRANSFORM, Armor;
|
|
3558
|
+
var init_Armor = __esm({
|
|
3559
|
+
"src/armor/Armor.ts"() {
|
|
3560
|
+
init_AssetKey();
|
|
3561
|
+
init_AssetLoader();
|
|
3562
|
+
init_Entities();
|
|
3563
|
+
init_AssetParsers();
|
|
3564
|
+
init_Caching();
|
|
3565
|
+
init_MineRenderError();
|
|
3566
|
+
ARMOR_TRANSFORM = [
|
|
3567
|
+
{ rotate: [0, Math.PI, 0] },
|
|
3568
|
+
{ scale: [-1, -1, 1] },
|
|
3569
|
+
{ translate: [0, -24, 0] }
|
|
3570
|
+
];
|
|
3571
|
+
Armor = class {
|
|
3572
|
+
/** Loads 1.21.4+ armor in SkinObject's frame, or returns undefined when no layer draws. */
|
|
3573
|
+
static async getEntity(armor) {
|
|
3574
|
+
const model = await Entities.getModelFile(new BasicAssetKey("minecraft", "player"));
|
|
3575
|
+
const layers = {};
|
|
3576
|
+
const slots = { chest: "chestplate", legs: "leggings", feet: "boots", head: "helmet" };
|
|
3577
|
+
for (const slot of Object.keys(slots)) {
|
|
3578
|
+
const value = armor[slot];
|
|
3579
|
+
if (value === void 0) continue;
|
|
3580
|
+
const piece = typeof value === "string" ? { asset: value } : value;
|
|
3581
|
+
const name = slots[slot], geometry = model?.layers[name];
|
|
3582
|
+
if (!geometry) throw new MineRenderError(`Missing armor geometry ${name}; armor needs Minecraft 1.21.4 or later`);
|
|
3583
|
+
const id = this.identifier(piece.asset);
|
|
3584
|
+
const key = new AssetKey(id.namespace, id.path, "equipment", void 0, "assets", ".json");
|
|
3585
|
+
const equipment = await Caching.equipmentCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
3586
|
+
if (!equipment) throw new MineRenderError(`Missing equipment asset ${piece.asset}; armor takes equipment asset IDs such as minecraft:diamond and needs Minecraft 1.21.4 or later`);
|
|
3587
|
+
const layerType = slot === "legs" ? "humanoid_leggings" : "humanoid";
|
|
3588
|
+
const equipmentLayers = equipment.layers[layerType];
|
|
3589
|
+
if (!equipmentLayers?.length) continue;
|
|
3590
|
+
let count = 0;
|
|
3591
|
+
const add = (texture, settings) => {
|
|
3592
|
+
layers[++count === 1 ? name : `${name}#${count}`] = { key: texture, texture, layer: geometry, ...settings };
|
|
3593
|
+
};
|
|
3594
|
+
let glint = piece.glint;
|
|
3595
|
+
for (const layer of equipmentLayers) {
|
|
3596
|
+
let color2;
|
|
3597
|
+
if (layer.dyeable) {
|
|
3598
|
+
const undyed = layer.dyeable.color_when_undyed;
|
|
3599
|
+
color2 = piece.color || (Array.isArray(undyed) ? Math.floor(undyed[0] * 255) << 16 | Math.floor(undyed[1] * 255) << 8 | Math.floor(undyed[2] * 255) : undyed === void 0 ? void 0 : undyed & 16777215);
|
|
3600
|
+
if (color2 === void 0) continue;
|
|
3601
|
+
}
|
|
3602
|
+
const texture = this.identifier(layer.texture);
|
|
3603
|
+
add(
|
|
3604
|
+
new AssetKey(texture.namespace, `equipment/${layerType}/${texture.path}`, "textures", "entity", "assets", ".png"),
|
|
3605
|
+
{ ...color2 !== void 0 && { color: color2 }, ...glint && { glint: true } }
|
|
3606
|
+
);
|
|
3607
|
+
glint = false;
|
|
3608
|
+
}
|
|
3609
|
+
if (piece.trim) {
|
|
3610
|
+
const patternId = this.identifier(piece.trim.pattern), materialId = this.identifier(piece.trim.material);
|
|
3611
|
+
const patternKey = new AssetKey(patternId.namespace, patternId.path, "trim_pattern", void 0, "data", ".json");
|
|
3612
|
+
const materialKey = new AssetKey(materialId.namespace, materialId.path, "trim_material", void 0, "data", ".json");
|
|
3613
|
+
const pattern2 = await Caching.trimCache.get(patternKey.serialize(), () => AssetLoader.get(patternKey, "json" /* JSON */));
|
|
3614
|
+
if (!pattern2) throw new MineRenderError(`Missing trim pattern ${piece.trim.pattern}`);
|
|
3615
|
+
const material = await Caching.trimCache.get(materialKey.serialize(), () => AssetLoader.get(materialKey, "json" /* JSON */));
|
|
3616
|
+
if (!material) throw new MineRenderError(`Missing trim material ${piece.trim.material}`);
|
|
3617
|
+
const patternAsset = this.identifier(pattern2.asset_id);
|
|
3618
|
+
const suffix = material.override_armor_assets?.[id.toNamespacedString()] ?? material.asset_name;
|
|
3619
|
+
add(new AssetKey(patternAsset.namespace, `entity/${layerType}/${patternAsset.path}`, "textures", "trims", "assets", ".png"), {
|
|
3620
|
+
palette: {
|
|
3621
|
+
key: new AssetKey("minecraft", "color_palettes/trim_palette", "textures", "trims", "assets", ".png"),
|
|
3622
|
+
permutation: new AssetKey("minecraft", `color_palettes/${suffix}`, "textures", "trims", "assets", ".png")
|
|
3623
|
+
},
|
|
3624
|
+
render: pattern2.decal ? "cutout_z_offset" : "cutout"
|
|
3625
|
+
});
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
const first = Object.values(layers)[0];
|
|
3629
|
+
return first ? { ...first, id: "minecraft:player", layers, transform: ARMOR_TRANSFORM } : void 0;
|
|
3630
|
+
}
|
|
3631
|
+
static identifier(value) {
|
|
3632
|
+
if (!isResourceLocation(value) || value.split(/[:/]/).some((part) => !part || part === "." || part === "..")) {
|
|
3633
|
+
throw new MineRenderError(`Invalid armor identifier ${value}`);
|
|
3634
|
+
}
|
|
3635
|
+
const [namespace, path] = value.includes(":") ? value.split(":") : ["minecraft", value];
|
|
3636
|
+
return new BasicAssetKey(namespace, path);
|
|
3637
|
+
}
|
|
3638
|
+
};
|
|
3639
|
+
}
|
|
3640
|
+
});
|
|
3641
|
+
|
|
3335
3642
|
// src/assets/MineRenderData.ts
|
|
3336
|
-
var object2,
|
|
3643
|
+
var object2, MineRenderData;
|
|
3337
3644
|
var init_MineRenderData = __esm({
|
|
3338
3645
|
"src/assets/MineRenderData.ts"() {
|
|
3646
|
+
init_DatasetVersions();
|
|
3339
3647
|
init_AssetKey();
|
|
3340
3648
|
init_AssetLoader();
|
|
3341
3649
|
init_AssetParsers();
|
|
3342
3650
|
init_Caching();
|
|
3343
3651
|
object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3344
|
-
release = (value) => /^\d+\.\d+(?:\.\d+)?$/.test(value) ? value.split(".").map(Number) : void 0;
|
|
3345
|
-
compare2 = (left, right) => {
|
|
3346
|
-
for (let i = 0; i < 3; i++) {
|
|
3347
|
-
const difference = (left[i] ?? 0) - (right[i] ?? 0);
|
|
3348
|
-
if (difference) return difference;
|
|
3349
|
-
}
|
|
3350
|
-
return 0;
|
|
3351
|
-
};
|
|
3352
3652
|
MineRenderData = class {
|
|
3353
3653
|
/** Loads one registry. Missing files and invalid data reject the request. */
|
|
3354
3654
|
static async get(dataset, root) {
|
|
@@ -3378,9 +3678,9 @@ var init_MineRenderData = __esm({
|
|
|
3378
3678
|
const scope = AssetLoader.persistentScope;
|
|
3379
3679
|
return this.cached(`resolve:${requestRoot === void 0 ? "sources" : "explicit"}:${root}`, scope, defaultRoot, async () => {
|
|
3380
3680
|
const requestedVersion = root.slice(root.lastIndexOf("/") + 1);
|
|
3381
|
-
let manifest = await this.manifest(root, requestRoot !== void 0 &&
|
|
3681
|
+
let manifest = await this.manifest(root, requestRoot !== void 0 && parseRelease(requestedVersion) ? requestedVersion : void 0, requestRoot);
|
|
3382
3682
|
if (manifest) return { requestedVersion, version: manifest.minecraftVersion, root, manifest };
|
|
3383
|
-
const requested =
|
|
3683
|
+
const requested = parseRelease(requestedVersion);
|
|
3384
3684
|
if (!requested) {
|
|
3385
3685
|
throw new Error(`No MineRender data is published for ${requestedVersion}; automatic fallback requires a release`);
|
|
3386
3686
|
}
|
|
@@ -3392,14 +3692,12 @@ var init_MineRenderData = __esm({
|
|
|
3392
3692
|
}
|
|
3393
3693
|
return value.versions;
|
|
3394
3694
|
});
|
|
3395
|
-
const
|
|
3396
|
-
const sameLine = versions.filter((entry) => entry.number[0] === requested[0] && entry.number[1] === requested[1]);
|
|
3397
|
-
const selected = sameLine.sort((left, right) => Math.abs((left.number[2] ?? 0) - (requested[2] ?? 0)) - Math.abs((right.number[2] ?? 0) - (requested[2] ?? 0)) || compare2(left.number, right.number))[0] ?? versions.filter((entry) => compare2(entry.number, requested) <= 0).pop() ?? versions[0];
|
|
3695
|
+
const selected = nearestRelease(requestedVersion, index.map((entry) => entry.name));
|
|
3398
3696
|
if (!selected) throw new Error(`No compatible MineRender data is published for ${requestedVersion}`);
|
|
3399
|
-
const resolvedRoot = `${base}/${selected
|
|
3400
|
-
manifest = await this.manifest(resolvedRoot, selected
|
|
3401
|
-
if (!manifest) throw new Error(`Missing MineRender manifest for published version ${selected
|
|
3402
|
-
return { requestedVersion, version: selected
|
|
3697
|
+
const resolvedRoot = `${base}/${selected}`;
|
|
3698
|
+
manifest = await this.manifest(resolvedRoot, selected, resolvedRoot);
|
|
3699
|
+
if (!manifest) throw new Error(`Missing MineRender manifest for published version ${selected}`);
|
|
3700
|
+
return { requestedVersion, version: selected, root: resolvedRoot, manifest };
|
|
3403
3701
|
});
|
|
3404
3702
|
}
|
|
3405
3703
|
static async manifest(root, expectedVersion, requestRoot) {
|
|
@@ -3731,22 +4029,6 @@ var init_ItemDefaults = __esm({
|
|
|
3731
4029
|
}
|
|
3732
4030
|
});
|
|
3733
4031
|
|
|
3734
|
-
// src/error/MineRenderError.ts
|
|
3735
|
-
var MineRenderError;
|
|
3736
|
-
var init_MineRenderError = __esm({
|
|
3737
|
-
"src/error/MineRenderError.ts"() {
|
|
3738
|
-
MineRenderError = class _MineRenderError extends Error {
|
|
3739
|
-
constructor(msg) {
|
|
3740
|
-
super(msg);
|
|
3741
|
-
Object.setPrototypeOf(this, _MineRenderError.prototype);
|
|
3742
|
-
}
|
|
3743
|
-
get name() {
|
|
3744
|
-
return "MineRenderError";
|
|
3745
|
-
}
|
|
3746
|
-
};
|
|
3747
|
-
}
|
|
3748
|
-
});
|
|
3749
|
-
|
|
3750
4032
|
// src/texture/Colormaps.ts
|
|
3751
4033
|
var Colormaps;
|
|
3752
4034
|
var init_Colormaps = __esm({
|
|
@@ -4527,6 +4809,7 @@ var init_BlockEntities = __esm({
|
|
|
4527
4809
|
"src/assets/BlockEntities.ts"() {
|
|
4528
4810
|
import_three9 = require("three");
|
|
4529
4811
|
init_AssetKey();
|
|
4812
|
+
init_Entities();
|
|
4530
4813
|
init_AssetLoader();
|
|
4531
4814
|
init_source();
|
|
4532
4815
|
init_Caching();
|
|
@@ -4543,6 +4826,7 @@ var init_BlockEntities = __esm({
|
|
|
4543
4826
|
key.rootType = void 0;
|
|
4544
4827
|
const index = await Caching.blockEntityIndexCache.get(key.serialize(), async () => {
|
|
4545
4828
|
try {
|
|
4829
|
+
key.root = await Entities.getDatasetRoot(root);
|
|
4546
4830
|
return await AssetLoader.get(key, "json" /* JSON */) ?? {};
|
|
4547
4831
|
} catch (error) {
|
|
4548
4832
|
log9.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
|
|
@@ -4628,136 +4912,6 @@ var init_DecoratedPots = __esm({
|
|
|
4628
4912
|
}
|
|
4629
4913
|
});
|
|
4630
4914
|
|
|
4631
|
-
// src/assets/Entities.ts
|
|
4632
|
-
var Entities;
|
|
4633
|
-
var init_Entities = __esm({
|
|
4634
|
-
"src/assets/Entities.ts"() {
|
|
4635
|
-
init_AssetKey();
|
|
4636
|
-
init_AssetLoader();
|
|
4637
|
-
init_source();
|
|
4638
|
-
init_Caching();
|
|
4639
|
-
init_AssetDefaults();
|
|
4640
|
-
init_MineRenderError();
|
|
4641
|
-
init_ModelTextures();
|
|
4642
|
-
Entities = class {
|
|
4643
|
-
/** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */
|
|
4644
|
-
static async getEntityList() {
|
|
4645
|
-
const collect = async (path) => {
|
|
4646
|
-
const prefix2 = path ? `${path}/` : "";
|
|
4647
|
-
const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
|
|
4648
|
-
const list2 = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
|
|
4649
|
-
if (!list2) return [];
|
|
4650
|
-
const files = list2.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
|
|
4651
|
-
const children = await Promise.all(list2.directories.map((directory) => collect(`${prefix2}${directory}`)));
|
|
4652
|
-
return [...files, ...children.flat()];
|
|
4653
|
-
};
|
|
4654
|
-
return collect("");
|
|
4655
|
-
}
|
|
4656
|
-
static async getModelFile(modelKey) {
|
|
4657
|
-
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4658
|
-
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
|
|
4659
|
-
return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
4660
|
-
}
|
|
4661
|
-
/** Returns selectable geometry-layer names, or an empty list when the model is missing. */
|
|
4662
|
-
static async getLayerList(modelKey) {
|
|
4663
|
-
return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
|
|
4664
|
-
}
|
|
4665
|
-
/** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
|
|
4666
|
-
static async getPassList(modelKey) {
|
|
4667
|
-
return (await this.getModelFile(modelKey))?.passes ?? [];
|
|
4668
|
-
}
|
|
4669
|
-
/**
|
|
4670
|
-
* Loads the layers and textures to pass to {@link MineRenderScene.addEntity}.
|
|
4671
|
-
* By default, selects `main`, unconditional passes, and passes enabled by `options.when`.
|
|
4672
|
-
*
|
|
4673
|
-
* @param modelKey - Dataset model, such as `new BasicAssetKey("minecraft", "zombie")`.
|
|
4674
|
-
* @param textureKey - Texture override for the first selected layer.
|
|
4675
|
-
* @param options - Layer selection, conditional passes, and per-layer texture overrides.
|
|
4676
|
-
* @returns The selected model, or `undefined` when its dataset file is missing.
|
|
4677
|
-
*/
|
|
4678
|
-
static async getEntity(modelKey, textureKey, options) {
|
|
4679
|
-
const model = await this.getModelFile(modelKey);
|
|
4680
|
-
if (!model) return void 0;
|
|
4681
|
-
const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
|
|
4682
|
-
const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
|
|
4683
|
-
if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
|
|
4684
|
-
draws.push(...passes);
|
|
4685
|
-
const names = [];
|
|
4686
|
-
const selected = draws.map((pass) => {
|
|
4687
|
-
const layer = model.layers[pass.layer];
|
|
4688
|
-
if (!layer) {
|
|
4689
|
-
throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
|
|
4690
|
-
}
|
|
4691
|
-
let name = pass.layer;
|
|
4692
|
-
for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;
|
|
4693
|
-
names.push(name);
|
|
4694
|
-
return { name, layer, pass };
|
|
4695
|
-
});
|
|
4696
|
-
const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {
|
|
4697
|
-
const override = options?.textures?.[name] ?? (index === 0 ? textureKey : void 0);
|
|
4698
|
-
const textureLocation = pass.textureLocation ?? layer.textureLocation;
|
|
4699
|
-
let texture;
|
|
4700
|
-
if (override) {
|
|
4701
|
-
const path = isAssetKey(override) ? override.getFullPath() : override.path;
|
|
4702
|
-
texture = isAssetKey(override) && override.assetType === "textures" && path.startsWith("entity/") ? override : new AssetKey(override.namespace, path, "textures", "entity", "assets", ".png", isAssetKey(override) ? override.root : void 0);
|
|
4703
|
-
} else if (textureLocation !== void 0) {
|
|
4704
|
-
texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
4705
|
-
if (isAssetKey(modelKey)) texture.root = modelKey.root;
|
|
4706
|
-
} else {
|
|
4707
|
-
texture = await this.resolveTexture(modelKey);
|
|
4708
|
-
}
|
|
4709
|
-
const render = pass.render ?? layer.render;
|
|
4710
|
-
return [name, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
|
|
4711
|
-
})));
|
|
4712
|
-
return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
|
|
4713
|
-
}
|
|
4714
|
-
/**
|
|
4715
|
-
* Native and sampled vanilla clips by name, or undefined when the model or selected version has none.
|
|
4716
|
-
*/
|
|
4717
|
-
static async getAnimations(modelKey) {
|
|
4718
|
-
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4719
|
-
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
|
|
4720
|
-
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
4721
|
-
return file?.animations;
|
|
4722
|
-
}
|
|
4723
|
-
/** Finds a fallback texture using the model path, its directory, and vanilla variant data. */
|
|
4724
|
-
static async resolveTexture(modelKey) {
|
|
4725
|
-
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
4726
|
-
const root = isAssetKey(modelKey) ? modelKey.root : void 0;
|
|
4727
|
-
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", root);
|
|
4728
|
-
return Caching.entityTextureCache.get(key.serialize(), async () => {
|
|
4729
|
-
const name = path.split("/").pop();
|
|
4730
|
-
for (const candidate of [path, `${path}/${name}`]) {
|
|
4731
|
-
const texture2 = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png", root);
|
|
4732
|
-
if (await ModelTextures.get(texture2)) return texture2;
|
|
4733
|
-
}
|
|
4734
|
-
const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json", root);
|
|
4735
|
-
const list2 = await AssetLoader.get(listKey, "list" /* LIST */);
|
|
4736
|
-
const files = list2?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
|
|
4737
|
-
const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
|
|
4738
|
-
if (!file) return void 0;
|
|
4739
|
-
const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json", root);
|
|
4740
|
-
const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
|
|
4741
|
-
const assets = variant?.assets;
|
|
4742
|
-
const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
|
|
4743
|
-
if (typeof textureId !== "string") return void 0;
|
|
4744
|
-
const texture = AssetKey.parse("textures", textureId);
|
|
4745
|
-
texture.root = root;
|
|
4746
|
-
return texture;
|
|
4747
|
-
});
|
|
4748
|
-
}
|
|
4749
|
-
/** @deprecated Use getEntityList(); block entities share the entity dataset. */
|
|
4750
|
-
static getBlockList() {
|
|
4751
|
-
return this.getEntityList();
|
|
4752
|
-
}
|
|
4753
|
-
/** @deprecated Use getEntity(); block entities share the entity dataset. */
|
|
4754
|
-
static getBlock(modelKey, textureKey, options) {
|
|
4755
|
-
return this.getEntity(modelKey, textureKey, options);
|
|
4756
|
-
}
|
|
4757
|
-
};
|
|
4758
|
-
}
|
|
4759
|
-
});
|
|
4760
|
-
|
|
4761
4915
|
// src/assets/_fonts/Unihex.ts
|
|
4762
4916
|
var Unihex_exports = {};
|
|
4763
4917
|
__export(Unihex_exports, {
|
|
@@ -5898,6 +6052,266 @@ var init_model = __esm({
|
|
|
5898
6052
|
}
|
|
5899
6053
|
});
|
|
5900
6054
|
|
|
6055
|
+
// src/model/ItemGlint.ts
|
|
6056
|
+
var ItemGlint_exports = {};
|
|
6057
|
+
__export(ItemGlint_exports, {
|
|
6058
|
+
ItemGlint: () => ItemGlint
|
|
6059
|
+
});
|
|
6060
|
+
var import_three14, ItemGlint;
|
|
6061
|
+
var init_ItemGlint = __esm({
|
|
6062
|
+
"src/model/ItemGlint.ts"() {
|
|
6063
|
+
import_three14 = require("three");
|
|
6064
|
+
init_AssetKey();
|
|
6065
|
+
init_Models();
|
|
6066
|
+
init_ModelTextures();
|
|
6067
|
+
init_Caching();
|
|
6068
|
+
init_Textures();
|
|
6069
|
+
init_Ticker();
|
|
6070
|
+
init_CubeFace();
|
|
6071
|
+
init_DisplayPosition();
|
|
6072
|
+
ItemGlint = class _ItemGlint {
|
|
6073
|
+
constructor(owner, material) {
|
|
6074
|
+
this.owner = owner;
|
|
6075
|
+
this.material = material;
|
|
6076
|
+
this.updateTime();
|
|
6077
|
+
}
|
|
6078
|
+
/** Enables glint for enchantments or a lodestone compass unless a boolean component overrides them. */
|
|
6079
|
+
static enabled(components = {}, itemId) {
|
|
6080
|
+
const override = Models.componentValue(components, "enchantment_glint_override");
|
|
6081
|
+
if (override !== void 0) {
|
|
6082
|
+
if (typeof override !== "boolean") throw new Error("Item enchantment_glint_override must be a boolean");
|
|
6083
|
+
return override;
|
|
6084
|
+
}
|
|
6085
|
+
if (itemId === "minecraft:compass") {
|
|
6086
|
+
Models.componentValue(components, "lodestone_tracker");
|
|
6087
|
+
if (Object.prototype.hasOwnProperty.call(components, "lodestone_tracker") || Object.prototype.hasOwnProperty.call(components, "minecraft:lodestone_tracker")) return true;
|
|
6088
|
+
}
|
|
6089
|
+
const enchantments = Models.componentValue(components, "enchantments");
|
|
6090
|
+
if (enchantments === void 0) return false;
|
|
6091
|
+
if (!enchantments || typeof enchantments !== "object" || Array.isArray(enchantments)) throw new Error("Item enchantments must be an object");
|
|
6092
|
+
return Object.keys(enchantments).length > 0;
|
|
6093
|
+
}
|
|
6094
|
+
/** @internal */
|
|
6095
|
+
static async create(owner, baseMap, root, entityMeshes, kind = "item") {
|
|
6096
|
+
const key = new AssetKey("minecraft", `enchanted_glint_${kind}`, "textures", "misc", "assets", ".png", root);
|
|
6097
|
+
const assetKey = key.serialize(), textureKey = `item-glint:${assetKey}`;
|
|
6098
|
+
let texture = Caching.textureCache.getIfPresent(textureKey);
|
|
6099
|
+
if (!texture) {
|
|
6100
|
+
const pending = ModelTextures.get(key);
|
|
6101
|
+
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKey);
|
|
6102
|
+
const [image, metadata] = await Promise.all([pending, ModelTextures.getMeta(key)]);
|
|
6103
|
+
if (!image) throw new Error(`Missing ${kind} glint texture ${key.toNamespacedString()}`);
|
|
6104
|
+
if (cachedAsset && Caching.textureAssetCache.getIfPresent(assetKey) !== cachedAsset) return this.create(owner, baseMap, root, entityMeshes, kind);
|
|
6105
|
+
texture = Caching.textureCache.get(textureKey, () => {
|
|
6106
|
+
const texture2 = Textures.createCanvasTexture(image.data.canvas);
|
|
6107
|
+
texture2.wrapS = texture2.wrapT = metadata?.texture?.clamp ? import_three14.ClampToEdgeWrapping : import_three14.RepeatWrapping;
|
|
6108
|
+
if (metadata?.texture?.blur) texture2.magFilter = texture2.minFilter = import_three14.LinearFilter;
|
|
6109
|
+
return texture2;
|
|
6110
|
+
});
|
|
6111
|
+
}
|
|
6112
|
+
const material = new import_three14.ShaderMaterial({
|
|
6113
|
+
name: "item-glint",
|
|
6114
|
+
transparent: true,
|
|
6115
|
+
depthWrite: false,
|
|
6116
|
+
depthFunc: import_three14.EqualDepth,
|
|
6117
|
+
side: import_three14.DoubleSide,
|
|
6118
|
+
forceSinglePass: true,
|
|
6119
|
+
blending: import_three14.CustomBlending,
|
|
6120
|
+
blendSrc: import_three14.SrcColorFactor,
|
|
6121
|
+
blendDst: import_three14.OneFactor,
|
|
6122
|
+
blendSrcAlpha: import_three14.ZeroFactor,
|
|
6123
|
+
blendDstAlpha: import_three14.OneFactor,
|
|
6124
|
+
toneMapped: false,
|
|
6125
|
+
// TextureTransform.ARMOR_ENTITY_GLINT_TEXTURING uses a smaller UV scale than item glint.
|
|
6126
|
+
defines: entityMeshes ? { ENTITY_GLINT: true, ENTITY_GLINT_SCALE: kind === "armor" ? "0.16" : "0.5" } : {},
|
|
6127
|
+
uniforms: {
|
|
6128
|
+
...!entityMeshes && { baseMap: { value: baseMap } },
|
|
6129
|
+
glintMap: { value: texture },
|
|
6130
|
+
glintOffset: { value: new import_three14.Vector2() },
|
|
6131
|
+
glintAlpha: { value: 0.75 }
|
|
6132
|
+
},
|
|
6133
|
+
vertexShader: `
|
|
6134
|
+
uniform vec2 glintOffset;
|
|
6135
|
+
#ifndef ENTITY_GLINT
|
|
6136
|
+
attribute vec4 uvBounds;
|
|
6137
|
+
attribute vec2 glintUv;
|
|
6138
|
+
flat out vec4 vUvBounds;
|
|
6139
|
+
centroid out vec2 vUv;
|
|
6140
|
+
#endif
|
|
6141
|
+
varying vec2 vGlintUv;
|
|
6142
|
+
void main() {
|
|
6143
|
+
#ifdef ENTITY_GLINT
|
|
6144
|
+
vec2 p = vec2(uv.x, 1.0 - uv.y) * ENTITY_GLINT_SCALE;
|
|
6145
|
+
#else
|
|
6146
|
+
vUv = uv;
|
|
6147
|
+
vUvBounds = uvBounds;
|
|
6148
|
+
vec2 p = glintUv * 8.0;
|
|
6149
|
+
#endif
|
|
6150
|
+
float angle = radians(10.0);
|
|
6151
|
+
vGlintUv = vec2(cos(angle) * p.x - sin(angle) * p.y, sin(angle) * p.x + cos(angle) * p.y) + glintOffset;
|
|
6152
|
+
vec4 mvPosition = vec4(position, 1.0);
|
|
6153
|
+
mvPosition = modelViewMatrix * mvPosition;
|
|
6154
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
6155
|
+
}
|
|
6156
|
+
`,
|
|
6157
|
+
fragmentShader: `
|
|
6158
|
+
#ifndef ENTITY_GLINT
|
|
6159
|
+
uniform sampler2D baseMap;
|
|
6160
|
+
flat in vec4 vUvBounds;
|
|
6161
|
+
centroid in vec2 vUv;
|
|
6162
|
+
#endif
|
|
6163
|
+
uniform sampler2D glintMap;
|
|
6164
|
+
uniform float glintAlpha;
|
|
6165
|
+
varying vec2 vGlintUv;
|
|
6166
|
+
void main() {
|
|
6167
|
+
#ifndef ENTITY_GLINT
|
|
6168
|
+
vec2 mapUv = clamp(vUv, vUvBounds.xy, vUvBounds.zw);
|
|
6169
|
+
if (texture2D(baseMap, mapUv).a < 0.01) discard;
|
|
6170
|
+
#endif
|
|
6171
|
+
vec4 color = texture2D(glintMap, vec2(vGlintUv.x, 1.0 - vGlintUv.y));
|
|
6172
|
+
if (color.a < 0.1) discard;
|
|
6173
|
+
gl_FragColor = color;
|
|
6174
|
+
#include <colorspace_fragment>
|
|
6175
|
+
gl_FragColor.rgb *= glintAlpha;
|
|
6176
|
+
}
|
|
6177
|
+
`
|
|
6178
|
+
});
|
|
6179
|
+
if (!entityMeshes) Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });
|
|
6180
|
+
const targets = entityMeshes ? [...entityMeshes] : [];
|
|
6181
|
+
if (!entityMeshes) owner.iterateAllMeshes((mesh) => targets.push({ mesh }));
|
|
6182
|
+
for (const { mesh: base, parent = base } of targets) {
|
|
6183
|
+
const pass = new import_three14.Mesh(base.geometry, material);
|
|
6184
|
+
pass.name = `${base.name}:glint`;
|
|
6185
|
+
pass.userData.minerenderItemGlint = true;
|
|
6186
|
+
pass.raycast = () => {
|
|
6187
|
+
};
|
|
6188
|
+
pass.renderOrder = parent.renderOrder + 0.5;
|
|
6189
|
+
parent.add(pass);
|
|
6190
|
+
}
|
|
6191
|
+
return new _ItemGlint(owner, material);
|
|
6192
|
+
}
|
|
6193
|
+
/**
|
|
6194
|
+
* Maps glint before model centering and display transforms. Ordinary sprites approximate Minecraft's shared atlas density.
|
|
6195
|
+
* @internal
|
|
6196
|
+
*/
|
|
6197
|
+
static mapUvs(geometry, faces, atlas, itemId, display) {
|
|
6198
|
+
const uv = geometry.getAttribute("uv");
|
|
6199
|
+
const mapped = new Float32Array(uv.count * 2);
|
|
6200
|
+
if (itemId === "minecraft:compass" || itemId === "minecraft:recovery_compass" || itemId === "minecraft:clock") {
|
|
6201
|
+
const positions = geometry.getAttribute("position"), normals = geometry.getAttribute("normal");
|
|
6202
|
+
const scale = display === "gui" /* GUI */ ? 0.5 : display === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || display === "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */ ? 0.75 : 1;
|
|
6203
|
+
const factor = 1 / (16 * 128 * scale);
|
|
6204
|
+
for (let index = 0; index < positions.count; index++) {
|
|
6205
|
+
const x = positions.getX(index), y = positions.getY(index), z = positions.getZ(index);
|
|
6206
|
+
const nx = normals.getX(index), ny = normals.getY(index), nz = normals.getZ(index);
|
|
6207
|
+
const ax = Math.abs(nx), ay = Math.abs(ny), az = Math.abs(nz);
|
|
6208
|
+
let u, v;
|
|
6209
|
+
if (ay >= az && ay >= ax) {
|
|
6210
|
+
u = x;
|
|
6211
|
+
v = ny < 0 ? -z : z;
|
|
6212
|
+
} else if (az >= ax) {
|
|
6213
|
+
u = nz < 0 ? -x : x;
|
|
6214
|
+
v = -y;
|
|
6215
|
+
} else {
|
|
6216
|
+
u = nx < 0 ? -z : z;
|
|
6217
|
+
v = -y;
|
|
6218
|
+
}
|
|
6219
|
+
mapped[index * 2] = u * factor;
|
|
6220
|
+
mapped[index * 2 + 1] = v * factor;
|
|
6221
|
+
}
|
|
6222
|
+
geometry.setAttribute("glintUv", new import_three14.Float32BufferAttribute(mapped, 2));
|
|
6223
|
+
return;
|
|
6224
|
+
}
|
|
6225
|
+
for (const [faceIndex, face] of CUBE_FACES.entries()) {
|
|
6226
|
+
const texture = faces[face]?.texture?.substring(1);
|
|
6227
|
+
const position = texture && atlas.positions[texture] || [0, 0];
|
|
6228
|
+
const size = texture && atlas.sizes[texture] || [atlas.image.width, atlas.image.height];
|
|
6229
|
+
for (let corner = 0; corner < 4; corner++) {
|
|
6230
|
+
const index = faceIndex * 4 + corner;
|
|
6231
|
+
mapped[index * 2] = (uv.getX(index) * atlas.image.width - position[0]) / size[0] / 32;
|
|
6232
|
+
mapped[index * 2 + 1] = ((1 - uv.getY(index)) * atlas.image.height - position[1]) / size[1] / 32;
|
|
6233
|
+
}
|
|
6234
|
+
}
|
|
6235
|
+
geometry.setAttribute("glintUv", new import_three14.Float32BufferAttribute(mapped, 2));
|
|
6236
|
+
}
|
|
6237
|
+
updateTime() {
|
|
6238
|
+
const time = Math.trunc(Date.now() * 4);
|
|
6239
|
+
this.material.uniforms.glintOffset.value.set(-(time % 11e4) / 11e4, time % 3e4 / 3e4);
|
|
6240
|
+
}
|
|
6241
|
+
/** @internal */
|
|
6242
|
+
updateSubscription(active) {
|
|
6243
|
+
if (active && this.ticker === void 0) {
|
|
6244
|
+
this.updateTime();
|
|
6245
|
+
this.ticker = Ticker.add(() => {
|
|
6246
|
+
this.updateTime();
|
|
6247
|
+
this.owner.notifyDirty();
|
|
6248
|
+
});
|
|
6249
|
+
} else if (!active) {
|
|
6250
|
+
Ticker.remove(this.ticker);
|
|
6251
|
+
this.ticker = void 0;
|
|
6252
|
+
}
|
|
6253
|
+
}
|
|
6254
|
+
dispose() {
|
|
6255
|
+
Ticker.remove(this.ticker);
|
|
6256
|
+
this.ticker = void 0;
|
|
6257
|
+
this.material.dispose();
|
|
6258
|
+
}
|
|
6259
|
+
};
|
|
6260
|
+
}
|
|
6261
|
+
});
|
|
6262
|
+
|
|
6263
|
+
// src/texture/PalettedTextures.ts
|
|
6264
|
+
var PalettedTextures_exports = {};
|
|
6265
|
+
__export(PalettedTextures_exports, {
|
|
6266
|
+
PalettedTextures: () => PalettedTextures
|
|
6267
|
+
});
|
|
6268
|
+
var PalettedTextures;
|
|
6269
|
+
var init_PalettedTextures = __esm({
|
|
6270
|
+
"src/texture/PalettedTextures.ts"() {
|
|
6271
|
+
init_ModelTextures();
|
|
6272
|
+
init_Caching();
|
|
6273
|
+
init_CanvasImage();
|
|
6274
|
+
init_MineRenderError();
|
|
6275
|
+
PalettedTextures = class {
|
|
6276
|
+
/** Loads a texture with a palette permutation, sharing the resulting canvas between callers. */
|
|
6277
|
+
static async get(texture, key, permutation2) {
|
|
6278
|
+
return Caching.canvasImageDataCache.get(`palette:${texture.serialize()}:${key.serialize()}:${permutation2.serialize()}`, async () => {
|
|
6279
|
+
const source = await ModelTextures.get(texture);
|
|
6280
|
+
if (!source) return void 0;
|
|
6281
|
+
const [palette, replacement] = await Promise.all([ModelTextures.get(key), ModelTextures.get(permutation2)]);
|
|
6282
|
+
if (!palette) throw new MineRenderError(`Missing palette ${key.toNamespacedString()}`);
|
|
6283
|
+
if (!replacement) throw new MineRenderError(`Missing palette ${permutation2.toNamespacedString()}`);
|
|
6284
|
+
const pixels = source.data.getImageData(0, 0, source.width, source.height);
|
|
6285
|
+
const colors2 = palette.data.getImageData(0, 0, palette.width, palette.height).data;
|
|
6286
|
+
const replacements = replacement.data.getImageData(0, 0, replacement.width, replacement.height).data;
|
|
6287
|
+
const image = new CanvasImage(source.width, source.height);
|
|
6288
|
+
const output = image.context.createImageData(source.width, source.height);
|
|
6289
|
+
output.data.set(this.permute(pixels.data, colors2, replacements));
|
|
6290
|
+
image.putData(output);
|
|
6291
|
+
return { data: image.context, width: image.width, height: image.height };
|
|
6292
|
+
});
|
|
6293
|
+
}
|
|
6294
|
+
/** @internal */
|
|
6295
|
+
static permute(pixels, key, permutation2) {
|
|
6296
|
+
if (key.length !== permutation2.length) throw new MineRenderError("Palette images must have the same pixel count");
|
|
6297
|
+
const mapping = /* @__PURE__ */ new Map();
|
|
6298
|
+
for (let i = 0; i < key.length; i += 4) {
|
|
6299
|
+
if (key[i + 3] !== 0) mapping.set(key[i] << 16 | key[i + 1] << 8 | key[i + 2], i);
|
|
6300
|
+
}
|
|
6301
|
+
const output = new Uint8ClampedArray(pixels);
|
|
6302
|
+
for (let i = 0; i < pixels.length; i += 4) {
|
|
6303
|
+
if (pixels[i + 3] === 0) continue;
|
|
6304
|
+
const mapped = mapping.get(pixels[i] << 16 | pixels[i + 1] << 8 | pixels[i + 2]);
|
|
6305
|
+
if (mapped === void 0) continue;
|
|
6306
|
+
output.set(permutation2.subarray(mapped, mapped + 3), i);
|
|
6307
|
+
output[i + 3] = Math.floor(pixels[i + 3] * permutation2[mapped + 3] / 255);
|
|
6308
|
+
}
|
|
6309
|
+
return output;
|
|
6310
|
+
}
|
|
6311
|
+
};
|
|
6312
|
+
}
|
|
6313
|
+
});
|
|
6314
|
+
|
|
5901
6315
|
// src/entity/scene/EntityObject.ts
|
|
5902
6316
|
var EntityObject_exports = {};
|
|
5903
6317
|
__export(EntityObject_exports, {
|
|
@@ -5907,13 +6321,13 @@ __export(EntityObject_exports, {
|
|
|
5907
6321
|
function isEntityObject(obj) {
|
|
5908
6322
|
return obj.isEntityObject;
|
|
5909
6323
|
}
|
|
5910
|
-
var
|
|
6324
|
+
var import_three15, ItemGlintClass, PalettedTexturesClass, EntityObject;
|
|
5911
6325
|
var init_EntityObject = __esm({
|
|
5912
6326
|
"src/entity/scene/EntityObject.ts"() {
|
|
5913
6327
|
init_SceneObject();
|
|
5914
6328
|
init_Caching();
|
|
5915
6329
|
init_merge();
|
|
5916
|
-
|
|
6330
|
+
import_three15 = require("three");
|
|
5917
6331
|
init_Ticker();
|
|
5918
6332
|
init_model();
|
|
5919
6333
|
init_ModelTextures();
|
|
@@ -5938,8 +6352,14 @@ var init_EntityObject = __esm({
|
|
|
5938
6352
|
this.animationPlayers = [];
|
|
5939
6353
|
this.partPoses = /* @__PURE__ */ new Map();
|
|
5940
6354
|
this.options = (0, import_ts_deepmerge.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
|
|
5941
|
-
this.addEventListener("added", () =>
|
|
5942
|
-
|
|
6355
|
+
this.addEventListener("added", () => {
|
|
6356
|
+
this.updateScrollSubscription();
|
|
6357
|
+
this.glint?.updateSubscription(!!this.parent);
|
|
6358
|
+
});
|
|
6359
|
+
this.addEventListener("removed", () => {
|
|
6360
|
+
this.updateScrollSubscription();
|
|
6361
|
+
this.glint?.updateSubscription(!!this.parent);
|
|
6362
|
+
});
|
|
5943
6363
|
}
|
|
5944
6364
|
static {
|
|
5945
6365
|
this.DEFAULT_OPTIONS = (0, import_ts_deepmerge.default)({}, SceneObject.DEFAULT_OPTIONS);
|
|
@@ -5953,12 +6373,26 @@ var init_EntityObject = __esm({
|
|
|
5953
6373
|
mesh.material = material;
|
|
5954
6374
|
});
|
|
5955
6375
|
this.notifyDirty();
|
|
5956
|
-
} else
|
|
6376
|
+
} else {
|
|
6377
|
+
await this.applyTextures();
|
|
6378
|
+
const layers = Object.entries(this.entityLayers).filter(([, layer]) => layer.glint);
|
|
6379
|
+
const meshes = [];
|
|
6380
|
+
for (const [name] of layers) this.getLayerGroup(name)?.traverse((object4) => {
|
|
6381
|
+
if (isMesh(object4)) meshes.push(object4);
|
|
6382
|
+
});
|
|
6383
|
+
if (meshes.length) {
|
|
6384
|
+
const ItemGlint2 = ItemGlintClass ??= (await Promise.resolve().then(() => (init_ItemGlint(), ItemGlint_exports))).ItemGlint;
|
|
6385
|
+
this.glint = await ItemGlint2.create(this, void 0, this.getTextureKey(layers[0][1]).root, meshes.map((mesh) => ({ mesh })), "armor");
|
|
6386
|
+
this.glint.updateSubscription(!!this.parent);
|
|
6387
|
+
}
|
|
6388
|
+
}
|
|
5957
6389
|
}
|
|
5958
6390
|
dispose() {
|
|
5959
6391
|
super.dispose();
|
|
5960
6392
|
}
|
|
5961
6393
|
disposeAndRemoveAllChildren() {
|
|
6394
|
+
this.glint?.dispose();
|
|
6395
|
+
this.glint = void 0;
|
|
5962
6396
|
this.clearScrollMaterials();
|
|
5963
6397
|
for (const geometry of this.geometries) geometry.dispose();
|
|
5964
6398
|
this.geometries.clear();
|
|
@@ -6117,17 +6551,21 @@ var init_EntityObject = __esm({
|
|
|
6117
6551
|
);
|
|
6118
6552
|
}
|
|
6119
6553
|
async loadTextures(layer = this.entity) {
|
|
6554
|
+
if (layer.palette) {
|
|
6555
|
+
const PalettedTextures2 = PalettedTexturesClass ??= (await Promise.resolve().then(() => (init_PalettedTextures(), PalettedTextures_exports))).PalettedTextures;
|
|
6556
|
+
return PalettedTextures2.get(this.getTextureKey(layer), layer.palette.key, layer.palette.permutation);
|
|
6557
|
+
}
|
|
6120
6558
|
return ModelTextures.get(this.getTextureKey(layer));
|
|
6121
6559
|
}
|
|
6122
6560
|
createMeshes(force = false) {
|
|
6123
6561
|
if (this.meshesCreated && !force) return;
|
|
6124
|
-
const modelRoot = new
|
|
6562
|
+
const modelRoot = new import_three15.Object3D();
|
|
6125
6563
|
let transformNode = modelRoot;
|
|
6126
6564
|
const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
|
|
6127
6565
|
if (transform) {
|
|
6128
6566
|
for (const [index, op] of transform.entries()) {
|
|
6129
6567
|
if (index > 0) {
|
|
6130
|
-
const child = new
|
|
6568
|
+
const child = new import_three15.Object3D();
|
|
6131
6569
|
transformNode.add(child);
|
|
6132
6570
|
transformNode = child;
|
|
6133
6571
|
}
|
|
@@ -6189,10 +6627,10 @@ var init_EntityObject = __esm({
|
|
|
6189
6627
|
this.clearScrollMaterials();
|
|
6190
6628
|
const results = await Promise.allSettled(Object.entries(this.entityLayers).map(async ([name, layer]) => {
|
|
6191
6629
|
const mode = layer.render ?? layer.layer.render ?? "cutout";
|
|
6192
|
-
const tint = layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint];
|
|
6630
|
+
const tint = (layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint]) ?? layer.color;
|
|
6193
6631
|
const scroll = Materials.entityModeScroll(mode);
|
|
6194
6632
|
const assetKeyStr = this.getTextureKey(layer).serialize();
|
|
6195
|
-
const keyStr = `entity:${mode}:${tint === void 0 ? "" : new
|
|
6633
|
+
const keyStr = `entity:${mode}:${tint === void 0 ? "" : new import_three15.Color(tint).getHexString()}:${assetKeyStr}` + (layer.palette ? `:${layer.palette.key.serialize()}:${layer.palette.permutation.serialize()}` : "");
|
|
6196
6634
|
let mat = scroll ? void 0 : Caching.materialCache.getIfPresent(keyStr);
|
|
6197
6635
|
if (!mat) {
|
|
6198
6636
|
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
|
|
@@ -6255,7 +6693,7 @@ function getMinMax(attribute, start, count) {
|
|
|
6255
6693
|
else if (a === 2) value = attribute.getZ(i);
|
|
6256
6694
|
else if (a === 3) value = attribute.getW(i);
|
|
6257
6695
|
if (attribute.normalized === true) {
|
|
6258
|
-
value =
|
|
6696
|
+
value = import_three19.MathUtils.normalize(value, attribute.array);
|
|
6259
6697
|
}
|
|
6260
6698
|
}
|
|
6261
6699
|
output.min[a] = Math.min(output.min[a], value);
|
|
@@ -6303,10 +6741,10 @@ function getToBlobPromise(canvas, mimeType) {
|
|
|
6303
6741
|
return new Promise((resolve) => canvas.toBlob(resolve, mimeType));
|
|
6304
6742
|
}
|
|
6305
6743
|
}
|
|
6306
|
-
var
|
|
6744
|
+
var import_three19, KHR_mesh_quantization_ExtraAttrTypes, GLTFExporter, WEBGL_CONSTANTS, KHR_MESH_QUANTIZATION, THREE_TO_WEBGL, PATH_PROPERTIES, DEFAULT_SPECULAR_COLOR, GLB_HEADER_BYTES, GLB_HEADER_MAGIC, GLB_VERSION, GLB_CHUNK_PREFIX_BYTES, GLB_CHUNK_TYPE_JSON, GLB_CHUNK_TYPE_BIN, GLTFWriter, GLTFLightExtension, GLTFMaterialsUnlitExtension, GLTFMaterialsClearcoatExtension, GLTFMaterialsDispersionExtension, GLTFMaterialsIridescenceExtension, GLTFMaterialsTransmissionExtension, GLTFMaterialsVolumeExtension, GLTFMaterialsIorExtension, GLTFMaterialsSpecularExtension, GLTFMaterialsSheenExtension, GLTFMaterialsAnisotropyExtension, GLTFMaterialsEmissiveStrengthExtension, GLTFMaterialsBumpExtension, GLTFMeshGpuInstancing;
|
|
6307
6745
|
var init_GLTFExporter = __esm({
|
|
6308
6746
|
"../../node_modules/three/examples/jsm/exporters/GLTFExporter.js"() {
|
|
6309
|
-
|
|
6747
|
+
import_three19 = require("three");
|
|
6310
6748
|
KHR_mesh_quantization_ExtraAttrTypes = {
|
|
6311
6749
|
POSITION: [
|
|
6312
6750
|
"byte",
|
|
@@ -6485,22 +6923,22 @@ var init_GLTFExporter = __esm({
|
|
|
6485
6923
|
};
|
|
6486
6924
|
KHR_MESH_QUANTIZATION = "KHR_mesh_quantization";
|
|
6487
6925
|
THREE_TO_WEBGL = {};
|
|
6488
|
-
THREE_TO_WEBGL[
|
|
6489
|
-
THREE_TO_WEBGL[
|
|
6490
|
-
THREE_TO_WEBGL[
|
|
6491
|
-
THREE_TO_WEBGL[
|
|
6492
|
-
THREE_TO_WEBGL[
|
|
6493
|
-
THREE_TO_WEBGL[
|
|
6494
|
-
THREE_TO_WEBGL[
|
|
6495
|
-
THREE_TO_WEBGL[
|
|
6496
|
-
THREE_TO_WEBGL[
|
|
6926
|
+
THREE_TO_WEBGL[import_three19.NearestFilter] = WEBGL_CONSTANTS.NEAREST;
|
|
6927
|
+
THREE_TO_WEBGL[import_three19.NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
|
|
6928
|
+
THREE_TO_WEBGL[import_three19.NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
|
|
6929
|
+
THREE_TO_WEBGL[import_three19.LinearFilter] = WEBGL_CONSTANTS.LINEAR;
|
|
6930
|
+
THREE_TO_WEBGL[import_three19.LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
|
|
6931
|
+
THREE_TO_WEBGL[import_three19.LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
|
|
6932
|
+
THREE_TO_WEBGL[import_three19.ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
|
|
6933
|
+
THREE_TO_WEBGL[import_three19.RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
|
|
6934
|
+
THREE_TO_WEBGL[import_three19.MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
|
|
6497
6935
|
PATH_PROPERTIES = {
|
|
6498
6936
|
scale: "scale",
|
|
6499
6937
|
position: "translation",
|
|
6500
6938
|
quaternion: "rotation",
|
|
6501
6939
|
morphTargetInfluences: "weights"
|
|
6502
6940
|
};
|
|
6503
|
-
DEFAULT_SPECULAR_COLOR = new
|
|
6941
|
+
DEFAULT_SPECULAR_COLOR = new import_three19.Color();
|
|
6504
6942
|
GLB_HEADER_BYTES = 12;
|
|
6505
6943
|
GLB_HEADER_MAGIC = 1179937895;
|
|
6506
6944
|
GLB_VERSION = 2;
|
|
@@ -6524,7 +6962,7 @@ var init_GLTFExporter = __esm({
|
|
|
6524
6962
|
this.json = {
|
|
6525
6963
|
asset: {
|
|
6526
6964
|
version: "2.0",
|
|
6527
|
-
generator: "THREE.GLTFExporter r" +
|
|
6965
|
+
generator: "THREE.GLTFExporter r" + import_three19.REVISION
|
|
6528
6966
|
}
|
|
6529
6967
|
};
|
|
6530
6968
|
this.cache = {
|
|
@@ -6676,7 +7114,7 @@ var init_GLTFExporter = __esm({
|
|
|
6676
7114
|
isNormalizedNormalAttribute(normal) {
|
|
6677
7115
|
const cache = this.cache;
|
|
6678
7116
|
if (cache.attributesNormalized.has(normal)) return false;
|
|
6679
|
-
const v = new
|
|
7117
|
+
const v = new import_three19.Vector3();
|
|
6680
7118
|
for (let i = 0, il = normal.count; i < il; i++) {
|
|
6681
7119
|
if (Math.abs(v.fromBufferAttribute(normal, i).length() - 1) > 5e-4) return false;
|
|
6682
7120
|
}
|
|
@@ -6693,7 +7131,7 @@ var init_GLTFExporter = __esm({
|
|
|
6693
7131
|
const cache = this.cache;
|
|
6694
7132
|
if (cache.attributesNormalized.has(normal)) return cache.attributesNormalized.get(normal);
|
|
6695
7133
|
const attribute = normal.clone();
|
|
6696
|
-
const v = new
|
|
7134
|
+
const v = new import_three19.Vector3();
|
|
6697
7135
|
for (let i = 0, il = attribute.count; i < il; i++) {
|
|
6698
7136
|
v.fromBufferAttribute(attribute, i);
|
|
6699
7137
|
if (v.x === 0 && v.y === 0 && v.z === 0) {
|
|
@@ -6737,7 +7175,7 @@ var init_GLTFExporter = __esm({
|
|
|
6737
7175
|
async buildMetalRoughTextureAsync(metalnessMap, roughnessMap) {
|
|
6738
7176
|
if (metalnessMap === roughnessMap) return metalnessMap;
|
|
6739
7177
|
function getEncodingConversion(map) {
|
|
6740
|
-
if (map.colorSpace ===
|
|
7178
|
+
if (map.colorSpace === import_three19.SRGBColorSpace) {
|
|
6741
7179
|
return function SRGBToLinear(c) {
|
|
6742
7180
|
return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
|
|
6743
7181
|
};
|
|
@@ -6746,10 +7184,10 @@ var init_GLTFExporter = __esm({
|
|
|
6746
7184
|
return c;
|
|
6747
7185
|
};
|
|
6748
7186
|
}
|
|
6749
|
-
if (metalnessMap instanceof
|
|
7187
|
+
if (metalnessMap instanceof import_three19.CompressedTexture) {
|
|
6750
7188
|
metalnessMap = await this.decompressTextureAsync(metalnessMap);
|
|
6751
7189
|
}
|
|
6752
|
-
if (roughnessMap instanceof
|
|
7190
|
+
if (roughnessMap instanceof import_three19.CompressedTexture) {
|
|
6753
7191
|
roughnessMap = await this.decompressTextureAsync(roughnessMap);
|
|
6754
7192
|
}
|
|
6755
7193
|
const metalness = metalnessMap ? metalnessMap.image : null;
|
|
@@ -6784,8 +7222,8 @@ var init_GLTFExporter = __esm({
|
|
|
6784
7222
|
context.putImageData(composite, 0, 0);
|
|
6785
7223
|
const reference = metalnessMap || roughnessMap;
|
|
6786
7224
|
const texture = reference.clone();
|
|
6787
|
-
texture.source = new
|
|
6788
|
-
texture.colorSpace =
|
|
7225
|
+
texture.source = new import_three19.TextureSource(canvas);
|
|
7226
|
+
texture.colorSpace = import_three19.NoColorSpace;
|
|
6789
7227
|
texture.channel = (metalnessMap || roughnessMap).channel;
|
|
6790
7228
|
if (metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel) {
|
|
6791
7229
|
console.warn("THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.");
|
|
@@ -6806,7 +7244,7 @@ var init_GLTFExporter = __esm({
|
|
|
6806
7244
|
* @return {Promise<THREE.Texture>} The derived normal map texture.
|
|
6807
7245
|
*/
|
|
6808
7246
|
async buildNormalMapTextureAsync(normalMap, flipX, flipY) {
|
|
6809
|
-
if (normalMap instanceof
|
|
7247
|
+
if (normalMap instanceof import_three19.CompressedTexture) {
|
|
6810
7248
|
normalMap = await this.decompressTextureAsync(normalMap);
|
|
6811
7249
|
}
|
|
6812
7250
|
const image = normalMap.image;
|
|
@@ -6825,7 +7263,7 @@ var init_GLTFExporter = __esm({
|
|
|
6825
7263
|
}
|
|
6826
7264
|
context.putImageData(imageData, 0, 0);
|
|
6827
7265
|
const texture = normalMap.clone();
|
|
6828
|
-
texture.source = new
|
|
7266
|
+
texture.source = new import_three19.TextureSource(canvas);
|
|
6829
7267
|
return texture;
|
|
6830
7268
|
}
|
|
6831
7269
|
async decompressTextureAsync(texture, maxTextureSize = Infinity) {
|
|
@@ -6889,7 +7327,7 @@ var init_GLTFExporter = __esm({
|
|
|
6889
7327
|
else if (a === 2) value = attribute.getZ(i);
|
|
6890
7328
|
else if (a === 3) value = attribute.getW(i);
|
|
6891
7329
|
if (attribute.normalized === true) {
|
|
6892
|
-
value =
|
|
7330
|
+
value = import_three19.MathUtils.normalize(value, attribute.array);
|
|
6893
7331
|
}
|
|
6894
7332
|
}
|
|
6895
7333
|
if (componentType === WEBGL_CONSTANTS.FLOAT) {
|
|
@@ -7044,7 +7482,7 @@ var init_GLTFExporter = __esm({
|
|
|
7044
7482
|
ctx.scale(1, -1);
|
|
7045
7483
|
}
|
|
7046
7484
|
if (image.data !== void 0) {
|
|
7047
|
-
if (format2 !==
|
|
7485
|
+
if (format2 !== import_three19.RGBAFormat) {
|
|
7048
7486
|
console.error("GLTFExporter: Only RGBAFormat is supported.", format2);
|
|
7049
7487
|
}
|
|
7050
7488
|
if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
|
|
@@ -7072,7 +7510,7 @@ var init_GLTFExporter = __esm({
|
|
|
7072
7510
|
})
|
|
7073
7511
|
);
|
|
7074
7512
|
} else {
|
|
7075
|
-
imageDef.uri =
|
|
7513
|
+
imageDef.uri = import_three19.ImageUtils.getDataURL(canvas, mimeType);
|
|
7076
7514
|
}
|
|
7077
7515
|
const index = json.images.push(imageDef) - 1;
|
|
7078
7516
|
cachedImages[key] = index;
|
|
@@ -7109,7 +7547,7 @@ var init_GLTFExporter = __esm({
|
|
|
7109
7547
|
const json = this.json;
|
|
7110
7548
|
if (cache.textures.has(map)) return cache.textures.get(map);
|
|
7111
7549
|
if (!json.textures) json.textures = [];
|
|
7112
|
-
if (map instanceof
|
|
7550
|
+
if (map instanceof import_three19.CompressedTexture) {
|
|
7113
7551
|
map = await this.decompressTextureAsync(map, options.maxTextureSize);
|
|
7114
7552
|
}
|
|
7115
7553
|
const mimeType = map.userData.mimeType;
|
|
@@ -7242,7 +7680,7 @@ var init_GLTFExporter = __esm({
|
|
|
7242
7680
|
materialDef.alphaCutoff = material.alphaTest;
|
|
7243
7681
|
}
|
|
7244
7682
|
}
|
|
7245
|
-
if (material.side ===
|
|
7683
|
+
if (material.side === import_three19.DoubleSide) materialDef.doubleSided = true;
|
|
7246
7684
|
if (material.name !== "") materialDef.name = material.name;
|
|
7247
7685
|
this.serializeUserData(material, materialDef);
|
|
7248
7686
|
await this._invokeAllAsync(async function(ext) {
|
|
@@ -7491,7 +7929,7 @@ var init_GLTFExporter = __esm({
|
|
|
7491
7929
|
} else {
|
|
7492
7930
|
cameraDef.perspective = {
|
|
7493
7931
|
aspectRatio: camera.aspect,
|
|
7494
|
-
yfov:
|
|
7932
|
+
yfov: import_three19.MathUtils.degToRad(camera.fov),
|
|
7495
7933
|
zfar: camera.far <= 0 ? 1e-3 : camera.far,
|
|
7496
7934
|
znear: camera.near < 0 ? 0 : camera.near
|
|
7497
7935
|
};
|
|
@@ -7519,8 +7957,8 @@ var init_GLTFExporter = __esm({
|
|
|
7519
7957
|
const samplers = [];
|
|
7520
7958
|
for (let i = 0; i < tracks.length; ++i) {
|
|
7521
7959
|
const track = tracks[i];
|
|
7522
|
-
const trackBinding =
|
|
7523
|
-
let trackNode =
|
|
7960
|
+
const trackBinding = import_three19.PropertyBinding.parseTrackName(track.name);
|
|
7961
|
+
let trackNode = import_three19.PropertyBinding.findNode(root, trackBinding.nodeName);
|
|
7524
7962
|
const trackProperty = PATH_PROPERTIES[trackBinding.propertyName];
|
|
7525
7963
|
if (trackBinding.objectName === "bones") {
|
|
7526
7964
|
if (trackNode.isSkinnedMesh === true) {
|
|
@@ -7542,14 +7980,14 @@ var init_GLTFExporter = __esm({
|
|
|
7542
7980
|
if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
|
|
7543
7981
|
interpolation = "CUBICSPLINE";
|
|
7544
7982
|
outputItemSize /= 3;
|
|
7545
|
-
} else if (track.getInterpolation() ===
|
|
7983
|
+
} else if (track.getInterpolation() === import_three19.InterpolateDiscrete) {
|
|
7546
7984
|
interpolation = "STEP";
|
|
7547
7985
|
} else {
|
|
7548
7986
|
interpolation = "LINEAR";
|
|
7549
7987
|
}
|
|
7550
7988
|
samplers.push({
|
|
7551
|
-
input: this.processAccessor(new
|
|
7552
|
-
output: this.processAccessor(new
|
|
7989
|
+
input: this.processAccessor(new import_three19.BufferAttribute(track.times, inputItemSize)),
|
|
7990
|
+
output: this.processAccessor(new import_three19.BufferAttribute(track.values, outputItemSize)),
|
|
7553
7991
|
interpolation
|
|
7554
7992
|
});
|
|
7555
7993
|
channels.push({
|
|
@@ -7583,7 +8021,7 @@ var init_GLTFExporter = __esm({
|
|
|
7583
8021
|
if (rootJoint === void 0) return null;
|
|
7584
8022
|
const joints = [];
|
|
7585
8023
|
const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
|
|
7586
|
-
const temporaryBoneInverse = new
|
|
8024
|
+
const temporaryBoneInverse = new import_three19.Matrix4();
|
|
7587
8025
|
for (let i = 0; i < skeleton.bones.length; ++i) {
|
|
7588
8026
|
joints.push(nodeMap.get(skeleton.bones[i]));
|
|
7589
8027
|
temporaryBoneInverse.copy(skeleton.boneInverses[i]);
|
|
@@ -7591,7 +8029,7 @@ var init_GLTFExporter = __esm({
|
|
|
7591
8029
|
}
|
|
7592
8030
|
if (json.skins === void 0) json.skins = [];
|
|
7593
8031
|
json.skins.push({
|
|
7594
|
-
inverseBindMatrices: this.processAccessor(new
|
|
8032
|
+
inverseBindMatrices: this.processAccessor(new import_three19.BufferAttribute(inverseBindMatrices, 16)),
|
|
7595
8033
|
joints,
|
|
7596
8034
|
skeleton: nodeMap.get(rootJoint)
|
|
7597
8035
|
});
|
|
@@ -7753,7 +8191,7 @@ var init_GLTFExporter = __esm({
|
|
|
7753
8191
|
* @param {Array<THREE.Object3D>} objects List of objects to process
|
|
7754
8192
|
*/
|
|
7755
8193
|
async processObjectsAsync(objects) {
|
|
7756
|
-
const scene = new
|
|
8194
|
+
const scene = new import_three19.Scene();
|
|
7757
8195
|
scene.name = "AuxScene";
|
|
7758
8196
|
for (let i = 0; i < objects.length; i++) {
|
|
7759
8197
|
scene.children.push(objects[i]);
|
|
@@ -7771,7 +8209,7 @@ var init_GLTFExporter = __esm({
|
|
|
7771
8209
|
});
|
|
7772
8210
|
const objectsWithoutScene = [];
|
|
7773
8211
|
for (let i = 0; i < input.length; i++) {
|
|
7774
|
-
if (input[i] instanceof
|
|
8212
|
+
if (input[i] instanceof import_three19.Scene) {
|
|
7775
8213
|
await this.processSceneAsync(input[i]);
|
|
7776
8214
|
} else {
|
|
7777
8215
|
objectsWithoutScene.push(input[i]);
|
|
@@ -8169,10 +8607,10 @@ var init_GLTFExporter = __esm({
|
|
|
8169
8607
|
const translationAttr = new Float32Array(mesh.count * 3);
|
|
8170
8608
|
const rotationAttr = new Float32Array(mesh.count * 4);
|
|
8171
8609
|
const scaleAttr = new Float32Array(mesh.count * 3);
|
|
8172
|
-
const matrix = new
|
|
8173
|
-
const position = new
|
|
8174
|
-
const quaternion = new
|
|
8175
|
-
const scale = new
|
|
8610
|
+
const matrix = new import_three19.Matrix4();
|
|
8611
|
+
const position = new import_three19.Vector3();
|
|
8612
|
+
const quaternion = new import_three19.Quaternion();
|
|
8613
|
+
const scale = new import_three19.Vector3();
|
|
8176
8614
|
for (let i = 0; i < mesh.count; i++) {
|
|
8177
8615
|
mesh.getMatrixAt(i, matrix);
|
|
8178
8616
|
matrix.decompose(position, quaternion, scale);
|
|
@@ -8181,9 +8619,9 @@ var init_GLTFExporter = __esm({
|
|
|
8181
8619
|
scale.toArray(scaleAttr, i * 3);
|
|
8182
8620
|
}
|
|
8183
8621
|
const attributes = {
|
|
8184
|
-
TRANSLATION: writer.processAccessor(new
|
|
8185
|
-
ROTATION: writer.processAccessor(new
|
|
8186
|
-
SCALE: writer.processAccessor(new
|
|
8622
|
+
TRANSLATION: writer.processAccessor(new import_three19.BufferAttribute(translationAttr, 3)),
|
|
8623
|
+
ROTATION: writer.processAccessor(new import_three19.BufferAttribute(rotationAttr, 4)),
|
|
8624
|
+
SCALE: writer.processAccessor(new import_three19.BufferAttribute(scaleAttr, 3))
|
|
8187
8625
|
};
|
|
8188
8626
|
if (mesh.instanceColor)
|
|
8189
8627
|
attributes._COLOR_0 = writer.processAccessor(mesh.instanceColor);
|
|
@@ -8248,8 +8686,8 @@ var init_GLTFExporter = __esm({
|
|
|
8248
8686
|
const sourceTracks = clip.tracks;
|
|
8249
8687
|
for (let i = 0; i < sourceTracks.length; ++i) {
|
|
8250
8688
|
let sourceTrack = sourceTracks[i];
|
|
8251
|
-
const sourceTrackBinding =
|
|
8252
|
-
const sourceTrackNode =
|
|
8689
|
+
const sourceTrackBinding = import_three19.PropertyBinding.parseTrackName(sourceTrack.name);
|
|
8690
|
+
const sourceTrackNode = import_three19.PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
|
|
8253
8691
|
if (sourceTrackBinding.propertyName !== "morphTargetInfluences" || sourceTrackBinding.propertyIndex === void 0) {
|
|
8254
8692
|
tracks.push(sourceTrack);
|
|
8255
8693
|
continue;
|
|
@@ -8260,7 +8698,7 @@ var init_GLTFExporter = __esm({
|
|
|
8260
8698
|
}
|
|
8261
8699
|
console.warn("THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.");
|
|
8262
8700
|
sourceTrack = sourceTrack.clone();
|
|
8263
|
-
sourceTrack.setInterpolation(
|
|
8701
|
+
sourceTrack.setInterpolation(import_three19.InterpolateLinear);
|
|
8264
8702
|
}
|
|
8265
8703
|
const targetCount = sourceTrackNode.morphTargetInfluences.length;
|
|
8266
8704
|
const targetIndex = sourceTrackNode.morphTargetDictionary[sourceTrackBinding.propertyIndex];
|
|
@@ -8294,7 +8732,7 @@ var init_GLTFExporter = __esm({
|
|
|
8294
8732
|
return clip;
|
|
8295
8733
|
},
|
|
8296
8734
|
toTypedBufferAttribute: function(srcAttribute, TypedArray) {
|
|
8297
|
-
const dstAttribute = new
|
|
8735
|
+
const dstAttribute = new import_three19.BufferAttribute(new TypedArray(srcAttribute.count * srcAttribute.itemSize), srcAttribute.itemSize, false);
|
|
8298
8736
|
if (!srcAttribute.normalized && !srcAttribute.isInterleavedBufferAttribute) {
|
|
8299
8737
|
dstAttribute.array.set(srcAttribute.array);
|
|
8300
8738
|
return dstAttribute;
|
|
@@ -8372,7 +8810,7 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8372
8810
|
batch = { image: glyph?.image, positions: [], uvs: [], colors: [], indices: [] };
|
|
8373
8811
|
batches.push(batch);
|
|
8374
8812
|
}
|
|
8375
|
-
const color2 = new
|
|
8813
|
+
const color2 = new import_three21.Color(isShadow ? (style.color & 16579836) >> 2 : style.color);
|
|
8376
8814
|
const offset = isShadow ? glyph?.shadowOffset ?? 1 : 0;
|
|
8377
8815
|
const top = glyph ? 7 - glyph.ascent : 0;
|
|
8378
8816
|
const height = glyph ? glyph.height * glyph.scale : 8;
|
|
@@ -8414,12 +8852,12 @@ function createGuiTextGeometry(layout, shadow = true) {
|
|
|
8414
8852
|
}
|
|
8415
8853
|
}
|
|
8416
8854
|
}
|
|
8417
|
-
return batches.map(({ image, positions, uvs, colors: colors2, indices }) => ({ image, geometry: new
|
|
8855
|
+
return batches.map(({ image, positions, uvs, colors: colors2, indices }) => ({ image, geometry: new import_three21.BufferGeometry().setAttribute("position", new import_three21.Float32BufferAttribute(positions, 3)).setAttribute("uv", new import_three21.Float32BufferAttribute(uvs, 2)).setAttribute("color", new import_three21.Float32BufferAttribute(colors2, 3)).setIndex(indices) }));
|
|
8418
8856
|
}
|
|
8419
|
-
var
|
|
8857
|
+
var import_three21;
|
|
8420
8858
|
var init_GuiText = __esm({
|
|
8421
8859
|
"src/gui/GuiText.ts"() {
|
|
8422
|
-
|
|
8860
|
+
import_three21 = require("three");
|
|
8423
8861
|
init_Fonts();
|
|
8424
8862
|
}
|
|
8425
8863
|
});
|
|
@@ -8428,7 +8866,7 @@ var init_GuiText = __esm({
|
|
|
8428
8866
|
function createGuiTextureGeometry(width, height, imageWidth, imageHeight, crop, scaling) {
|
|
8429
8867
|
if (crop || !scaling || scaling.type === "stretch") {
|
|
8430
8868
|
const [x, y, w, h] = crop ?? [0, 0, imageWidth, imageHeight];
|
|
8431
|
-
const geometry = new
|
|
8869
|
+
const geometry = new import_three22.PlaneGeometry(width, height);
|
|
8432
8870
|
const uv = geometry.getAttribute("uv");
|
|
8433
8871
|
for (let i = 0; i < uv.count; i++) {
|
|
8434
8872
|
uv.setXY(
|
|
@@ -8499,12 +8937,12 @@ function createGuiTextureGeometry(width, height, imageWidth, imageHeight, crop,
|
|
|
8499
8937
|
}
|
|
8500
8938
|
}
|
|
8501
8939
|
}
|
|
8502
|
-
return new
|
|
8940
|
+
return new import_three22.BufferGeometry().setAttribute("position", new import_three22.Float32BufferAttribute(positions, 3)).setAttribute("normal", new import_three22.Float32BufferAttribute(normals, 3)).setAttribute("uv", new import_three22.Float32BufferAttribute(uvs, 2)).setIndex(indices);
|
|
8503
8941
|
}
|
|
8504
|
-
var
|
|
8942
|
+
var import_three22;
|
|
8505
8943
|
var init_GuiTextureGeometry = __esm({
|
|
8506
8944
|
"src/gui/GuiTextureGeometry.ts"() {
|
|
8507
|
-
|
|
8945
|
+
import_three22 = require("three");
|
|
8508
8946
|
}
|
|
8509
8947
|
});
|
|
8510
8948
|
|
|
@@ -8520,7 +8958,7 @@ function mergeBufferGeometries(geometries, useGroups = false) {
|
|
|
8520
8958
|
const attributes = {};
|
|
8521
8959
|
const morphAttributes = {};
|
|
8522
8960
|
const morphTargetsRelative = geometries[0].morphTargetsRelative;
|
|
8523
|
-
const mergedGeometry = new
|
|
8961
|
+
const mergedGeometry = new import_three23.BufferGeometry();
|
|
8524
8962
|
let offset = 0;
|
|
8525
8963
|
for (let i = 0; i < geometries.length; ++i) {
|
|
8526
8964
|
const geometry = geometries[i];
|
|
@@ -8644,7 +9082,7 @@ function mergeBufferAttributes(attributes) {
|
|
|
8644
9082
|
array.set(attributes[i].array, offset);
|
|
8645
9083
|
offset += attributes[i].array.length;
|
|
8646
9084
|
}
|
|
8647
|
-
return new
|
|
9085
|
+
return new import_three23.BufferAttribute(array, itemSize, normalized);
|
|
8648
9086
|
}
|
|
8649
9087
|
function interleaveAttributes(attributes) {
|
|
8650
9088
|
let TypedArray;
|
|
@@ -8660,7 +9098,7 @@ function interleaveAttributes(attributes) {
|
|
|
8660
9098
|
arrayLength += attribute.array.length;
|
|
8661
9099
|
stride += attribute.itemSize;
|
|
8662
9100
|
}
|
|
8663
|
-
const interleavedBuffer = new
|
|
9101
|
+
const interleavedBuffer = new import_three23.InterleavedBuffer(new TypedArray(arrayLength), stride);
|
|
8664
9102
|
let offset = 0;
|
|
8665
9103
|
const res = [];
|
|
8666
9104
|
const getters = ["getX", "getY", "getZ", "getW"];
|
|
@@ -8669,7 +9107,7 @@ function interleaveAttributes(attributes) {
|
|
|
8669
9107
|
const attribute = attributes[j];
|
|
8670
9108
|
const itemSize = attribute.itemSize;
|
|
8671
9109
|
const count = attribute.count;
|
|
8672
|
-
const iba = new
|
|
9110
|
+
const iba = new import_three23.InterleavedBufferAttribute(interleavedBuffer, itemSize, offset, attribute.normalized);
|
|
8673
9111
|
res.push(iba);
|
|
8674
9112
|
offset += itemSize;
|
|
8675
9113
|
for (let c = 0; c < count; c++) {
|
|
@@ -8753,13 +9191,13 @@ function mergeVertices(geometry, tolerance = 1e-4) {
|
|
|
8753
9191
|
const name = attributeNames[i];
|
|
8754
9192
|
const oldAttribute = geometry.getAttribute(name);
|
|
8755
9193
|
const buffer = new oldAttribute.array.constructor(attrArrays[name]);
|
|
8756
|
-
const attribute = new
|
|
9194
|
+
const attribute = new import_three23.BufferAttribute(buffer, oldAttribute.itemSize, oldAttribute.normalized);
|
|
8757
9195
|
result.setAttribute(name, attribute);
|
|
8758
9196
|
if (name in morphAttrsArrays) {
|
|
8759
9197
|
for (let j = 0; j < morphAttrsArrays[name].length; j++) {
|
|
8760
9198
|
const oldMorphAttribute = geometry.morphAttributes[name][j];
|
|
8761
9199
|
const buffer2 = new oldMorphAttribute.array.constructor(morphAttrsArrays[name][j]);
|
|
8762
|
-
const morphAttribute = new
|
|
9200
|
+
const morphAttribute = new import_three23.BufferAttribute(buffer2, oldMorphAttribute.itemSize, oldMorphAttribute.normalized);
|
|
8763
9201
|
result.morphAttributes[name][j] = morphAttribute;
|
|
8764
9202
|
}
|
|
8765
9203
|
}
|
|
@@ -8768,11 +9206,11 @@ function mergeVertices(geometry, tolerance = 1e-4) {
|
|
|
8768
9206
|
return result;
|
|
8769
9207
|
}
|
|
8770
9208
|
function toTrianglesDrawMode(geometry, drawMode) {
|
|
8771
|
-
if (drawMode ===
|
|
9209
|
+
if (drawMode === import_three23.TrianglesDrawMode) {
|
|
8772
9210
|
console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.");
|
|
8773
9211
|
return geometry;
|
|
8774
9212
|
}
|
|
8775
|
-
if (drawMode ===
|
|
9213
|
+
if (drawMode === import_three23.TriangleFanDrawMode || drawMode === import_three23.TriangleStripDrawMode) {
|
|
8776
9214
|
let index = geometry.getIndex();
|
|
8777
9215
|
if (index === null) {
|
|
8778
9216
|
const indices = [];
|
|
@@ -8790,7 +9228,7 @@ function toTrianglesDrawMode(geometry, drawMode) {
|
|
|
8790
9228
|
}
|
|
8791
9229
|
const numberOfTriangles = index.count - 2;
|
|
8792
9230
|
const newIndices = [];
|
|
8793
|
-
if (drawMode ===
|
|
9231
|
+
if (drawMode === import_three23.TriangleFanDrawMode) {
|
|
8794
9232
|
for (let i = 1; i <= numberOfTriangles; i++) {
|
|
8795
9233
|
newIndices.push(index.getX(0));
|
|
8796
9234
|
newIndices.push(index.getX(i));
|
|
@@ -8826,15 +9264,15 @@ function computeMorphedAttributes(object4) {
|
|
|
8826
9264
|
console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
|
|
8827
9265
|
return null;
|
|
8828
9266
|
}
|
|
8829
|
-
const _vA = new
|
|
8830
|
-
const _vB = new
|
|
8831
|
-
const _vC = new
|
|
8832
|
-
const _tempA = new
|
|
8833
|
-
const _tempB = new
|
|
8834
|
-
const _tempC = new
|
|
8835
|
-
const _morphA = new
|
|
8836
|
-
const _morphB = new
|
|
8837
|
-
const _morphC = new
|
|
9267
|
+
const _vA = new import_three23.Vector3();
|
|
9268
|
+
const _vB = new import_three23.Vector3();
|
|
9269
|
+
const _vC = new import_three23.Vector3();
|
|
9270
|
+
const _tempA = new import_three23.Vector3();
|
|
9271
|
+
const _tempB = new import_three23.Vector3();
|
|
9272
|
+
const _tempC = new import_three23.Vector3();
|
|
9273
|
+
const _morphA = new import_three23.Vector3();
|
|
9274
|
+
const _morphB = new import_three23.Vector3();
|
|
9275
|
+
const _morphC = new import_three23.Vector3();
|
|
8838
9276
|
function _calculateMorphedAttributeData(object5, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
|
|
8839
9277
|
_vA.fromBufferAttribute(attribute, a2);
|
|
8840
9278
|
_vB.fromBufferAttribute(attribute, b2);
|
|
@@ -9029,8 +9467,8 @@ function computeMorphedAttributes(object4) {
|
|
|
9029
9467
|
}
|
|
9030
9468
|
}
|
|
9031
9469
|
}
|
|
9032
|
-
const morphedPositionAttribute = new
|
|
9033
|
-
const morphedNormalAttribute = new
|
|
9470
|
+
const morphedPositionAttribute = new import_three23.Float32BufferAttribute(modifiedPosition, 3);
|
|
9471
|
+
const morphedNormalAttribute = new import_three23.Float32BufferAttribute(modifiedNormal, 3);
|
|
9034
9472
|
return {
|
|
9035
9473
|
positionAttribute,
|
|
9036
9474
|
normalAttribute,
|
|
@@ -9038,25 +9476,25 @@ function computeMorphedAttributes(object4) {
|
|
|
9038
9476
|
morphedNormalAttribute
|
|
9039
9477
|
};
|
|
9040
9478
|
}
|
|
9041
|
-
var
|
|
9479
|
+
var import_three23;
|
|
9042
9480
|
var init_BufferGeometryUtils = __esm({
|
|
9043
9481
|
"src/three/BufferGeometryUtils.js"() {
|
|
9044
|
-
|
|
9482
|
+
import_three23 = require("three");
|
|
9045
9483
|
}
|
|
9046
9484
|
});
|
|
9047
9485
|
|
|
9048
9486
|
// src/model/ModelCulling.ts
|
|
9049
|
-
var
|
|
9487
|
+
var import_three24, ModelCulling;
|
|
9050
9488
|
var init_ModelCulling = __esm({
|
|
9051
9489
|
"src/model/ModelCulling.ts"() {
|
|
9052
|
-
|
|
9490
|
+
import_three24 = require("three");
|
|
9053
9491
|
init_CubeFace();
|
|
9054
9492
|
ModelCulling = class {
|
|
9055
9493
|
/** Rotates a world-direction bit mask into model space. Bits follow {@link CUBE_FACES}. */
|
|
9056
9494
|
static toLocalMask(worldMask, rotation) {
|
|
9057
9495
|
let localMask = 0;
|
|
9058
9496
|
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
9059
|
-
const normal = new
|
|
9497
|
+
const normal = new import_three24.Vector3(...offset).applyEuler(rotation);
|
|
9060
9498
|
const worldFace = CUBE_FACE_OFFSETS.findIndex(([x, y, z]) => Math.abs(normal.x - x) < 1e-6 && Math.abs(normal.y - y) < 1e-6 && Math.abs(normal.z - z) < 1e-6);
|
|
9061
9499
|
if (worldFace < 0) return 0;
|
|
9062
9500
|
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
@@ -9319,10 +9757,10 @@ var init_SkinImage = __esm({
|
|
|
9319
9757
|
});
|
|
9320
9758
|
|
|
9321
9759
|
// src/skin/SkinTextures.ts
|
|
9322
|
-
var
|
|
9760
|
+
var import_three25, SkinTextures;
|
|
9323
9761
|
var init_SkinTextures = __esm({
|
|
9324
9762
|
"src/skin/SkinTextures.ts"() {
|
|
9325
|
-
|
|
9763
|
+
import_three25 = require("three");
|
|
9326
9764
|
init_Caching();
|
|
9327
9765
|
init_CacheKey();
|
|
9328
9766
|
init_MineRenderError();
|
|
@@ -9360,11 +9798,11 @@ var init_SkinTextures = __esm({
|
|
|
9360
9798
|
});
|
|
9361
9799
|
}
|
|
9362
9800
|
static createMaterial(pixels, width, height, transparent = true) {
|
|
9363
|
-
const texture = Textures.initTextureProps(new
|
|
9364
|
-
texture.colorSpace =
|
|
9801
|
+
const texture = Textures.initTextureProps(new import_three25.DataTexture(pixels, width, height));
|
|
9802
|
+
texture.colorSpace = import_three25.SRGBColorSpace;
|
|
9365
9803
|
texture.flipY = true;
|
|
9366
9804
|
texture.needsUpdate = true;
|
|
9367
|
-
return new
|
|
9805
|
+
return new import_three25.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three25.DoubleSide : import_three25.FrontSide, alphaTest: transparent ? 0.1 : 0 });
|
|
9368
9806
|
}
|
|
9369
9807
|
static isSlim(image, scale) {
|
|
9370
9808
|
for (const [x, y] of [[46, 52], [54, 20]]) {
|
|
@@ -9417,7 +9855,7 @@ var init_SkinTextures = __esm({
|
|
|
9417
9855
|
return pixels;
|
|
9418
9856
|
}
|
|
9419
9857
|
static makeBaseOpaque(pixels, width, scale) {
|
|
9420
|
-
for (const [x0, y0, x1, y1] of [[0, 0, 32, 16], [0, 16, 64, 32], [16, 48, 48, 64]]) {
|
|
9858
|
+
for (const [x0, y0, x1, y1] of [[0, 0, 32, 16], [0, 16, 64, 32], [16, 48, 48, 64], [32, 0, 38, 7]]) {
|
|
9421
9859
|
for (let y = y0 * scale; y < y1 * scale; y++) {
|
|
9422
9860
|
for (let x = x0 * scale; x < x1 * scale; x++) pixels[(y * width + x) * 4 + 3] = 255;
|
|
9423
9861
|
}
|
|
@@ -9428,6 +9866,10 @@ var init_SkinTextures = __esm({
|
|
|
9428
9866
|
});
|
|
9429
9867
|
|
|
9430
9868
|
// src/skin/PlayerHeadTextures.ts
|
|
9869
|
+
var PlayerHeadTextures_exports = {};
|
|
9870
|
+
__export(PlayerHeadTextures_exports, {
|
|
9871
|
+
PlayerHeadTextures: () => PlayerHeadTextures
|
|
9872
|
+
});
|
|
9431
9873
|
var PlayerHeadTextures;
|
|
9432
9874
|
var init_PlayerHeadTextures = __esm({
|
|
9433
9875
|
"src/skin/PlayerHeadTextures.ts"() {
|
|
@@ -9548,10 +9990,10 @@ var init_PlayerHeadTextures = __esm({
|
|
|
9548
9990
|
});
|
|
9549
9991
|
|
|
9550
9992
|
// src/model/SpecialItems.ts
|
|
9551
|
-
var
|
|
9993
|
+
var import_three26, SpecialItems;
|
|
9552
9994
|
var init_SpecialItems = __esm({
|
|
9553
9995
|
"src/model/SpecialItems.ts"() {
|
|
9554
|
-
|
|
9996
|
+
import_three26 = require("three");
|
|
9555
9997
|
init_AssetKey();
|
|
9556
9998
|
init_Entities();
|
|
9557
9999
|
init_BannerPatterns();
|
|
@@ -9589,8 +10031,8 @@ var init_SpecialItems = __esm({
|
|
|
9589
10031
|
const sideTextures = DecoratedPots.getSideTextures(components["minecraft:pot_decorations"], root);
|
|
9590
10032
|
const baseTexture = texture("decorated_pot_base", "decorated_pot");
|
|
9591
10033
|
const [base, sides] = await Promise.all([
|
|
9592
|
-
load("decorated_pot_base", baseTexture, new
|
|
9593
|
-
load("decorated_pot_sides", texture("decorated_pot_side", "decorated_pot"), new
|
|
10034
|
+
load("decorated_pot_base", baseTexture, new import_three26.Matrix4()),
|
|
10035
|
+
load("decorated_pot_sides", texture("decorated_pot_side", "decorated_pot"), new import_three26.Matrix4())
|
|
9594
10036
|
]);
|
|
9595
10037
|
const layers = {
|
|
9596
10038
|
base: { key: base.model.key, texture: baseTexture, layer: base.model.layer, render: "solid" }
|
|
@@ -9618,7 +10060,7 @@ var init_SpecialItems = __esm({
|
|
|
9618
10060
|
const part = await load(
|
|
9619
10061
|
"player_head",
|
|
9620
10062
|
skin.texture,
|
|
9621
|
-
new
|
|
10063
|
+
new import_three26.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three26.Matrix4().makeScale(-1, -1, 1)),
|
|
9622
10064
|
{ head: [0, Math.PI, 0] }
|
|
9623
10065
|
);
|
|
9624
10066
|
const main = { ...part.model, texture: skin.texture, render: "translucent" };
|
|
@@ -9635,7 +10077,7 @@ var init_SpecialItems = __esm({
|
|
|
9635
10077
|
const statue = await load(
|
|
9636
10078
|
special.pose === "standing" ? "copper_golem" : `copper_golem_${special.pose}`,
|
|
9637
10079
|
key,
|
|
9638
|
-
new
|
|
10080
|
+
new import_three26.Matrix4().makeTranslation(8, 24, 8).multiply(new import_three26.Matrix4().makeScale(-1, -1, 1))
|
|
9639
10081
|
);
|
|
9640
10082
|
const pose = statue.model.layer.root.pose;
|
|
9641
10083
|
statue.rotations.root = [pose.rotation[0], Math.PI, Math.PI];
|
|
@@ -9651,7 +10093,7 @@ var init_SpecialItems = __esm({
|
|
|
9651
10093
|
const part = await load(
|
|
9652
10094
|
trident ? "trident" : "conduit",
|
|
9653
10095
|
texture(trident ? "trident" : "conduit/base", ""),
|
|
9654
|
-
trident ? new
|
|
10096
|
+
trident ? new import_three26.Matrix4().makeScale(1, -1, -1) : new import_three26.Matrix4().makeTranslation(8, 8, 8),
|
|
9655
10097
|
{},
|
|
9656
10098
|
trident ? ["main"] : ["shell"]
|
|
9657
10099
|
);
|
|
@@ -9672,7 +10114,7 @@ var init_SpecialItems = __esm({
|
|
|
9672
10114
|
const patterns = await BannerPatterns.getLayers(components["minecraft:banner_patterns"], banner ? "banner" : "shield", root);
|
|
9673
10115
|
const patterned = banner || color2 !== void 0 || patterns.length > 0;
|
|
9674
10116
|
const baseTexture = texture(banner ? "banner_base" : patterned ? "shield_base" : "shield_base_nopattern", "");
|
|
9675
|
-
const transform = banner ? new
|
|
10117
|
+
const transform = banner ? new import_three26.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three26.Matrix4().makeScale(2 / 3, -2 / 3, -2 / 3)) : new import_three26.Matrix4().makeScale(1, -1, -1);
|
|
9676
10118
|
const part = await load(banner ? "standing_banner" : "shield", baseTexture, transform, {}, banner ? ["main", "flag"] : ["main"]);
|
|
9677
10119
|
const layers = Object.fromEntries(Object.entries(part.model.layers ?? { main: part.model }).map(([name, layer]) => [name, { ...layer, render: "solid" }]));
|
|
9678
10120
|
let overlay2;
|
|
@@ -9710,7 +10152,7 @@ var init_SpecialItems = __esm({
|
|
|
9710
10152
|
case "minecraft:chest":
|
|
9711
10153
|
case "chest": {
|
|
9712
10154
|
const angle = -(special.openness ?? 0) * Math.PI / 2;
|
|
9713
|
-
const chest = await load("chest", texture(special.texture, "chest"), new
|
|
10155
|
+
const chest = await load("chest", texture(special.texture, "chest"), new import_three26.Matrix4(), {
|
|
9714
10156
|
lid: [angle, 0, 0],
|
|
9715
10157
|
lock: [angle, 0, 0]
|
|
9716
10158
|
});
|
|
@@ -9732,18 +10174,18 @@ var init_SpecialItems = __esm({
|
|
|
9732
10174
|
if (!Object.prototype.hasOwnProperty.call(directions, orientation)) throw new Error(`Unsupported shulker-box orientation ${orientation}`);
|
|
9733
10175
|
if (typeof openness !== "number" || !Number.isFinite(openness)) throw new Error("Shulker-box openness must be finite");
|
|
9734
10176
|
if (typeof special.texture !== "string" || !special.texture) throw new Error("Shulker-box texture is required");
|
|
9735
|
-
const transform = new
|
|
10177
|
+
const transform = new import_three26.Matrix4().makeTranslation(8, 8, 8).multiply(new import_three26.Matrix4().makeScale(0.9995, 0.9995, 0.9995)).multiply(new import_three26.Matrix4().makeRotationFromEuler(new import_three26.Euler(...directions[orientation], "XYZ"))).multiply(new import_three26.Matrix4().makeScale(1, -1, -1)).multiply(new import_three26.Matrix4().makeTranslation(0, -16, 0));
|
|
9736
10178
|
const box = await load("shulker_box", texture(special.texture, "shulker"), transform, { lid: [0, openness * Math.PI * 1.5, 0] });
|
|
9737
10179
|
box.positions = { lid: [0, 24 - openness * 8, 0] };
|
|
9738
10180
|
return [box];
|
|
9739
10181
|
}
|
|
9740
10182
|
case "minecraft:bed":
|
|
9741
10183
|
case "bed": {
|
|
9742
|
-
const transform = new
|
|
10184
|
+
const transform = new import_three26.Matrix4().makeTranslation(0, 9, 0).multiply(new import_three26.Matrix4().makeRotationX(Math.PI / 2)).multiply(new import_three26.Matrix4().makeTranslation(8, 8, 8)).multiply(new import_three26.Matrix4().makeRotationZ(Math.PI)).multiply(new import_three26.Matrix4().makeTranslation(-8, -8, -8));
|
|
9743
10185
|
const key = texture(special.texture, "bed");
|
|
9744
10186
|
return Promise.all([
|
|
9745
10187
|
load("bed_head", key, transform),
|
|
9746
|
-
load("bed_foot", key, new
|
|
10188
|
+
load("bed_foot", key, new import_three26.Matrix4().makeTranslation(0, 0, -16).multiply(transform))
|
|
9747
10189
|
]);
|
|
9748
10190
|
}
|
|
9749
10191
|
case "minecraft:head":
|
|
@@ -9755,265 +10197,62 @@ var init_SpecialItems = __esm({
|
|
|
9755
10197
|
creeper: "creeper_head",
|
|
9756
10198
|
dragon: "dragon_skull",
|
|
9757
10199
|
piglin: "piglin_head"
|
|
9758
|
-
};
|
|
9759
|
-
const id = Object.prototype.hasOwnProperty.call(models, special.kind) ? models[special.kind] : void 0;
|
|
9760
|
-
if (!id) throw new Error(`Unsupported special item head kind ${special.kind}`);
|
|
9761
|
-
const animation = (special.animation ?? 0) * Math.PI * 0.2;
|
|
9762
|
-
const rotations = { head: [0, Math.PI, 0] };
|
|
9763
|
-
if (special.kind === "dragon") rotations.jaw = [(Math.sin(animation) + 1) * 0.2, 0, 0];
|
|
9764
|
-
if (special.kind === "piglin") {
|
|
9765
|
-
rotations.left_ear = [0, 0, -(Math.cos(animation * 1.2) + 2.5) * 0.2];
|
|
9766
|
-
rotations.right_ear = [0, 0, (Math.cos(animation) + 2.5) * 0.2];
|
|
9767
|
-
}
|
|
9768
|
-
return [await load(
|
|
9769
|
-
id,
|
|
9770
|
-
special.texture ? texture(special.texture, "") : void 0,
|
|
9771
|
-
new
|
|
9772
|
-
rotations
|
|
9773
|
-
)];
|
|
9774
|
-
}
|
|
9775
|
-
}
|
|
9776
|
-
}
|
|
9777
|
-
/** An owned material with model-preview shading; its entity texture remains shared. */
|
|
9778
|
-
static createMaterial(source, shade) {
|
|
9779
|
-
const material = source.clone();
|
|
9780
|
-
if (shade) {
|
|
9781
|
-
material.onBeforeCompile = (shader) => {
|
|
9782
|
-
shader.vertexShader = `varying float itemLight;
|
|
9783
|
-
${shader.vertexShader}`.replace("#include <begin_vertex>", `
|
|
9784
|
-
#include <begin_vertex>
|
|
9785
|
-
vec3 N = inverseTransformDirection(normalMatrix * normal, viewMatrix);
|
|
9786
|
-
itemLight = (1.0 + N.y) * 0.25 - N.x * N.x * 0.15 + N.z * N.z * 0.05 + 0.5;
|
|
9787
|
-
`);
|
|
9788
|
-
shader.fragmentShader = `varying float itemLight;
|
|
9789
|
-
${shader.fragmentShader}`.replace(
|
|
9790
|
-
"#include <color_fragment>",
|
|
9791
|
-
"#include <color_fragment>\ndiffuseColor.rgb *= itemLight;"
|
|
9792
|
-
);
|
|
9793
|
-
};
|
|
9794
|
-
material.customProgramCacheKey = () => "special-item-side";
|
|
9795
|
-
}
|
|
9796
|
-
return material;
|
|
9797
|
-
}
|
|
9798
|
-
};
|
|
9799
|
-
}
|
|
9800
|
-
});
|
|
9801
|
-
|
|
9802
|
-
// src/model/GuiLight.ts
|
|
9803
|
-
var GuiLight;
|
|
9804
|
-
var init_GuiLight = __esm({
|
|
9805
|
-
"src/model/GuiLight.ts"() {
|
|
9806
|
-
GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
9807
|
-
GuiLight2["FRONT"] = "front";
|
|
9808
|
-
GuiLight2["SIDE"] = "side";
|
|
9809
|
-
return GuiLight2;
|
|
9810
|
-
})(GuiLight || {});
|
|
9811
|
-
}
|
|
9812
|
-
});
|
|
9813
|
-
|
|
9814
|
-
// src/model/ItemGlint.ts
|
|
9815
|
-
var import_three26, ItemGlint;
|
|
9816
|
-
var init_ItemGlint = __esm({
|
|
9817
|
-
"src/model/ItemGlint.ts"() {
|
|
9818
|
-
import_three26 = require("three");
|
|
9819
|
-
init_AssetKey();
|
|
9820
|
-
init_Models();
|
|
9821
|
-
init_ModelTextures();
|
|
9822
|
-
init_Caching();
|
|
9823
|
-
init_Textures();
|
|
9824
|
-
init_Ticker();
|
|
9825
|
-
init_CubeFace();
|
|
9826
|
-
init_DisplayPosition();
|
|
9827
|
-
ItemGlint = class _ItemGlint {
|
|
9828
|
-
constructor(owner, material) {
|
|
9829
|
-
this.owner = owner;
|
|
9830
|
-
this.material = material;
|
|
9831
|
-
this.updateTime();
|
|
9832
|
-
}
|
|
9833
|
-
/** Enables glint for enchantments or a lodestone compass unless a boolean component overrides them. */
|
|
9834
|
-
static enabled(components = {}, itemId) {
|
|
9835
|
-
const override = Models.componentValue(components, "enchantment_glint_override");
|
|
9836
|
-
if (override !== void 0) {
|
|
9837
|
-
if (typeof override !== "boolean") throw new Error("Item enchantment_glint_override must be a boolean");
|
|
9838
|
-
return override;
|
|
9839
|
-
}
|
|
9840
|
-
if (itemId === "minecraft:compass") {
|
|
9841
|
-
Models.componentValue(components, "lodestone_tracker");
|
|
9842
|
-
if (Object.prototype.hasOwnProperty.call(components, "lodestone_tracker") || Object.prototype.hasOwnProperty.call(components, "minecraft:lodestone_tracker")) return true;
|
|
9843
|
-
}
|
|
9844
|
-
const enchantments = Models.componentValue(components, "enchantments");
|
|
9845
|
-
if (enchantments === void 0) return false;
|
|
9846
|
-
if (!enchantments || typeof enchantments !== "object" || Array.isArray(enchantments)) throw new Error("Item enchantments must be an object");
|
|
9847
|
-
return Object.keys(enchantments).length > 0;
|
|
9848
|
-
}
|
|
9849
|
-
/** @internal */
|
|
9850
|
-
static async create(owner, baseMap, root, entityMeshes) {
|
|
9851
|
-
const key = new AssetKey("minecraft", "enchanted_glint_item", "textures", "misc", "assets", ".png", root);
|
|
9852
|
-
const assetKey = key.serialize(), textureKey = `item-glint:${assetKey}`;
|
|
9853
|
-
let texture = Caching.textureCache.getIfPresent(textureKey);
|
|
9854
|
-
if (!texture) {
|
|
9855
|
-
const pending = ModelTextures.get(key);
|
|
9856
|
-
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKey);
|
|
9857
|
-
const [image, metadata] = await Promise.all([pending, ModelTextures.getMeta(key)]);
|
|
9858
|
-
if (!image) throw new Error(`Missing item glint texture ${key.toNamespacedString()}`);
|
|
9859
|
-
if (cachedAsset && Caching.textureAssetCache.getIfPresent(assetKey) !== cachedAsset) return this.create(owner, baseMap, root, entityMeshes);
|
|
9860
|
-
texture = Caching.textureCache.get(textureKey, () => {
|
|
9861
|
-
const texture2 = Textures.createCanvasTexture(image.data.canvas);
|
|
9862
|
-
texture2.wrapS = texture2.wrapT = metadata?.texture?.clamp ? import_three26.ClampToEdgeWrapping : import_three26.RepeatWrapping;
|
|
9863
|
-
if (metadata?.texture?.blur) texture2.magFilter = texture2.minFilter = import_three26.LinearFilter;
|
|
9864
|
-
return texture2;
|
|
9865
|
-
});
|
|
9866
|
-
}
|
|
9867
|
-
const material = new import_three26.ShaderMaterial({
|
|
9868
|
-
name: "item-glint",
|
|
9869
|
-
transparent: true,
|
|
9870
|
-
depthWrite: false,
|
|
9871
|
-
depthFunc: import_three26.EqualDepth,
|
|
9872
|
-
side: import_three26.DoubleSide,
|
|
9873
|
-
forceSinglePass: true,
|
|
9874
|
-
blending: import_three26.CustomBlending,
|
|
9875
|
-
blendSrc: import_three26.SrcColorFactor,
|
|
9876
|
-
blendDst: import_three26.OneFactor,
|
|
9877
|
-
blendSrcAlpha: import_three26.ZeroFactor,
|
|
9878
|
-
blendDstAlpha: import_three26.OneFactor,
|
|
9879
|
-
toneMapped: false,
|
|
9880
|
-
defines: entityMeshes ? { ENTITY_GLINT: true } : {},
|
|
9881
|
-
uniforms: {
|
|
9882
|
-
...!entityMeshes && { baseMap: { value: baseMap } },
|
|
9883
|
-
glintMap: { value: texture },
|
|
9884
|
-
glintOffset: { value: new import_three26.Vector2() },
|
|
9885
|
-
glintAlpha: { value: 0.75 }
|
|
9886
|
-
},
|
|
9887
|
-
vertexShader: `
|
|
9888
|
-
uniform vec2 glintOffset;
|
|
9889
|
-
#ifndef ENTITY_GLINT
|
|
9890
|
-
attribute vec4 uvBounds;
|
|
9891
|
-
attribute vec2 glintUv;
|
|
9892
|
-
flat out vec4 vUvBounds;
|
|
9893
|
-
centroid out vec2 vUv;
|
|
9894
|
-
#endif
|
|
9895
|
-
varying vec2 vGlintUv;
|
|
9896
|
-
void main() {
|
|
9897
|
-
#ifdef ENTITY_GLINT
|
|
9898
|
-
vec2 p = vec2(uv.x, 1.0 - uv.y) * 0.5;
|
|
9899
|
-
#else
|
|
9900
|
-
vUv = uv;
|
|
9901
|
-
vUvBounds = uvBounds;
|
|
9902
|
-
vec2 p = glintUv * 8.0;
|
|
9903
|
-
#endif
|
|
9904
|
-
float angle = radians(10.0);
|
|
9905
|
-
vGlintUv = vec2(cos(angle) * p.x - sin(angle) * p.y, sin(angle) * p.x + cos(angle) * p.y) + glintOffset;
|
|
9906
|
-
vec4 mvPosition = vec4(position, 1.0);
|
|
9907
|
-
mvPosition = modelViewMatrix * mvPosition;
|
|
9908
|
-
gl_Position = projectionMatrix * mvPosition;
|
|
9909
|
-
}
|
|
9910
|
-
`,
|
|
9911
|
-
fragmentShader: `
|
|
9912
|
-
#ifndef ENTITY_GLINT
|
|
9913
|
-
uniform sampler2D baseMap;
|
|
9914
|
-
flat in vec4 vUvBounds;
|
|
9915
|
-
centroid in vec2 vUv;
|
|
9916
|
-
#endif
|
|
9917
|
-
uniform sampler2D glintMap;
|
|
9918
|
-
uniform float glintAlpha;
|
|
9919
|
-
varying vec2 vGlintUv;
|
|
9920
|
-
void main() {
|
|
9921
|
-
#ifndef ENTITY_GLINT
|
|
9922
|
-
vec2 mapUv = clamp(vUv, vUvBounds.xy, vUvBounds.zw);
|
|
9923
|
-
if (texture2D(baseMap, mapUv).a < 0.01) discard;
|
|
9924
|
-
#endif
|
|
9925
|
-
vec4 color = texture2D(glintMap, vec2(vGlintUv.x, 1.0 - vGlintUv.y));
|
|
9926
|
-
if (color.a < 0.1) discard;
|
|
9927
|
-
gl_FragColor = color;
|
|
9928
|
-
#include <colorspace_fragment>
|
|
9929
|
-
gl_FragColor.rgb *= glintAlpha;
|
|
9930
|
-
}
|
|
9931
|
-
`
|
|
9932
|
-
});
|
|
9933
|
-
if (!entityMeshes) Object.assign(material.defaultAttributeValues, { uvBounds: [0, 0, 1, 1] });
|
|
9934
|
-
const targets = entityMeshes ? [...entityMeshes] : [];
|
|
9935
|
-
if (!entityMeshes) owner.iterateAllMeshes((mesh) => targets.push({ mesh }));
|
|
9936
|
-
for (const { mesh: base, parent = base } of targets) {
|
|
9937
|
-
const pass = new import_three26.Mesh(base.geometry, material);
|
|
9938
|
-
pass.name = `${base.name}:glint`;
|
|
9939
|
-
pass.userData.minerenderItemGlint = true;
|
|
9940
|
-
pass.raycast = () => {
|
|
9941
|
-
};
|
|
9942
|
-
pass.renderOrder = parent.renderOrder + 0.5;
|
|
9943
|
-
parent.add(pass);
|
|
9944
|
-
}
|
|
9945
|
-
return new _ItemGlint(owner, material);
|
|
9946
|
-
}
|
|
9947
|
-
/**
|
|
9948
|
-
* Maps glint before model centering and display transforms. Ordinary sprites approximate Minecraft's shared atlas density.
|
|
9949
|
-
* @internal
|
|
9950
|
-
*/
|
|
9951
|
-
static mapUvs(geometry, faces, atlas, itemId, display) {
|
|
9952
|
-
const uv = geometry.getAttribute("uv");
|
|
9953
|
-
const mapped = new Float32Array(uv.count * 2);
|
|
9954
|
-
if (itemId === "minecraft:compass" || itemId === "minecraft:recovery_compass" || itemId === "minecraft:clock") {
|
|
9955
|
-
const positions = geometry.getAttribute("position"), normals = geometry.getAttribute("normal");
|
|
9956
|
-
const scale = display === "gui" /* GUI */ ? 0.5 : display === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || display === "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */ ? 0.75 : 1;
|
|
9957
|
-
const factor = 1 / (16 * 128 * scale);
|
|
9958
|
-
for (let index = 0; index < positions.count; index++) {
|
|
9959
|
-
const x = positions.getX(index), y = positions.getY(index), z = positions.getZ(index);
|
|
9960
|
-
const nx = normals.getX(index), ny = normals.getY(index), nz = normals.getZ(index);
|
|
9961
|
-
const ax = Math.abs(nx), ay = Math.abs(ny), az = Math.abs(nz);
|
|
9962
|
-
let u, v;
|
|
9963
|
-
if (ay >= az && ay >= ax) {
|
|
9964
|
-
u = x;
|
|
9965
|
-
v = ny < 0 ? -z : z;
|
|
9966
|
-
} else if (az >= ax) {
|
|
9967
|
-
u = nz < 0 ? -x : x;
|
|
9968
|
-
v = -y;
|
|
9969
|
-
} else {
|
|
9970
|
-
u = nx < 0 ? -z : z;
|
|
9971
|
-
v = -y;
|
|
9972
|
-
}
|
|
9973
|
-
mapped[index * 2] = u * factor;
|
|
9974
|
-
mapped[index * 2 + 1] = v * factor;
|
|
9975
|
-
}
|
|
9976
|
-
geometry.setAttribute("glintUv", new import_three26.Float32BufferAttribute(mapped, 2));
|
|
9977
|
-
return;
|
|
9978
|
-
}
|
|
9979
|
-
for (const [faceIndex, face] of CUBE_FACES.entries()) {
|
|
9980
|
-
const texture = faces[face]?.texture?.substring(1);
|
|
9981
|
-
const position = texture && atlas.positions[texture] || [0, 0];
|
|
9982
|
-
const size = texture && atlas.sizes[texture] || [atlas.image.width, atlas.image.height];
|
|
9983
|
-
for (let corner = 0; corner < 4; corner++) {
|
|
9984
|
-
const index = faceIndex * 4 + corner;
|
|
9985
|
-
mapped[index * 2] = (uv.getX(index) * atlas.image.width - position[0]) / size[0] / 32;
|
|
9986
|
-
mapped[index * 2 + 1] = ((1 - uv.getY(index)) * atlas.image.height - position[1]) / size[1] / 32;
|
|
10200
|
+
};
|
|
10201
|
+
const id = Object.prototype.hasOwnProperty.call(models, special.kind) ? models[special.kind] : void 0;
|
|
10202
|
+
if (!id) throw new Error(`Unsupported special item head kind ${special.kind}`);
|
|
10203
|
+
const animation = (special.animation ?? 0) * Math.PI * 0.2;
|
|
10204
|
+
const rotations = { head: [0, Math.PI, 0] };
|
|
10205
|
+
if (special.kind === "dragon") rotations.jaw = [(Math.sin(animation) + 1) * 0.2, 0, 0];
|
|
10206
|
+
if (special.kind === "piglin") {
|
|
10207
|
+
rotations.left_ear = [0, 0, -(Math.cos(animation * 1.2) + 2.5) * 0.2];
|
|
10208
|
+
rotations.right_ear = [0, 0, (Math.cos(animation) + 2.5) * 0.2];
|
|
10209
|
+
}
|
|
10210
|
+
return [await load(
|
|
10211
|
+
id,
|
|
10212
|
+
special.texture ? texture(special.texture, "") : void 0,
|
|
10213
|
+
new import_three26.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three26.Matrix4().makeScale(-1, -1, 1)),
|
|
10214
|
+
rotations
|
|
10215
|
+
)];
|
|
9987
10216
|
}
|
|
9988
10217
|
}
|
|
9989
|
-
geometry.setAttribute("glintUv", new import_three26.Float32BufferAttribute(mapped, 2));
|
|
9990
|
-
}
|
|
9991
|
-
updateTime() {
|
|
9992
|
-
const time = Math.trunc(Date.now() * 4);
|
|
9993
|
-
this.material.uniforms.glintOffset.value.set(-(time % 11e4) / 11e4, time % 3e4 / 3e4);
|
|
9994
10218
|
}
|
|
9995
|
-
/**
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9999
|
-
|
|
10000
|
-
|
|
10001
|
-
|
|
10002
|
-
|
|
10003
|
-
|
|
10004
|
-
|
|
10005
|
-
|
|
10219
|
+
/** An owned material with model-preview shading; its entity texture remains shared. */
|
|
10220
|
+
static createMaterial(source, shade) {
|
|
10221
|
+
const material = source.clone();
|
|
10222
|
+
if (shade) {
|
|
10223
|
+
material.onBeforeCompile = (shader) => {
|
|
10224
|
+
shader.vertexShader = `varying float itemLight;
|
|
10225
|
+
${shader.vertexShader}`.replace("#include <begin_vertex>", `
|
|
10226
|
+
#include <begin_vertex>
|
|
10227
|
+
vec3 N = inverseTransformDirection(normalMatrix * normal, viewMatrix);
|
|
10228
|
+
itemLight = (1.0 + N.y) * 0.25 - N.x * N.x * 0.15 + N.z * N.z * 0.05 + 0.5;
|
|
10229
|
+
`);
|
|
10230
|
+
shader.fragmentShader = `varying float itemLight;
|
|
10231
|
+
${shader.fragmentShader}`.replace(
|
|
10232
|
+
"#include <color_fragment>",
|
|
10233
|
+
"#include <color_fragment>\ndiffuseColor.rgb *= itemLight;"
|
|
10234
|
+
);
|
|
10235
|
+
};
|
|
10236
|
+
material.customProgramCacheKey = () => "special-item-side";
|
|
10006
10237
|
}
|
|
10007
|
-
|
|
10008
|
-
dispose() {
|
|
10009
|
-
Ticker.remove(this.ticker);
|
|
10010
|
-
this.ticker = void 0;
|
|
10011
|
-
this.material.dispose();
|
|
10238
|
+
return material;
|
|
10012
10239
|
}
|
|
10013
10240
|
};
|
|
10014
10241
|
}
|
|
10015
10242
|
});
|
|
10016
10243
|
|
|
10244
|
+
// src/model/GuiLight.ts
|
|
10245
|
+
var GuiLight;
|
|
10246
|
+
var init_GuiLight = __esm({
|
|
10247
|
+
"src/model/GuiLight.ts"() {
|
|
10248
|
+
GuiLight = /* @__PURE__ */ ((GuiLight2) => {
|
|
10249
|
+
GuiLight2["FRONT"] = "front";
|
|
10250
|
+
GuiLight2["SIDE"] = "side";
|
|
10251
|
+
return GuiLight2;
|
|
10252
|
+
})(GuiLight || {});
|
|
10253
|
+
}
|
|
10254
|
+
});
|
|
10255
|
+
|
|
10017
10256
|
// src/model/scene/ModelObject.ts
|
|
10018
10257
|
var ModelObject_exports = {};
|
|
10019
10258
|
__export(ModelObject_exports, {
|
|
@@ -11159,17 +11398,25 @@ var init_BlockObject = __esm({
|
|
|
11159
11398
|
if (!key || this.options.displayPosition) return false;
|
|
11160
11399
|
const generation = this._entityGeneration;
|
|
11161
11400
|
const created = [];
|
|
11401
|
+
const placement = new import_three34.Matrix4();
|
|
11162
11402
|
let resolved;
|
|
11163
11403
|
try {
|
|
11164
11404
|
resolved = BlockEntities.resolve(await BlockEntities.getIndex(key.root), key.toNamespacedString(), this.state);
|
|
11165
11405
|
if (!resolved) return false;
|
|
11406
|
+
BlockEntities.matrix(resolved, placement);
|
|
11166
11407
|
for (const part of resolved.parts) {
|
|
11167
11408
|
const [namespace, path] = part.model.includes(":") ? part.model.split(":") : [key.namespace, part.model];
|
|
11168
|
-
|
|
11409
|
+
let texture = part.textureLocation === void 0 ? void 0 : AssetKey.parse("textures", part.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
|
|
11410
|
+
if (part.textureLocation === void 0 && namespace === "minecraft" && path === "player_head") {
|
|
11411
|
+
const { PlayerHeadTextures: PlayerHeadTextures2 } = await Promise.resolve().then(() => (init_PlayerHeadTextures(), PlayerHeadTextures_exports));
|
|
11412
|
+
texture = (await PlayerHeadTextures2.get(void 0, key.root)).texture;
|
|
11413
|
+
}
|
|
11169
11414
|
if (texture) texture.root = key.root;
|
|
11170
11415
|
const entity = await Entities.getEntity(new BasicAssetKey(namespace, path), texture, { layer: part.layer });
|
|
11171
11416
|
if (!entity) throw new MineRenderError(`Missing entity model ${part.model}`);
|
|
11172
|
-
|
|
11417
|
+
const object4 = await this.scene.addEntity(entity, { wireframe: this.options.wireframe });
|
|
11418
|
+
this.placeEntity(object4, placement);
|
|
11419
|
+
created.push(object4);
|
|
11173
11420
|
}
|
|
11174
11421
|
} catch (error) {
|
|
11175
11422
|
log15.warn(`Could not draw block entity ${key.toNamespacedString()}, using its block model`, error);
|
|
@@ -11180,18 +11427,21 @@ var init_BlockObject = __esm({
|
|
|
11180
11427
|
this.removeEntities(created);
|
|
11181
11428
|
return true;
|
|
11182
11429
|
}
|
|
11183
|
-
|
|
11430
|
+
this._entityPlacement.copy(placement);
|
|
11184
11431
|
this._entities = created;
|
|
11185
11432
|
this.placeEntities();
|
|
11186
11433
|
this.setVisible(this.visible);
|
|
11187
11434
|
return true;
|
|
11188
11435
|
}
|
|
11189
11436
|
placeEntities() {
|
|
11190
|
-
const matrix = new import_three34.Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
|
|
11191
11437
|
for (const entity of this._entities) {
|
|
11192
|
-
|
|
11438
|
+
this.placeEntity(entity, this._entityPlacement);
|
|
11193
11439
|
}
|
|
11194
11440
|
}
|
|
11441
|
+
placeEntity(entity, placement) {
|
|
11442
|
+
const matrix = new import_three34.Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(placement);
|
|
11443
|
+
matrix.decompose(entity.position, entity.quaternion, entity.scale);
|
|
11444
|
+
}
|
|
11195
11445
|
get isOccluding() {
|
|
11196
11446
|
if (!this.visible) {
|
|
11197
11447
|
return false;
|
|
@@ -11481,6 +11731,7 @@ __export(index_node_exports, {
|
|
|
11481
11731
|
AnvilParser: () => AnvilParser,
|
|
11482
11732
|
AnvilWorldSource: () => AnvilWorldSource,
|
|
11483
11733
|
ArchiveAssetSource: () => ArchiveAssetSource,
|
|
11734
|
+
Armor: () => Armor,
|
|
11484
11735
|
AssetKey: () => AssetKey,
|
|
11485
11736
|
AssetLoadError: () => AssetLoadError,
|
|
11486
11737
|
AssetLoader: () => AssetLoader,
|
|
@@ -11564,6 +11815,7 @@ __export(index_node_exports, {
|
|
|
11564
11815
|
OrbitControls: () => OrbitControls,
|
|
11565
11816
|
PackFormats: () => PackFormats,
|
|
11566
11817
|
PackMetadata: () => PackMetadata,
|
|
11818
|
+
PalettedTextures: () => PalettedTextures,
|
|
11567
11819
|
PersistentCache: () => PersistentCache,
|
|
11568
11820
|
PlayerHeadTextures: () => PlayerHeadTextures,
|
|
11569
11821
|
Renames: () => Renames,
|
|
@@ -11706,6 +11958,7 @@ init_PersistentCache();
|
|
|
11706
11958
|
var NodeCache = class extends PersistentCache {
|
|
11707
11959
|
constructor(backing) {
|
|
11708
11960
|
super(backing);
|
|
11961
|
+
this.pendingWrites = /* @__PURE__ */ new Map();
|
|
11709
11962
|
}
|
|
11710
11963
|
ready() {
|
|
11711
11964
|
return this.initialized ??= this.backing.init();
|
|
@@ -11716,7 +11969,14 @@ var NodeCache = class extends PersistentCache {
|
|
|
11716
11969
|
}
|
|
11717
11970
|
async put(key, value) {
|
|
11718
11971
|
await this.ready();
|
|
11719
|
-
|
|
11972
|
+
const previous = this.pendingWrites.get(key);
|
|
11973
|
+
const write = (previous ? previous.catch(() => void 0) : Promise.resolve()).then(() => this.backing.setItem(key, value)).then(() => value);
|
|
11974
|
+
this.pendingWrites.set(key, write);
|
|
11975
|
+
try {
|
|
11976
|
+
return await write;
|
|
11977
|
+
} finally {
|
|
11978
|
+
if (this.pendingWrites.get(key) === write) this.pendingWrites.delete(key);
|
|
11979
|
+
}
|
|
11720
11980
|
}
|
|
11721
11981
|
async delete(key) {
|
|
11722
11982
|
await this.ready();
|
|
@@ -11762,7 +12022,10 @@ var NodeEnv = class {
|
|
|
11762
12022
|
openCache(name, version2) {
|
|
11763
12023
|
return new NodeCache(import_node_persist.default.create({
|
|
11764
12024
|
dir: name + version2,
|
|
11765
|
-
encoding: "utf8"
|
|
12025
|
+
encoding: "utf8",
|
|
12026
|
+
// node-persist's unref'd one-second write queue delays loads and lets Node exit before writes finish.
|
|
12027
|
+
// NodeCache serializes writes to each key while allowing different files to write concurrently.
|
|
12028
|
+
writeQueue: false
|
|
11766
12029
|
}));
|
|
11767
12030
|
}
|
|
11768
12031
|
};
|
|
@@ -11839,6 +12102,9 @@ function shutdown() {
|
|
|
11839
12102
|
Caching.end();
|
|
11840
12103
|
}
|
|
11841
12104
|
|
|
12105
|
+
// src/armor/index.ts
|
|
12106
|
+
init_Armor();
|
|
12107
|
+
|
|
11842
12108
|
// src/assets/index.ts
|
|
11843
12109
|
init_AssetDefaults();
|
|
11844
12110
|
init_AssetKey();
|
|
@@ -11930,10 +12196,10 @@ init_EntityObject();
|
|
|
11930
12196
|
init_MineRenderError();
|
|
11931
12197
|
|
|
11932
12198
|
// src/export/SceneExporter.ts
|
|
11933
|
-
var
|
|
12199
|
+
var import_three20 = require("three");
|
|
11934
12200
|
|
|
11935
12201
|
// ../../node_modules/three/examples/jsm/exporters/OBJExporter.js
|
|
11936
|
-
var
|
|
12202
|
+
var import_three17 = require("three");
|
|
11937
12203
|
var OBJExporter = class {
|
|
11938
12204
|
/**
|
|
11939
12205
|
* Parses the given 3D object and generates the OBJ output.
|
|
@@ -11948,17 +12214,17 @@ var OBJExporter = class {
|
|
|
11948
12214
|
let indexVertex = 0;
|
|
11949
12215
|
let indexVertexUvs = 0;
|
|
11950
12216
|
let indexNormals = 0;
|
|
11951
|
-
const vertex = new
|
|
11952
|
-
const color2 = new
|
|
11953
|
-
const normal = new
|
|
11954
|
-
const uv = new
|
|
12217
|
+
const vertex = new import_three17.Vector3();
|
|
12218
|
+
const color2 = new import_three17.Color();
|
|
12219
|
+
const normal = new import_three17.Vector3();
|
|
12220
|
+
const uv = new import_three17.Vector2();
|
|
11955
12221
|
const face = [];
|
|
11956
12222
|
function parseMesh(mesh) {
|
|
11957
12223
|
let nbVertex = 0;
|
|
11958
12224
|
let nbNormals = 0;
|
|
11959
12225
|
let nbVertexUvs = 0;
|
|
11960
12226
|
const geometry = mesh.geometry;
|
|
11961
|
-
const normalMatrixWorld = new
|
|
12227
|
+
const normalMatrixWorld = new import_three17.Matrix3();
|
|
11962
12228
|
const vertices = geometry.getAttribute("position");
|
|
11963
12229
|
const normals = geometry.getAttribute("normal");
|
|
11964
12230
|
const uvs = geometry.getAttribute("uv");
|
|
@@ -12049,7 +12315,7 @@ var OBJExporter = class {
|
|
|
12049
12315
|
output += "v " + vertex.x + " " + vertex.y + " " + vertex.z;
|
|
12050
12316
|
if (colors2 !== void 0) {
|
|
12051
12317
|
color2.fromBufferAttribute(colors2, i);
|
|
12052
|
-
|
|
12318
|
+
import_three17.ColorManagement.workingToColorSpace(color2, import_three17.SRGBColorSpace);
|
|
12053
12319
|
output += " " + color2.r + " " + color2.g + " " + color2.b;
|
|
12054
12320
|
}
|
|
12055
12321
|
output += "\n";
|
|
@@ -12078,7 +12344,7 @@ var OBJExporter = class {
|
|
|
12078
12344
|
};
|
|
12079
12345
|
|
|
12080
12346
|
// ../../node_modules/three/examples/jsm/exporters/PLYExporter.js
|
|
12081
|
-
var
|
|
12347
|
+
var import_three18 = require("three");
|
|
12082
12348
|
var PLYExporter = class {
|
|
12083
12349
|
/**
|
|
12084
12350
|
* Parses the given 3D object and generates the PLY output.
|
|
@@ -12179,7 +12445,7 @@ var PLYExporter = class {
|
|
|
12179
12445
|
includeIndices = false;
|
|
12180
12446
|
}
|
|
12181
12447
|
});
|
|
12182
|
-
const tempColor = new
|
|
12448
|
+
const tempColor = new import_three18.Color();
|
|
12183
12449
|
includeIndices = includeIndices && excludeAttributes.indexOf("index") === -1;
|
|
12184
12450
|
includeNormals = includeNormals && excludeAttributes.indexOf("normal") === -1;
|
|
12185
12451
|
includeColors = includeColors && excludeAttributes.indexOf("color") === -1;
|
|
@@ -12228,8 +12494,8 @@ property list uchar int vertex_index
|
|
|
12228
12494
|
`;
|
|
12229
12495
|
}
|
|
12230
12496
|
header += "end_header\n";
|
|
12231
|
-
const vertex = new
|
|
12232
|
-
const normalMatrixWorld = new
|
|
12497
|
+
const vertex = new import_three18.Vector3();
|
|
12498
|
+
const normalMatrixWorld = new import_three18.Matrix3();
|
|
12233
12499
|
let result = null;
|
|
12234
12500
|
if (options.binary === true) {
|
|
12235
12501
|
const headerBin = new TextEncoder().encode(header);
|
|
@@ -12307,7 +12573,7 @@ property list uchar int vertex_index
|
|
|
12307
12573
|
if (includeColors === true) {
|
|
12308
12574
|
if (colors2 != null) {
|
|
12309
12575
|
tempColor.fromBufferAttribute(colors2, i);
|
|
12310
|
-
|
|
12576
|
+
import_three18.ColorManagement.workingToColorSpace(tempColor, import_three18.SRGBColorSpace);
|
|
12311
12577
|
const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
|
|
12312
12578
|
const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
|
|
12313
12579
|
const b = colorIsFloat ? tempColor.b : Math.round(tempColor.b * colorScale);
|
|
@@ -12409,7 +12675,7 @@ property list uchar int vertex_index
|
|
|
12409
12675
|
if (includeColors === true) {
|
|
12410
12676
|
if (colors2 != null) {
|
|
12411
12677
|
tempColor.fromBufferAttribute(colors2, i);
|
|
12412
|
-
|
|
12678
|
+
import_three18.ColorManagement.workingToColorSpace(tempColor, import_three18.SRGBColorSpace);
|
|
12413
12679
|
const r = colorIsFloat ? tempColor.r : Math.round(tempColor.r * colorScale);
|
|
12414
12680
|
const g = colorIsFloat ? tempColor.g : Math.round(tempColor.g * colorScale);
|
|
12415
12681
|
const b = colorIsFloat ? tempColor.b : Math.round(tempColor.b * colorScale);
|
|
@@ -12561,10 +12827,10 @@ var SceneExporter = class {
|
|
|
12561
12827
|
}
|
|
12562
12828
|
};
|
|
12563
12829
|
function localMatrix(object4) {
|
|
12564
|
-
return object4.matrixAutoUpdate ? new
|
|
12830
|
+
return object4.matrixAutoUpdate ? new import_three20.Matrix4().compose(object4.position, object4.quaternion, object4.scale) : object4.matrix.clone();
|
|
12565
12831
|
}
|
|
12566
12832
|
function createSnapshot(root, gltf, bakeColors = false) {
|
|
12567
|
-
const scene = new
|
|
12833
|
+
const scene = new import_three20.Scene();
|
|
12568
12834
|
const geometries = [];
|
|
12569
12835
|
const materials = [];
|
|
12570
12836
|
const textures = [];
|
|
@@ -12582,7 +12848,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12582
12848
|
if (!uniforms.map?.value?.isTexture || !uniforms.SHADE || !uniforms.BRIGHTNESS || !uniforms.EMISSIVE) {
|
|
12583
12849
|
throw new MineRenderError("glTF export does not support this custom ShaderMaterial");
|
|
12584
12850
|
}
|
|
12585
|
-
material = new
|
|
12851
|
+
material = new import_three20.MeshBasicMaterial({
|
|
12586
12852
|
map: uniforms.map.value,
|
|
12587
12853
|
vertexColors: source.vertexColors,
|
|
12588
12854
|
transparent: source.transparent,
|
|
@@ -12592,7 +12858,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12592
12858
|
});
|
|
12593
12859
|
material.name = source.name;
|
|
12594
12860
|
} else if (shader.isShaderMaterial) {
|
|
12595
|
-
material = new
|
|
12861
|
+
material = new import_three20.MeshBasicMaterial({ vertexColors: source.vertexColors });
|
|
12596
12862
|
material.name = source.name;
|
|
12597
12863
|
} else {
|
|
12598
12864
|
const copySource = Object.create(source);
|
|
@@ -12646,11 +12912,11 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12646
12912
|
const material = copyMaterial(sourceMaterial, geometry);
|
|
12647
12913
|
if (!sourceMaterial.vertexColors) geometry.deleteAttribute("color");
|
|
12648
12914
|
if (bakeColors || instanceColor) {
|
|
12649
|
-
const tint = (material.color ?? new
|
|
12915
|
+
const tint = (material.color ?? new import_three20.Color()).clone();
|
|
12650
12916
|
if (instanceColor) tint.multiply(instanceColor);
|
|
12651
12917
|
if (bakeColors) {
|
|
12652
12918
|
const original = geometry.getAttribute("color");
|
|
12653
|
-
const colors2 = new
|
|
12919
|
+
const colors2 = new import_three20.Float32BufferAttribute(new Float32Array(geometry.getAttribute("position").count * 3), 3);
|
|
12654
12920
|
for (let i = 0; i < colors2.count; i++) {
|
|
12655
12921
|
colors2.setXYZ(i, (original?.getX(i) ?? 1) * tint.r, (original?.getY(i) ?? 1) * tint.g, (original?.getZ(i) ?? 1) * tint.b);
|
|
12656
12922
|
}
|
|
@@ -12659,7 +12925,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12659
12925
|
material.color.copy(tint);
|
|
12660
12926
|
}
|
|
12661
12927
|
}
|
|
12662
|
-
const copy = new
|
|
12928
|
+
const copy = new import_three20.Mesh(geometry, material);
|
|
12663
12929
|
copy.name = mesh.name;
|
|
12664
12930
|
copy.renderOrder = mesh.renderOrder;
|
|
12665
12931
|
scene.add(copy);
|
|
@@ -12673,9 +12939,9 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12673
12939
|
const instanced = mesh;
|
|
12674
12940
|
if (instanced.isInstancedMesh) {
|
|
12675
12941
|
for (let i = 0; i < instanced.count; i++) {
|
|
12676
|
-
const matrix = new
|
|
12942
|
+
const matrix = new import_three20.Matrix4();
|
|
12677
12943
|
instanced.getMatrixAt(i, matrix);
|
|
12678
|
-
const color2 = instanced.instanceColor ? new
|
|
12944
|
+
const color2 = instanced.instanceColor ? new import_three20.Color().fromBufferAttribute(instanced.instanceColor, i) : void 0;
|
|
12679
12945
|
addMesh(mesh, world.clone().multiply(matrix), color2);
|
|
12680
12946
|
}
|
|
12681
12947
|
} else {
|
|
@@ -12687,7 +12953,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12687
12953
|
try {
|
|
12688
12954
|
const ancestors = [];
|
|
12689
12955
|
for (let parent = root.parent; parent; parent = parent.parent) ancestors.unshift(parent);
|
|
12690
|
-
const world = new
|
|
12956
|
+
const world = new import_three20.Matrix4();
|
|
12691
12957
|
for (const ancestor of ancestors) {
|
|
12692
12958
|
if (!ancestor.visible) return { scene, dispose };
|
|
12693
12959
|
world.multiply(localMatrix(ancestor));
|
|
@@ -12701,7 +12967,7 @@ function createSnapshot(root, gltf, bakeColors = false) {
|
|
|
12701
12967
|
}
|
|
12702
12968
|
function selectAlphaMode(material, geometry) {
|
|
12703
12969
|
const texture = material.map;
|
|
12704
|
-
if (material.type !== "MeshBasicMaterial" || !material.transparent || !material.depthWrite || material.opacity !== 1 || material.alphaMap || !texture?.isDataTexture || texture.format !==
|
|
12970
|
+
if (material.type !== "MeshBasicMaterial" || !material.transparent || !material.depthWrite || material.opacity !== 1 || material.alphaMap || !texture?.isDataTexture || texture.format !== import_three20.RGBAFormat || texture.type !== import_three20.UnsignedByteType || texture.wrapS !== import_three20.ClampToEdgeWrapping || texture.wrapT !== import_three20.ClampToEdgeWrapping || texture.magFilter !== import_three20.NearestFilter || texture.minFilter !== import_three20.NearestFilter || texture.anisotropy > 1 || texture.offset.x !== 0 || texture.offset.y !== 0 || texture.repeat.x !== 1 || texture.repeat.y !== 1 || texture.rotation !== 0 || !texture.matrixAutoUpdate && !texture.matrix.elements.every((value, i) => value === (i % 4 === 0 ? 1 : 0))) return;
|
|
12705
12971
|
const uv = geometry.getAttribute(texture.channel === 0 ? "uv" : `uv${texture.channel}`);
|
|
12706
12972
|
const colors2 = geometry.getAttribute("color");
|
|
12707
12973
|
if (!uv || material.vertexColors && colors2?.itemSize === 4) return;
|
|
@@ -12738,7 +13004,7 @@ function selectAlphaMode(material, geometry) {
|
|
|
12738
13004
|
}
|
|
12739
13005
|
function copyDataTexture(source) {
|
|
12740
13006
|
const image = source.image;
|
|
12741
|
-
if (!image.data || source.format !==
|
|
13007
|
+
if (!image.data || source.format !== import_three20.RGBAFormat || source.type !== import_three20.UnsignedByteType) {
|
|
12742
13008
|
throw new MineRenderError("glTF export requires RGBA unsigned-byte data textures");
|
|
12743
13009
|
}
|
|
12744
13010
|
const canvas = createCanvas2(image.width, image.height);
|
|
@@ -12749,8 +13015,8 @@ function copyDataTexture(source) {
|
|
|
12749
13015
|
context.putImageData(pixels, 0, 0);
|
|
12750
13016
|
const copySource = Object.create(source);
|
|
12751
13017
|
copySource.userData = {};
|
|
12752
|
-
copySource.source = new
|
|
12753
|
-
return new
|
|
13018
|
+
copySource.source = new import_three20.TextureSource(canvas);
|
|
13019
|
+
return new import_three20.Texture().copy(copySource);
|
|
12754
13020
|
}
|
|
12755
13021
|
|
|
12756
13022
|
// src/export/VideoExporter.ts
|
|
@@ -14360,12 +14626,13 @@ function isFlyControls(obj) {
|
|
|
14360
14626
|
}
|
|
14361
14627
|
|
|
14362
14628
|
// src/renderer/MineRenderScene.ts
|
|
14363
|
-
var
|
|
14629
|
+
var import_three37 = require("three");
|
|
14364
14630
|
init_SceneObject();
|
|
14365
14631
|
init_merge();
|
|
14366
14632
|
|
|
14367
14633
|
// src/skin/scene/SkinObject.ts
|
|
14368
14634
|
init_SceneObject();
|
|
14635
|
+
var import_three36 = require("three");
|
|
14369
14636
|
|
|
14370
14637
|
// src/skin/SkinPart.ts
|
|
14371
14638
|
var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
|
|
@@ -14382,11 +14649,21 @@ var SkinPart = /* @__PURE__ */ ((SkinPart2) => {
|
|
|
14382
14649
|
SkinPart2["RIGHT_TROUSERS"] = "rightTrousers";
|
|
14383
14650
|
SkinPart2["LEFT_TROUSERS"] = "leftTrousers";
|
|
14384
14651
|
SkinPart2["CAPE"] = "cape";
|
|
14652
|
+
SkinPart2["LEFT_EAR"] = "leftEar";
|
|
14653
|
+
SkinPart2["RIGHT_EAR"] = "rightEar";
|
|
14385
14654
|
return SkinPart2;
|
|
14386
14655
|
})(SkinPart || {});
|
|
14387
14656
|
var SKIN_PARTS = Object.values(SkinPart);
|
|
14388
14657
|
|
|
14389
14658
|
// src/skin/SkinTextureCoordinates.ts
|
|
14659
|
+
var earCoordinates = {
|
|
14660
|
+
west: { uv: [24, 1, 25, 7] },
|
|
14661
|
+
east: { uv: [31, 1, 32, 7] },
|
|
14662
|
+
south: { uv: [25, 1, 31, 7] },
|
|
14663
|
+
north: { uv: [32, 1, 38, 7] },
|
|
14664
|
+
up: { uv: [25, 0, 31, 1] },
|
|
14665
|
+
down: { uv: [31, 1, 37, 0] }
|
|
14666
|
+
};
|
|
14390
14667
|
var baseSkinCoordinates = {
|
|
14391
14668
|
head: {
|
|
14392
14669
|
west: {
|
|
@@ -15007,7 +15284,9 @@ var baseSkinCoordinates = {
|
|
|
15007
15284
|
south: { uv: [12, 1, 22, 17] },
|
|
15008
15285
|
up: { uv: [11, 1, 1, 0] },
|
|
15009
15286
|
down: { uv: [21, 0, 11, 1] }
|
|
15010
|
-
}
|
|
15287
|
+
},
|
|
15288
|
+
leftEar: earCoordinates,
|
|
15289
|
+
rightEar: earCoordinates
|
|
15011
15290
|
};
|
|
15012
15291
|
var classicSkinTextureCoordinates = {
|
|
15013
15292
|
...baseSkinCoordinates
|
|
@@ -15058,6 +15337,7 @@ var box4_12_4outer = [4.5, 12.5, 4.5];
|
|
|
15058
15337
|
var box3_12_4inner = [3, 12, 4];
|
|
15059
15338
|
var box3_12_4outer = [3.5, 12.5, 4.5];
|
|
15060
15339
|
var box10_16_1 = [10, 16, 1];
|
|
15340
|
+
var box8_8_3ear = [8, 8, 3];
|
|
15061
15341
|
var baseSkinGeometries = {
|
|
15062
15342
|
head: box8inner,
|
|
15063
15343
|
hat: box8outer,
|
|
@@ -15071,7 +15351,9 @@ var baseSkinGeometries = {
|
|
|
15071
15351
|
leftTrousers: box4_12_4outer,
|
|
15072
15352
|
rightLeg: box4_12_4inner,
|
|
15073
15353
|
rightTrousers: box4_12_4outer,
|
|
15074
|
-
cape: box10_16_1
|
|
15354
|
+
cape: box10_16_1,
|
|
15355
|
+
leftEar: box8_8_3ear,
|
|
15356
|
+
rightEar: box8_8_3ear
|
|
15075
15357
|
};
|
|
15076
15358
|
var classicSkinGeometries = { ...{}, ...baseSkinGeometries };
|
|
15077
15359
|
var slimSkinGeometries = {
|
|
@@ -15100,6 +15382,12 @@ var capeTextureSizes = {
|
|
|
15100
15382
|
};
|
|
15101
15383
|
|
|
15102
15384
|
// src/skin/scene/SkinObject.ts
|
|
15385
|
+
var ArmorClass;
|
|
15386
|
+
var EntityObjectClass;
|
|
15387
|
+
function hasCubes(part) {
|
|
15388
|
+
return part.cubes.length > 0 || Object.values(part.children).some(hasCubes);
|
|
15389
|
+
}
|
|
15390
|
+
var UPSIDE_DOWN_OFFSET = (1.8 + 0.1) * 16 / 0.9375;
|
|
15103
15391
|
var SkinObject = class extends SceneObject {
|
|
15104
15392
|
constructor(options) {
|
|
15105
15393
|
super();
|
|
@@ -15107,27 +15395,42 @@ var SkinObject = class extends SceneObject {
|
|
|
15107
15395
|
this.detectedSlim = false;
|
|
15108
15396
|
this.skinLoad = 0;
|
|
15109
15397
|
this.capeLoad = 0;
|
|
15398
|
+
this.armorLoad = 0;
|
|
15399
|
+
this.armorObjects = [];
|
|
15110
15400
|
this.options = (0, import_ts_deepmerge.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
|
|
15111
15401
|
this.slim = this.options.slim ?? false;
|
|
15112
15402
|
}
|
|
15113
15403
|
async init() {
|
|
15114
15404
|
const cape = this.getGroupByName("cape" /* CAPE */);
|
|
15405
|
+
const capeOnBody = cape?.parent === this.getGroupByName("body" /* BODY */);
|
|
15115
15406
|
this.createMeshes();
|
|
15116
|
-
if (cape)
|
|
15407
|
+
if (cape) {
|
|
15408
|
+
const body = this.getGroupByName("body" /* BODY */);
|
|
15409
|
+
if (capeOnBody) body.add(cape);
|
|
15410
|
+
else body.attach(cape);
|
|
15411
|
+
}
|
|
15412
|
+
for (const { part, object: object4 } of this.armorObjects) this.getGroupByName(part).add(object4);
|
|
15413
|
+
this.updateEars();
|
|
15414
|
+
this.updateUpsideDown();
|
|
15117
15415
|
}
|
|
15118
15416
|
removeMeshes() {
|
|
15119
15417
|
}
|
|
15120
15418
|
createMeshes() {
|
|
15121
15419
|
const mat = this.skinMaterial ?? Materials.MISSING_TEXTURE;
|
|
15420
|
+
this.model?.removeFromParent();
|
|
15421
|
+
const model = this.model = new import_three36.Object3D();
|
|
15422
|
+
this.add(model);
|
|
15122
15423
|
{
|
|
15123
|
-
const headGroup = this.
|
|
15424
|
+
const headGroup = this.createGroup("head", 0, 28, 0, "y" /* Y */, -4);
|
|
15425
|
+
model.add(headGroup);
|
|
15124
15426
|
const headGeo = this.getBoxGeometry("head" /* HEAD */);
|
|
15125
15427
|
const head = this.createAndAddMesh("head", headGroup, headGeo, mat, "y" /* Y */, 4);
|
|
15126
15428
|
const hatGeo = this.getBoxGeometry("hat" /* HAT */);
|
|
15127
15429
|
const hat = this.createAndAddMesh("hat", headGroup, hatGeo, mat, "y" /* Y */, 4);
|
|
15128
15430
|
}
|
|
15129
15431
|
{
|
|
15130
|
-
const bodyGroup = this.
|
|
15432
|
+
const bodyGroup = this.createGroup("body", 0, 24, 0);
|
|
15433
|
+
model.add(bodyGroup);
|
|
15131
15434
|
const bodyGeo = this.getBoxGeometry("body" /* BODY */);
|
|
15132
15435
|
const body = this.createAndAddMesh("body", bodyGroup, bodyGeo, mat, "y" /* Y */, -6);
|
|
15133
15436
|
const jacketGeo = this.getBoxGeometry("jacket" /* JACKET */);
|
|
@@ -15135,7 +15438,8 @@ var SkinObject = class extends SceneObject {
|
|
|
15135
15438
|
}
|
|
15136
15439
|
{
|
|
15137
15440
|
{
|
|
15138
|
-
const leftArmGroup = this.
|
|
15441
|
+
const leftArmGroup = this.createGroup("leftArm", 5, 22, 0);
|
|
15442
|
+
model.add(leftArmGroup);
|
|
15139
15443
|
const leftArmGeo = this.getBoxGeometry("leftArm" /* LEFT_ARM */);
|
|
15140
15444
|
const leftArm = this.createAndAddMesh("leftArm", leftArmGroup, leftArmGeo, mat, "y" /* Y */, -4);
|
|
15141
15445
|
leftArm.position.x = this.slim ? 0.5 : 1;
|
|
@@ -15144,7 +15448,8 @@ var SkinObject = class extends SceneObject {
|
|
|
15144
15448
|
leftSleeve.position.x = this.slim ? 0.5 : 1;
|
|
15145
15449
|
}
|
|
15146
15450
|
{
|
|
15147
|
-
const rightArmGroup = this.
|
|
15451
|
+
const rightArmGroup = this.createGroup("rightArm", -5, 22, 0);
|
|
15452
|
+
model.add(rightArmGroup);
|
|
15148
15453
|
const rightArmGeo = this.getBoxGeometry("rightArm" /* RIGHT_ARM */);
|
|
15149
15454
|
const rightArm = this.createAndAddMesh("rightArm", rightArmGroup, rightArmGeo, mat, "y" /* Y */, -4);
|
|
15150
15455
|
rightArm.position.x = this.slim ? -0.5 : -1;
|
|
@@ -15155,14 +15460,16 @@ var SkinObject = class extends SceneObject {
|
|
|
15155
15460
|
}
|
|
15156
15461
|
{
|
|
15157
15462
|
{
|
|
15158
|
-
const leftLegGroup = this.
|
|
15463
|
+
const leftLegGroup = this.createGroup("leftLeg", 1.9, 12, 0);
|
|
15464
|
+
model.add(leftLegGroup);
|
|
15159
15465
|
const leftLegGeo = this.getBoxGeometry("leftLeg" /* LEFT_LEG */);
|
|
15160
15466
|
const leftLeg = this.createAndAddMesh("leftLeg", leftLegGroup, leftLegGeo, mat, "y" /* Y */, -6);
|
|
15161
15467
|
const leftTrousersGeo = this.getBoxGeometry("leftTrousers" /* LEFT_TROUSERS */);
|
|
15162
15468
|
const leftTrousers = this.createAndAddMesh("leftTrousers", leftLegGroup, leftTrousersGeo, mat, "y" /* Y */, -6);
|
|
15163
15469
|
}
|
|
15164
15470
|
{
|
|
15165
|
-
const rightLegGroup = this.
|
|
15471
|
+
const rightLegGroup = this.createGroup("rightLeg", -1.9, 12, 0);
|
|
15472
|
+
model.add(rightLegGroup);
|
|
15166
15473
|
const rightLegGeo = this.getBoxGeometry("rightLeg" /* RIGHT_LEG */);
|
|
15167
15474
|
const rightLeg = this.createAndAddMesh("rightLeg", rightLegGroup, rightLegGeo, mat, "y" /* Y */, -6);
|
|
15168
15475
|
const rightTrousersGeo = this.getBoxGeometry("rightTrousers" /* RIGHT_TROUSERS */);
|
|
@@ -15229,6 +15536,54 @@ var SkinObject = class extends SceneObject {
|
|
|
15229
15536
|
}
|
|
15230
15537
|
this.notifyDirty();
|
|
15231
15538
|
}
|
|
15539
|
+
/**
|
|
15540
|
+
* Loads armor from 1.21.4+ equipment assets, or pass undefined to remove it.
|
|
15541
|
+
* Each piece moves with the skin part it covers.
|
|
15542
|
+
*/
|
|
15543
|
+
async setArmor(armor) {
|
|
15544
|
+
const load = ++this.armorLoad;
|
|
15545
|
+
const objects = [];
|
|
15546
|
+
if (armor) {
|
|
15547
|
+
const Armor2 = ArmorClass ??= (await Promise.resolve().then(() => (init_Armor(), Armor_exports))).Armor;
|
|
15548
|
+
const EntityObject2 = EntityObjectClass ??= (await Promise.resolve().then(() => (init_EntityObject(), EntityObject_exports))).EntityObject;
|
|
15549
|
+
const model = await Armor2.getEntity(armor);
|
|
15550
|
+
if (model) {
|
|
15551
|
+
const parts = { head: "head", body: "body", left_arm: "leftArm", right_arm: "rightArm", left_leg: "leftLeg", right_leg: "rightLeg" };
|
|
15552
|
+
for (const [name, part] of Object.entries(parts)) {
|
|
15553
|
+
const layers = {};
|
|
15554
|
+
for (const [draw, layer] of Object.entries(model.layers)) {
|
|
15555
|
+
const child = layer.layer.root.children[name];
|
|
15556
|
+
if (!child || !hasCubes(child)) continue;
|
|
15557
|
+
const pose = { offset: [0, 0, 0], rotation: [0, 0, 0] };
|
|
15558
|
+
layers[draw] = { ...layer, layer: { ...layer.layer, root: {
|
|
15559
|
+
pose,
|
|
15560
|
+
cubes: [],
|
|
15561
|
+
children: { [name]: { ...child, pose } }
|
|
15562
|
+
} } };
|
|
15563
|
+
}
|
|
15564
|
+
const first = Object.values(layers)[0];
|
|
15565
|
+
if (!first) continue;
|
|
15566
|
+
const object4 = new EntityObject2({ ...first, id: model.id, layers }, { flip: false });
|
|
15567
|
+
object4.rotation.x = Math.PI;
|
|
15568
|
+
objects.push({ part, object: object4 });
|
|
15569
|
+
}
|
|
15570
|
+
}
|
|
15571
|
+
}
|
|
15572
|
+
const results = await Promise.allSettled(objects.map(({ object: object4 }) => object4.init()));
|
|
15573
|
+
const failure = results.find((result) => result.status === "rejected");
|
|
15574
|
+
if (load !== this.armorLoad || failure) {
|
|
15575
|
+
for (const { object: object4 } of objects) object4.dispose();
|
|
15576
|
+
if (load === this.armorLoad && failure?.status === "rejected") throw failure.reason;
|
|
15577
|
+
return;
|
|
15578
|
+
}
|
|
15579
|
+
for (const { object: object4 } of this.armorObjects) {
|
|
15580
|
+
object4.dispose();
|
|
15581
|
+
object4.removeFromParent();
|
|
15582
|
+
}
|
|
15583
|
+
this.armorObjects = objects;
|
|
15584
|
+
for (const { part, object: object4 } of objects) this.getGroupByName(part)?.add(object4);
|
|
15585
|
+
this.notifyDirty();
|
|
15586
|
+
}
|
|
15232
15587
|
/** Select the arm model, or pass undefined to use texture detection. */
|
|
15233
15588
|
setSlim(slim) {
|
|
15234
15589
|
this.options.slim = slim;
|
|
@@ -15247,6 +15602,39 @@ var SkinObject = class extends SceneObject {
|
|
|
15247
15602
|
}
|
|
15248
15603
|
this.notifyDirty();
|
|
15249
15604
|
}
|
|
15605
|
+
/** Shows or hides deadmau5's ears, which vanilla draws from the skin texture at 24,0 for that player only. */
|
|
15606
|
+
setEars(ears) {
|
|
15607
|
+
if (ears === (this.options.ears ?? false)) return;
|
|
15608
|
+
this.options.ears = ears;
|
|
15609
|
+
this.updateEars();
|
|
15610
|
+
}
|
|
15611
|
+
updateEars() {
|
|
15612
|
+
const head = this.getGroupByName("head" /* HEAD */);
|
|
15613
|
+
if (!head) return;
|
|
15614
|
+
for (const [part, x] of [["leftEar" /* LEFT_EAR */, 6], ["rightEar" /* RIGHT_EAR */, -6]]) {
|
|
15615
|
+
const ear = this.getMeshByName(part);
|
|
15616
|
+
if (!this.options.ears) {
|
|
15617
|
+
ear?.removeFromParent();
|
|
15618
|
+
} else if (!ear) {
|
|
15619
|
+
const mesh = this.createAndAddMesh(part, head, this.getBoxGeometry(part), this.skinMaterial ?? Materials.MISSING_TEXTURE);
|
|
15620
|
+
mesh.position.set(x, 9, 0.5);
|
|
15621
|
+
}
|
|
15622
|
+
}
|
|
15623
|
+
this.notifyDirty();
|
|
15624
|
+
}
|
|
15625
|
+
/** Turns the player upside down, as vanilla does for players named Dinnerbone or Grumm. */
|
|
15626
|
+
setUpsideDown(upsideDown) {
|
|
15627
|
+
if (upsideDown === (this.options.upsideDown ?? false)) return;
|
|
15628
|
+
this.options.upsideDown = upsideDown;
|
|
15629
|
+
this.updateUpsideDown();
|
|
15630
|
+
}
|
|
15631
|
+
updateUpsideDown() {
|
|
15632
|
+
if (!this.model) return;
|
|
15633
|
+
const upsideDown = this.options.upsideDown ?? false;
|
|
15634
|
+
this.model.position.y = upsideDown ? UPSIDE_DOWN_OFFSET : 0;
|
|
15635
|
+
this.model.rotation.z = upsideDown ? Math.PI : 0;
|
|
15636
|
+
this.notifyDirty();
|
|
15637
|
+
}
|
|
15250
15638
|
/** Select the texture layout, or pass undefined to detect it from image dimensions. */
|
|
15251
15639
|
async setLegacy(legacy) {
|
|
15252
15640
|
if (legacy === this.options.legacy) return;
|
|
@@ -15256,6 +15644,11 @@ var SkinObject = class extends SceneObject {
|
|
|
15256
15644
|
dispose() {
|
|
15257
15645
|
this.skinLoad++;
|
|
15258
15646
|
this.capeLoad++;
|
|
15647
|
+
this.armorLoad++;
|
|
15648
|
+
for (const { object: object4 } of this.armorObjects.splice(0)) {
|
|
15649
|
+
object4.dispose();
|
|
15650
|
+
object4.removeFromParent();
|
|
15651
|
+
}
|
|
15259
15652
|
super.dispose();
|
|
15260
15653
|
}
|
|
15261
15654
|
//TODO: layer toggles
|
|
@@ -15275,10 +15668,10 @@ function isBlockObject2(obj) {
|
|
|
15275
15668
|
}
|
|
15276
15669
|
var ModelObjectClass;
|
|
15277
15670
|
var BlockObjectClass;
|
|
15278
|
-
var
|
|
15671
|
+
var EntityObjectClass2;
|
|
15279
15672
|
var GuiObjectClass;
|
|
15280
15673
|
var ItemTintsClass;
|
|
15281
|
-
var MineRenderScene = class _MineRenderScene extends
|
|
15674
|
+
var MineRenderScene = class _MineRenderScene extends import_three37.Scene {
|
|
15282
15675
|
constructor(options) {
|
|
15283
15676
|
super();
|
|
15284
15677
|
this.isMineRenderScene = true;
|
|
@@ -15419,7 +15812,7 @@ var MineRenderScene = class _MineRenderScene extends import_three36.Scene {
|
|
|
15419
15812
|
}
|
|
15420
15813
|
/** Adds an entity loaded with {@link Entities.getEntity}, using its selected layers and textures. */
|
|
15421
15814
|
async addEntity(entity, options, parent = this) {
|
|
15422
|
-
const EntityObject2 =
|
|
15815
|
+
const EntityObject2 = EntityObjectClass2 ??= (await Promise.resolve().then(() => (init_EntityObject(), EntityObject_exports))).EntityObject;
|
|
15423
15816
|
return this.addSceneObject(entity, () => new EntityObject2(entity, options), options, parent);
|
|
15424
15817
|
}
|
|
15425
15818
|
/**
|
|
@@ -15441,7 +15834,7 @@ function isMineRenderScene(obj) {
|
|
|
15441
15834
|
}
|
|
15442
15835
|
|
|
15443
15836
|
// src/renderer/Renderer.ts
|
|
15444
|
-
var
|
|
15837
|
+
var import_three39 = require("three");
|
|
15445
15838
|
init_merge();
|
|
15446
15839
|
var import_stats = __toESM(require("stats.js"));
|
|
15447
15840
|
var import_postprocessing = require("postprocessing");
|
|
@@ -15450,11 +15843,11 @@ init_Model();
|
|
|
15450
15843
|
init_three();
|
|
15451
15844
|
|
|
15452
15845
|
// src/three/OrbitControls.js
|
|
15453
|
-
var
|
|
15846
|
+
var import_three38 = require("three");
|
|
15454
15847
|
var _changeEvent = { type: "change" };
|
|
15455
15848
|
var _startEvent = { type: "start" };
|
|
15456
15849
|
var _endEvent = { type: "end" };
|
|
15457
|
-
var OrbitControls = class extends
|
|
15850
|
+
var OrbitControls = class extends import_three38.EventDispatcher {
|
|
15458
15851
|
constructor(object4, domElement) {
|
|
15459
15852
|
super();
|
|
15460
15853
|
if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
|
|
@@ -15463,7 +15856,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15463
15856
|
this.domElement = domElement;
|
|
15464
15857
|
this.domElement.style.touchAction = "none";
|
|
15465
15858
|
this.enabled = true;
|
|
15466
|
-
this.target = new
|
|
15859
|
+
this.target = new import_three38.Vector3();
|
|
15467
15860
|
this.minDistance = 0;
|
|
15468
15861
|
this.maxDistance = Infinity;
|
|
15469
15862
|
this.minZoom = 0;
|
|
@@ -15485,8 +15878,8 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15485
15878
|
this.autoRotate = false;
|
|
15486
15879
|
this.autoRotateSpeed = 2;
|
|
15487
15880
|
this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
|
|
15488
|
-
this.mouseButtons = { LEFT:
|
|
15489
|
-
this.touches = { ONE:
|
|
15881
|
+
this.mouseButtons = { LEFT: import_three38.MOUSE.ROTATE, MIDDLE: import_three38.MOUSE.DOLLY, RIGHT: import_three38.MOUSE.PAN };
|
|
15882
|
+
this.touches = { ONE: import_three38.TOUCH.ROTATE, TWO: import_three38.TOUCH.DOLLY_PAN };
|
|
15490
15883
|
this.target0 = this.target.clone();
|
|
15491
15884
|
this.position0 = this.object.position.clone();
|
|
15492
15885
|
this.zoom0 = this.object.zoom;
|
|
@@ -15515,11 +15908,11 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15515
15908
|
state = STATE.NONE;
|
|
15516
15909
|
};
|
|
15517
15910
|
this.update = function() {
|
|
15518
|
-
const offset = new
|
|
15519
|
-
const quat = new
|
|
15911
|
+
const offset = new import_three38.Vector3();
|
|
15912
|
+
const quat = new import_three38.Quaternion().setFromUnitVectors(object4.up, new import_three38.Vector3(0, 1, 0));
|
|
15520
15913
|
const quatInverse = quat.clone().invert();
|
|
15521
|
-
const lastPosition = new
|
|
15522
|
-
const lastQuaternion = new
|
|
15914
|
+
const lastPosition = new import_three38.Vector3();
|
|
15915
|
+
const lastQuaternion = new import_three38.Quaternion();
|
|
15523
15916
|
const twoPI = 2 * Math.PI;
|
|
15524
15917
|
return function update() {
|
|
15525
15918
|
const position = scope.object.position;
|
|
@@ -15605,20 +15998,20 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15605
15998
|
};
|
|
15606
15999
|
let state = STATE.NONE;
|
|
15607
16000
|
const EPS = 1e-6;
|
|
15608
|
-
const spherical = new
|
|
15609
|
-
const sphericalDelta = new
|
|
16001
|
+
const spherical = new import_three38.Spherical();
|
|
16002
|
+
const sphericalDelta = new import_three38.Spherical();
|
|
15610
16003
|
let scale = 1;
|
|
15611
|
-
const panOffset = new
|
|
16004
|
+
const panOffset = new import_three38.Vector3();
|
|
15612
16005
|
let zoomChanged = false;
|
|
15613
|
-
const rotateStart = new
|
|
15614
|
-
const rotateEnd = new
|
|
15615
|
-
const rotateDelta = new
|
|
15616
|
-
const panStart = new
|
|
15617
|
-
const panEnd = new
|
|
15618
|
-
const panDelta = new
|
|
15619
|
-
const dollyStart = new
|
|
15620
|
-
const dollyEnd = new
|
|
15621
|
-
const dollyDelta = new
|
|
16006
|
+
const rotateStart = new import_three38.Vector2();
|
|
16007
|
+
const rotateEnd = new import_three38.Vector2();
|
|
16008
|
+
const rotateDelta = new import_three38.Vector2();
|
|
16009
|
+
const panStart = new import_three38.Vector2();
|
|
16010
|
+
const panEnd = new import_three38.Vector2();
|
|
16011
|
+
const panDelta = new import_three38.Vector2();
|
|
16012
|
+
const dollyStart = new import_three38.Vector2();
|
|
16013
|
+
const dollyEnd = new import_three38.Vector2();
|
|
16014
|
+
const dollyDelta = new import_three38.Vector2();
|
|
15622
16015
|
const pointers = [];
|
|
15623
16016
|
const pointerPositions = {};
|
|
15624
16017
|
function getAutoRotationAngle() {
|
|
@@ -15634,7 +16027,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15634
16027
|
sphericalDelta.phi -= angle;
|
|
15635
16028
|
}
|
|
15636
16029
|
const panLeft = function() {
|
|
15637
|
-
const v = new
|
|
16030
|
+
const v = new import_three38.Vector3();
|
|
15638
16031
|
return function panLeft2(distance, objectMatrix) {
|
|
15639
16032
|
v.setFromMatrixColumn(objectMatrix, 0);
|
|
15640
16033
|
v.multiplyScalar(-distance);
|
|
@@ -15642,7 +16035,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15642
16035
|
};
|
|
15643
16036
|
}();
|
|
15644
16037
|
const panUp = function() {
|
|
15645
|
-
const v = new
|
|
16038
|
+
const v = new import_three38.Vector3();
|
|
15646
16039
|
return function panUp2(distance, objectMatrix) {
|
|
15647
16040
|
if (scope.screenSpacePanning === true) {
|
|
15648
16041
|
v.setFromMatrixColumn(objectMatrix, 1);
|
|
@@ -15655,7 +16048,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15655
16048
|
};
|
|
15656
16049
|
}();
|
|
15657
16050
|
const pan = function() {
|
|
15658
|
-
const offset = new
|
|
16051
|
+
const offset = new import_three38.Vector3();
|
|
15659
16052
|
return function pan2(deltaX, deltaY) {
|
|
15660
16053
|
const element = scope.domElement;
|
|
15661
16054
|
if (scope.object.isPerspectiveCamera) {
|
|
@@ -15904,12 +16297,12 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15904
16297
|
mouseAction = -1;
|
|
15905
16298
|
}
|
|
15906
16299
|
switch (mouseAction) {
|
|
15907
|
-
case
|
|
16300
|
+
case import_three38.MOUSE.DOLLY:
|
|
15908
16301
|
if (scope.enableZoom === false) return;
|
|
15909
16302
|
handleMouseDownDolly(event);
|
|
15910
16303
|
state = STATE.DOLLY;
|
|
15911
16304
|
break;
|
|
15912
|
-
case
|
|
16305
|
+
case import_three38.MOUSE.ROTATE:
|
|
15913
16306
|
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
15914
16307
|
if (scope.enablePan === false) return;
|
|
15915
16308
|
handleMouseDownPan(event);
|
|
@@ -15920,7 +16313,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15920
16313
|
state = STATE.ROTATE;
|
|
15921
16314
|
}
|
|
15922
16315
|
break;
|
|
15923
|
-
case
|
|
16316
|
+
case import_three38.MOUSE.PAN:
|
|
15924
16317
|
if (event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
15925
16318
|
if (scope.enableRotate === false) return;
|
|
15926
16319
|
handleMouseDownRotate(event);
|
|
@@ -15976,12 +16369,12 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15976
16369
|
switch (pointers.length) {
|
|
15977
16370
|
case 1:
|
|
15978
16371
|
switch (scope.touches.ONE) {
|
|
15979
|
-
case
|
|
16372
|
+
case import_three38.TOUCH.ROTATE:
|
|
15980
16373
|
if (scope.enableRotate === false) return;
|
|
15981
16374
|
handleTouchStartRotate();
|
|
15982
16375
|
state = STATE.TOUCH_ROTATE;
|
|
15983
16376
|
break;
|
|
15984
|
-
case
|
|
16377
|
+
case import_three38.TOUCH.PAN:
|
|
15985
16378
|
if (scope.enablePan === false) return;
|
|
15986
16379
|
handleTouchStartPan();
|
|
15987
16380
|
state = STATE.TOUCH_PAN;
|
|
@@ -15992,12 +16385,12 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
15992
16385
|
break;
|
|
15993
16386
|
case 2:
|
|
15994
16387
|
switch (scope.touches.TWO) {
|
|
15995
|
-
case
|
|
16388
|
+
case import_three38.TOUCH.DOLLY_PAN:
|
|
15996
16389
|
if (scope.enableZoom === false && scope.enablePan === false) return;
|
|
15997
16390
|
handleTouchStartDollyPan();
|
|
15998
16391
|
state = STATE.TOUCH_DOLLY_PAN;
|
|
15999
16392
|
break;
|
|
16000
|
-
case
|
|
16393
|
+
case import_three38.TOUCH.DOLLY_ROTATE:
|
|
16001
16394
|
if (scope.enableZoom === false && scope.enableRotate === false) return;
|
|
16002
16395
|
handleTouchStartDollyRotate();
|
|
16003
16396
|
state = STATE.TOUCH_DOLLY_ROTATE;
|
|
@@ -16064,7 +16457,7 @@ var OrbitControls = class extends import_three37.EventDispatcher {
|
|
|
16064
16457
|
function trackPointer(event) {
|
|
16065
16458
|
let position = pointerPositions[event.pointerId];
|
|
16066
16459
|
if (position === void 0) {
|
|
16067
|
-
position = new
|
|
16460
|
+
position = new import_three38.Vector2();
|
|
16068
16461
|
pointerPositions[event.pointerId] = position;
|
|
16069
16462
|
}
|
|
16070
16463
|
position.set(event.pageX, event.pageY);
|
|
@@ -16084,10 +16477,10 @@ var MapControls = class extends OrbitControls {
|
|
|
16084
16477
|
constructor(object4, domElement) {
|
|
16085
16478
|
super(object4, domElement);
|
|
16086
16479
|
this.screenSpacePanning = false;
|
|
16087
|
-
this.mouseButtons.LEFT =
|
|
16088
|
-
this.mouseButtons.RIGHT =
|
|
16089
|
-
this.touches.ONE =
|
|
16090
|
-
this.touches.TWO =
|
|
16480
|
+
this.mouseButtons.LEFT = import_three38.MOUSE.PAN;
|
|
16481
|
+
this.mouseButtons.RIGHT = import_three38.MOUSE.ROTATE;
|
|
16482
|
+
this.touches.ONE = import_three38.TOUCH.PAN;
|
|
16483
|
+
this.touches.TWO = import_three38.TOUCH.DOLLY_ROTATE;
|
|
16091
16484
|
}
|
|
16092
16485
|
};
|
|
16093
16486
|
|
|
@@ -16168,8 +16561,8 @@ var Renderer = class _Renderer {
|
|
|
16168
16561
|
top: void 0,
|
|
16169
16562
|
bottom: void 0
|
|
16170
16563
|
},
|
|
16171
|
-
position: new
|
|
16172
|
-
lookingAt: new
|
|
16564
|
+
position: new import_three39.Vector3(50, 50, 50),
|
|
16565
|
+
lookingAt: new import_three39.Vector3(0, 0, 0)
|
|
16173
16566
|
},
|
|
16174
16567
|
render: {
|
|
16175
16568
|
fpsLimit: 60,
|
|
@@ -16201,14 +16594,14 @@ var Renderer = class _Renderer {
|
|
|
16201
16594
|
switch (this.options.camera.type) {
|
|
16202
16595
|
case "perspective":
|
|
16203
16596
|
default:
|
|
16204
|
-
return new
|
|
16597
|
+
return new import_three39.PerspectiveCamera(
|
|
16205
16598
|
this.options.camera.perspective.fov,
|
|
16206
16599
|
this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
|
|
16207
16600
|
this.options.camera.near,
|
|
16208
16601
|
this.options.camera.far
|
|
16209
16602
|
);
|
|
16210
16603
|
case "orthographic":
|
|
16211
|
-
return new
|
|
16604
|
+
return new import_three39.OrthographicCamera(
|
|
16212
16605
|
this.options.camera.orthographic.left ?? this.viewWidth / -2,
|
|
16213
16606
|
this.options.camera.orthographic.right ?? this.viewWidth / 2,
|
|
16214
16607
|
this.options.camera.orthographic.top ?? this.viewHeight / 2,
|
|
@@ -16224,7 +16617,7 @@ var Renderer = class _Renderer {
|
|
|
16224
16617
|
}
|
|
16225
16618
|
const pixelRatio = this.options.render.pixelRatio ?? 1;
|
|
16226
16619
|
this._surface?.resize?.(Math.floor(this.viewWidth * pixelRatio), Math.floor(this.viewHeight * pixelRatio));
|
|
16227
|
-
const renderer = new
|
|
16620
|
+
const renderer = new import_three39.WebGLRenderer({
|
|
16228
16621
|
canvas: this._surface?.canvas,
|
|
16229
16622
|
context: this._surface?.context,
|
|
16230
16623
|
antialias: this.options.render.antialias,
|
|
@@ -16234,8 +16627,8 @@ var Renderer = class _Renderer {
|
|
|
16234
16627
|
});
|
|
16235
16628
|
renderer.setClearColor(0, 0);
|
|
16236
16629
|
renderer.shadowMap.enabled = true;
|
|
16237
|
-
renderer.shadowMap.type =
|
|
16238
|
-
renderer.outputColorSpace =
|
|
16630
|
+
renderer.shadowMap.type = import_three39.PCFShadowMap;
|
|
16631
|
+
renderer.outputColorSpace = import_three39.SRGBColorSpace;
|
|
16239
16632
|
if (this._surface) {
|
|
16240
16633
|
renderer.setDrawingBufferSize(this.viewWidth, this.viewHeight, pixelRatio);
|
|
16241
16634
|
} else {
|
|
@@ -16258,8 +16651,8 @@ var Renderer = class _Renderer {
|
|
|
16258
16651
|
initialTarget() {
|
|
16259
16652
|
const target = this.options.camera.lookingAt;
|
|
16260
16653
|
if (isVector3(target)) return target.clone();
|
|
16261
|
-
if (isTripleArray(target)) return new
|
|
16262
|
-
return new
|
|
16654
|
+
if (isTripleArray(target)) return new import_three39.Vector3(target[0], target[1], target[2]);
|
|
16655
|
+
return new import_three39.Vector3();
|
|
16263
16656
|
}
|
|
16264
16657
|
createControlsFor(mode, target) {
|
|
16265
16658
|
let controls;
|
|
@@ -16292,7 +16685,7 @@ var Renderer = class _Renderer {
|
|
|
16292
16685
|
let target;
|
|
16293
16686
|
if (isFlyControls(current)) {
|
|
16294
16687
|
const distance = this._orbitDistance ?? (this.camera.position.distanceTo(this.initialTarget()) || 1);
|
|
16295
|
-
target = new
|
|
16688
|
+
target = new import_three39.Vector3(0, 0, -distance).applyQuaternion(this.camera.quaternion).add(this.camera.position);
|
|
16296
16689
|
} else {
|
|
16297
16690
|
target = current.target.clone();
|
|
16298
16691
|
this._orbitDistance = this.camera.position.distanceTo(target);
|
|
@@ -16332,20 +16725,20 @@ var Renderer = class _Renderer {
|
|
|
16332
16725
|
window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
|
|
16333
16726
|
}
|
|
16334
16727
|
if (this.options.debug.grid) {
|
|
16335
|
-
const gridHelper = new
|
|
16728
|
+
const gridHelper = new import_three39.GridHelper(128, 16);
|
|
16336
16729
|
this._debugHelpers.push(gridHelper);
|
|
16337
16730
|
this.scene.add(gridHelper);
|
|
16338
|
-
const gridHelper2 = new
|
|
16731
|
+
const gridHelper2 = new import_three39.GridHelper(128, 16);
|
|
16339
16732
|
this._debugHelpers.push(gridHelper2);
|
|
16340
16733
|
gridHelper2.rotation.x = 90 * (Math.PI / 180);
|
|
16341
16734
|
this.scene.add(gridHelper2);
|
|
16342
|
-
const gridHelper3 = new
|
|
16735
|
+
const gridHelper3 = new import_three39.GridHelper(128, 16);
|
|
16343
16736
|
this._debugHelpers.push(gridHelper3);
|
|
16344
16737
|
gridHelper3.rotation.z = 90 * (Math.PI / 180);
|
|
16345
16738
|
this.scene.add(gridHelper3);
|
|
16346
16739
|
}
|
|
16347
16740
|
if (this.options.debug.axes) {
|
|
16348
|
-
const axesHelper = new
|
|
16741
|
+
const axesHelper = new import_three39.AxesHelper(64);
|
|
16349
16742
|
this._debugHelpers.push(axesHelper);
|
|
16350
16743
|
this.scene.add(axesHelper);
|
|
16351
16744
|
}
|
|
@@ -16766,6 +17159,23 @@ var itemContext = (withDisplayContext) => (value, path) => {
|
|
|
16766
17159
|
}
|
|
16767
17160
|
});
|
|
16768
17161
|
};
|
|
17162
|
+
function entityAnimation(value, path) {
|
|
17163
|
+
const animation = object3(value, path);
|
|
17164
|
+
if (["name", "clips"].filter((key) => animation[key] !== void 0).length !== 1) {
|
|
17165
|
+
fail(path, "expected exactly one of name or clips");
|
|
17166
|
+
}
|
|
17167
|
+
fields(value, path, { name: text, clips: (value2, path2) => {
|
|
17168
|
+
list((value3, path3) => {
|
|
17169
|
+
fields(value3, path3, { name: text, weight: nonnegative }, ["name"]);
|
|
17170
|
+
})(value2, path2);
|
|
17171
|
+
if (!value2.length) fail(path2, "expected at least one clip");
|
|
17172
|
+
const names = /* @__PURE__ */ new Set();
|
|
17173
|
+
for (const [index, clip] of value2.entries()) {
|
|
17174
|
+
if (names.has(clip.name)) fail(`${path2}[${index}].name`, `duplicate clip "${clip.name}"`);
|
|
17175
|
+
names.add(clip.name);
|
|
17176
|
+
}
|
|
17177
|
+
}, loop: boolean, speed: nonnegative, time: nonnegative, paused: boolean });
|
|
17178
|
+
}
|
|
16769
17179
|
function guiLayer(value, path) {
|
|
16770
17180
|
const layer = object3(value, path);
|
|
16771
17181
|
if (["texture", "item", "text"].filter((key) => layer[key] !== void 0).length !== 1) {
|
|
@@ -16806,13 +17216,27 @@ function validateObject(value, path) {
|
|
|
16806
17216
|
const required = ["id", "type"];
|
|
16807
17217
|
const renderOptions = { wireframe: boolean };
|
|
16808
17218
|
switch (input.type) {
|
|
16809
|
-
case "skin":
|
|
17219
|
+
case "skin": {
|
|
17220
|
+
const piece = (value2, path2) => {
|
|
17221
|
+
if (typeof value2 === "string") asset(value2, path2);
|
|
17222
|
+
else fields(value2, path2, {
|
|
17223
|
+
asset,
|
|
17224
|
+
color,
|
|
17225
|
+
glint: boolean,
|
|
17226
|
+
trim: (value3, path3) => {
|
|
17227
|
+
fields(value3, path3, { pattern: asset, material: asset }, ["pattern", "material"]);
|
|
17228
|
+
}
|
|
17229
|
+
}, ["asset"]);
|
|
17230
|
+
};
|
|
16810
17231
|
fields(value, path, {
|
|
16811
17232
|
...common,
|
|
16812
17233
|
skin: text,
|
|
16813
17234
|
cape: (value2, path2) => {
|
|
16814
17235
|
fields(value2, path2, { texture: text, layout: enumeration(["minecraft", "optifine", "labymod"]) }, ["texture"]);
|
|
16815
17236
|
},
|
|
17237
|
+
armor: (value2, path2) => {
|
|
17238
|
+
fields(value2, path2, { head: piece, chest: piece, legs: piece, feet: piece });
|
|
17239
|
+
},
|
|
16816
17240
|
hiddenParts: list(enumeration(SKIN_PARTS)),
|
|
16817
17241
|
pose: (value2, path2) => {
|
|
16818
17242
|
fields(value2, path2, {
|
|
@@ -16826,10 +17250,11 @@ function validateObject(value, path) {
|
|
|
16826
17250
|
});
|
|
16827
17251
|
},
|
|
16828
17252
|
options: (value2, path2) => {
|
|
16829
|
-
fields(value2, path2, { slim: boolean, legacy: boolean });
|
|
17253
|
+
fields(value2, path2, { slim: boolean, legacy: boolean, ears: boolean, upsideDown: boolean });
|
|
16830
17254
|
}
|
|
16831
17255
|
}, required);
|
|
16832
17256
|
break;
|
|
17257
|
+
}
|
|
16833
17258
|
case "block":
|
|
16834
17259
|
fields(value, path, {
|
|
16835
17260
|
...common,
|
|
@@ -16868,9 +17293,7 @@ function validateObject(value, path) {
|
|
|
16868
17293
|
})
|
|
16869
17294
|
});
|
|
16870
17295
|
},
|
|
16871
|
-
animation:
|
|
16872
|
-
fields(value2, path2, { name: text, loop: boolean, speed: nonnegative, time: nonnegative, paused: boolean }, ["name"]);
|
|
16873
|
-
}
|
|
17296
|
+
animation: entityAnimation
|
|
16874
17297
|
}, [...required, "asset"]);
|
|
16875
17298
|
if (Array.isArray(input.layers) && !input.layers.length) fail(`${path}.layers`, "expected at least one layer");
|
|
16876
17299
|
break;
|
|
@@ -16978,7 +17401,7 @@ async function decodeSceneDocument(value) {
|
|
|
16978
17401
|
}
|
|
16979
17402
|
|
|
16980
17403
|
// src/scene/SceneDocumentLoader.ts
|
|
16981
|
-
var
|
|
17404
|
+
var import_three41 = require("three");
|
|
16982
17405
|
init_AssetKey();
|
|
16983
17406
|
init_AssetLoader();
|
|
16984
17407
|
init_BlockStates();
|
|
@@ -17040,7 +17463,7 @@ var SceneDocumentLoader = class {
|
|
|
17040
17463
|
if (definition.minecraftVersion !== void 0 && definition.minecraftVersion !== AssetLoader.version) {
|
|
17041
17464
|
throw new Error(`Scene requires Minecraft ${definition.minecraftVersion}; call AssetLoader.setVersion("${definition.minecraftVersion}") before loading it`);
|
|
17042
17465
|
}
|
|
17043
|
-
const root = new
|
|
17466
|
+
const root = new import_three41.Group();
|
|
17044
17467
|
root.name = "MineRender scene document";
|
|
17045
17468
|
const objects = [];
|
|
17046
17469
|
let disposed = false;
|
|
@@ -17080,7 +17503,7 @@ var SceneDocumentLoader = class {
|
|
|
17080
17503
|
return this.loadValidatedObject(scene, definition, parent);
|
|
17081
17504
|
}
|
|
17082
17505
|
static async loadValidatedObject(scene, definition, parent) {
|
|
17083
|
-
const root = new
|
|
17506
|
+
const root = new import_three41.Group();
|
|
17084
17507
|
root.name = definition.name ?? definition.id;
|
|
17085
17508
|
root.userData.sceneObjectId = definition.id;
|
|
17086
17509
|
root.position.fromArray(definition.position ?? [0, 0, 0]);
|
|
@@ -17099,6 +17522,7 @@ var SceneDocumentLoader = class {
|
|
|
17099
17522
|
await skin.setSkinTexture(texture);
|
|
17100
17523
|
await content.initialize(skin);
|
|
17101
17524
|
if (definition.cape) await skin.setCapeTexture(await skinTexture(definition.cape.texture, true), definition.cape.layout);
|
|
17525
|
+
if (definition.armor) await skin.setArmor(definition.armor);
|
|
17102
17526
|
for (const [part, rotation] of Object.entries(definition.pose ?? {})) {
|
|
17103
17527
|
skin.getGroupByName(part)?.rotation.set(...rotation, "XYZ");
|
|
17104
17528
|
}
|
|
@@ -17137,10 +17561,20 @@ var SceneDocumentLoader = class {
|
|
|
17137
17561
|
const entity = await content.addEntity(model, { ...definition.options, instanceMeshes: false });
|
|
17138
17562
|
object4 = entity;
|
|
17139
17563
|
if (definition.animation) {
|
|
17564
|
+
const animation = definition.animation;
|
|
17140
17565
|
const animations = await Entities.getAnimations(key);
|
|
17141
|
-
|
|
17142
|
-
|
|
17143
|
-
|
|
17566
|
+
if (animation.name !== void 0) {
|
|
17567
|
+
const clip = animations && Object.prototype.hasOwnProperty.call(animations, animation.name) ? animations[animation.name] : void 0;
|
|
17568
|
+
if (!clip) throw new Error(`Entity ${definition.asset} has no animation "${animation.name}"`);
|
|
17569
|
+
entity.playAnimation(clip, animation);
|
|
17570
|
+
} else {
|
|
17571
|
+
const clips = animation.clips.map(({ name }) => {
|
|
17572
|
+
const clip = animations && Object.prototype.hasOwnProperty.call(animations, name) ? animations[name] : void 0;
|
|
17573
|
+
if (!clip) throw new Error(`Entity ${definition.asset} has no animation "${name}"`);
|
|
17574
|
+
return clip;
|
|
17575
|
+
});
|
|
17576
|
+
entity.playAnimations(clips, { ...animation, weights: animation.clips.map((clip) => clip.weight ?? 1) });
|
|
17577
|
+
}
|
|
17144
17578
|
}
|
|
17145
17579
|
break;
|
|
17146
17580
|
}
|
|
@@ -17189,6 +17623,7 @@ init_Skins();
|
|
|
17189
17623
|
|
|
17190
17624
|
// src/texture/index.ts
|
|
17191
17625
|
init_Colormaps();
|
|
17626
|
+
init_PalettedTextures();
|
|
17192
17627
|
init_TextureAtlas();
|
|
17193
17628
|
init_TextureLoader();
|
|
17194
17629
|
init_Textures();
|
|
@@ -17978,7 +18413,7 @@ var AnvilWorldSource = class {
|
|
|
17978
18413
|
read.waiters++;
|
|
17979
18414
|
return new Promise((resolve, reject) => {
|
|
17980
18415
|
let finished = false;
|
|
17981
|
-
const
|
|
18416
|
+
const release = () => {
|
|
17982
18417
|
if (finished) return false;
|
|
17983
18418
|
finished = true;
|
|
17984
18419
|
signal?.removeEventListener("abort", abort);
|
|
@@ -17986,7 +18421,7 @@ var AnvilWorldSource = class {
|
|
|
17986
18421
|
return true;
|
|
17987
18422
|
};
|
|
17988
18423
|
const abort = () => {
|
|
17989
|
-
if (!
|
|
18424
|
+
if (!release()) return;
|
|
17990
18425
|
if (!read.waiters && !read.settled) {
|
|
17991
18426
|
if (this.pending.get(key) === read) this.pending.delete(key);
|
|
17992
18427
|
read.controller.abort(signal.reason);
|
|
@@ -17996,10 +18431,10 @@ var AnvilWorldSource = class {
|
|
|
17996
18431
|
signal?.addEventListener("abort", abort, { once: true });
|
|
17997
18432
|
read.promise.then(
|
|
17998
18433
|
(data) => {
|
|
17999
|
-
if (
|
|
18434
|
+
if (release()) resolve(data);
|
|
18000
18435
|
},
|
|
18001
18436
|
(error) => {
|
|
18002
|
-
if (
|
|
18437
|
+
if (release()) reject(error);
|
|
18003
18438
|
}
|
|
18004
18439
|
);
|
|
18005
18440
|
if (signal?.aborted) abort();
|
|
@@ -18021,20 +18456,22 @@ var AnvilWorldSource = class {
|
|
|
18021
18456
|
};
|
|
18022
18457
|
|
|
18023
18458
|
// src/world/Chunk.ts
|
|
18024
|
-
|
|
18459
|
+
init_BlockObject();
|
|
18460
|
+
var import_three48 = require("three");
|
|
18025
18461
|
init_BlockStates();
|
|
18026
18462
|
init_AssetKey();
|
|
18027
18463
|
|
|
18028
18464
|
// src/world/MineRenderWorld.ts
|
|
18029
|
-
var
|
|
18465
|
+
var import_three46 = require("three");
|
|
18030
18466
|
init_Model();
|
|
18031
18467
|
init_util();
|
|
18032
18468
|
init_AssetKey();
|
|
18033
18469
|
init_BlockStates();
|
|
18470
|
+
init_BlockEntities();
|
|
18034
18471
|
init_CubeFace();
|
|
18035
18472
|
|
|
18036
18473
|
// src/world/SectionModels.ts
|
|
18037
|
-
var
|
|
18474
|
+
var import_three42 = require("three");
|
|
18038
18475
|
init_AssetKey();
|
|
18039
18476
|
init_Models();
|
|
18040
18477
|
init_CubeFace();
|
|
@@ -18060,7 +18497,7 @@ function cached(map, key, load) {
|
|
|
18060
18497
|
}
|
|
18061
18498
|
function compactQuads(geometry, keep) {
|
|
18062
18499
|
const quads = keep.flatMap((kept, index) => kept ? [index] : []);
|
|
18063
|
-
const compact = new
|
|
18500
|
+
const compact = new import_three42.BufferGeometry();
|
|
18064
18501
|
for (const [name, size] of Object.entries({ position: 3, normal: 3, uv: 2, uvBounds: 4, color: 3, shade: 1 })) {
|
|
18065
18502
|
const source2 = geometry.getAttribute(name);
|
|
18066
18503
|
const defaults = name === "uvBounds" ? [0, 0, 1, 1] : name === "color" ? [1, 1, 1] : name === "shade" ? [1] : void 0;
|
|
@@ -18072,7 +18509,7 @@ function compactQuads(geometry, keep) {
|
|
|
18072
18509
|
}
|
|
18073
18510
|
}
|
|
18074
18511
|
}
|
|
18075
|
-
compact.setAttribute(name, new
|
|
18512
|
+
compact.setAttribute(name, new import_three42.BufferAttribute(values, size));
|
|
18076
18513
|
}
|
|
18077
18514
|
const source = geometry.getIndex();
|
|
18078
18515
|
const indices = [];
|
|
@@ -18128,6 +18565,10 @@ var SectionModels = class {
|
|
|
18128
18565
|
biomeTint: source ? [...templates.values()].some((template) => template.biomeTint?.some((value) => value === 1)) || void 0 : void 0
|
|
18129
18566
|
};
|
|
18130
18567
|
}
|
|
18568
|
+
/** Starts loading the state's models and atlases so a later `prepareState` with the same properties finds them loaded. */
|
|
18569
|
+
async preload(blockState3, properties = {}) {
|
|
18570
|
+
await this.state(blockState3, properties);
|
|
18571
|
+
}
|
|
18131
18572
|
async state(blockState3, properties) {
|
|
18132
18573
|
let states = this.states.get(blockState3);
|
|
18133
18574
|
if (!states) this.states.set(blockState3, states = /* @__PURE__ */ new Map());
|
|
@@ -18150,22 +18591,24 @@ var SectionModels = class {
|
|
|
18150
18591
|
async prepare(blockState3, properties) {
|
|
18151
18592
|
const state = { ...await BlockStateResolver.defaults(blockState3), ...properties };
|
|
18152
18593
|
const groups = BlockStateResolver.matching(blockState3, state);
|
|
18153
|
-
if (!groups.length) return void 0;
|
|
18594
|
+
if (!groups.length || groups.some((group) => Array.isArray(group) && !group.length)) return void 0;
|
|
18595
|
+
const variants = groups.flatMap((group) => Array.isArray(group) ? group : [group]);
|
|
18596
|
+
if (variants.some((variant) => !variant.model)) return void 0;
|
|
18597
|
+
const settled = await Promise.allSettled(variants.map(async (variant) => {
|
|
18598
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
18599
|
+
modelKey.root = blockState3.key?.root;
|
|
18600
|
+
const model = await Models.getMerged(modelKey);
|
|
18601
|
+
if (!model?.elements?.length) return void 0;
|
|
18602
|
+
const atlas = await UVMapper.getAtlas(model);
|
|
18603
|
+
const rotation = BlockStateResolver.rotation(variant);
|
|
18604
|
+
if (!atlas || atlas.image.width > this.maxAtlasSize || atlas.image.height > this.maxAtlasSize) return void 0;
|
|
18605
|
+
return { model, atlas, rotation };
|
|
18606
|
+
}));
|
|
18154
18607
|
const prepared = /* @__PURE__ */ new Map();
|
|
18155
|
-
for (const
|
|
18156
|
-
|
|
18157
|
-
if (!
|
|
18158
|
-
|
|
18159
|
-
if (!variant.model) return void 0;
|
|
18160
|
-
const modelKey = AssetKey.parse("models", variant.model);
|
|
18161
|
-
modelKey.root = blockState3.key?.root;
|
|
18162
|
-
const model = await Models.getMerged(modelKey);
|
|
18163
|
-
if (!model?.elements?.length) return void 0;
|
|
18164
|
-
const atlas = await UVMapper.getAtlas(model);
|
|
18165
|
-
const rotation = BlockStateResolver.rotation(variant);
|
|
18166
|
-
if (!atlas || atlas.image.width > this.maxAtlasSize || atlas.image.height > this.maxAtlasSize) return void 0;
|
|
18167
|
-
prepared.set(variant, { model, atlas, rotation });
|
|
18168
|
-
}
|
|
18608
|
+
for (const [i, result] of settled.entries()) {
|
|
18609
|
+
if (result.status === "rejected") throw result.reason;
|
|
18610
|
+
if (!result.value) return void 0;
|
|
18611
|
+
prepared.set(variants[i], result.value);
|
|
18169
18612
|
}
|
|
18170
18613
|
return { state, groups, choices: prepared };
|
|
18171
18614
|
}
|
|
@@ -18182,7 +18625,7 @@ var SectionModels = class {
|
|
|
18182
18625
|
});
|
|
18183
18626
|
await object4.init();
|
|
18184
18627
|
let geometry = object4.children[0].geometry;
|
|
18185
|
-
geometry.applyMatrix4(new
|
|
18628
|
+
geometry.applyMatrix4(new import_three42.Matrix4().makeRotationFromEuler(rotation));
|
|
18186
18629
|
object4.clear();
|
|
18187
18630
|
const keep = [];
|
|
18188
18631
|
const cullFaces = [];
|
|
@@ -18198,7 +18641,7 @@ var SectionModels = class {
|
|
|
18198
18641
|
cullFaces.push(0);
|
|
18199
18642
|
continue;
|
|
18200
18643
|
}
|
|
18201
|
-
const normal = new
|
|
18644
|
+
const normal = new import_three42.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
|
|
18202
18645
|
const world = CUBE_FACE_OFFSETS.findIndex(([x, y, z]) => Math.abs(normal.x - x) < 1e-6 && Math.abs(normal.y - y) < 1e-6 && Math.abs(normal.z - z) < 1e-6);
|
|
18203
18646
|
cullFaces.push(world < 0 ? 0 : 1 << world);
|
|
18204
18647
|
}
|
|
@@ -18302,10 +18745,10 @@ function resolveSavedEntity(entity) {
|
|
|
18302
18745
|
|
|
18303
18746
|
// src/world/_entities/WorldEntities.ts
|
|
18304
18747
|
init_BannerPatterns();
|
|
18305
|
-
var
|
|
18748
|
+
var import_three45 = require("three");
|
|
18306
18749
|
|
|
18307
18750
|
// src/world/_picking/Picking.ts
|
|
18308
|
-
var
|
|
18751
|
+
var import_three43 = require("three");
|
|
18309
18752
|
init_three();
|
|
18310
18753
|
function pickableMeshes(root, scene, raycaster) {
|
|
18311
18754
|
const result = [];
|
|
@@ -18333,11 +18776,11 @@ function hitNormal(hit) {
|
|
|
18333
18776
|
const mesh = hit.object;
|
|
18334
18777
|
const matrix = mesh.matrixWorld.clone();
|
|
18335
18778
|
if (isInstancedMesh(mesh) && hit.instanceId !== void 0) {
|
|
18336
|
-
const instance = new
|
|
18779
|
+
const instance = new import_three43.Matrix4();
|
|
18337
18780
|
mesh.getMatrixAt(hit.instanceId, instance);
|
|
18338
18781
|
matrix.multiply(instance);
|
|
18339
18782
|
}
|
|
18340
|
-
return hit.face.normal.clone().applyNormalMatrix(new
|
|
18783
|
+
return hit.face.normal.clone().applyNormalMatrix(new import_three43.Matrix3().getNormalMatrix(matrix));
|
|
18341
18784
|
}
|
|
18342
18785
|
|
|
18343
18786
|
// src/world/_entities/WorldEntities.ts
|
|
@@ -18363,7 +18806,7 @@ var WorldEntities = class {
|
|
|
18363
18806
|
const owner = owners.get(mesh);
|
|
18364
18807
|
return {
|
|
18365
18808
|
type: owner.type,
|
|
18366
|
-
position: new
|
|
18809
|
+
position: new import_three45.Vector3(...owner.position),
|
|
18367
18810
|
object: owner.object,
|
|
18368
18811
|
point: hit.point.clone(),
|
|
18369
18812
|
normal: hitNormal(hit),
|
|
@@ -18625,6 +19068,7 @@ function skipsBlockFace(data, rule, block, neighbor, face) {
|
|
|
18625
19068
|
// src/world/MineRenderWorld.ts
|
|
18626
19069
|
init_log();
|
|
18627
19070
|
var log18 = logger("MineRenderWorld");
|
|
19071
|
+
var YIELD_INTERVAL_MS = 8;
|
|
18628
19072
|
var MineRenderWorld = class {
|
|
18629
19073
|
constructor(scene, options = {}) {
|
|
18630
19074
|
this._chunks = /* @__PURE__ */ new Map();
|
|
@@ -18738,7 +19182,7 @@ var MineRenderWorld = class {
|
|
|
18738
19182
|
failures.set(chunk, error);
|
|
18739
19183
|
if (this._chunks.get(`${chunk.x}_${chunk.y}_${chunk.z}`) === chunk) this.pendingBiomes.set(chunk, void 0);
|
|
18740
19184
|
}
|
|
18741
|
-
if (performance.now() - sliceStart >
|
|
19185
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
18742
19186
|
await yieldToEventLoop();
|
|
18743
19187
|
sliceStart = performance.now();
|
|
18744
19188
|
}
|
|
@@ -18751,25 +19195,25 @@ var MineRenderWorld = class {
|
|
|
18751
19195
|
}
|
|
18752
19196
|
getBlockAt(posOrX, y, z) {
|
|
18753
19197
|
if (typeof posOrX == "number") {
|
|
18754
|
-
return this.getBlockAt(new
|
|
19198
|
+
return this.getBlockAt(new import_three46.Vector3(posOrX, y, z));
|
|
18755
19199
|
}
|
|
18756
19200
|
if (isTripleArray(posOrX)) {
|
|
18757
|
-
return this.getBlockAt(new
|
|
19201
|
+
return this.getBlockAt(new import_three46.Vector3(posOrX[0], posOrX[1], posOrX[2]));
|
|
18758
19202
|
}
|
|
18759
19203
|
this.validatePosBounds(posOrX);
|
|
18760
19204
|
return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
|
|
18761
19205
|
}
|
|
18762
19206
|
getBiomeAt(posOrX, y, z) {
|
|
18763
|
-
if (typeof posOrX === "number") return this.getBiomeAt(new
|
|
18764
|
-
if (isTripleArray(posOrX)) return this.getBiomeAt(new
|
|
19207
|
+
if (typeof posOrX === "number") return this.getBiomeAt(new import_three46.Vector3(posOrX, y, z));
|
|
19208
|
+
if (isTripleArray(posOrX)) return this.getBiomeAt(new import_three46.Vector3(...posOrX));
|
|
18765
19209
|
this.validatePosBounds(posOrX);
|
|
18766
19210
|
const cx = Math.floor(posOrX.x / 16), cy = Math.floor(posOrX.y / 16), cz = Math.floor(posOrX.z / 16);
|
|
18767
19211
|
const lx = posOrX.x - cx * 16, ly = posOrX.y - cy * 16, lz = posOrX.z - cz * 16;
|
|
18768
19212
|
return this.biomes.get(`${cx}_${cz}`)?.get(cy)?.[Math.floor(lx / 4) + Math.floor(lz / 4) * 4 + Math.floor(ly / 4) * 16];
|
|
18769
19213
|
}
|
|
18770
19214
|
getLightAt(posOrX, y, z) {
|
|
18771
|
-
if (typeof posOrX === "number") return this.getLightAt(new
|
|
18772
|
-
if (isTripleArray(posOrX)) return this.getLightAt(new
|
|
19215
|
+
if (typeof posOrX === "number") return this.getLightAt(new import_three46.Vector3(posOrX, y, z));
|
|
19216
|
+
if (isTripleArray(posOrX)) return this.getLightAt(new import_three46.Vector3(...posOrX));
|
|
18773
19217
|
this.validatePosBounds(posOrX);
|
|
18774
19218
|
const { x, y: py, z: pz } = posOrX;
|
|
18775
19219
|
const cx = Math.floor(x / 16), cy = Math.floor(py / 16), cz = Math.floor(pz / 16);
|
|
@@ -18787,10 +19231,10 @@ var MineRenderWorld = class {
|
|
|
18787
19231
|
}
|
|
18788
19232
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
18789
19233
|
if (typeof posOrX == "number") {
|
|
18790
|
-
return this.setBlockAt(new
|
|
19234
|
+
return this.setBlockAt(new import_three46.Vector3(posOrX, yOrBlock, z), block);
|
|
18791
19235
|
}
|
|
18792
19236
|
if (isTripleArray(posOrX)) {
|
|
18793
|
-
return this.setBlockAt(new
|
|
19237
|
+
return this.setBlockAt(new import_three46.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
18794
19238
|
}
|
|
18795
19239
|
return this.placeBlock(posOrX, yOrBlock);
|
|
18796
19240
|
}
|
|
@@ -18801,10 +19245,10 @@ var MineRenderWorld = class {
|
|
|
18801
19245
|
}
|
|
18802
19246
|
async setBlockVisibleAt(posOrX, yOrVisible, z, visible) {
|
|
18803
19247
|
if (typeof posOrX === "number") {
|
|
18804
|
-
return this.setBlockVisibleAt(new
|
|
19248
|
+
return this.setBlockVisibleAt(new import_three46.Vector3(posOrX, yOrVisible, z), visible);
|
|
18805
19249
|
}
|
|
18806
19250
|
if (isTripleArray(posOrX)) {
|
|
18807
|
-
return this.setBlockVisibleAt(new
|
|
19251
|
+
return this.setBlockVisibleAt(new import_three46.Vector3(...posOrX), yOrVisible);
|
|
18808
19252
|
}
|
|
18809
19253
|
this.validatePosBounds(posOrX);
|
|
18810
19254
|
await this.getChunkAt(posOrX)?.setBlockVisibleAt(posOrX, yOrVisible);
|
|
@@ -18830,7 +19274,7 @@ var MineRenderWorld = class {
|
|
|
18830
19274
|
const collect = async (positions2) => {
|
|
18831
19275
|
for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
|
|
18832
19276
|
};
|
|
18833
|
-
const place = (block) => this.placeBlock(new
|
|
19277
|
+
const place = (block) => this.placeBlock(new import_three46.Vector3(...block.position), block, collect);
|
|
18834
19278
|
const keys = /* @__PURE__ */ new Map();
|
|
18835
19279
|
const types = /* @__PURE__ */ new Set();
|
|
18836
19280
|
for (const block of multiblock.blocks) {
|
|
@@ -18839,15 +19283,18 @@ var MineRenderWorld = class {
|
|
|
18839
19283
|
const key = AssetKey.parse("blockstates", block.type);
|
|
18840
19284
|
keys.set(key.serialize(), key);
|
|
18841
19285
|
}
|
|
18842
|
-
await BlockStates.getAll(keys.values());
|
|
19286
|
+
const loaded = await BlockStates.getAll(keys.values());
|
|
19287
|
+
const states = new Map([...keys.keys()].map((key, i) => [key, loaded[i]]));
|
|
18843
19288
|
if (!useBatches) {
|
|
18844
19289
|
for (const block of multiblock.blocks) await place(block);
|
|
18845
19290
|
return;
|
|
18846
19291
|
}
|
|
18847
19292
|
if (!executor) {
|
|
18848
19293
|
const groups2 = /* @__PURE__ */ new Map();
|
|
18849
|
-
const
|
|
19294
|
+
const distinct = /* @__PURE__ */ new Map();
|
|
19295
|
+
const position = new import_three46.Vector3();
|
|
18850
19296
|
for (const block of multiblock.blocks) {
|
|
19297
|
+
if (this.sectionModels && !Chunk.isAir(block)) distinct.set(ChunkData.paletteKey(block), block);
|
|
18851
19298
|
const [x, y, z] = block.position;
|
|
18852
19299
|
this.validatePosBounds(position.set(x, y, z));
|
|
18853
19300
|
const cx = Math.floor(x / 16), cy = Math.floor(y / 16), cz = Math.floor(z / 16);
|
|
@@ -18858,6 +19305,16 @@ var MineRenderWorld = class {
|
|
|
18858
19305
|
if (!group) groups2.set(chunk, group = []);
|
|
18859
19306
|
group.push({ index: (y - cy * 16) * 256 + (z - cz * 16) * 16 + x - cx * 16, block });
|
|
18860
19307
|
}
|
|
19308
|
+
if (this.sectionModels) {
|
|
19309
|
+
for (const block of distinct.values()) {
|
|
19310
|
+
const state = states.get(AssetKey.parse("blockstates", block.type).serialize());
|
|
19311
|
+
if (!state) continue;
|
|
19312
|
+
void (async () => {
|
|
19313
|
+
if (state.key && BlockEntities.entry(await BlockEntities.getIndex(state.key.root), state.key.toNamespacedString())) return;
|
|
19314
|
+
await this.sectionModels.preload(state, block.properties);
|
|
19315
|
+
})().catch(() => void 0);
|
|
19316
|
+
}
|
|
19317
|
+
}
|
|
18861
19318
|
await this.placeChunkGroups(groups2, changes);
|
|
18862
19319
|
return;
|
|
18863
19320
|
}
|
|
@@ -18886,14 +19343,14 @@ var MineRenderWorld = class {
|
|
|
18886
19343
|
try {
|
|
18887
19344
|
positions = await chunk.placeBlocks(blocks);
|
|
18888
19345
|
} finally {
|
|
18889
|
-
positions ??= blocks.map(({ index }) => new
|
|
19346
|
+
positions ??= blocks.map(({ index }) => new import_three46.Vector3(
|
|
18890
19347
|
chunk.x * 16 + index % 16,
|
|
18891
19348
|
chunk.y * 16 + Math.floor(index / 256),
|
|
18892
19349
|
chunk.z * 16 + Math.floor(index / 16) % 16
|
|
18893
19350
|
));
|
|
18894
19351
|
for (const pos of positions) changes.set(`${pos.x},${pos.y},${pos.z}`, pos);
|
|
18895
19352
|
}
|
|
18896
|
-
if (performance.now() - sliceStart >
|
|
19353
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
18897
19354
|
await yieldToEventLoop();
|
|
18898
19355
|
sliceStart = performance.now();
|
|
18899
19356
|
}
|
|
@@ -18901,6 +19358,62 @@ var MineRenderWorld = class {
|
|
|
18901
19358
|
}
|
|
18902
19359
|
/** Replaces a chunk column's blocks, biomes, and saved light and, with `renderEntities`, its supported saved mobs. */
|
|
18903
19360
|
async placeChunk(chunk, executor) {
|
|
19361
|
+
return this.placeColumn(chunk, executor);
|
|
19362
|
+
}
|
|
19363
|
+
/**
|
|
19364
|
+
* Replaces parsed columns in input order, then refreshes neighboring geometry once.
|
|
19365
|
+
* Duplicate coordinates retain their order. A failed column stops placement; queued refreshes finish before rejection.
|
|
19366
|
+
*/
|
|
19367
|
+
async placeChunks(chunks) {
|
|
19368
|
+
const columns = [];
|
|
19369
|
+
for (const chunk of chunks) {
|
|
19370
|
+
const { x, z } = chunk ?? {};
|
|
19371
|
+
if (![x, z].every(Number.isSafeInteger)) {
|
|
19372
|
+
throw new RangeError("Chunk column coordinates must be safe integers");
|
|
19373
|
+
}
|
|
19374
|
+
const sections = Array.from(chunk.sections, (section) => {
|
|
19375
|
+
const { y } = section ?? {};
|
|
19376
|
+
if (!Number.isSafeInteger(y)) throw new RangeError("Chunk section coordinates must be safe integers");
|
|
19377
|
+
return { ...section, y };
|
|
19378
|
+
});
|
|
19379
|
+
columns.push({ ...chunk, x, z, sections });
|
|
19380
|
+
}
|
|
19381
|
+
if (!columns.length) return;
|
|
19382
|
+
await this.culling;
|
|
19383
|
+
let failed = false, failure, sliceStart = performance.now();
|
|
19384
|
+
try {
|
|
19385
|
+
for (const column of columns) {
|
|
19386
|
+
await this.placeColumn(column, void 0, true);
|
|
19387
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
19388
|
+
await yieldToEventLoop();
|
|
19389
|
+
sliceStart = performance.now();
|
|
19390
|
+
}
|
|
19391
|
+
}
|
|
19392
|
+
} catch (error) {
|
|
19393
|
+
failed = true;
|
|
19394
|
+
failure = error;
|
|
19395
|
+
} finally {
|
|
19396
|
+
try {
|
|
19397
|
+
const failures = await this.refreshBiomes(true);
|
|
19398
|
+
if (failures.size) log18.warn("Failed to refresh biome colors", failures.values().next().value);
|
|
19399
|
+
} catch (error) {
|
|
19400
|
+
if (!failed) {
|
|
19401
|
+
failed = true;
|
|
19402
|
+
failure = error;
|
|
19403
|
+
}
|
|
19404
|
+
}
|
|
19405
|
+
try {
|
|
19406
|
+
await this.updateCulling([]);
|
|
19407
|
+
} catch (error) {
|
|
19408
|
+
if (!failed) {
|
|
19409
|
+
failed = true;
|
|
19410
|
+
failure = error;
|
|
19411
|
+
}
|
|
19412
|
+
}
|
|
19413
|
+
}
|
|
19414
|
+
if (failed) throw failure;
|
|
19415
|
+
}
|
|
19416
|
+
async placeColumn(chunk, executor, deferCulling = false) {
|
|
18904
19417
|
if (![chunk.x, chunk.z].every(Number.isSafeInteger)) {
|
|
18905
19418
|
throw new RangeError("Chunk column coordinates must be safe integers");
|
|
18906
19419
|
}
|
|
@@ -18938,7 +19451,7 @@ var MineRenderWorld = class {
|
|
|
18938
19451
|
}
|
|
18939
19452
|
for (const section of chunk.sections) {
|
|
18940
19453
|
if (section.biomes) {
|
|
18941
|
-
const position = new
|
|
19454
|
+
const position = new import_three46.Vector3(chunk.x * 16, section.y * 16, chunk.z * 16);
|
|
18942
19455
|
this.validatePosBounds(position);
|
|
18943
19456
|
const copy = [...section.biomes];
|
|
18944
19457
|
if (copy.length !== 64 || !copy.every((id) => typeof id === "string" && id.length > 0)) {
|
|
@@ -18954,7 +19467,7 @@ var MineRenderWorld = class {
|
|
|
18954
19467
|
for (const section of chunk.sections) {
|
|
18955
19468
|
if (!executor) {
|
|
18956
19469
|
if (!occupiedSections.has(section.y)) continue;
|
|
18957
|
-
const position = new
|
|
19470
|
+
const position = new import_three46.Vector3(chunk.x * 16, section.y * 16, chunk.z * 16);
|
|
18958
19471
|
this.validatePosBounds(position);
|
|
18959
19472
|
const target = this.getOrCreateChunkAt(position);
|
|
18960
19473
|
try {
|
|
@@ -18962,7 +19475,7 @@ var MineRenderWorld = class {
|
|
|
18962
19475
|
} finally {
|
|
18963
19476
|
this.markSectionChanged(target);
|
|
18964
19477
|
}
|
|
18965
|
-
if (performance.now() - sliceStart >
|
|
19478
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
18966
19479
|
await yieldToEventLoop();
|
|
18967
19480
|
sliceStart = performance.now();
|
|
18968
19481
|
}
|
|
@@ -18985,9 +19498,12 @@ var MineRenderWorld = class {
|
|
|
18985
19498
|
await placeEntities?.();
|
|
18986
19499
|
} finally {
|
|
18987
19500
|
this.markBiomesChanged(chunk.x, chunk.z, void 0, false);
|
|
18988
|
-
|
|
18989
|
-
|
|
18990
|
-
|
|
19501
|
+
if (deferCulling) await this.updateCulling([...changes.values()], true);
|
|
19502
|
+
else {
|
|
19503
|
+
const failures = await this.refreshBiomes();
|
|
19504
|
+
if (failures.size) log18.warn("Failed to refresh biome colors", failures.values().next().value);
|
|
19505
|
+
await this.updateCulling([...changes.values()]);
|
|
19506
|
+
}
|
|
18991
19507
|
}
|
|
18992
19508
|
}
|
|
18993
19509
|
/**
|
|
@@ -19017,7 +19533,7 @@ var MineRenderWorld = class {
|
|
|
19017
19533
|
for (const { x, z } of columns.values()) {
|
|
19018
19534
|
this.entities?.clearColumn(x, z);
|
|
19019
19535
|
await this.clearChunkColumn(x, z);
|
|
19020
|
-
if (performance.now() - sliceStart >
|
|
19536
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
19021
19537
|
await yieldToEventLoop();
|
|
19022
19538
|
sliceStart = performance.now();
|
|
19023
19539
|
}
|
|
@@ -19087,7 +19603,7 @@ var MineRenderWorld = class {
|
|
|
19087
19603
|
this.sectionModels?.clear();
|
|
19088
19604
|
}
|
|
19089
19605
|
updateCulling(positions, defer = false) {
|
|
19090
|
-
const neighbor = new
|
|
19606
|
+
const neighbor = new import_three46.Vector3();
|
|
19091
19607
|
for (const pos of positions) {
|
|
19092
19608
|
const cx = Math.floor(pos.x / 16), cy = Math.floor(pos.y / 16), cz = Math.floor(pos.z / 16);
|
|
19093
19609
|
const chunk = this._chunks.get(`${cx}_${cy}_${cz}`);
|
|
@@ -19156,15 +19672,25 @@ var MineRenderWorld = class {
|
|
|
19156
19672
|
for (const [index, mask] of masks) await chunk.setCullMaskIndex(index, mask);
|
|
19157
19673
|
await chunk.refreshLight(indices === "all" ? void 0 : indices);
|
|
19158
19674
|
chunk.refreshAmbientOcclusion(this._ambientOcclusion);
|
|
19159
|
-
if (
|
|
19675
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
19160
19676
|
await yieldToEventLoop();
|
|
19161
19677
|
sliceStart = performance.now();
|
|
19162
19678
|
}
|
|
19163
19679
|
}
|
|
19164
|
-
const
|
|
19165
|
-
|
|
19166
|
-
|
|
19167
|
-
|
|
19680
|
+
const pending = [];
|
|
19681
|
+
for (const chunk of [...batch.keys()]) {
|
|
19682
|
+
const build = (async () => {
|
|
19683
|
+
await chunk.rebuildSectionMesh();
|
|
19684
|
+
batch.delete(chunk);
|
|
19685
|
+
})();
|
|
19686
|
+
void build.catch(() => void 0);
|
|
19687
|
+
pending.push(build);
|
|
19688
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
19689
|
+
await yieldToEventLoop();
|
|
19690
|
+
sliceStart = performance.now();
|
|
19691
|
+
}
|
|
19692
|
+
}
|
|
19693
|
+
const builds = await Promise.allSettled(pending);
|
|
19168
19694
|
const failure = builds.find((result) => result.status === "rejected");
|
|
19169
19695
|
if (failure?.status === "rejected") throw failure.reason;
|
|
19170
19696
|
} catch (error) {
|
|
@@ -19247,7 +19773,7 @@ var MineRenderWorld = class {
|
|
|
19247
19773
|
}
|
|
19248
19774
|
/** Converts block coordinates to scene units by multiplying each component by 16. */
|
|
19249
19775
|
static worldToScenePosition(pos) {
|
|
19250
|
-
return new
|
|
19776
|
+
return new import_three46.Vector3(
|
|
19251
19777
|
pos.x * 16,
|
|
19252
19778
|
pos.y * 16,
|
|
19253
19779
|
pos.z * 16
|
|
@@ -19255,7 +19781,7 @@ var MineRenderWorld = class {
|
|
|
19255
19781
|
}
|
|
19256
19782
|
/** Converts scene units to block coordinates without rounding to an integer block. */
|
|
19257
19783
|
static sceneToWorldPosition(pos) {
|
|
19258
|
-
return new
|
|
19784
|
+
return new import_three46.Vector3(
|
|
19259
19785
|
pos.x / 16,
|
|
19260
19786
|
pos.y / 16,
|
|
19261
19787
|
pos.z / 16
|
|
@@ -19279,7 +19805,7 @@ init_Model();
|
|
|
19279
19805
|
init_BlockEntities();
|
|
19280
19806
|
|
|
19281
19807
|
// src/world/SectionMesh.ts
|
|
19282
|
-
var
|
|
19808
|
+
var import_three47 = require("three");
|
|
19283
19809
|
init_CanvasCompat();
|
|
19284
19810
|
init_Materials();
|
|
19285
19811
|
|
|
@@ -19556,6 +20082,8 @@ function sectionGeometryTransferables(pages) {
|
|
|
19556
20082
|
|
|
19557
20083
|
// src/world/SectionWorker.ts
|
|
19558
20084
|
init_Env();
|
|
20085
|
+
init_log();
|
|
20086
|
+
var log19 = logger("SectionWorker");
|
|
19559
20087
|
var SectionWorker = class _SectionWorker {
|
|
19560
20088
|
constructor(worker) {
|
|
19561
20089
|
this.worker = worker;
|
|
@@ -19569,8 +20097,12 @@ var SectionWorker = class _SectionWorker {
|
|
|
19569
20097
|
if (reply.type === "pages") pending.resolve(reply.pages);
|
|
19570
20098
|
else pending.reject(new Error(reply.message));
|
|
19571
20099
|
});
|
|
19572
|
-
|
|
19573
|
-
|
|
20100
|
+
const fallBack = (message) => {
|
|
20101
|
+
log19.warn(`${message}, so sections build on the main thread`);
|
|
20102
|
+
this.fail(message);
|
|
20103
|
+
};
|
|
20104
|
+
worker.addEventListener("error", (event) => fallBack(event.message || "Section worker failed"));
|
|
20105
|
+
worker.addEventListener("messageerror", () => fallBack("Section worker message could not be deserialized"));
|
|
19574
20106
|
}
|
|
19575
20107
|
static {
|
|
19576
20108
|
this.initialized = false;
|
|
@@ -19608,8 +20140,11 @@ var SectionWorker = class _SectionWorker {
|
|
|
19608
20140
|
};
|
|
19609
20141
|
|
|
19610
20142
|
// src/world/SectionMesh.ts
|
|
20143
|
+
var BLOCK_SIZE = 16;
|
|
20144
|
+
var QUAD_VERTICES = 4;
|
|
20145
|
+
var QUAD_INDICES = 6;
|
|
19611
20146
|
var templateCache = /* @__PURE__ */ new WeakMap();
|
|
19612
|
-
var WATER_TINT = new
|
|
20147
|
+
var WATER_TINT = new import_three47.Color(4159204).toArray();
|
|
19613
20148
|
function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
19614
20149
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
19615
20150
|
const atlases2 = [];
|
|
@@ -19644,8 +20179,8 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19644
20179
|
if (!data) {
|
|
19645
20180
|
const indices = template.geometry.getIndex();
|
|
19646
20181
|
const position = template.geometry.getAttribute("position");
|
|
19647
|
-
const quads = indices.count /
|
|
19648
|
-
if (indices.count %
|
|
20182
|
+
const quads = indices.count / QUAD_INDICES;
|
|
20183
|
+
if (indices.count % QUAD_INDICES !== 0 || position.count !== quads * QUAD_VERTICES) {
|
|
19649
20184
|
throw new RangeError("Section template geometry must hold four vertices and six indices per quad");
|
|
19650
20185
|
}
|
|
19651
20186
|
data = {
|
|
@@ -19655,8 +20190,8 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19655
20190
|
uvs: new Float32Array(quads * 8),
|
|
19656
20191
|
uvBounds: new Float32Array(quads * 16),
|
|
19657
20192
|
colors: new Float32Array(quads * 12),
|
|
19658
|
-
shade: new Float32Array(quads *
|
|
19659
|
-
indices: new Uint16Array(quads *
|
|
20193
|
+
shade: new Float32Array(quads * QUAD_VERTICES),
|
|
20194
|
+
indices: new Uint16Array(quads * QUAD_INDICES),
|
|
19660
20195
|
cullFaces: new Uint8Array(template.cullFaces),
|
|
19661
20196
|
biomeTint: template.biomeTint ? new Uint8Array(template.biomeTint) : void 0,
|
|
19662
20197
|
atlas: 0,
|
|
@@ -19668,7 +20203,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19668
20203
|
const bounds = template.geometry.getAttribute("uvBounds");
|
|
19669
20204
|
const color2 = template.geometry.getAttribute("color");
|
|
19670
20205
|
const shade = template.geometry.getAttribute("shade");
|
|
19671
|
-
for (let vertex = 0; vertex < quads *
|
|
20206
|
+
for (let vertex = 0; vertex < quads * QUAD_VERTICES; vertex++) {
|
|
19672
20207
|
data.positions.set([position.getX(vertex), position.getY(vertex), position.getZ(vertex)], vertex * 3);
|
|
19673
20208
|
data.normals.set([normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex)], vertex * 3);
|
|
19674
20209
|
data.uvs.set([uv.getX(vertex), uv.getY(vertex)], vertex * 2);
|
|
@@ -19681,7 +20216,7 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19681
20216
|
data.colors.set([color2?.getX(vertex) ?? 1, color2?.getY(vertex) ?? 1, color2?.getZ(vertex) ?? 1], vertex * 3);
|
|
19682
20217
|
data.shade[vertex] = shade?.getX(vertex) ?? 1;
|
|
19683
20218
|
}
|
|
19684
|
-
for (let i2 = 0; i2 < data.indices.length; i2++) data.indices[i2] = indices.getX(i2) -
|
|
20219
|
+
for (let i2 = 0; i2 < data.indices.length; i2++) data.indices[i2] = indices.getX(i2) - QUAD_VERTICES * Math.floor(i2 / QUAD_INDICES);
|
|
19685
20220
|
templateCache.set(template, data);
|
|
19686
20221
|
}
|
|
19687
20222
|
id = input.templateData.length;
|
|
@@ -19714,7 +20249,55 @@ function toInput(entries, maxAtlasSize, fluids, lighting) {
|
|
|
19714
20249
|
}
|
|
19715
20250
|
return { input, atlases: atlases2 };
|
|
19716
20251
|
}
|
|
19717
|
-
|
|
20252
|
+
function sortTransparentQuads(mesh) {
|
|
20253
|
+
const index = mesh.geometry.getIndex();
|
|
20254
|
+
if (index.count <= QUAD_INDICES) return;
|
|
20255
|
+
index.setUsage(import_three47.DynamicDrawUsage);
|
|
20256
|
+
const count = index.count / QUAD_INDICES;
|
|
20257
|
+
let source, centers, depths, order;
|
|
20258
|
+
const view = new import_three47.Matrix4(), localCamera = new import_three47.Vector3(), key = new import_three47.Vector3(), previous = new import_three47.Vector3();
|
|
20259
|
+
let previousOrthographic;
|
|
20260
|
+
mesh.onBeforeRender = (_renderer, _scene, camera) => {
|
|
20261
|
+
localCamera.setFromMatrixPosition(camera.matrixWorld).applyMatrix4(view.copy(mesh.matrixWorld).invert());
|
|
20262
|
+
const orthographic = !!camera.isOrthographicCamera;
|
|
20263
|
+
if (orthographic) {
|
|
20264
|
+
view.multiplyMatrices(camera.matrixWorldInverse, mesh.matrixWorld);
|
|
20265
|
+
key.set(view.elements[2], view.elements[6], view.elements[10]);
|
|
20266
|
+
} else {
|
|
20267
|
+
key.copy(localCamera).divideScalar(BLOCK_SIZE).floor();
|
|
20268
|
+
}
|
|
20269
|
+
if (orthographic === previousOrthographic && key.equals(previous)) return;
|
|
20270
|
+
previous.copy(key);
|
|
20271
|
+
previousOrthographic = orthographic;
|
|
20272
|
+
if (!centers) {
|
|
20273
|
+
source = new Uint32Array(index.array);
|
|
20274
|
+
centers = new Float32Array(count * 3);
|
|
20275
|
+
depths = new Float32Array(count);
|
|
20276
|
+
order = Uint32Array.from({ length: count }, (_, quad) => quad);
|
|
20277
|
+
const positions = mesh.geometry.getAttribute("position");
|
|
20278
|
+
for (let quad = 0; quad < count; quad++) {
|
|
20279
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
20280
|
+
let center = 0;
|
|
20281
|
+
for (let corner = 0; corner < QUAD_VERTICES; corner++) center += positions.getComponent(quad * QUAD_VERTICES + corner, axis);
|
|
20282
|
+
centers[quad * 3 + axis] = center / QUAD_VERTICES;
|
|
20283
|
+
}
|
|
20284
|
+
}
|
|
20285
|
+
}
|
|
20286
|
+
for (let quad = 0; quad < count; quad++) {
|
|
20287
|
+
const x = centers[quad * 3], y = centers[quad * 3 + 1], z = centers[quad * 3 + 2];
|
|
20288
|
+
depths[quad] = orthographic ? key.x * x + key.y * y + key.z * z : -((x - localCamera.x) ** 2 + (y - localCamera.y) ** 2 + (z - localCamera.z) ** 2);
|
|
20289
|
+
}
|
|
20290
|
+
order.sort((a, b) => depths[a] - depths[b] || a - b);
|
|
20291
|
+
if (!order.some((quad, offset) => index.array[offset * QUAD_INDICES] !== source[quad * QUAD_INDICES])) return;
|
|
20292
|
+
for (let offset = 0; offset < count; offset++) {
|
|
20293
|
+
for (let indexOffset = 0; indexOffset < QUAD_INDICES; indexOffset++) {
|
|
20294
|
+
index.array[offset * QUAD_INDICES + indexOffset] = source[order[offset] * QUAD_INDICES + indexOffset];
|
|
20295
|
+
}
|
|
20296
|
+
}
|
|
20297
|
+
index.needsUpdate = true;
|
|
20298
|
+
};
|
|
20299
|
+
}
|
|
20300
|
+
var SectionMesh = class _SectionMesh extends import_three47.Group {
|
|
19718
20301
|
constructor() {
|
|
19719
20302
|
super(...arguments);
|
|
19720
20303
|
this.ownedMeshes = [];
|
|
@@ -19723,7 +20306,11 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19723
20306
|
/** Returns the owning section cell for a triangle hit on this mesh's merged geometry. */
|
|
19724
20307
|
getBlockIndex(hit) {
|
|
19725
20308
|
if (hit.faceIndex === void 0 || hit.faceIndex === null) return void 0;
|
|
19726
|
-
|
|
20309
|
+
const mesh = hit.object;
|
|
20310
|
+
const owners = this.blockIndices.get(mesh);
|
|
20311
|
+
if (!owners) return void 0;
|
|
20312
|
+
const vertex = mesh.geometry.getIndex().getX(hit.faceIndex * 3);
|
|
20313
|
+
return owners[Math.floor(vertex / QUAD_VERTICES)];
|
|
19727
20314
|
}
|
|
19728
20315
|
/** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
19729
20316
|
static build(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
@@ -19745,27 +20332,28 @@ var SectionMesh = class _SectionMesh extends import_three46.Group {
|
|
|
19745
20332
|
for (const { atlas, x, y } of page.placements) {
|
|
19746
20333
|
context.drawImage(atlases2[atlas].image.canvas, x, y);
|
|
19747
20334
|
}
|
|
19748
|
-
const geometry = new
|
|
19749
|
-
geometry.setAttribute("position", new
|
|
19750
|
-
geometry.setAttribute("normal", new
|
|
19751
|
-
geometry.setAttribute("uv", new
|
|
19752
|
-
geometry.setAttribute("uvBounds", new
|
|
19753
|
-
geometry.setAttribute("color", new
|
|
19754
|
-
geometry.setAttribute("shade", new
|
|
19755
|
-
geometry.setIndex(new
|
|
20335
|
+
const geometry = new import_three47.BufferGeometry();
|
|
20336
|
+
geometry.setAttribute("position", new import_three47.Float32BufferAttribute(page.positions.buffer, 3));
|
|
20337
|
+
geometry.setAttribute("normal", new import_three47.Float32BufferAttribute(page.normals.buffer, 3));
|
|
20338
|
+
geometry.setAttribute("uv", new import_three47.Float32BufferAttribute(page.uvs.buffer, 2));
|
|
20339
|
+
geometry.setAttribute("uvBounds", new import_three47.Float32BufferAttribute(page.uvBounds.buffer, 4));
|
|
20340
|
+
geometry.setAttribute("color", new import_three47.Float32BufferAttribute(page.colors.buffer, 3));
|
|
20341
|
+
geometry.setAttribute("shade", new import_three47.Float32BufferAttribute(page.shade.buffer, 1));
|
|
20342
|
+
geometry.setIndex(new import_three47.Uint32BufferAttribute(page.indices.buffer, 1));
|
|
19756
20343
|
geometry.computeBoundingBox();
|
|
19757
20344
|
geometry.computeBoundingSphere();
|
|
19758
20345
|
const transparent = page.layer === 2 ? atlases2[page.placements[0].atlas].hasTranslucency : page.layer === 1;
|
|
19759
20346
|
const material = Materials.createShadedCanvasMaterial(canvas, transparent, false, true);
|
|
19760
|
-
material.side =
|
|
20347
|
+
material.side = import_three47.FrontSide;
|
|
19761
20348
|
if (page.layer === 2) {
|
|
19762
|
-
material.side = import_three46.DoubleSide;
|
|
19763
|
-
material.forceSinglePass = true;
|
|
19764
20349
|
material.depthWrite = !material.transparent;
|
|
20350
|
+
material.side = import_three47.DoubleSide;
|
|
20351
|
+
material.forceSinglePass = true;
|
|
19765
20352
|
}
|
|
19766
20353
|
material.vertexColors = true;
|
|
19767
20354
|
const texture = material.uniforms?.map?.value ?? material.map;
|
|
19768
|
-
const mesh = new
|
|
20355
|
+
const mesh = new import_three47.Mesh(geometry, material);
|
|
20356
|
+
if (transparent) sortTransparentQuads(mesh);
|
|
19769
20357
|
section.add(mesh);
|
|
19770
20358
|
section.blockIndices.set(mesh, page.blockIndices);
|
|
19771
20359
|
const unsubscribe = [];
|
|
@@ -19806,7 +20394,7 @@ init_CubeFace();
|
|
|
19806
20394
|
init_BlockTints();
|
|
19807
20395
|
init_Biomes();
|
|
19808
20396
|
init_InstanceReference();
|
|
19809
|
-
var WATER_TINT2 = new
|
|
20397
|
+
var WATER_TINT2 = new import_three48.Color(4159204).toArray();
|
|
19810
20398
|
var Chunk = class _Chunk {
|
|
19811
20399
|
constructor(scene, x, y, z, onBlocksChanged, sectionModels, neighborCell, biomeAt, onBiomesChanged, lightAt, onLightCleared, ambientLight = 0, biomeBlend) {
|
|
19812
20400
|
this.onBlocksChanged = onBlocksChanged;
|
|
@@ -19824,7 +20412,7 @@ var Chunk = class _Chunk {
|
|
|
19824
20412
|
this.sectionBlocks = /* @__PURE__ */ new Map();
|
|
19825
20413
|
this.hiddenBlocks = /* @__PURE__ */ new Set();
|
|
19826
20414
|
this.fluidCells = new Uint8Array(4096);
|
|
19827
|
-
this.blockPosition = new
|
|
20415
|
+
this.blockPosition = new import_three48.Vector3();
|
|
19828
20416
|
this.meshDirty = false;
|
|
19829
20417
|
this.meshGeneration = 0;
|
|
19830
20418
|
this.blockChanges = /* @__PURE__ */ new Set();
|
|
@@ -19884,7 +20472,7 @@ var Chunk = class _Chunk {
|
|
|
19884
20472
|
const info = owner.chunk.renderedBlocks.get(owner.index);
|
|
19885
20473
|
if (!info) continue;
|
|
19886
20474
|
return {
|
|
19887
|
-
position: new
|
|
20475
|
+
position: new import_three48.Vector3(
|
|
19888
20476
|
owner.chunk.x * 16 + owner.index % 16,
|
|
19889
20477
|
owner.chunk.y * 16 + Math.floor(owner.index / 256),
|
|
19890
20478
|
owner.chunk.z * 16 + Math.floor(owner.index / 16) % 16
|
|
@@ -19899,18 +20487,18 @@ var Chunk = class _Chunk {
|
|
|
19899
20487
|
}
|
|
19900
20488
|
getBlockAt(posOrX, y, z) {
|
|
19901
20489
|
if (typeof posOrX == "number") {
|
|
19902
|
-
return this.getBlockAt(new
|
|
20490
|
+
return this.getBlockAt(new import_three48.Vector3(posOrX, y, z));
|
|
19903
20491
|
}
|
|
19904
20492
|
if (isTripleArray(posOrX)) {
|
|
19905
|
-
return this.getBlockAt(new
|
|
20493
|
+
return this.getBlockAt(new import_three48.Vector3(posOrX[0], posOrX[1], posOrX[2]));
|
|
19906
20494
|
}
|
|
19907
20495
|
const pos = this.blockPosition.set(posOrX.x - this.x * 16, posOrX.y - this.y * 16, posOrX.z - this.z * 16);
|
|
19908
20496
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
19909
20497
|
return this.renderedBlocks.get(index);
|
|
19910
20498
|
}
|
|
19911
20499
|
getBiomeAt(posOrX, y, z) {
|
|
19912
|
-
if (typeof posOrX === "number") return this.getBiomeAt(new
|
|
19913
|
-
if (isTripleArray(posOrX)) return this.getBiomeAt(new
|
|
20500
|
+
if (typeof posOrX === "number") return this.getBiomeAt(new import_three48.Vector3(posOrX, y, z));
|
|
20501
|
+
if (isTripleArray(posOrX)) return this.getBiomeAt(new import_three48.Vector3(...posOrX));
|
|
19914
20502
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
19915
20503
|
_Chunk.chunkPosToBlockIndex(pos);
|
|
19916
20504
|
return this.biomeAt ? this.biomeAt(posOrX.x, posOrX.y, posOrX.z) : this.biomes?.[Math.floor(pos.x / 4) + Math.floor(pos.z / 4) * 4 + Math.floor(pos.y / 4) * 16];
|
|
@@ -19988,17 +20576,17 @@ var Chunk = class _Chunk {
|
|
|
19988
20576
|
this.hiddenBlocks.add(index);
|
|
19989
20577
|
this.renderedBlocks.get(index)?.object?.setVisible(false);
|
|
19990
20578
|
}
|
|
19991
|
-
const positions = blocks.map(({ index }) => new
|
|
20579
|
+
const positions = blocks.map(({ index }) => new import_three48.Vector3(...this.positionAt(index)));
|
|
19992
20580
|
if (this.onBlocksChanged) await this.onBlocksChanged(positions, deferCulling);
|
|
19993
20581
|
else await this.rebuildSectionMesh();
|
|
19994
20582
|
}
|
|
19995
20583
|
}
|
|
19996
20584
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
19997
20585
|
if (typeof posOrX == "number") {
|
|
19998
|
-
return this.setBlockAt(new
|
|
20586
|
+
return this.setBlockAt(new import_three48.Vector3(posOrX, yOrBlock, z), block);
|
|
19999
20587
|
}
|
|
20000
20588
|
if (isTripleArray(posOrX)) {
|
|
20001
|
-
return this.setBlockAt(new
|
|
20589
|
+
return this.setBlockAt(new import_three48.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
20002
20590
|
}
|
|
20003
20591
|
const worldPos = posOrX;
|
|
20004
20592
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -20060,8 +20648,10 @@ var Chunk = class _Chunk {
|
|
|
20060
20648
|
if (rejected?.status === "rejected") throw rejected.reason;
|
|
20061
20649
|
}
|
|
20062
20650
|
const positions = [];
|
|
20063
|
-
|
|
20064
|
-
|
|
20651
|
+
const jobs = /* @__PURE__ */ new Map();
|
|
20652
|
+
let failureOrder = Infinity, failure;
|
|
20653
|
+
for (const [order, { index, key, block }] of placements.entries()) {
|
|
20654
|
+
jobs.delete(index);
|
|
20065
20655
|
this.hiddenBlocks.delete(index);
|
|
20066
20656
|
this.data.assign(index, this.data.intern(block), block?.nbt);
|
|
20067
20657
|
const readBlock = this.data.snapshot(index);
|
|
@@ -20071,13 +20661,12 @@ var Chunk = class _Chunk {
|
|
|
20071
20661
|
this.fluidCells[index] = 0;
|
|
20072
20662
|
this.renderedBlocks.delete(index);
|
|
20073
20663
|
this.objectBlocks.delete(index);
|
|
20074
|
-
const worldPos = new
|
|
20664
|
+
const worldPos = new import_three48.Vector3(
|
|
20075
20665
|
this.x * 16 + index % 16,
|
|
20076
20666
|
this.y * 16 + Math.floor(index / 256),
|
|
20077
20667
|
this.z * 16 + Math.floor(index / 16) % 16
|
|
20078
20668
|
);
|
|
20079
20669
|
positions.push(worldPos);
|
|
20080
|
-
let object4;
|
|
20081
20670
|
try {
|
|
20082
20671
|
if (!readBlock) continue;
|
|
20083
20672
|
const resolved = resolutions.get(key);
|
|
@@ -20099,7 +20688,7 @@ var Chunk = class _Chunk {
|
|
|
20099
20688
|
this.sectionBlocks.set(index, templates.map((template) => ({ index, template, cullMask: 0, biomeTint: context?.tint })));
|
|
20100
20689
|
this.meshDirty = true;
|
|
20101
20690
|
} else {
|
|
20102
|
-
|
|
20691
|
+
jobs.set(index, { order, readBlock, blockState: blockState3, position: MineRenderWorld.worldToScenePosition(worldPos), options: {
|
|
20103
20692
|
mergeMeshes: true,
|
|
20104
20693
|
instanceMeshes: true,
|
|
20105
20694
|
maxInstanceCount: 2e3,
|
|
@@ -20107,13 +20696,12 @@ var Chunk = class _Chunk {
|
|
|
20107
20696
|
variantPosition,
|
|
20108
20697
|
biome: context?.biome,
|
|
20109
20698
|
biomePosition: this.biomePosition(index, blockState3, stored)
|
|
20110
|
-
});
|
|
20111
|
-
|
|
20699
|
+
} });
|
|
20700
|
+
continue;
|
|
20112
20701
|
}
|
|
20113
20702
|
this.renderedBlocks.set(index, { get block() {
|
|
20114
20703
|
return readBlock();
|
|
20115
|
-
}, object:
|
|
20116
|
-
if (object4) this.objectBlocks.add(index);
|
|
20704
|
+
}, object: void 0 });
|
|
20117
20705
|
} catch (error) {
|
|
20118
20706
|
if (preserveDataOnFailure && readBlock) {
|
|
20119
20707
|
this.renderedBlocks.set(index, { get block() {
|
|
@@ -20121,12 +20709,35 @@ var Chunk = class _Chunk {
|
|
|
20121
20709
|
}, object: void 0 });
|
|
20122
20710
|
} else this.data.assign(index, 0);
|
|
20123
20711
|
this.fluidCells[index] = 0;
|
|
20124
|
-
|
|
20125
|
-
|
|
20126
|
-
|
|
20712
|
+
if (order < failureOrder) {
|
|
20713
|
+
failureOrder = order;
|
|
20714
|
+
failure = error;
|
|
20715
|
+
}
|
|
20127
20716
|
}
|
|
20128
20717
|
}
|
|
20129
|
-
|
|
20718
|
+
const pending = [...jobs];
|
|
20719
|
+
const objects = await Promise.allSettled(pending.map(([, job]) => this.createBlockObject(job.blockState, job.position, job.options)));
|
|
20720
|
+
for (const [i, [index, { order, readBlock }]] of pending.entries()) {
|
|
20721
|
+
const result = objects[i];
|
|
20722
|
+
if (result.status === "fulfilled") {
|
|
20723
|
+
this.renderedBlocks.set(index, { get block() {
|
|
20724
|
+
return readBlock();
|
|
20725
|
+
}, object: result.value });
|
|
20726
|
+
this.objectBlocks.add(index);
|
|
20727
|
+
} else {
|
|
20728
|
+
if (preserveDataOnFailure) {
|
|
20729
|
+
this.renderedBlocks.set(index, { get block() {
|
|
20730
|
+
return readBlock();
|
|
20731
|
+
}, object: void 0 });
|
|
20732
|
+
} else this.data.assign(index, 0);
|
|
20733
|
+
this.fluidCells[index] = 0;
|
|
20734
|
+
if (order < failureOrder) {
|
|
20735
|
+
failureOrder = order;
|
|
20736
|
+
failure = result.reason;
|
|
20737
|
+
}
|
|
20738
|
+
}
|
|
20739
|
+
}
|
|
20740
|
+
if (failureOrder < Infinity) throw failure;
|
|
20130
20741
|
return positions;
|
|
20131
20742
|
}
|
|
20132
20743
|
/** Replaces every cell from parsed section data. The caller refreshes neighbor culling. */
|
|
@@ -20197,37 +20808,42 @@ var Chunk = class _Chunk {
|
|
|
20197
20808
|
failed = true;
|
|
20198
20809
|
}
|
|
20199
20810
|
}
|
|
20200
|
-
|
|
20201
|
-
|
|
20202
|
-
|
|
20203
|
-
|
|
20204
|
-
|
|
20205
|
-
|
|
20206
|
-
|
|
20207
|
-
|
|
20208
|
-
|
|
20209
|
-
|
|
20210
|
-
|
|
20211
|
-
|
|
20212
|
-
|
|
20213
|
-
|
|
20214
|
-
|
|
20215
|
-
|
|
20216
|
-
)
|
|
20217
|
-
this.renderedBlocks.get(index).object = object4;
|
|
20811
|
+
const objects = await Promise.allSettled(perBlocks.map(({ index, blockState: blockState3, biome }) => this.createBlockObject(blockState3, new import_three48.Vector3(
|
|
20812
|
+
this.x * 256 + index % 16 * 16,
|
|
20813
|
+
this.y * 256 + Math.floor(index / 256) * 16,
|
|
20814
|
+
this.z * 256 + Math.floor(index / 16) % 16 * 16
|
|
20815
|
+
), {
|
|
20816
|
+
mergeMeshes: true,
|
|
20817
|
+
instanceMeshes: true,
|
|
20818
|
+
maxInstanceCount: 2e3,
|
|
20819
|
+
initialState: this.data.stateAt(this.data.idAt(index)).properties,
|
|
20820
|
+
variantPosition: this.positionAt(index),
|
|
20821
|
+
biome,
|
|
20822
|
+
biomePosition: this.biomePosition(index, blockState3, this.data.stateAt(this.data.idAt(index)))
|
|
20823
|
+
})));
|
|
20824
|
+
for (const [i, { index }] of perBlocks.entries()) {
|
|
20825
|
+
const result = objects[i];
|
|
20826
|
+
if (result.status === "fulfilled") {
|
|
20827
|
+
this.renderedBlocks.get(index).object = result.value;
|
|
20218
20828
|
this.objectBlocks.add(index);
|
|
20219
|
-
}
|
|
20829
|
+
} else {
|
|
20220
20830
|
this.data.assign(index, 0);
|
|
20221
20831
|
this.fluidCells[index] = 0;
|
|
20222
20832
|
this.renderedBlocks.delete(index);
|
|
20223
20833
|
this.objectBlocks.delete(index);
|
|
20224
|
-
|
|
20225
|
-
if (!failed) failure = error;
|
|
20834
|
+
if (!failed) failure = result.reason;
|
|
20226
20835
|
failed = true;
|
|
20227
20836
|
}
|
|
20228
20837
|
}
|
|
20229
20838
|
if (failed) throw failure;
|
|
20230
20839
|
}
|
|
20840
|
+
createBlockObject(blockState3, position, options) {
|
|
20841
|
+
return this.scene.addSceneObject(blockState3, () => {
|
|
20842
|
+
const object4 = new BlockObject(blockState3, options);
|
|
20843
|
+
object4.position.copy(position);
|
|
20844
|
+
return object4;
|
|
20845
|
+
}, options);
|
|
20846
|
+
}
|
|
20231
20847
|
positionAt(index) {
|
|
20232
20848
|
return [this.x * 16 + index % 16, this.y * 16 + Math.floor(index / 256), this.z * 16 + Math.floor(index / 16) % 16];
|
|
20233
20849
|
}
|
|
@@ -20282,11 +20898,11 @@ var Chunk = class _Chunk {
|
|
|
20282
20898
|
const context = {};
|
|
20283
20899
|
if (source && prepared2?.biomeTint) {
|
|
20284
20900
|
const color2 = await biomeColor(source);
|
|
20285
|
-
if (color2 !== void 0) context.tint = new
|
|
20901
|
+
if (color2 !== void 0) context.tint = new import_three48.Color(color2).toArray();
|
|
20286
20902
|
}
|
|
20287
20903
|
if (fluid?.kind === "water") {
|
|
20288
20904
|
const color2 = await biomeColor("water");
|
|
20289
|
-
if (color2 !== void 0 && color2 !== 4159204) context.waterTint = new
|
|
20905
|
+
if (color2 !== void 0 && color2 !== 4159204) context.waterTint = new import_three48.Color(color2).toArray();
|
|
20290
20906
|
}
|
|
20291
20907
|
contexts.set(index, context);
|
|
20292
20908
|
}));
|
|
@@ -20324,7 +20940,7 @@ var Chunk = class _Chunk {
|
|
|
20324
20940
|
context.prepared = await prepare(async () => await available() ? BlockTints.getBiomeColor(blockState3?.key, biome, position) : void 0);
|
|
20325
20941
|
if (fluid?.kind === "water" && await available()) {
|
|
20326
20942
|
const color2 = await Biomes.getColor(biome, "water", blockState3?.key);
|
|
20327
|
-
if (color2 !== void 0 && color2 !== 4159204) context.waterTint = new
|
|
20943
|
+
if (color2 !== void 0 && color2 !== 4159204) context.waterTint = new import_three48.Color(color2).toArray();
|
|
20328
20944
|
}
|
|
20329
20945
|
}
|
|
20330
20946
|
for (const index of indices2) contexts.set(index, context);
|
|
@@ -20516,7 +21132,7 @@ var Chunk = class _Chunk {
|
|
|
20516
21132
|
async clear(notify = true) {
|
|
20517
21133
|
if (this.blockChanges.size) await Promise.allSettled(this.blockChanges);
|
|
20518
21134
|
const positions = notify && this.onBlocksChanged ? [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
20519
|
-
new
|
|
21135
|
+
new import_three48.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
20520
21136
|
)) : [];
|
|
20521
21137
|
for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
|
|
20522
21138
|
this.sectionBlocks.clear();
|
|
@@ -20552,14 +21168,14 @@ var Chunk = class _Chunk {
|
|
|
20552
21168
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
20553
21169
|
}
|
|
20554
21170
|
worldPosToChunkPos(pos) {
|
|
20555
|
-
return new
|
|
21171
|
+
return new import_three48.Vector3(
|
|
20556
21172
|
pos.x - this.x * 16,
|
|
20557
21173
|
pos.y - this.y * 16,
|
|
20558
21174
|
pos.z - this.z * 16
|
|
20559
21175
|
);
|
|
20560
21176
|
}
|
|
20561
21177
|
chunkPosToWorldPos(pos) {
|
|
20562
|
-
return new
|
|
21178
|
+
return new import_three48.Vector3(
|
|
20563
21179
|
this.x * 16 + pos.x,
|
|
20564
21180
|
this.y * 16 + pos.y,
|
|
20565
21181
|
this.z * 16 + pos.z
|
|
@@ -20568,6 +21184,7 @@ var Chunk = class _Chunk {
|
|
|
20568
21184
|
};
|
|
20569
21185
|
|
|
20570
21186
|
// src/world/WorldStreamer.ts
|
|
21187
|
+
var MAX_PREFETCHED_COLUMNS = 4;
|
|
20571
21188
|
var WorldStreamer = class {
|
|
20572
21189
|
constructor(world, source, options = {}) {
|
|
20573
21190
|
this.world = world;
|
|
@@ -20577,6 +21194,7 @@ var WorldStreamer = class {
|
|
|
20577
21194
|
this.missing = /* @__PURE__ */ new Map();
|
|
20578
21195
|
this.failed = /* @__PURE__ */ new Map();
|
|
20579
21196
|
this.desired = [];
|
|
21197
|
+
this.reads = /* @__PURE__ */ new Map();
|
|
20580
21198
|
this.disposed = false;
|
|
20581
21199
|
this.loadRadius = options.loadRadius ?? 2;
|
|
20582
21200
|
this.unloadRadius = options.unloadRadius ?? Math.min(32, this.loadRadius + 1);
|
|
@@ -20621,6 +21239,12 @@ var WorldStreamer = class {
|
|
|
20621
21239
|
if (this.loading && !this.within(this.loading.position, this.loadRadius)) {
|
|
20622
21240
|
this.loading.controller.abort();
|
|
20623
21241
|
}
|
|
21242
|
+
for (const [key, read] of this.reads) {
|
|
21243
|
+
if (!this.within(read.position, this.loadRadius)) {
|
|
21244
|
+
read.controller.abort();
|
|
21245
|
+
if (read.ready) this.reads.delete(key);
|
|
21246
|
+
}
|
|
21247
|
+
}
|
|
20624
21248
|
}
|
|
20625
21249
|
return this.running ??= Promise.resolve().then(() => this.drain());
|
|
20626
21250
|
}
|
|
@@ -20641,8 +21265,11 @@ var WorldStreamer = class {
|
|
|
20641
21265
|
this.desired = [];
|
|
20642
21266
|
this.center = void 0;
|
|
20643
21267
|
this.loading?.controller.abort();
|
|
21268
|
+
for (const read of this.reads.values()) read.controller.abort();
|
|
20644
21269
|
return this.disposal ??= Promise.resolve().then(async () => {
|
|
20645
21270
|
await this.running?.catch(() => void 0);
|
|
21271
|
+
await Promise.all([...this.reads.values()].map((read) => read.promise));
|
|
21272
|
+
this.reads.clear();
|
|
20646
21273
|
try {
|
|
20647
21274
|
await this.unloadMany([...this.owned.values()]);
|
|
20648
21275
|
} finally {
|
|
@@ -20668,6 +21295,10 @@ var WorldStreamer = class {
|
|
|
20668
21295
|
await this.unloadMany(obsolete);
|
|
20669
21296
|
continue;
|
|
20670
21297
|
}
|
|
21298
|
+
if (this.world.placeChunks) {
|
|
21299
|
+
if (await this.placeReadyChunks()) continue;
|
|
21300
|
+
return;
|
|
21301
|
+
}
|
|
20671
21302
|
const position = this.desired.find((position2) => this.needsLoad(position2));
|
|
20672
21303
|
if (!position) return;
|
|
20673
21304
|
let chunk;
|
|
@@ -20690,26 +21321,105 @@ var WorldStreamer = class {
|
|
|
20690
21321
|
continue;
|
|
20691
21322
|
}
|
|
20692
21323
|
this.owned.set(this.key(position), position);
|
|
21324
|
+
await this.placeOwnedColumns([position], () => this.world.placeChunk(chunk));
|
|
21325
|
+
}
|
|
21326
|
+
} finally {
|
|
21327
|
+
for (const [key, read] of this.reads) {
|
|
21328
|
+
read.controller.abort();
|
|
21329
|
+
if (read.ready) this.reads.delete(key);
|
|
21330
|
+
}
|
|
21331
|
+
this.running = void 0;
|
|
21332
|
+
}
|
|
21333
|
+
}
|
|
21334
|
+
fillReadSlots() {
|
|
21335
|
+
while (!this.disposed && this.reads.size < MAX_PREFETCHED_COLUMNS) {
|
|
21336
|
+
const position = this.desired.find((position2) => this.needsLoad(position2) && !this.reads.has(this.key(position2)));
|
|
21337
|
+
if (!position) return;
|
|
21338
|
+
const key = this.key(position);
|
|
21339
|
+
const read = {
|
|
21340
|
+
position,
|
|
21341
|
+
controller: new AbortController(),
|
|
21342
|
+
promise: Promise.resolve(),
|
|
21343
|
+
ready: false,
|
|
21344
|
+
failed: false
|
|
21345
|
+
};
|
|
21346
|
+
this.reads.set(key, read);
|
|
21347
|
+
read.promise = (async () => {
|
|
20693
21348
|
try {
|
|
20694
|
-
await this.
|
|
20695
|
-
this.
|
|
21349
|
+
read.chunk = await this.source.getChunk(position.x, position.z, read.controller.signal);
|
|
21350
|
+
if (read.chunk) this.validateChunk(read.chunk, position);
|
|
20696
21351
|
} catch (error) {
|
|
20697
|
-
|
|
20698
|
-
|
|
20699
|
-
|
|
20700
|
-
|
|
20701
|
-
|
|
20702
|
-
|
|
20703
|
-
} catch {
|
|
20704
|
-
throw Object.assign(new Error(failure.message), { cause: cleanupError });
|
|
20705
|
-
}
|
|
20706
|
-
throw failure;
|
|
21352
|
+
read.failed = true;
|
|
21353
|
+
read.error = error;
|
|
21354
|
+
} finally {
|
|
21355
|
+
read.ready = true;
|
|
21356
|
+
if (read.controller.signal.aborted || this.disposed || !this.within(position, this.loadRadius)) {
|
|
21357
|
+
this.reads.delete(key);
|
|
20707
21358
|
}
|
|
20708
|
-
|
|
21359
|
+
}
|
|
21360
|
+
})();
|
|
21361
|
+
}
|
|
21362
|
+
}
|
|
21363
|
+
/** Places only the ready prefix, so later source reads cannot delay the nearest ready column. */
|
|
21364
|
+
async placeReadyChunks() {
|
|
21365
|
+
this.fillReadSlots();
|
|
21366
|
+
const position = this.desired.find((position2) => this.needsLoad(position2));
|
|
21367
|
+
if (!position) {
|
|
21368
|
+
if (!this.reads.size) return false;
|
|
21369
|
+
await Promise.all([...this.reads.values()].map((read) => read.promise));
|
|
21370
|
+
return true;
|
|
21371
|
+
}
|
|
21372
|
+
const head = this.reads.get(this.key(position));
|
|
21373
|
+
if (!head) {
|
|
21374
|
+
for (let index = this.desired.length - 1; index >= 0; index--) {
|
|
21375
|
+
const key = this.key(this.desired[index]);
|
|
21376
|
+
if (this.reads.get(key)?.ready) {
|
|
21377
|
+
this.reads.delete(key);
|
|
21378
|
+
return true;
|
|
20709
21379
|
}
|
|
20710
21380
|
}
|
|
20711
|
-
|
|
20712
|
-
|
|
21381
|
+
await Promise.race([...this.reads.values()].map((read) => read.promise));
|
|
21382
|
+
return true;
|
|
21383
|
+
}
|
|
21384
|
+
if (!head.ready) {
|
|
21385
|
+
await head.promise;
|
|
21386
|
+
return true;
|
|
21387
|
+
}
|
|
21388
|
+
const chunks = [], positions = [];
|
|
21389
|
+
for (const desired of this.desired) {
|
|
21390
|
+
if (!this.needsLoad(desired)) continue;
|
|
21391
|
+
const key = this.key(desired), read = this.reads.get(key);
|
|
21392
|
+
if (!read?.ready) break;
|
|
21393
|
+
this.reads.delete(key);
|
|
21394
|
+
if (read.failed) this.failed.set(key, { ...desired, error: read.error });
|
|
21395
|
+
else if (!read.chunk) this.missing.set(key, desired);
|
|
21396
|
+
else {
|
|
21397
|
+
chunks.push(read.chunk);
|
|
21398
|
+
positions.push(desired);
|
|
21399
|
+
}
|
|
21400
|
+
}
|
|
21401
|
+
if (!chunks.length) return true;
|
|
21402
|
+
for (const position2 of positions) this.owned.set(this.key(position2), position2);
|
|
21403
|
+
await this.placeOwnedColumns(positions, () => this.world.placeChunks(chunks));
|
|
21404
|
+
return true;
|
|
21405
|
+
}
|
|
21406
|
+
async placeOwnedColumns(positions, place) {
|
|
21407
|
+
try {
|
|
21408
|
+
await place();
|
|
21409
|
+
for (const position of positions) this.loaded.set(this.key(position), position);
|
|
21410
|
+
} catch (error) {
|
|
21411
|
+
try {
|
|
21412
|
+
await this.unloadMany(positions);
|
|
21413
|
+
} catch (cleanupError) {
|
|
21414
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
21415
|
+
try {
|
|
21416
|
+
Object.defineProperty(failure, "cause", { value: cleanupError, configurable: true });
|
|
21417
|
+
} catch {
|
|
21418
|
+
throw Object.assign(new Error(failure.message), { cause: cleanupError });
|
|
21419
|
+
}
|
|
21420
|
+
throw failure;
|
|
21421
|
+
}
|
|
21422
|
+
throw error;
|
|
20713
21423
|
}
|
|
20714
21424
|
}
|
|
20715
21425
|
needsLoad(position) {
|
|
@@ -20911,6 +21621,7 @@ var NodeRenderer = class _NodeRenderer extends Renderer {
|
|
|
20911
21621
|
AnvilParser,
|
|
20912
21622
|
AnvilWorldSource,
|
|
20913
21623
|
ArchiveAssetSource,
|
|
21624
|
+
Armor,
|
|
20914
21625
|
AssetKey,
|
|
20915
21626
|
AssetLoadError,
|
|
20916
21627
|
AssetLoader,
|
|
@@ -20994,6 +21705,7 @@ var NodeRenderer = class _NodeRenderer extends Renderer {
|
|
|
20994
21705
|
OrbitControls,
|
|
20995
21706
|
PackFormats,
|
|
20996
21707
|
PackMetadata,
|
|
21708
|
+
PalettedTextures,
|
|
20997
21709
|
PersistentCache,
|
|
20998
21710
|
PlayerHeadTextures,
|
|
20999
21711
|
Renames,
|