minerender 2.1.0-alpha.75 → 2.1.0-alpha.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.d.mts +473 -12
- package/dist/browser/index.d.ts +473 -12
- package/dist/browser/index.js +245 -9
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +245 -9
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +245 -9
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +473 -12
- package/dist/node/index.d.ts +473 -12
- package/dist/node/index.js +245 -9
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +245 -9
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -4056,6 +4056,7 @@ var MineRender = (() => {
|
|
|
4056
4056
|
constructor(backing) {
|
|
4057
4057
|
this.backing = backing;
|
|
4058
4058
|
}
|
|
4059
|
+
/** Opens a named store in the active environment using the current cache schema version. */
|
|
4059
4060
|
static open(name2) {
|
|
4060
4061
|
return Env.provider.openCache(name2, _PersistentCache.VERSION);
|
|
4061
4062
|
}
|
|
@@ -41425,6 +41426,7 @@ void main() {
|
|
|
41425
41426
|
this.fontCache
|
|
41426
41427
|
];
|
|
41427
41428
|
}
|
|
41429
|
+
/** Invalidates in-memory entries so later lookups reload them. Persisted entries are retained. */
|
|
41428
41430
|
static clear() {
|
|
41429
41431
|
for (const cache of this.all) {
|
|
41430
41432
|
cache.invalidateAll();
|
|
@@ -41493,6 +41495,7 @@ void main() {
|
|
|
41493
41495
|
}
|
|
41494
41496
|
return geometry;
|
|
41495
41497
|
}
|
|
41498
|
+
/** Returns shared geometry. Use {@link createBox} when the caller needs to modify or dispose it independently. */
|
|
41496
41499
|
static getBox(key) {
|
|
41497
41500
|
const keyStr = serializeBoxGeometryKey(key);
|
|
41498
41501
|
return Caching.boxGeometryCache.get(keyStr, (k4) => {
|
|
@@ -42047,12 +42050,15 @@ void main() {
|
|
|
42047
42050
|
}
|
|
42048
42051
|
};
|
|
42049
42052
|
Requests = class {
|
|
42053
|
+
/** Queues a general request. Set `request.signal` to cancel it and `request.timeout` to limit each attempt. */
|
|
42050
42054
|
static genericRequest(request) {
|
|
42051
42055
|
return this.genericQueue.request(request);
|
|
42052
42056
|
}
|
|
42057
|
+
/** Queues a request separately from general traffic, using the configured asset base URL for relative paths. */
|
|
42053
42058
|
static mcAssetRequest(request) {
|
|
42054
42059
|
return this.mcAssetRequestQueue.request(request);
|
|
42055
42060
|
}
|
|
42061
|
+
/** Sets the base URL for relative asset requests. Use {@link AssetLoader.setVersion} to change Minecraft versions. */
|
|
42056
42062
|
static setMcAssetRoot(root) {
|
|
42057
42063
|
this.mcAssetRequestQueue.baseURL = root;
|
|
42058
42064
|
}
|
|
@@ -42110,6 +42116,7 @@ void main() {
|
|
|
42110
42116
|
}
|
|
42111
42117
|
return false;
|
|
42112
42118
|
}
|
|
42119
|
+
/** Whether the dimensions form a vertical strip of square frames, without consulting `.mcmeta`. */
|
|
42113
42120
|
get animated() {
|
|
42114
42121
|
return this.height > this.width && this.height % this.width === 0;
|
|
42115
42122
|
}
|
|
@@ -42159,6 +42166,7 @@ void main() {
|
|
|
42159
42166
|
static _createImage() {
|
|
42160
42167
|
return createImage();
|
|
42161
42168
|
}
|
|
42169
|
+
/** Resolves when an image URL has decoded, or rejects if decoding fails. */
|
|
42162
42170
|
static async loadAsync(src) {
|
|
42163
42171
|
return new Promise((resolve, reject) => {
|
|
42164
42172
|
const image = this._createImage();
|
|
@@ -42167,6 +42175,7 @@ void main() {
|
|
|
42167
42175
|
image.src = src;
|
|
42168
42176
|
});
|
|
42169
42177
|
}
|
|
42178
|
+
/** Returns an image immediately. Use the callbacks to observe loading, or await {@link loadAsync}. */
|
|
42170
42179
|
static loadElement(src, onload, onerr) {
|
|
42171
42180
|
const image = this._createImage();
|
|
42172
42181
|
if (onload)
|
|
@@ -42194,6 +42203,7 @@ void main() {
|
|
|
42194
42203
|
throw err2;
|
|
42195
42204
|
}
|
|
42196
42205
|
}
|
|
42206
|
+
/** Decodes the supplied bytes into a canvas without fetching the source URL again. */
|
|
42197
42207
|
static async infoToCanvasData(info) {
|
|
42198
42208
|
const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
|
|
42199
42209
|
const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
|
|
@@ -42210,12 +42220,14 @@ void main() {
|
|
|
42210
42220
|
const image = await this.infoToCanvasData(info);
|
|
42211
42221
|
return image.data.getImageData(0, 0, image.width, image.height);
|
|
42212
42222
|
}
|
|
42223
|
+
/** Returns cached RGBA pixels for an image URL or data URL. Failed loads can be retried. */
|
|
42213
42224
|
static async getData(src) {
|
|
42214
42225
|
const keyStr = serializeImageKey({ src });
|
|
42215
42226
|
return await Caching.imageDataCache.get(keyStr, (k4) => {
|
|
42216
42227
|
return _ImageLoader.loadData(src);
|
|
42217
42228
|
});
|
|
42218
42229
|
}
|
|
42230
|
+
/** Returns a cached canvas context and dimensions for an image URL or data URL. */
|
|
42219
42231
|
static async getCanvasData(src) {
|
|
42220
42232
|
const keyStr = serializeImageKey({ src });
|
|
42221
42233
|
return await Caching.canvasImageDataCache.get(keyStr, (k4) => {
|
|
@@ -42315,6 +42327,7 @@ void main() {
|
|
|
42315
42327
|
texture.rotation = rotation;
|
|
42316
42328
|
return Textures.initTextureProps(texture);
|
|
42317
42329
|
}
|
|
42330
|
+
/** Loads image pixels in the background. `rotation` is in radians. Check {@link hasFailed} for load failures. */
|
|
42318
42331
|
static load(src, format3 = RGBAFormat, rotation = 0) {
|
|
42319
42332
|
const texture = new Texture();
|
|
42320
42333
|
texture.colorSpace = SRGBColorSpace;
|
|
@@ -42367,6 +42380,7 @@ void main() {
|
|
|
42367
42380
|
return this.initTextureProps(texture);
|
|
42368
42381
|
});
|
|
42369
42382
|
}
|
|
42383
|
+
/** Sets nearest-neighbor filters without changing the texture's color space. Returns the same texture. */
|
|
42370
42384
|
static initTextureProps(texture) {
|
|
42371
42385
|
texture.magFilter = NearestFilter;
|
|
42372
42386
|
texture.minFilter = NearestFilter;
|
|
@@ -42379,11 +42393,13 @@ void main() {
|
|
|
42379
42393
|
static createAsset(key) {
|
|
42380
42394
|
return new Texture();
|
|
42381
42395
|
}
|
|
42396
|
+
/** Creates an sRGB color texture from a canvas. */
|
|
42382
42397
|
static createCanvasTexture(canvas) {
|
|
42383
42398
|
const texture = new CanvasTexture(canvas);
|
|
42384
42399
|
texture.colorSpace = SRGBColorSpace;
|
|
42385
42400
|
return this.initTextureProps(texture);
|
|
42386
42401
|
}
|
|
42402
|
+
/** Returns a shared texture immediately and loads its image asynchronously. Failed cached loads are retried. */
|
|
42387
42403
|
static getImage(key) {
|
|
42388
42404
|
const keyStr = serializeTextureKey(key);
|
|
42389
42405
|
const cached2 = Caching.textureCache.peek(keyStr);
|
|
@@ -42411,6 +42427,7 @@ void main() {
|
|
|
42411
42427
|
init_TextureLoader();
|
|
42412
42428
|
init_Caching();
|
|
42413
42429
|
Materials = class _Materials {
|
|
42430
|
+
/** Shared checkerboard material, created on first access. */
|
|
42414
42431
|
static get MISSING_TEXTURE() {
|
|
42415
42432
|
return Caching.materialCache.get("builtin:missing-texture", () => new MeshBasicMaterial({
|
|
42416
42433
|
map: Textures.getMissing(),
|
|
@@ -42514,6 +42531,7 @@ void main() {
|
|
|
42514
42531
|
if (tint !== void 0) material.color.multiply(new Color(tint));
|
|
42515
42532
|
return material;
|
|
42516
42533
|
}
|
|
42534
|
+
/** Creates an unlit, transparent GUI material without depth writes or tone mapping. */
|
|
42517
42535
|
static createGuiCanvasMaterial(canvas) {
|
|
42518
42536
|
const material = new MeshBasicMaterial({
|
|
42519
42537
|
map: Textures.createCanvasTexture(canvas),
|
|
@@ -42680,6 +42698,7 @@ void main() {
|
|
|
42680
42698
|
}
|
|
42681
42699
|
return this.createBasicCanvasMaterial(canvas, transparent, shade);
|
|
42682
42700
|
}
|
|
42701
|
+
/** Returns a shared image material. Use {@link createImage} for a separate material instance. */
|
|
42683
42702
|
static getImage(key) {
|
|
42684
42703
|
const keyStr = serializeMaterialKey(key);
|
|
42685
42704
|
const map = Caching.materialCache.peek(keyStr)?.map;
|
|
@@ -42863,6 +42882,14 @@ void main() {
|
|
|
42863
42882
|
}
|
|
42864
42883
|
};
|
|
42865
42884
|
AssetKey = class _AssetKey extends BasicAssetKey {
|
|
42885
|
+
/**
|
|
42886
|
+
* Creates a key from separate path components. Use {@link parse} for a combined reference.
|
|
42887
|
+
*
|
|
42888
|
+
* @param assetType - Asset directory, such as `models`, `textures`, or `blockstates`.
|
|
42889
|
+
* @param type - Subdirectory, such as `block` or `item`.
|
|
42890
|
+
* @param rootType - Top-level directory, usually `assets` or `data`.
|
|
42891
|
+
* @param root - Base URL override for hosted asset sources.
|
|
42892
|
+
*/
|
|
42866
42893
|
constructor(namespace, path, assetType, type, rootType = "assets", extension = ".json", root) {
|
|
42867
42894
|
super(namespace, path);
|
|
42868
42895
|
this.namespace = namespace;
|
|
@@ -42874,6 +42901,16 @@ void main() {
|
|
|
42874
42901
|
this.root = root;
|
|
42875
42902
|
this.isAssetKey = true;
|
|
42876
42903
|
}
|
|
42904
|
+
/**
|
|
42905
|
+
* Parses an asset reference such as `minecraft:block/stone`.
|
|
42906
|
+
* A missing namespace defaults to the origin's namespace or `minecraft`.
|
|
42907
|
+
*
|
|
42908
|
+
* @param assetType - Asset category, such as `models` or `textures`.
|
|
42909
|
+
* @param str - Path with an optional namespace and file extension.
|
|
42910
|
+
* @param origin - Supplies the asset root, default namespace, and non-texture extension.
|
|
42911
|
+
* @returns A key with the matching extension removed from its path. Textures use `.png`;
|
|
42912
|
+
* other assets use the origin's extension or `.json`.
|
|
42913
|
+
*/
|
|
42877
42914
|
static parse(assetType, str, origin) {
|
|
42878
42915
|
let namespace = origin?.namespace || DEFAULT_NAMESPACE;
|
|
42879
42916
|
if (str.includes(":")) {
|
|
@@ -42905,6 +42942,7 @@ void main() {
|
|
|
42905
42942
|
];
|
|
42906
42943
|
return a4.join("/");
|
|
42907
42944
|
}
|
|
42945
|
+
/** Joins the type subdirectory and path without adding a namespace or file extension. */
|
|
42908
42946
|
getFullPath() {
|
|
42909
42947
|
let p13 = [];
|
|
42910
42948
|
if (this.type) {
|
|
@@ -42916,6 +42954,7 @@ void main() {
|
|
|
42916
42954
|
toNamespacedString() {
|
|
42917
42955
|
return this.namespace + ":" + this.getFullPath();
|
|
42918
42956
|
}
|
|
42957
|
+
/** Returns a cache identifier that includes the explicit root or {@link AssetLoader.ROOT}. */
|
|
42919
42958
|
serialize() {
|
|
42920
42959
|
return this.toString();
|
|
42921
42960
|
}
|
|
@@ -42981,6 +43020,7 @@ void main() {
|
|
|
42981
43020
|
const scale = new Vector3(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
|
|
42982
43021
|
return new Matrix4().compose(translation, rotation, scale);
|
|
42983
43022
|
}
|
|
43023
|
+
/** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
|
|
42984
43024
|
static apply(geometry, matrix) {
|
|
42985
43025
|
geometry.applyMatrix4(matrix);
|
|
42986
43026
|
if (matrix.determinant() < 0) {
|
|
@@ -43011,6 +43051,7 @@ void main() {
|
|
|
43011
43051
|
init_AssetKey();
|
|
43012
43052
|
init_DisplayTransforms();
|
|
43013
43053
|
ModelMerger = class {
|
|
43054
|
+
/** Loads the parent chain and returns a merged model without modifying the supplied definition. */
|
|
43014
43055
|
static async mergeWithParents(model) {
|
|
43015
43056
|
const models = await this.collectAllParents(model);
|
|
43016
43057
|
let merged = {};
|
|
@@ -43084,6 +43125,7 @@ void main() {
|
|
|
43084
43125
|
static get PERSISTENT_CACHE() {
|
|
43085
43126
|
return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-models"));
|
|
43086
43127
|
}
|
|
43128
|
+
/** Lists item filenames from the asset source's `_list.json`, with a legacy model-directory fallback. */
|
|
43087
43129
|
static async getItemList() {
|
|
43088
43130
|
const key = new AssetKey(DEFAULT_NAMESPACE, "_list", "items");
|
|
43089
43131
|
const legacyKey = new AssetKey(DEFAULT_NAMESPACE, "_list", "models", "item");
|
|
@@ -43154,6 +43196,7 @@ void main() {
|
|
|
43154
43196
|
}
|
|
43155
43197
|
throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
|
|
43156
43198
|
}
|
|
43199
|
+
/** Loads one model file without resolving its parents. Returns `undefined` when the file is missing. */
|
|
43157
43200
|
static async getRaw(key) {
|
|
43158
43201
|
if (!key.assetType) {
|
|
43159
43202
|
key.assetType = "models";
|
|
@@ -43173,6 +43216,12 @@ void main() {
|
|
|
43173
43216
|
return asset;
|
|
43174
43217
|
});
|
|
43175
43218
|
}
|
|
43219
|
+
/**
|
|
43220
|
+
* Loads a model and resolves its parent chain. Returns `undefined` when the model is missing.
|
|
43221
|
+
* Item keys use GUI context, false conditions, and zero numeric properties.
|
|
43222
|
+
*
|
|
43223
|
+
* @param key - Model key, for example `AssetKey.parse("models", "minecraft:item/diamond_sword")`.
|
|
43224
|
+
*/
|
|
43176
43225
|
static async getMerged(key) {
|
|
43177
43226
|
if (!key.assetType) {
|
|
43178
43227
|
key.assetType = "models";
|
|
@@ -43185,9 +43234,11 @@ void main() {
|
|
|
43185
43234
|
return _Models.loadAndMerge(key);
|
|
43186
43235
|
});
|
|
43187
43236
|
}
|
|
43237
|
+
/** Alias for {@link getMerged}. */
|
|
43188
43238
|
static async get(key) {
|
|
43189
43239
|
return this.getMerged(key);
|
|
43190
43240
|
}
|
|
43241
|
+
/** Clears persisted models. Use {@link Caching.clear} to also discard in-memory assets. */
|
|
43191
43242
|
static async clearCache() {
|
|
43192
43243
|
return this.PERSISTENT_CACHE.clear();
|
|
43193
43244
|
}
|
|
@@ -43213,6 +43264,7 @@ void main() {
|
|
|
43213
43264
|
return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-blockstates"));
|
|
43214
43265
|
}
|
|
43215
43266
|
// BlockState names are hardcoded
|
|
43267
|
+
/** Returns blockstate filenames from the selected version's `_list.json`, or an empty list. */
|
|
43216
43268
|
static async getList() {
|
|
43217
43269
|
const key = new AssetKey(
|
|
43218
43270
|
DEFAULT_NAMESPACE,
|
|
@@ -43233,6 +43285,7 @@ void main() {
|
|
|
43233
43285
|
return AssetLoader.get(key, "json" /* JSON */);
|
|
43234
43286
|
});
|
|
43235
43287
|
}
|
|
43288
|
+
/** Looks up vanilla property definitions for the key's block path, or returns `undefined`. */
|
|
43236
43289
|
static async getDefaultState(key) {
|
|
43237
43290
|
const defaultStates = await this.getDefaultStates();
|
|
43238
43291
|
if (!defaultStates) {
|
|
@@ -43240,6 +43293,7 @@ void main() {
|
|
|
43240
43293
|
}
|
|
43241
43294
|
return defaultStates["minecraft:" + key.path];
|
|
43242
43295
|
}
|
|
43296
|
+
/** Loads a cached blockstate definition for {@link MineRenderScene.addBlock}, or returns `undefined`. */
|
|
43243
43297
|
static async get(key) {
|
|
43244
43298
|
if (!key.assetType) {
|
|
43245
43299
|
key.assetType = "blockstates";
|
|
@@ -43266,6 +43320,7 @@ void main() {
|
|
|
43266
43320
|
}
|
|
43267
43321
|
return Promise.all(promises);
|
|
43268
43322
|
}
|
|
43323
|
+
/** Clears persisted blockstates. Use {@link Caching.clear} to also discard in-memory assets. */
|
|
43269
43324
|
static async clearCache() {
|
|
43270
43325
|
await this.PERSISTENT_CACHE.clear();
|
|
43271
43326
|
}
|
|
@@ -43294,9 +43349,11 @@ void main() {
|
|
|
43294
43349
|
static parseAssetKey(assetType, str, origin) {
|
|
43295
43350
|
return AssetKey.parse(assetType, str, origin);
|
|
43296
43351
|
}
|
|
43352
|
+
/** Loads a model with its parent chain resolved. See {@link Models.getMerged}. */
|
|
43297
43353
|
static async getModel(key) {
|
|
43298
43354
|
return Models.getMerged(key);
|
|
43299
43355
|
}
|
|
43356
|
+
/** Loads a blockstate definition. See {@link BlockStates.get}. */
|
|
43300
43357
|
static async getBlockState(key) {
|
|
43301
43358
|
return BlockStates.get(key);
|
|
43302
43359
|
}
|
|
@@ -43349,6 +43406,10 @@ void main() {
|
|
|
43349
43406
|
init_process2();
|
|
43350
43407
|
import_jobqu2 = __toESM(require_src());
|
|
43351
43408
|
BatchedExecutor = class {
|
|
43409
|
+
/**
|
|
43410
|
+
* @param interval - Delay between queue runs, in milliseconds.
|
|
43411
|
+
* @param batch - Maximum tasks started per run and maximum tasks active at once.
|
|
43412
|
+
*/
|
|
43352
43413
|
constructor(interval = 1, batch = 30) {
|
|
43353
43414
|
if (!Number.isFinite(interval) || interval < 0) throw new RangeError("Batch interval must be finite and nonnegative");
|
|
43354
43415
|
if (!Number.isInteger(batch) || batch < 1) throw new RangeError("Batch size must be a positive integer");
|
|
@@ -43356,9 +43417,11 @@ void main() {
|
|
|
43356
43417
|
this.batch = batch;
|
|
43357
43418
|
this.queue = new import_jobqu2.JobQueue(async (task) => task(), { interval, maxPerRun: batch, maxActive: batch });
|
|
43358
43419
|
}
|
|
43420
|
+
/** Queues a task and resolves with its result, or rejects with its error. */
|
|
43359
43421
|
submit(task) {
|
|
43360
43422
|
return this.queue.add(() => task());
|
|
43361
43423
|
}
|
|
43424
|
+
/** Rejects queued and future tasks. Tasks already running are allowed to finish. */
|
|
43362
43425
|
stop() {
|
|
43363
43426
|
this.queue.end();
|
|
43364
43427
|
}
|
|
@@ -77161,6 +77224,7 @@ return ${compiler2.callType("value", tagType)}
|
|
|
77161
77224
|
init_process2();
|
|
77162
77225
|
init_buffer();
|
|
77163
77226
|
NBTHelper = class {
|
|
77227
|
+
/** Parses NBT bytes and preserves format and compression metadata. Omit `format` for automatic detection. */
|
|
77164
77228
|
static async fromBuffer(data, format3) {
|
|
77165
77229
|
const buffer2 = Buffer.from(data instanceof Uint8Array ? data : new Uint8Array(data));
|
|
77166
77230
|
const prismarineNbt = await Promise.resolve().then(() => __toESM(require_nbt2()));
|
|
@@ -77247,6 +77311,7 @@ return ${compiler2.callType("value", tagType)}
|
|
|
77247
77311
|
retryDefaults: true
|
|
77248
77312
|
};
|
|
77249
77313
|
_HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
77314
|
+
/** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */
|
|
77250
77315
|
async loadOrRetryWithDefaults(key, parser) {
|
|
77251
77316
|
const direct = await this.load(key, parser);
|
|
77252
77317
|
if (typeof direct !== "undefined") {
|
|
@@ -77304,6 +77369,10 @@ return ${compiler2.callType("value", tagType)}
|
|
|
77304
77369
|
assetBasePath(key) {
|
|
77305
77370
|
return `${key.root ?? this.root ?? AssetLoader.ROOT}/${key.rootType !== void 0 ? key.rootType + "/" : ""}${key.namespace !== void 0 ? key.namespace + "/" : ""}${key.assetType !== void 0 ? key.assetType + "/" : ""}`;
|
|
77306
77371
|
}
|
|
77372
|
+
/**
|
|
77373
|
+
* Creates a hosted source for {@link AssetLoader.addSource}.
|
|
77374
|
+
* Set `options.retryDefaults` to `false` to restrict lookups to the requested namespace and root.
|
|
77375
|
+
*/
|
|
77307
77376
|
constructor(root, options) {
|
|
77308
77377
|
super();
|
|
77309
77378
|
this._root = root;
|
|
@@ -87008,6 +87077,11 @@ return ${compiler2.callType("value", tagType)}
|
|
|
87008
87077
|
init_process2();
|
|
87009
87078
|
init_zip();
|
|
87010
87079
|
BrowserArchiveProxy = class {
|
|
87080
|
+
/**
|
|
87081
|
+
* Opens a ZIP for asset lookup.
|
|
87082
|
+
* @param id - Cache identity for this content. Change it when the pack changes.
|
|
87083
|
+
* A File supplies an identity from its name, size, and modification time when omitted.
|
|
87084
|
+
*/
|
|
87011
87085
|
constructor(blob, id) {
|
|
87012
87086
|
this._blob = blob;
|
|
87013
87087
|
this._reader = new ZipReader(new BlobReader(this._blob));
|
|
@@ -87214,6 +87288,7 @@ return ${compiler2.callType("value", tagType)}
|
|
|
87214
87288
|
dataPackFormat: copyFormat(options.dataPackFormat)
|
|
87215
87289
|
};
|
|
87216
87290
|
}
|
|
87291
|
+
/** Creates a browser ZIP source from a Blob or File. */
|
|
87217
87292
|
static blob(blob, options) {
|
|
87218
87293
|
return new _ArchiveAssetSource(new BrowserArchiveProxy(blob), options);
|
|
87219
87294
|
}
|
|
@@ -87363,6 +87438,7 @@ return ${compiler2.callType("value", tagType)}
|
|
|
87363
87438
|
static get version() {
|
|
87364
87439
|
return this.ROOT.substring(this.ROOT.lastIndexOf("/") + 1);
|
|
87365
87440
|
}
|
|
87441
|
+
/** Selects an mcasset.cloud version, updates the vanilla source, and clears in-memory caches. */
|
|
87366
87442
|
static setVersion(version2) {
|
|
87367
87443
|
this.ROOT = `https://assets.mcasset.cloud/${version2}`;
|
|
87368
87444
|
const source = new HostedAssetSource(this.ROOT, { retryDefaults: false });
|
|
@@ -87396,6 +87472,13 @@ return ${compiler2.callType("value", tagType)}
|
|
|
87396
87472
|
return scope ? `${scope}
|
|
87397
87473
|
${key}` : key;
|
|
87398
87474
|
}
|
|
87475
|
+
/**
|
|
87476
|
+
* Registers a source at the highest priority.
|
|
87477
|
+
* Call {@link Caching.clear} after changing sources to discard previously loaded assets.
|
|
87478
|
+
*
|
|
87479
|
+
* @param key - Name used to replace or remove this source.
|
|
87480
|
+
* @param override - Removes the first source with this name before adding the new one.
|
|
87481
|
+
*/
|
|
87399
87482
|
static addSource(key, source, override = true) {
|
|
87400
87483
|
if (override) {
|
|
87401
87484
|
const existing = this.removeSource(key);
|
|
@@ -87406,6 +87489,7 @@ ${key}` : key;
|
|
|
87406
87489
|
this._SOURCES.unshift({ key, source });
|
|
87407
87490
|
console.log(p7, "Added AssetSource", key);
|
|
87408
87491
|
}
|
|
87492
|
+
/** Removes and returns the first source with this name. Call {@link Caching.clear} to reload assets. */
|
|
87409
87493
|
static removeSource(key) {
|
|
87410
87494
|
const index = this._SOURCES.findIndex((s4) => s4.key === key);
|
|
87411
87495
|
if (index != -1) {
|
|
@@ -87416,6 +87500,7 @@ ${key}` : key;
|
|
|
87416
87500
|
}
|
|
87417
87501
|
return void 0;
|
|
87418
87502
|
}
|
|
87503
|
+
/** Loads from all sources and returns defined results in priority order. Any source failure rejects the call. */
|
|
87419
87504
|
static async getAll(key, parser) {
|
|
87420
87505
|
const sources = [...this._SOURCES];
|
|
87421
87506
|
const results = [];
|
|
@@ -87460,6 +87545,7 @@ ${key}` : key;
|
|
|
87460
87545
|
return void 0;
|
|
87461
87546
|
}
|
|
87462
87547
|
};
|
|
87548
|
+
/** Default asset base URL. Use {@link setVersion} to select a Minecraft version. */
|
|
87463
87549
|
_AssetLoader.ROOT = DEFAULT_ROOT;
|
|
87464
87550
|
_AssetLoader._SOURCES = [];
|
|
87465
87551
|
/** Used when a registered source cannot identify its content, so nothing persists past this session. */
|
|
@@ -87487,6 +87573,7 @@ ${key}` : key;
|
|
|
87487
87573
|
static get PERSISTENT_META_CACHE() {
|
|
87488
87574
|
return this._persistentMetaCache ?? (this._persistentMetaCache = PersistentCache.open("minerender-texturemeta"));
|
|
87489
87575
|
}
|
|
87576
|
+
/** Loads and decodes a texture into a readable canvas, or returns `undefined` when missing. */
|
|
87490
87577
|
static async get(key) {
|
|
87491
87578
|
const keyStr = key.serialize();
|
|
87492
87579
|
const pending = this.preload(key);
|
|
@@ -87504,6 +87591,7 @@ ${key}` : key;
|
|
|
87504
87591
|
throw err2;
|
|
87505
87592
|
}
|
|
87506
87593
|
}
|
|
87594
|
+
/** Fetches and caches encoded texture bytes without decoding the pixels. */
|
|
87507
87595
|
static async preload(key) {
|
|
87508
87596
|
const keyStr = key.serialize();
|
|
87509
87597
|
return Caching.textureAssetCache.get(keyStr, (k4) => {
|
|
@@ -87514,6 +87602,7 @@ ${key}` : key;
|
|
|
87514
87602
|
});
|
|
87515
87603
|
});
|
|
87516
87604
|
}
|
|
87605
|
+
/** Loads a texture's `.mcmeta` file, or returns `undefined` when no metadata file exists. */
|
|
87517
87606
|
static async getMeta(key) {
|
|
87518
87607
|
if (!key.extension || !key.extension.endsWith(".mcmeta")) {
|
|
87519
87608
|
key = Object.assign(new AssetKey("", ""), key);
|
|
@@ -87530,6 +87619,7 @@ ${key}` : key;
|
|
|
87530
87619
|
});
|
|
87531
87620
|
});
|
|
87532
87621
|
}
|
|
87622
|
+
/** Clears persisted texture metadata. Use {@link Caching.clear} to discard in-memory textures and metadata. */
|
|
87533
87623
|
static async clearCache() {
|
|
87534
87624
|
await this.PERSISTENT_META_CACHE.clear();
|
|
87535
87625
|
}
|
|
@@ -87602,6 +87692,7 @@ ${key}` : key;
|
|
|
87602
87692
|
}
|
|
87603
87693
|
return handle;
|
|
87604
87694
|
}
|
|
87695
|
+
/** Starts or resumes the shared tick loop. Repeated calls have no effect. */
|
|
87605
87696
|
static start() {
|
|
87606
87697
|
if (this.interval) return;
|
|
87607
87698
|
this.interval = this.schedule(() => {
|
|
@@ -87624,6 +87715,7 @@ ${key}` : key;
|
|
|
87624
87715
|
_Ticker.fiveSecondTicks = 0;
|
|
87625
87716
|
}, 1e3 * 5);
|
|
87626
87717
|
}
|
|
87718
|
+
/** Pauses the loop while retaining callbacks for a later {@link start}. */
|
|
87627
87719
|
static stop() {
|
|
87628
87720
|
if (this.interval) clearInterval(this.interval);
|
|
87629
87721
|
if (this.oneSecondTicksTracker) clearInterval(this.oneSecondTicksTracker);
|
|
@@ -87632,12 +87724,14 @@ ${key}` : key;
|
|
|
87632
87724
|
this.oneSecondTicksTracker = void 0;
|
|
87633
87725
|
this.fiveSecondTicksTracker = void 0;
|
|
87634
87726
|
}
|
|
87727
|
+
/** Registers a callback, starts the loop if needed, and returns an ID for {@link remove}. */
|
|
87635
87728
|
static add(tick) {
|
|
87636
87729
|
this.start();
|
|
87637
87730
|
const c4 = this.counter++;
|
|
87638
87731
|
this._tickers.set(c4, tick);
|
|
87639
87732
|
return c4;
|
|
87640
87733
|
}
|
|
87734
|
+
/** Removes a callback by ID and stops the timers when no callbacks remain. */
|
|
87641
87735
|
static remove(c4) {
|
|
87642
87736
|
if (typeof c4 === "number") this._tickers.delete(c4);
|
|
87643
87737
|
if (!this._tickers.size) this.stop();
|
|
@@ -87651,6 +87745,7 @@ ${key}` : key;
|
|
|
87651
87745
|
static get tpsFiveSeconds() {
|
|
87652
87746
|
return this.fiveSecondTps;
|
|
87653
87747
|
}
|
|
87748
|
+
/** Stops the loop and removes all registered callbacks. */
|
|
87654
87749
|
static dispose() {
|
|
87655
87750
|
this.stop();
|
|
87656
87751
|
this._tickers.clear();
|
|
@@ -87708,6 +87803,7 @@ ${key}` : key;
|
|
|
87708
87803
|
}
|
|
87709
87804
|
};
|
|
87710
87805
|
}
|
|
87806
|
+
/** Copies pixels for a texture variable from its current atlas rectangle. */
|
|
87711
87807
|
getData(texture) {
|
|
87712
87808
|
const pos = this.positions[texture];
|
|
87713
87809
|
const size = this.sizes[texture];
|
|
@@ -87991,6 +88087,7 @@ ${key}` : key;
|
|
|
87991
88087
|
}
|
|
87992
88088
|
uv.needsUpdate = true;
|
|
87993
88089
|
}
|
|
88090
|
+
/** Returns the shared atlas for a keyed, merged model, creating it on first use. */
|
|
87994
88091
|
static async getAtlas(model) {
|
|
87995
88092
|
const keyStr = model.key.serialize();
|
|
87996
88093
|
return Caching.modelTextureAtlasCache.get(keyStr, (k4) => {
|
|
@@ -88061,6 +88158,11 @@ ${key}` : key;
|
|
|
88061
88158
|
}
|
|
88062
88159
|
return [tl, tr, bl, br];
|
|
88063
88160
|
}
|
|
88161
|
+
/**
|
|
88162
|
+
* Combines model textures and animation metadata into an atlas.
|
|
88163
|
+
* Mapped UVs are stored on copies of the model's elements, available through the returned atlas.
|
|
88164
|
+
* Returns `undefined` for models without a texture map.
|
|
88165
|
+
*/
|
|
88064
88166
|
static async createAtlas(originalModel) {
|
|
88065
88167
|
const textureMap = {};
|
|
88066
88168
|
const metaMap = {};
|
|
@@ -88434,6 +88536,7 @@ ${key}` : key;
|
|
|
88434
88536
|
init_MineRenderError();
|
|
88435
88537
|
init_ModelTextures();
|
|
88436
88538
|
Entities = class {
|
|
88539
|
+
/** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */
|
|
88437
88540
|
static async getEntityList() {
|
|
88438
88541
|
const collect = async (path) => {
|
|
88439
88542
|
const prefix2 = path ? `${path}/` : "";
|
|
@@ -88451,6 +88554,7 @@ ${key}` : key;
|
|
|
88451
88554
|
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
|
|
88452
88555
|
return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
88453
88556
|
}
|
|
88557
|
+
/** Returns selectable geometry-layer names, or an empty list when the model is missing. */
|
|
88454
88558
|
static async getLayerList(modelKey) {
|
|
88455
88559
|
return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
|
|
88456
88560
|
}
|
|
@@ -88458,6 +88562,15 @@ ${key}` : key;
|
|
|
88458
88562
|
static async getPassList(modelKey) {
|
|
88459
88563
|
return (await this.getModelFile(modelKey))?.passes ?? [];
|
|
88460
88564
|
}
|
|
88565
|
+
/**
|
|
88566
|
+
* Loads the layers and textures to pass to {@link MineRenderScene.addEntity}.
|
|
88567
|
+
* By default, selects `main`, unconditional passes, and passes enabled by `options.when`.
|
|
88568
|
+
*
|
|
88569
|
+
* @param modelKey - Dataset model, such as `new BasicAssetKey("minecraft", "zombie")`.
|
|
88570
|
+
* @param textureKey - Texture override for the first selected layer.
|
|
88571
|
+
* @param options - Layer selection, conditional passes, and per-layer texture overrides.
|
|
88572
|
+
* @returns The selected model, or `undefined` when its dataset file is missing.
|
|
88573
|
+
*/
|
|
88461
88574
|
static async getEntity(modelKey, textureKey, options) {
|
|
88462
88575
|
const model = await this.getModelFile(modelKey);
|
|
88463
88576
|
if (!model) return void 0;
|
|
@@ -88503,6 +88616,7 @@ ${key}` : key;
|
|
|
88503
88616
|
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
88504
88617
|
return file?.animations;
|
|
88505
88618
|
}
|
|
88619
|
+
/** Finds a fallback texture using the model path, its directory, and vanilla variant data. */
|
|
88506
88620
|
static async resolveTexture(modelKey) {
|
|
88507
88621
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
88508
88622
|
const root = isAssetKey(modelKey) ? modelKey.root : void 0;
|
|
@@ -88669,12 +88783,14 @@ ${key}` : key;
|
|
|
88669
88783
|
this._animation = void 0;
|
|
88670
88784
|
this._time = 0;
|
|
88671
88785
|
}
|
|
88786
|
+
/** Applies the pose at an absolute playback time. Returns `false` when no clip is active. */
|
|
88672
88787
|
setTime(seconds) {
|
|
88673
88788
|
if (!this._animation) return false;
|
|
88674
88789
|
this._time = seconds;
|
|
88675
88790
|
this.apply();
|
|
88676
88791
|
return true;
|
|
88677
88792
|
}
|
|
88793
|
+
/** Advances playback by elapsed seconds multiplied by the speed passed to {@link play}. */
|
|
88678
88794
|
advance(deltaSeconds) {
|
|
88679
88795
|
return this.setTime(this._time + deltaSeconds * this.speed);
|
|
88680
88796
|
}
|
|
@@ -88715,6 +88831,7 @@ ${key}` : key;
|
|
|
88715
88831
|
if (!this.instanceable.isInstanceActive(this.index, this)) throw new MineRenderError("Instance has been removed");
|
|
88716
88832
|
return this.instanceable;
|
|
88717
88833
|
}
|
|
88834
|
+
/** Releases this placement's slot for reuse. Repeated calls have no effect. */
|
|
88718
88835
|
removeFromScene() {
|
|
88719
88836
|
if (this.instanceable.isInstanceActive(this.index, this)) this.instanceable.removeInstanceAt(this.index);
|
|
88720
88837
|
}
|
|
@@ -88727,9 +88844,11 @@ ${key}` : key;
|
|
|
88727
88844
|
setMatrix(matrix) {
|
|
88728
88845
|
this.activeInstanceable.setMatrixAt(this.index, matrix);
|
|
88729
88846
|
}
|
|
88847
|
+
/** Hides or restores this placement while preserving its transform and allocated slot. */
|
|
88730
88848
|
setVisible(visible) {
|
|
88731
88849
|
this.activeInstanceable.setInstanceVisibleAt(this.index, visible);
|
|
88732
88850
|
}
|
|
88851
|
+
/** Updates the supplied transform components. Positions use scene units and rotations use radians. */
|
|
88733
88852
|
setPositionRotationScale(position, rotation, scale) {
|
|
88734
88853
|
this.activeInstanceable.setPositionRotationScaleAt(this.index, position, rotation, scale);
|
|
88735
88854
|
}
|
|
@@ -88801,6 +88920,7 @@ ${key}` : key;
|
|
|
88801
88920
|
}
|
|
88802
88921
|
async init() {
|
|
88803
88922
|
}
|
|
88923
|
+
/** Marks ancestor scenes for redraw and emits a `change` event. */
|
|
88804
88924
|
notifyDirty() {
|
|
88805
88925
|
this.traverseAncestors((parent) => {
|
|
88806
88926
|
const scene = parent;
|
|
@@ -88836,15 +88956,17 @@ ${key}` : key;
|
|
|
88836
88956
|
return obj;
|
|
88837
88957
|
}
|
|
88838
88958
|
/**
|
|
88839
|
-
*
|
|
88959
|
+
* Finds a named part, such as `head`, without the internal `group:` prefix.
|
|
88960
|
+
* Returns `undefined` when the group does not exist.
|
|
88840
88961
|
*/
|
|
88841
88962
|
getGroupByName(name2) {
|
|
88842
88963
|
return this.getObjectByName(`group:${name2}`);
|
|
88843
88964
|
}
|
|
88844
88965
|
/**
|
|
88845
|
-
*
|
|
88846
|
-
* @param name name
|
|
88847
|
-
* @param visible
|
|
88966
|
+
* Changes a named group's visibility and requests a redraw.
|
|
88967
|
+
* @param name - Part name without the `group:` prefix.
|
|
88968
|
+
* @param visible - Visibility to assign. Omit it to toggle the current value.
|
|
88969
|
+
* @returns The resulting visibility, or `false` if the group does not exist.
|
|
88848
88970
|
*/
|
|
88849
88971
|
toggleGroupVisibility(name2, visible) {
|
|
88850
88972
|
return this.toggleObjectVisibility(this.getGroupByName(name2), visible);
|
|
@@ -88895,15 +89017,16 @@ ${key}` : key;
|
|
|
88895
89017
|
return mesh;
|
|
88896
89018
|
}
|
|
88897
89019
|
/**
|
|
88898
|
-
*
|
|
89020
|
+
* Finds a named mesh without the internal `mesh:` prefix, or returns `undefined`.
|
|
88899
89021
|
*/
|
|
88900
89022
|
getMeshByName(name2) {
|
|
88901
89023
|
return this.getObjectByName(`mesh:${name2}`);
|
|
88902
89024
|
}
|
|
88903
89025
|
/**
|
|
88904
|
-
*
|
|
88905
|
-
* @param name name
|
|
88906
|
-
* @param visible
|
|
89026
|
+
* Changes a named mesh's visibility and requests a redraw.
|
|
89027
|
+
* @param name - Mesh name without the `mesh:` prefix.
|
|
89028
|
+
* @param visible - Visibility to assign. Omit it to toggle the current value.
|
|
89029
|
+
* @returns The resulting visibility, or `false` if the mesh does not exist.
|
|
88907
89030
|
*/
|
|
88908
89031
|
toggleMeshVisibility(name2, visible) {
|
|
88909
89032
|
return this.toggleObjectVisibility(this.getMeshByName(name2), visible);
|
|
@@ -88949,12 +89072,14 @@ ${key}` : key;
|
|
|
88949
89072
|
get isInstanced() {
|
|
88950
89073
|
return this._isInstanced;
|
|
88951
89074
|
}
|
|
89075
|
+
/** Number of live placements, excluding released instance slots. */
|
|
88952
89076
|
get instanceCounter() {
|
|
88953
89077
|
return this._instanceCounter;
|
|
88954
89078
|
}
|
|
88955
89079
|
constructInstanceReference(i4) {
|
|
88956
89080
|
return new InstanceReference(this, i4);
|
|
88957
89081
|
}
|
|
89082
|
+
/** Allocates a placement of this instanced object, reusing a released slot when available. */
|
|
88958
89083
|
nextInstance() {
|
|
88959
89084
|
const mesh = this.instanceMesh;
|
|
88960
89085
|
if (!mesh) throw new MineRenderError("Object is not instanced");
|
|
@@ -89101,6 +89226,7 @@ ${key}` : key;
|
|
|
89101
89226
|
vector.setFromMatrixScale(matrix);
|
|
89102
89227
|
return vector;
|
|
89103
89228
|
}
|
|
89229
|
+
/** Updates supplied transform components. For a shared model, affects every live instance. */
|
|
89104
89230
|
setPositionRotationScale(position, rotation, scale) {
|
|
89105
89231
|
if (this.isInstanced) {
|
|
89106
89232
|
for (const i4 of this.activeInstanceIndices()) {
|
|
@@ -89119,6 +89245,7 @@ ${key}` : key;
|
|
|
89119
89245
|
}
|
|
89120
89246
|
this.notifyDirty();
|
|
89121
89247
|
}
|
|
89248
|
+
/** Sets position in scene units. For a shared model, updates every live instance. */
|
|
89122
89249
|
setPosition(position) {
|
|
89123
89250
|
if (this.isInstanced) {
|
|
89124
89251
|
for (const i4 of this.activeInstanceIndices()) {
|
|
@@ -89136,6 +89263,7 @@ ${key}` : key;
|
|
|
89136
89263
|
return this.position;
|
|
89137
89264
|
}
|
|
89138
89265
|
}
|
|
89266
|
+
/** Sets rotation in radians. For a shared model, updates every live instance. */
|
|
89139
89267
|
setRotation(rotation) {
|
|
89140
89268
|
if (this.isInstanced) {
|
|
89141
89269
|
for (const i4 of this.activeInstanceIndices()) {
|
|
@@ -89153,6 +89281,7 @@ ${key}` : key;
|
|
|
89153
89281
|
return this.rotation;
|
|
89154
89282
|
}
|
|
89155
89283
|
}
|
|
89284
|
+
/** Sets scale factors. For a shared model, updates every live instance. */
|
|
89156
89285
|
setScale(scale) {
|
|
89157
89286
|
if (this.isInstanced) {
|
|
89158
89287
|
for (const i4 of this.activeInstanceIndices()) {
|
|
@@ -89190,6 +89319,7 @@ ${key}` : key;
|
|
|
89190
89319
|
this.notifyDirty();
|
|
89191
89320
|
super.dispose();
|
|
89192
89321
|
}
|
|
89322
|
+
/** Releases instance slots and removes children, disposing children that implement Disposable. */
|
|
89193
89323
|
disposeAndRemoveAllChildren() {
|
|
89194
89324
|
if (this.instanceMesh) {
|
|
89195
89325
|
if (this._scene) this._scene.stats.instanceCount -= this.instanceReferences.size;
|
|
@@ -89212,6 +89342,7 @@ ${key}` : key;
|
|
|
89212
89342
|
}
|
|
89213
89343
|
this.notifyDirty();
|
|
89214
89344
|
}
|
|
89345
|
+
/** Detaches the object from its parent and requests a redraw. */
|
|
89215
89346
|
removeFromScene() {
|
|
89216
89347
|
this.notifyDirty();
|
|
89217
89348
|
this.removeFromParent();
|
|
@@ -89370,12 +89501,15 @@ ${key}` : key;
|
|
|
89370
89501
|
if (this.animationPlayers.length) this.notifyDirty();
|
|
89371
89502
|
}
|
|
89372
89503
|
//</editor-fold>
|
|
89504
|
+
/** Finds a selected draw by its layer key, such as `main` or `main#2`, or returns `undefined`. */
|
|
89373
89505
|
getLayerGroup(name2) {
|
|
89374
89506
|
return super.getGroupByName(`layer:${name2}`);
|
|
89375
89507
|
}
|
|
89508
|
+
/** Finds a part name without `group:`. Supply `layerName` to restrict the search to one draw. */
|
|
89376
89509
|
getGroupByName(name2, layerName) {
|
|
89377
89510
|
return layerName === void 0 ? super.getGroupByName(name2) : this.getLayerGroup(layerName)?.getObjectByName(`group:${name2}`);
|
|
89378
89511
|
}
|
|
89512
|
+
/** Finds a mesh name without `mesh:`. Supply `layerName` to restrict the search to one draw. */
|
|
89379
89513
|
getMeshByName(name2, layerName) {
|
|
89380
89514
|
return layerName === void 0 ? super.getMeshByName(name2) : this.getLayerGroup(layerName)?.getObjectByName(`mesh:${name2}`);
|
|
89381
89515
|
}
|
|
@@ -90044,6 +90178,7 @@ ${key}` : key;
|
|
|
90044
90178
|
init_three_module();
|
|
90045
90179
|
init_CubeFace();
|
|
90046
90180
|
ModelCulling = class {
|
|
90181
|
+
/** Rotates a world-direction bit mask into model space. Bits follow {@link CUBE_FACES}. */
|
|
90047
90182
|
static toLocalMask(worldMask, rotation) {
|
|
90048
90183
|
let localMask = 0;
|
|
90049
90184
|
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
@@ -90054,6 +90189,7 @@ ${key}` : key;
|
|
|
90054
90189
|
}
|
|
90055
90190
|
return localMask;
|
|
90056
90191
|
}
|
|
90192
|
+
/** Whether a model fills one block with opaque faces and can hide adjacent block faces. */
|
|
90057
90193
|
static isOpaqueFullCube(atlas) {
|
|
90058
90194
|
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
90059
90195
|
const element = atlas.model.elements[0];
|
|
@@ -93935,6 +94071,7 @@ ${shader.fragmentShader}`.replace(
|
|
|
93935
94071
|
static createBox(key) {
|
|
93936
94072
|
return new Mesh(Geometries.getBox(key.geometry), Materials.getImage(key.material));
|
|
93937
94073
|
}
|
|
94074
|
+
/** Returns a shared Mesh object. Use {@link createBox} for a mesh with its own transform and parent. */
|
|
93938
94075
|
static getBox(key) {
|
|
93939
94076
|
const keyStr = serializeMeshKey(key);
|
|
93940
94077
|
return Caching.boxMeshCache.get(keyStr, (k4) => {
|
|
@@ -94083,6 +94220,7 @@ ${shader.fragmentShader}`.replace(
|
|
|
94083
94220
|
init_ModelTextures();
|
|
94084
94221
|
init_Caching();
|
|
94085
94222
|
var Fonts = class {
|
|
94223
|
+
/** Combines font definitions in source-priority order. Unsupported Unihex and TrueType providers are skipped. */
|
|
94086
94224
|
static async get(key = "minecraft:default") {
|
|
94087
94225
|
const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
|
|
94088
94226
|
return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
|
|
@@ -97334,6 +97472,13 @@ property list uchar int vertex_index
|
|
|
97334
97472
|
});
|
|
97335
97473
|
return layers;
|
|
97336
97474
|
}
|
|
97475
|
+
/**
|
|
97476
|
+
* Calculates a slot's top-left position in GUI pixels.
|
|
97477
|
+
* @param slot - Zero-based slot index, or `[column, row]`.
|
|
97478
|
+
* @param origin - Position of the first slot.
|
|
97479
|
+
* @param offset - Horizontal and vertical spacing between slot origins, in pixels.
|
|
97480
|
+
* @param rowSize - Slots per row when `slot` is an index.
|
|
97481
|
+
*/
|
|
97337
97482
|
static inventorySlot(slot, origin = [0, 0], offset = [18, 18], rowSize = 9) {
|
|
97338
97483
|
const [column, row] = typeof slot === "number" ? [slot % rowSize, Math.floor(slot / rowSize)] : slot;
|
|
97339
97484
|
return [origin[0] + column * offset[0], origin[1] + row * offset[1]];
|
|
@@ -98018,6 +98163,7 @@ property list uchar int vertex_index
|
|
|
98018
98163
|
appendTo(el) {
|
|
98019
98164
|
el.append(this.statsContainer);
|
|
98020
98165
|
}
|
|
98166
|
+
/** Stops the refresh timer and removes the panel from the page. */
|
|
98021
98167
|
dispose() {
|
|
98022
98168
|
clearInterval(this.interval);
|
|
98023
98169
|
this.interval = void 0;
|
|
@@ -98050,6 +98196,7 @@ property list uchar int vertex_index
|
|
|
98050
98196
|
this.isInstanceManager = true;
|
|
98051
98197
|
this.instanceCache = {};
|
|
98052
98198
|
}
|
|
98199
|
+
/** Allocates a new placement of a cached model, or returns `undefined` if the key is unknown. */
|
|
98053
98200
|
async get(key) {
|
|
98054
98201
|
if (key in this.instanceCache) {
|
|
98055
98202
|
console.debug(p12, "key in cache", key);
|
|
@@ -98057,6 +98204,7 @@ property list uchar int vertex_index
|
|
|
98057
98204
|
}
|
|
98058
98205
|
return void 0;
|
|
98059
98206
|
}
|
|
98207
|
+
/** Allocates a placement, calling the supplier once when the shared model is first needed. */
|
|
98060
98208
|
async getOrCreate(key, supplier) {
|
|
98061
98209
|
if (key in this.instanceCache) {
|
|
98062
98210
|
return await this.get(key);
|
|
@@ -98073,6 +98221,7 @@ property list uchar int vertex_index
|
|
|
98073
98221
|
throw error2;
|
|
98074
98222
|
}
|
|
98075
98223
|
}
|
|
98224
|
+
/** Forgets cached models without disposing them or releasing their existing placements. */
|
|
98076
98225
|
reset() {
|
|
98077
98226
|
for (let instanceCacheKey in this.instanceCache) {
|
|
98078
98227
|
delete this.instanceCache[instanceCacheKey];
|
|
@@ -98161,6 +98310,7 @@ property list uchar int vertex_index
|
|
|
98161
98310
|
});
|
|
98162
98311
|
}
|
|
98163
98312
|
var BlockStateResolver = class {
|
|
98313
|
+
/** Loads vanilla property defaults, falling back to preview values inferred from the blockstate file. */
|
|
98164
98314
|
static async defaults(blockState) {
|
|
98165
98315
|
const defaults = blockState.key ? await BlockStates.getDefaultState(blockState.key) : void 0;
|
|
98166
98316
|
const state = {};
|
|
@@ -98180,9 +98330,11 @@ property list uchar int vertex_index
|
|
|
98180
98330
|
}
|
|
98181
98331
|
return state;
|
|
98182
98332
|
}
|
|
98333
|
+
/** Selects matching models. Supply `choose` to control selection within each alternatives array. */
|
|
98183
98334
|
static select(blockState, state, choose = this.choose) {
|
|
98184
98335
|
return this.matching(blockState, state).map(choose);
|
|
98185
98336
|
}
|
|
98337
|
+
/** Returns matching model groups before choosing weighted alternatives. */
|
|
98186
98338
|
static matching(blockState, state) {
|
|
98187
98339
|
const out = [];
|
|
98188
98340
|
if (blockState.variants) {
|
|
@@ -98206,6 +98358,7 @@ property list uchar int vertex_index
|
|
|
98206
98358
|
}
|
|
98207
98359
|
return out;
|
|
98208
98360
|
}
|
|
98361
|
+
/** Selects a random alternative using positive integer weights, each defaulting to 1. */
|
|
98209
98362
|
static choose(variants) {
|
|
98210
98363
|
if (!Array.isArray(variants)) return variants;
|
|
98211
98364
|
if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
|
|
@@ -98223,6 +98376,7 @@ property list uchar int vertex_index
|
|
|
98223
98376
|
}
|
|
98224
98377
|
return variants[variants.length - 1];
|
|
98225
98378
|
}
|
|
98379
|
+
/** Converts blockstate rotations in degrees into the Euler rotation used by model rendering. */
|
|
98226
98380
|
static rotation(variant) {
|
|
98227
98381
|
const rotation = new Euler();
|
|
98228
98382
|
if (typeof variant.x !== "undefined") {
|
|
@@ -98515,6 +98669,7 @@ property list uchar int vertex_index
|
|
|
98515
98669
|
}
|
|
98516
98670
|
this.notifyDirty();
|
|
98517
98671
|
}
|
|
98672
|
+
/** Selected property values. Use {@link setState} to change properties and rebuild the rendered models. */
|
|
98518
98673
|
get state() {
|
|
98519
98674
|
return this._state;
|
|
98520
98675
|
}
|
|
@@ -98614,6 +98769,7 @@ property list uchar int vertex_index
|
|
|
98614
98769
|
obj.setPosition(this.position);
|
|
98615
98770
|
return obj;
|
|
98616
98771
|
}
|
|
98772
|
+
/** Clears selected properties and rebuilds models without reapplying property defaults. */
|
|
98617
98773
|
async resetState() {
|
|
98618
98774
|
this._previousState = this._state;
|
|
98619
98775
|
this._state = {};
|
|
@@ -100536,6 +100692,11 @@ property list uchar int vertex_index
|
|
|
100536
100692
|
init_process2();
|
|
100537
100693
|
init_MineRenderError();
|
|
100538
100694
|
var StructureParser = class {
|
|
100695
|
+
/**
|
|
100696
|
+
* Parses decoded NBT, omitting air blocks.
|
|
100697
|
+
* @param _nbt - Structure data decoded by {@link NBTHelper.fromBuffer}.
|
|
100698
|
+
* @param paletteIndex - Palette to select when the structure has several. Defaults to 0.
|
|
100699
|
+
*/
|
|
100539
100700
|
static async parse(_nbt, paletteIndex) {
|
|
100540
100701
|
const nbt = _nbt.value;
|
|
100541
100702
|
let palette;
|
|
@@ -101399,6 +101560,7 @@ property list uchar int vertex_index
|
|
|
101399
101560
|
// src/skin/SkinTextures.ts
|
|
101400
101561
|
init_Textures();
|
|
101401
101562
|
var SkinTextures = class {
|
|
101563
|
+
/** Loads a skin URL. Pass `legacy` to override layout detection from the image dimensions. */
|
|
101402
101564
|
static async get(src, legacy) {
|
|
101403
101565
|
const image = await SkinImage.getData(src);
|
|
101404
101566
|
const scale = image.width / 64;
|
|
@@ -101575,6 +101737,14 @@ property list uchar int vertex_index
|
|
|
101575
101737
|
}
|
|
101576
101738
|
}
|
|
101577
101739
|
}
|
|
101740
|
+
/**
|
|
101741
|
+
* Loads a skin texture, detecting slim arms and legacy layouts by default.
|
|
101742
|
+
* To override detection, set `slim` or `legacy` in the options passed to
|
|
101743
|
+
* `new SkinObject(options)` or `scene.addSkin(src, options)`.
|
|
101744
|
+
* Use {@link setSlim} or {@link setLegacy} to change these settings later.
|
|
101745
|
+
*
|
|
101746
|
+
* @param src - URL of the skin texture.
|
|
101747
|
+
*/
|
|
101578
101748
|
async setSkinTexture(src) {
|
|
101579
101749
|
if (typeof src === "undefined") return;
|
|
101580
101750
|
this.skinTextureSrc = src;
|
|
@@ -101723,6 +101893,7 @@ property list uchar int vertex_index
|
|
|
101723
101893
|
this.stats.sceneObjectCount += change;
|
|
101724
101894
|
}
|
|
101725
101895
|
}
|
|
101896
|
+
/** Initializes each object before attaching it to the scene. */
|
|
101726
101897
|
async initAndAdd(...object2) {
|
|
101727
101898
|
this.dirty = true;
|
|
101728
101899
|
for (let obj of object2) {
|
|
@@ -101758,13 +101929,33 @@ property list uchar int vertex_index
|
|
|
101758
101929
|
return obj;
|
|
101759
101930
|
}
|
|
101760
101931
|
}
|
|
101932
|
+
/**
|
|
101933
|
+
* Adds a model loaded with {@link Models.getMerged}.
|
|
101934
|
+
* Set `options.instanceMeshes` to `false` to create a separate ModelObject.
|
|
101935
|
+
*
|
|
101936
|
+
* @param parent - Object to attach the model to. Defaults to this scene.
|
|
101937
|
+
* @returns The model, or a reference to one placement of a shared model.
|
|
101938
|
+
*/
|
|
101761
101939
|
async addModel(model, options, parent = this) {
|
|
101762
101940
|
options = { ...options, tints: await ItemTints.get(model, options?.tints) };
|
|
101763
101941
|
return this.addSceneObject(model, () => new ModelObject(model, options), options, parent);
|
|
101764
101942
|
}
|
|
101943
|
+
/**
|
|
101944
|
+
* Adds the models selected by a blockstate loaded with {@link BlockStates.get}.
|
|
101945
|
+
* Set `options.initialState` to choose block properties such as `facing` or `axis`.
|
|
101946
|
+
* Use the returned object's `setPosition` method to move all of its model parts.
|
|
101947
|
+
*/
|
|
101765
101948
|
async addBlock(blockState, options, parent = this) {
|
|
101766
101949
|
return this.addSceneObject(blockState, () => new BlockObject(blockState, options), options, parent);
|
|
101767
101950
|
}
|
|
101951
|
+
/**
|
|
101952
|
+
* Loads a skin and adds an initialized player model.
|
|
101953
|
+
*
|
|
101954
|
+
* @param skin - Texture URL, such as one returned by {@link Skins.fromUuidOrUsername}.
|
|
101955
|
+
* Omit it to assign a texture later with {@link SkinObject.setSkinTexture}.
|
|
101956
|
+
* @param options - Player settings, including `slim` and `legacy` detection overrides.
|
|
101957
|
+
* @param parent - Object to attach the player to. Defaults to this scene.
|
|
101958
|
+
*/
|
|
101768
101959
|
async addSkin(skin, options, parent = this) {
|
|
101769
101960
|
this.dirty = true;
|
|
101770
101961
|
const obj = new SkinObject(options);
|
|
@@ -101776,9 +101967,14 @@ property list uchar int vertex_index
|
|
|
101776
101967
|
parent.add(obj);
|
|
101777
101968
|
return obj;
|
|
101778
101969
|
}
|
|
101970
|
+
/** Adds an entity loaded with {@link Entities.getEntity}, using its selected layers and textures. */
|
|
101779
101971
|
async addEntity(entity, options, parent = this) {
|
|
101780
101972
|
return this.addSceneObject(entity, () => new EntityObject(entity, options), options, parent);
|
|
101781
101973
|
}
|
|
101974
|
+
/**
|
|
101975
|
+
* Adds GUI layers in draw order. One GUI pixel equals one scene unit.
|
|
101976
|
+
* Layer positions start at the top left, with positive GUI y pointing down.
|
|
101977
|
+
*/
|
|
101782
101978
|
async addGui(layers, options, parent = this) {
|
|
101783
101979
|
const obj = new GuiObject(layers, options);
|
|
101784
101980
|
obj.scene = this;
|
|
@@ -104580,6 +104776,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104580
104776
|
get element() {
|
|
104581
104777
|
return this._element;
|
|
104582
104778
|
}
|
|
104779
|
+
/** Attaches the canvas to an element and sizes it to that element's dimensions. */
|
|
104583
104780
|
appendTo(element) {
|
|
104584
104781
|
if (this._disposed) return;
|
|
104585
104782
|
this._element = element;
|
|
@@ -104607,6 +104804,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104607
104804
|
events.add(changeEvent2);
|
|
104608
104805
|
dispatcher.addEventListener(changeEvent2, this._changeListener);
|
|
104609
104806
|
}
|
|
104807
|
+
/** Updates the camera and canvas size. Width and height are in CSS pixels. */
|
|
104610
104808
|
resize(width, height) {
|
|
104611
104809
|
if (this._disposed) return;
|
|
104612
104810
|
if (isPerspectiveCamera(this.camera)) {
|
|
@@ -104645,12 +104843,14 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104645
104843
|
if (this._frameCallbacks.get(callback) === subscription) this._frameCallbacks.delete(callback);
|
|
104646
104844
|
};
|
|
104647
104845
|
}
|
|
104846
|
+
/** Starts or resumes the animation loop and registered frame callbacks. */
|
|
104648
104847
|
start() {
|
|
104649
104848
|
if (this._disposed) return;
|
|
104650
104849
|
this.stop();
|
|
104651
104850
|
this._running = true;
|
|
104652
104851
|
if (!this._inAnimationLoop) this.renderer.setAnimationLoop(this._animationLoop);
|
|
104653
104852
|
}
|
|
104853
|
+
/** Pauses rendering and frame callbacks. Call {@link start} to resume. */
|
|
104654
104854
|
stop() {
|
|
104655
104855
|
if (this._disposed) return;
|
|
104656
104856
|
this._running = false;
|
|
@@ -104759,12 +104959,15 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104759
104959
|
const canvas = trim ? trimCanvas(this.renderer.domElement) : this.renderer.domElement;
|
|
104760
104960
|
return canvas.toDataURL(mime, quality);
|
|
104761
104961
|
}
|
|
104962
|
+
/** Exports visible scene meshes as OBJ text, without texture images. */
|
|
104762
104963
|
toObj() {
|
|
104763
104964
|
return SceneExporter.toObj(this.scene);
|
|
104764
104965
|
}
|
|
104966
|
+
/** Exports visible scene meshes as PLY. Set `options.binary` for an ArrayBuffer. */
|
|
104765
104967
|
toPLY(options) {
|
|
104766
104968
|
return SceneExporter.toPLY(this.scene, options);
|
|
104767
104969
|
}
|
|
104970
|
+
/** Exports a static textured scene in the browser. Set `options.binary` for GLB output. */
|
|
104768
104971
|
toGLTF(options) {
|
|
104769
104972
|
return SceneExporter.toGLTF(this.scene, options);
|
|
104770
104973
|
}
|
|
@@ -104859,12 +105062,14 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104859
105062
|
init_Requests();
|
|
104860
105063
|
var Skins = class {
|
|
104861
105064
|
//<editor-fold desc="Skins">
|
|
105065
|
+
/** Returns a skin URL for {@link MineRenderScene.addSkin}, or `undefined` if name lookup fails. */
|
|
104862
105066
|
static async fromUuidOrUsername(uuidOrUsername) {
|
|
104863
105067
|
if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
|
|
104864
105068
|
return this.fromUuid(uuidOrUsername);
|
|
104865
105069
|
}
|
|
104866
105070
|
return this.fromUsername(uuidOrUsername);
|
|
104867
105071
|
}
|
|
105072
|
+
/** Builds a proxy URL for a UUID without downloading or checking the skin. */
|
|
104868
105073
|
static async fromUuid(uuid) {
|
|
104869
105074
|
return this.getMcProxySkinUrl(uuid);
|
|
104870
105075
|
}
|
|
@@ -104876,6 +105081,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104876
105081
|
return void 0;
|
|
104877
105082
|
});
|
|
104878
105083
|
}
|
|
105084
|
+
/** Looks up a saved MineSkin skin and returns its texture URL, or `undefined` on lookup failure. */
|
|
104879
105085
|
static async fromMineSkin(mineskinId) {
|
|
104880
105086
|
return this.getMineSkin(mineskinId).then((mineskin) => {
|
|
104881
105087
|
if (mineskin) {
|
|
@@ -104886,12 +105092,14 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104886
105092
|
}
|
|
104887
105093
|
//</editor-fold>
|
|
104888
105094
|
//<editor-fold desc="Capes">
|
|
105095
|
+
/** Resolves a player's Minecraft cape URL for {@link SkinObject.setCapeTexture}. */
|
|
104889
105096
|
static async capeFromUuidOrUsername(uuidOrUsername) {
|
|
104890
105097
|
if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
|
|
104891
105098
|
return this.capeFromUuid(uuidOrUsername);
|
|
104892
105099
|
}
|
|
104893
105100
|
return this.capeFromUsername(uuidOrUsername);
|
|
104894
105101
|
}
|
|
105102
|
+
/** Builds a proxy URL without checking whether the player has a cape. */
|
|
104895
105103
|
static async capeFromUuid(uuid) {
|
|
104896
105104
|
return this.getMcProxyCapeUrl(uuid);
|
|
104897
105105
|
}
|
|
@@ -105068,16 +105276,19 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105068
105276
|
this.freeIds = [];
|
|
105069
105277
|
this.nbt = /* @__PURE__ */ new Map();
|
|
105070
105278
|
}
|
|
105279
|
+
/** Returns a detached copy of a cell, or `undefined` for air. Indices range from 0 to 4095. */
|
|
105071
105280
|
get(index) {
|
|
105072
105281
|
_ChunkData.validateIndex(index);
|
|
105073
105282
|
const entry = this.palette[this.indices[index]];
|
|
105074
105283
|
return entry ? _ChunkData.copyBlock(entry.state, this.nbt.get(index)) : void 0;
|
|
105075
105284
|
}
|
|
105285
|
+
/** Captures a cell's data and returns a copy-producing reader that survives later cell changes. */
|
|
105076
105286
|
snapshot(index) {
|
|
105077
105287
|
_ChunkData.validateIndex(index);
|
|
105078
105288
|
const entry = this.palette[this.indices[index]];
|
|
105079
105289
|
return entry ? _ChunkData.copyBlock.bind(void 0, entry.state, this.nbt.get(index)) : void 0;
|
|
105080
105290
|
}
|
|
105291
|
+
/** Copies block data into a cell. An omitted block or an air block clears the cell. */
|
|
105081
105292
|
set(index, block) {
|
|
105082
105293
|
_ChunkData.validateIndex(index);
|
|
105083
105294
|
let state;
|
|
@@ -105142,15 +105353,23 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105142
105353
|
|
|
105143
105354
|
// src/world/AnvilParser.ts
|
|
105144
105355
|
var AnvilParser = class {
|
|
105356
|
+
/** Lists occupied chunk positions within the region, using local coordinates from 0 to 31. */
|
|
105145
105357
|
static getChunkList(data) {
|
|
105146
105358
|
return this.locations(this.bytes(data)).map(({ x: x4, z: z4 }) => ({ x: x4, z: z4 }));
|
|
105147
105359
|
}
|
|
105360
|
+
/** Decodes all stored chunks. Gzip, zlib, and uncompressed payloads are supported. */
|
|
105148
105361
|
static async parse(data) {
|
|
105149
105362
|
const bytes = this.bytes(data);
|
|
105150
105363
|
const chunks = [];
|
|
105151
105364
|
for (const location of this.locations(bytes)) chunks.push(await this.readChunk(bytes, location));
|
|
105152
105365
|
return { chunks };
|
|
105153
105366
|
}
|
|
105367
|
+
/**
|
|
105368
|
+
* Decodes one chunk for {@link MineRenderWorld.placeChunk}.
|
|
105369
|
+
* @param localX - Chunk x within the region, from 0 to 31.
|
|
105370
|
+
* @param localZ - Chunk z within the region, from 0 to 31.
|
|
105371
|
+
* @returns The chunk with absolute coordinates, or `undefined` if the region has no chunk there.
|
|
105372
|
+
*/
|
|
105154
105373
|
static async parseChunk(data, localX, localZ) {
|
|
105155
105374
|
if (![localX, localZ].every((value) => Number.isInteger(value) && value >= 0 && value < 32)) {
|
|
105156
105375
|
throw new RangeError("Region-local chunk coordinates must be integers from 0 to 31");
|
|
@@ -105369,6 +105588,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105369
105588
|
this.templates = /* @__PURE__ */ new Set();
|
|
105370
105589
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("maxAtlasSize must be a positive integer");
|
|
105371
105590
|
}
|
|
105591
|
+
/** Returns a cube template, or `undefined` when the block requires an individual render object. */
|
|
105372
105592
|
async get(blockState, properties = {}) {
|
|
105373
105593
|
if (!blockState.variants || blockState.multipart) return void 0;
|
|
105374
105594
|
let states = this.states.get(blockState);
|
|
@@ -105422,6 +105642,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105422
105642
|
}
|
|
105423
105643
|
return { variants, templates };
|
|
105424
105644
|
}
|
|
105645
|
+
/** Disposes prepared geometry and clears this world's template caches. */
|
|
105425
105646
|
clear() {
|
|
105426
105647
|
for (const template of this.templates) template.geometry.dispose();
|
|
105427
105648
|
this.templates.clear();
|
|
@@ -105472,6 +105693,13 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105472
105693
|
this.validatePosBounds(posOrX);
|
|
105473
105694
|
await this.getChunkAt(posOrX)?.setBlockVisibleAt(posOrX, yOrVisible);
|
|
105474
105695
|
}
|
|
105696
|
+
/**
|
|
105697
|
+
* Places a structure's blocks at their stored positions, then refreshes neighboring faces.
|
|
105698
|
+
* Entity NBT is retained by the structure but is not rendered.
|
|
105699
|
+
*
|
|
105700
|
+
* @param useBatches - Uses bounded batches by default. Set to `false` for sequential placement.
|
|
105701
|
+
* @param executor - Optional queue for batched placement. The caller remains responsible for stopping it.
|
|
105702
|
+
*/
|
|
105475
105703
|
async placeMultiBlock(multiblock, useBatches = true, executor) {
|
|
105476
105704
|
const changes = /* @__PURE__ */ new Map();
|
|
105477
105705
|
try {
|
|
@@ -105568,6 +105796,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105568
105796
|
});
|
|
105569
105797
|
}
|
|
105570
105798
|
}
|
|
105799
|
+
/** Removes all chunks and releases their block placements and section meshes. */
|
|
105571
105800
|
async clear() {
|
|
105572
105801
|
await this.culling;
|
|
105573
105802
|
const chunks = [...this._chunks.values()];
|
|
@@ -105653,9 +105882,11 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105653
105882
|
}
|
|
105654
105883
|
return chunk;
|
|
105655
105884
|
}
|
|
105885
|
+
/** Returns the loaded chunk containing a world block position, without creating a chunk. */
|
|
105656
105886
|
getChunkAt(pos) {
|
|
105657
105887
|
return this._chunks.get(this.worldPosToChunkKey(pos));
|
|
105658
105888
|
}
|
|
105889
|
+
/** Converts block coordinates to scene units by multiplying each component by 16. */
|
|
105659
105890
|
static worldToScenePosition(pos) {
|
|
105660
105891
|
return new Vector3(
|
|
105661
105892
|
pos.x * 16,
|
|
@@ -105663,6 +105894,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105663
105894
|
pos.z * 16
|
|
105664
105895
|
);
|
|
105665
105896
|
}
|
|
105897
|
+
/** Converts scene units to block coordinates without rounding to an integer block. */
|
|
105666
105898
|
static sceneToWorldPosition(pos) {
|
|
105667
105899
|
return new Vector3(
|
|
105668
105900
|
pos.x / 16,
|
|
@@ -105698,6 +105930,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105698
105930
|
super(...arguments);
|
|
105699
105931
|
this.ownedMeshes = [];
|
|
105700
105932
|
}
|
|
105933
|
+
/** Builds section-local meshes from visible cube faces. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
105701
105934
|
static build(entries, maxAtlasSize = 2048) {
|
|
105702
105935
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
105703
105936
|
const visible = entries.filter((entry) => entry.template.cullFaces.some((direction) => !(entry.cullMask & direction)));
|
|
@@ -105842,7 +106075,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105842
106075
|
return this.setBlockInChunkAt(pos, block, worldPos);
|
|
105843
106076
|
}
|
|
105844
106077
|
/**
|
|
105845
|
-
*
|
|
106078
|
+
* Places a block at integer chunk-local coordinates from 0 to 15.
|
|
105846
106079
|
*/
|
|
105847
106080
|
async setBlockInChunkAt(pos, block, worldPos, onBlocksChanged = this.onBlocksChanged) {
|
|
105848
106081
|
if (typeof worldPos === "undefined") {
|
|
@@ -105891,6 +106124,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105891
106124
|
await onBlocksChanged?.([worldPos]);
|
|
105892
106125
|
}
|
|
105893
106126
|
}
|
|
106127
|
+
/** Changes visibility at world block coordinates while preserving the block's data. */
|
|
105894
106128
|
async setBlockVisibleAt(pos, visible) {
|
|
105895
106129
|
const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
|
|
105896
106130
|
const block = this.renderedBlocks.get(index);
|
|
@@ -105944,6 +106178,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105944
106178
|
this.scene.dirty = true;
|
|
105945
106179
|
this.meshDirty = false;
|
|
105946
106180
|
}
|
|
106181
|
+
/** Removes stored blocks and their render objects, then notifies the owning world of changed positions. */
|
|
105947
106182
|
async clear(onBlocksChanged = this.onBlocksChanged) {
|
|
105948
106183
|
const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
105949
106184
|
new Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
@@ -105964,6 +106199,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105964
106199
|
static isAir(block) {
|
|
105965
106200
|
return ChunkData.isAir(block);
|
|
105966
106201
|
}
|
|
106202
|
+
/** Maps chunk-local coordinates from 0 to 15 to a storage index, with x varying fastest, then z, then y. */
|
|
105967
106203
|
static chunkPosToBlockIndex(pos) {
|
|
105968
106204
|
if ([pos.x, pos.y, pos.z].some((value) => !Number.isInteger(value) || value < 0 || value >= 16)) {
|
|
105969
106205
|
throw new RangeError("Block coordinates must be integers from 0 to 15 within a chunk");
|