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/browser/index.js
CHANGED
|
@@ -65,6 +65,7 @@ var init_PersistentCache = __esm({
|
|
|
65
65
|
constructor(backing) {
|
|
66
66
|
this.backing = backing;
|
|
67
67
|
}
|
|
68
|
+
/** Opens a named store in the active environment using the current cache schema version. */
|
|
68
69
|
static open(name) {
|
|
69
70
|
return Env.provider.openCache(name, _PersistentCache.VERSION);
|
|
70
71
|
}
|
|
@@ -263,6 +264,7 @@ var init_Caching = __esm({
|
|
|
263
264
|
this.fontCache
|
|
264
265
|
];
|
|
265
266
|
}
|
|
267
|
+
/** Invalidates in-memory entries so later lookups reload them. Persisted entries are retained. */
|
|
266
268
|
static clear() {
|
|
267
269
|
for (const cache of this.all) {
|
|
268
270
|
cache.invalidateAll();
|
|
@@ -328,6 +330,7 @@ var init_Geometries = __esm({
|
|
|
328
330
|
}
|
|
329
331
|
return geometry;
|
|
330
332
|
}
|
|
333
|
+
/** Returns shared geometry. Use {@link createBox} when the caller needs to modify or dispose it independently. */
|
|
331
334
|
static getBox(key) {
|
|
332
335
|
const keyStr = serializeBoxGeometryKey(key);
|
|
333
336
|
return Caching.boxGeometryCache.get(keyStr, (k) => {
|
|
@@ -505,12 +508,15 @@ var init_Requests = __esm({
|
|
|
505
508
|
}
|
|
506
509
|
};
|
|
507
510
|
Requests = class {
|
|
511
|
+
/** Queues a general request. Set `request.signal` to cancel it and `request.timeout` to limit each attempt. */
|
|
508
512
|
static genericRequest(request) {
|
|
509
513
|
return this.genericQueue.request(request);
|
|
510
514
|
}
|
|
515
|
+
/** Queues a request separately from general traffic, using the configured asset base URL for relative paths. */
|
|
511
516
|
static mcAssetRequest(request) {
|
|
512
517
|
return this.mcAssetRequestQueue.request(request);
|
|
513
518
|
}
|
|
519
|
+
/** Sets the base URL for relative asset requests. Use {@link AssetLoader.setVersion} to change Minecraft versions. */
|
|
514
520
|
static setMcAssetRoot(root) {
|
|
515
521
|
this.mcAssetRequestQueue.baseURL = root;
|
|
516
522
|
}
|
|
@@ -565,6 +571,7 @@ var init_WrappedImage = __esm({
|
|
|
565
571
|
}
|
|
566
572
|
return false;
|
|
567
573
|
}
|
|
574
|
+
/** Whether the dimensions form a vertical strip of square frames, without consulting `.mcmeta`. */
|
|
568
575
|
get animated() {
|
|
569
576
|
return this.height > this.width && this.height % this.width === 0;
|
|
570
577
|
}
|
|
@@ -611,6 +618,7 @@ var init_ImageLoader = __esm({
|
|
|
611
618
|
static _createImage() {
|
|
612
619
|
return createImage();
|
|
613
620
|
}
|
|
621
|
+
/** Resolves when an image URL has decoded, or rejects if decoding fails. */
|
|
614
622
|
static async loadAsync(src) {
|
|
615
623
|
return new Promise((resolve, reject) => {
|
|
616
624
|
const image = this._createImage();
|
|
@@ -619,6 +627,7 @@ var init_ImageLoader = __esm({
|
|
|
619
627
|
image.src = src;
|
|
620
628
|
});
|
|
621
629
|
}
|
|
630
|
+
/** Returns an image immediately. Use the callbacks to observe loading, or await {@link loadAsync}. */
|
|
622
631
|
static loadElement(src, onload, onerr) {
|
|
623
632
|
const image = this._createImage();
|
|
624
633
|
if (onload)
|
|
@@ -646,6 +655,7 @@ var init_ImageLoader = __esm({
|
|
|
646
655
|
throw err;
|
|
647
656
|
}
|
|
648
657
|
}
|
|
658
|
+
/** Decodes the supplied bytes into a canvas without fetching the source URL again. */
|
|
649
659
|
static async infoToCanvasData(info) {
|
|
650
660
|
const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
|
|
651
661
|
const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
|
|
@@ -662,12 +672,14 @@ var init_ImageLoader = __esm({
|
|
|
662
672
|
const image = await this.infoToCanvasData(info);
|
|
663
673
|
return image.data.getImageData(0, 0, image.width, image.height);
|
|
664
674
|
}
|
|
675
|
+
/** Returns cached RGBA pixels for an image URL or data URL. Failed loads can be retried. */
|
|
665
676
|
static async getData(src) {
|
|
666
677
|
const keyStr = serializeImageKey({ src });
|
|
667
678
|
return await Caching.imageDataCache.get(keyStr, (k) => {
|
|
668
679
|
return _ImageLoader.loadData(src);
|
|
669
680
|
});
|
|
670
681
|
}
|
|
682
|
+
/** Returns a cached canvas context and dimensions for an image URL or data URL. */
|
|
671
683
|
static async getCanvasData(src) {
|
|
672
684
|
const keyStr = serializeImageKey({ src });
|
|
673
685
|
return await Caching.canvasImageDataCache.get(keyStr, (k) => {
|
|
@@ -764,6 +776,7 @@ var init_TextureLoader = __esm({
|
|
|
764
776
|
texture.rotation = rotation;
|
|
765
777
|
return Textures.initTextureProps(texture);
|
|
766
778
|
}
|
|
779
|
+
/** Loads image pixels in the background. `rotation` is in radians. Check {@link hasFailed} for load failures. */
|
|
767
780
|
static load(src, format2 = import_three3.RGBAFormat, rotation = 0) {
|
|
768
781
|
const texture = new import_three3.Texture();
|
|
769
782
|
texture.colorSpace = THREE.SRGBColorSpace;
|
|
@@ -813,6 +826,7 @@ var init_Textures = __esm({
|
|
|
813
826
|
return this.initTextureProps(texture);
|
|
814
827
|
});
|
|
815
828
|
}
|
|
829
|
+
/** Sets nearest-neighbor filters without changing the texture's color space. Returns the same texture. */
|
|
816
830
|
static initTextureProps(texture) {
|
|
817
831
|
texture.magFilter = THREE2.NearestFilter;
|
|
818
832
|
texture.minFilter = THREE2.NearestFilter;
|
|
@@ -825,11 +839,13 @@ var init_Textures = __esm({
|
|
|
825
839
|
static createAsset(key) {
|
|
826
840
|
return new import_three4.Texture();
|
|
827
841
|
}
|
|
842
|
+
/** Creates an sRGB color texture from a canvas. */
|
|
828
843
|
static createCanvasTexture(canvas) {
|
|
829
844
|
const texture = new import_three4.CanvasTexture(canvas);
|
|
830
845
|
texture.colorSpace = THREE2.SRGBColorSpace;
|
|
831
846
|
return this.initTextureProps(texture);
|
|
832
847
|
}
|
|
848
|
+
/** Returns a shared texture immediately and loads its image asynchronously. Failed cached loads are retried. */
|
|
833
849
|
static getImage(key) {
|
|
834
850
|
const keyStr = serializeTextureKey(key);
|
|
835
851
|
const cached2 = Caching.textureCache.peek(keyStr);
|
|
@@ -854,6 +870,7 @@ var init_Materials = __esm({
|
|
|
854
870
|
init_TextureLoader();
|
|
855
871
|
init_Caching();
|
|
856
872
|
Materials = class _Materials {
|
|
873
|
+
/** Shared checkerboard material, created on first access. */
|
|
857
874
|
static get MISSING_TEXTURE() {
|
|
858
875
|
return Caching.materialCache.get("builtin:missing-texture", () => new import_three5.MeshBasicMaterial({
|
|
859
876
|
map: Textures.getMissing(),
|
|
@@ -957,6 +974,7 @@ var init_Materials = __esm({
|
|
|
957
974
|
if (tint !== void 0) material.color.multiply(new import_three5.Color(tint));
|
|
958
975
|
return material;
|
|
959
976
|
}
|
|
977
|
+
/** Creates an unlit, transparent GUI material without depth writes or tone mapping. */
|
|
960
978
|
static createGuiCanvasMaterial(canvas) {
|
|
961
979
|
const material = new import_three5.MeshBasicMaterial({
|
|
962
980
|
map: Textures.createCanvasTexture(canvas),
|
|
@@ -1123,6 +1141,7 @@ var init_Materials = __esm({
|
|
|
1123
1141
|
}
|
|
1124
1142
|
return this.createBasicCanvasMaterial(canvas, transparent, shade);
|
|
1125
1143
|
}
|
|
1144
|
+
/** Returns a shared image material. Use {@link createImage} for a separate material instance. */
|
|
1126
1145
|
static getImage(key) {
|
|
1127
1146
|
const keyStr = serializeMaterialKey(key);
|
|
1128
1147
|
const map = Caching.materialCache.peek(keyStr)?.map;
|
|
@@ -1297,6 +1316,14 @@ var init_AssetKey = __esm({
|
|
|
1297
1316
|
}
|
|
1298
1317
|
};
|
|
1299
1318
|
AssetKey = class _AssetKey extends BasicAssetKey {
|
|
1319
|
+
/**
|
|
1320
|
+
* Creates a key from separate path components. Use {@link parse} for a combined reference.
|
|
1321
|
+
*
|
|
1322
|
+
* @param assetType - Asset directory, such as `models`, `textures`, or `blockstates`.
|
|
1323
|
+
* @param type - Subdirectory, such as `block` or `item`.
|
|
1324
|
+
* @param rootType - Top-level directory, usually `assets` or `data`.
|
|
1325
|
+
* @param root - Base URL override for hosted asset sources.
|
|
1326
|
+
*/
|
|
1300
1327
|
constructor(namespace, path, assetType, type, rootType = "assets", extension = ".json", root) {
|
|
1301
1328
|
super(namespace, path);
|
|
1302
1329
|
this.namespace = namespace;
|
|
@@ -1308,6 +1335,16 @@ var init_AssetKey = __esm({
|
|
|
1308
1335
|
this.root = root;
|
|
1309
1336
|
this.isAssetKey = true;
|
|
1310
1337
|
}
|
|
1338
|
+
/**
|
|
1339
|
+
* Parses an asset reference such as `minecraft:block/stone`.
|
|
1340
|
+
* A missing namespace defaults to the origin's namespace or `minecraft`.
|
|
1341
|
+
*
|
|
1342
|
+
* @param assetType - Asset category, such as `models` or `textures`.
|
|
1343
|
+
* @param str - Path with an optional namespace and file extension.
|
|
1344
|
+
* @param origin - Supplies the asset root, default namespace, and non-texture extension.
|
|
1345
|
+
* @returns A key with the matching extension removed from its path. Textures use `.png`;
|
|
1346
|
+
* other assets use the origin's extension or `.json`.
|
|
1347
|
+
*/
|
|
1311
1348
|
static parse(assetType, str, origin) {
|
|
1312
1349
|
let namespace = origin?.namespace || DEFAULT_NAMESPACE;
|
|
1313
1350
|
if (str.includes(":")) {
|
|
@@ -1339,6 +1376,7 @@ var init_AssetKey = __esm({
|
|
|
1339
1376
|
];
|
|
1340
1377
|
return a.join("/");
|
|
1341
1378
|
}
|
|
1379
|
+
/** Joins the type subdirectory and path without adding a namespace or file extension. */
|
|
1342
1380
|
getFullPath() {
|
|
1343
1381
|
let p10 = [];
|
|
1344
1382
|
if (this.type) {
|
|
@@ -1350,6 +1388,7 @@ var init_AssetKey = __esm({
|
|
|
1350
1388
|
toNamespacedString() {
|
|
1351
1389
|
return this.namespace + ":" + this.getFullPath();
|
|
1352
1390
|
}
|
|
1391
|
+
/** Returns a cache identifier that includes the explicit root or {@link AssetLoader.ROOT}. */
|
|
1353
1392
|
serialize() {
|
|
1354
1393
|
return this.toString();
|
|
1355
1394
|
}
|
|
@@ -1409,6 +1448,7 @@ var init_DisplayTransforms = __esm({
|
|
|
1409
1448
|
const scale = new import_three7.Vector3(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
|
|
1410
1449
|
return new import_three7.Matrix4().compose(translation, rotation, scale);
|
|
1411
1450
|
}
|
|
1451
|
+
/** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
|
|
1412
1452
|
static apply(geometry, matrix) {
|
|
1413
1453
|
geometry.applyMatrix4(matrix);
|
|
1414
1454
|
if (matrix.determinant() < 0) {
|
|
@@ -1436,6 +1476,7 @@ var init_ModelMerger = __esm({
|
|
|
1436
1476
|
init_AssetKey();
|
|
1437
1477
|
init_DisplayTransforms();
|
|
1438
1478
|
ModelMerger = class {
|
|
1479
|
+
/** Loads the parent chain and returns a merged model without modifying the supplied definition. */
|
|
1439
1480
|
static async mergeWithParents(model) {
|
|
1440
1481
|
const models = await this.collectAllParents(model);
|
|
1441
1482
|
let merged = {};
|
|
@@ -1503,6 +1544,7 @@ var init_Models = __esm({
|
|
|
1503
1544
|
static get PERSISTENT_CACHE() {
|
|
1504
1545
|
return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-models"));
|
|
1505
1546
|
}
|
|
1547
|
+
/** Lists item filenames from the asset source's `_list.json`, with a legacy model-directory fallback. */
|
|
1506
1548
|
static async getItemList() {
|
|
1507
1549
|
const key = new AssetKey(DEFAULT_NAMESPACE, "_list", "items");
|
|
1508
1550
|
const legacyKey = new AssetKey(DEFAULT_NAMESPACE, "_list", "models", "item");
|
|
@@ -1573,6 +1615,7 @@ var init_Models = __esm({
|
|
|
1573
1615
|
}
|
|
1574
1616
|
throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
|
|
1575
1617
|
}
|
|
1618
|
+
/** Loads one model file without resolving its parents. Returns `undefined` when the file is missing. */
|
|
1576
1619
|
static async getRaw(key) {
|
|
1577
1620
|
if (!key.assetType) {
|
|
1578
1621
|
key.assetType = "models";
|
|
@@ -1592,6 +1635,12 @@ var init_Models = __esm({
|
|
|
1592
1635
|
return asset;
|
|
1593
1636
|
});
|
|
1594
1637
|
}
|
|
1638
|
+
/**
|
|
1639
|
+
* Loads a model and resolves its parent chain. Returns `undefined` when the model is missing.
|
|
1640
|
+
* Item keys use GUI context, false conditions, and zero numeric properties.
|
|
1641
|
+
*
|
|
1642
|
+
* @param key - Model key, for example `AssetKey.parse("models", "minecraft:item/diamond_sword")`.
|
|
1643
|
+
*/
|
|
1595
1644
|
static async getMerged(key) {
|
|
1596
1645
|
if (!key.assetType) {
|
|
1597
1646
|
key.assetType = "models";
|
|
@@ -1604,9 +1653,11 @@ var init_Models = __esm({
|
|
|
1604
1653
|
return _Models.loadAndMerge(key);
|
|
1605
1654
|
});
|
|
1606
1655
|
}
|
|
1656
|
+
/** Alias for {@link getMerged}. */
|
|
1607
1657
|
static async get(key) {
|
|
1608
1658
|
return this.getMerged(key);
|
|
1609
1659
|
}
|
|
1660
|
+
/** Clears persisted models. Use {@link Caching.clear} to also discard in-memory assets. */
|
|
1610
1661
|
static async clearCache() {
|
|
1611
1662
|
return this.PERSISTENT_CACHE.clear();
|
|
1612
1663
|
}
|
|
@@ -1629,6 +1680,7 @@ var init_BlockStates = __esm({
|
|
|
1629
1680
|
return this._persistentCache ?? (this._persistentCache = PersistentCache.open("minerender-blockstates"));
|
|
1630
1681
|
}
|
|
1631
1682
|
// BlockState names are hardcoded
|
|
1683
|
+
/** Returns blockstate filenames from the selected version's `_list.json`, or an empty list. */
|
|
1632
1684
|
static async getList() {
|
|
1633
1685
|
const key = new AssetKey(
|
|
1634
1686
|
DEFAULT_NAMESPACE,
|
|
@@ -1649,6 +1701,7 @@ var init_BlockStates = __esm({
|
|
|
1649
1701
|
return AssetLoader.get(key, "json" /* JSON */);
|
|
1650
1702
|
});
|
|
1651
1703
|
}
|
|
1704
|
+
/** Looks up vanilla property definitions for the key's block path, or returns `undefined`. */
|
|
1652
1705
|
static async getDefaultState(key) {
|
|
1653
1706
|
const defaultStates = await this.getDefaultStates();
|
|
1654
1707
|
if (!defaultStates) {
|
|
@@ -1656,6 +1709,7 @@ var init_BlockStates = __esm({
|
|
|
1656
1709
|
}
|
|
1657
1710
|
return defaultStates["minecraft:" + key.path];
|
|
1658
1711
|
}
|
|
1712
|
+
/** Loads a cached blockstate definition for {@link MineRenderScene.addBlock}, or returns `undefined`. */
|
|
1659
1713
|
static async get(key) {
|
|
1660
1714
|
if (!key.assetType) {
|
|
1661
1715
|
key.assetType = "blockstates";
|
|
@@ -1682,6 +1736,7 @@ var init_BlockStates = __esm({
|
|
|
1682
1736
|
}
|
|
1683
1737
|
return Promise.all(promises);
|
|
1684
1738
|
}
|
|
1739
|
+
/** Clears persisted blockstates. Use {@link Caching.clear} to also discard in-memory assets. */
|
|
1685
1740
|
static async clearCache() {
|
|
1686
1741
|
await this.PERSISTENT_CACHE.clear();
|
|
1687
1742
|
}
|
|
@@ -1707,9 +1762,11 @@ var init_Assets = __esm({
|
|
|
1707
1762
|
static parseAssetKey(assetType, str, origin) {
|
|
1708
1763
|
return AssetKey.parse(assetType, str, origin);
|
|
1709
1764
|
}
|
|
1765
|
+
/** Loads a model with its parent chain resolved. See {@link Models.getMerged}. */
|
|
1710
1766
|
static async getModel(key) {
|
|
1711
1767
|
return Models.getMerged(key);
|
|
1712
1768
|
}
|
|
1769
|
+
/** Loads a blockstate definition. See {@link BlockStates.get}. */
|
|
1713
1770
|
static async getBlockState(key) {
|
|
1714
1771
|
return BlockStates.get(key);
|
|
1715
1772
|
}
|
|
@@ -1756,6 +1813,10 @@ var init_BatchedExecutor = __esm({
|
|
|
1756
1813
|
"src/util/BatchedExecutor.ts"() {
|
|
1757
1814
|
import_jobqu2 = require("jobqu");
|
|
1758
1815
|
BatchedExecutor = class {
|
|
1816
|
+
/**
|
|
1817
|
+
* @param interval - Delay between queue runs, in milliseconds.
|
|
1818
|
+
* @param batch - Maximum tasks started per run and maximum tasks active at once.
|
|
1819
|
+
*/
|
|
1759
1820
|
constructor(interval = 1, batch = 30) {
|
|
1760
1821
|
if (!Number.isFinite(interval) || interval < 0) throw new RangeError("Batch interval must be finite and nonnegative");
|
|
1761
1822
|
if (!Number.isInteger(batch) || batch < 1) throw new RangeError("Batch size must be a positive integer");
|
|
@@ -1763,9 +1824,11 @@ var init_BatchedExecutor = __esm({
|
|
|
1763
1824
|
this.batch = batch;
|
|
1764
1825
|
this.queue = new import_jobqu2.JobQueue(async (task) => task(), { interval, maxPerRun: batch, maxActive: batch });
|
|
1765
1826
|
}
|
|
1827
|
+
/** Queues a task and resolves with its result, or rejects with its error. */
|
|
1766
1828
|
submit(task) {
|
|
1767
1829
|
return this.queue.add(() => task());
|
|
1768
1830
|
}
|
|
1831
|
+
/** Rejects queued and future tasks. Tasks already running are allowed to finish. */
|
|
1769
1832
|
stop() {
|
|
1770
1833
|
this.queue.end();
|
|
1771
1834
|
}
|
|
@@ -1908,6 +1971,7 @@ var init_NBTHelper = __esm({
|
|
|
1908
1971
|
"src/nbt/NBTHelper.ts"() {
|
|
1909
1972
|
import_buffer2 = require("buffer");
|
|
1910
1973
|
NBTHelper = class {
|
|
1974
|
+
/** Parses NBT bytes and preserves format and compression metadata. Omit `format` for automatic detection. */
|
|
1911
1975
|
static async fromBuffer(data, format2) {
|
|
1912
1976
|
const buffer = import_buffer2.Buffer.from(data instanceof Uint8Array ? data : new Uint8Array(data));
|
|
1913
1977
|
const prismarineNbt = await import("prismarine-nbt");
|
|
@@ -1976,6 +2040,7 @@ var init_HostedAssetSource = __esm({
|
|
|
1976
2040
|
retryDefaults: true
|
|
1977
2041
|
};
|
|
1978
2042
|
_HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
2043
|
+
/** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */
|
|
1979
2044
|
async loadOrRetryWithDefaults(key, parser) {
|
|
1980
2045
|
const direct = await this.load(key, parser);
|
|
1981
2046
|
if (typeof direct !== "undefined") {
|
|
@@ -2033,6 +2098,10 @@ var init_HostedAssetSource = __esm({
|
|
|
2033
2098
|
assetBasePath(key) {
|
|
2034
2099
|
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 + "/" : ""}`;
|
|
2035
2100
|
}
|
|
2101
|
+
/**
|
|
2102
|
+
* Creates a hosted source for {@link AssetLoader.addSource}.
|
|
2103
|
+
* Set `options.retryDefaults` to `false` to restrict lookups to the requested namespace and root.
|
|
2104
|
+
*/
|
|
2036
2105
|
constructor(root, options) {
|
|
2037
2106
|
super();
|
|
2038
2107
|
this._root = root;
|
|
@@ -2125,6 +2194,11 @@ var init_BrowserArchiveProxy = __esm({
|
|
|
2125
2194
|
"src/assets/source/archive/BrowserArchiveProxy.ts"() {
|
|
2126
2195
|
import_zip = require("@zip.js/zip.js");
|
|
2127
2196
|
BrowserArchiveProxy = class {
|
|
2197
|
+
/**
|
|
2198
|
+
* Opens a ZIP for asset lookup.
|
|
2199
|
+
* @param id - Cache identity for this content. Change it when the pack changes.
|
|
2200
|
+
* A File supplies an identity from its name, size, and modification time when omitted.
|
|
2201
|
+
*/
|
|
2128
2202
|
constructor(blob, id) {
|
|
2129
2203
|
this._blob = blob;
|
|
2130
2204
|
this._reader = new import_zip.ZipReader(new import_zip.BlobReader(this._blob));
|
|
@@ -2322,6 +2396,7 @@ var init_ArchiveAssetSource = __esm({
|
|
|
2322
2396
|
dataPackFormat: copyFormat(options.dataPackFormat)
|
|
2323
2397
|
};
|
|
2324
2398
|
}
|
|
2399
|
+
/** Creates a browser ZIP source from a Blob or File. */
|
|
2325
2400
|
static blob(blob, options) {
|
|
2326
2401
|
return new _ArchiveAssetSource(new BrowserArchiveProxy(blob), options);
|
|
2327
2402
|
}
|
|
@@ -2456,6 +2531,7 @@ var init_AssetLoader = __esm({
|
|
|
2456
2531
|
static get version() {
|
|
2457
2532
|
return this.ROOT.substring(this.ROOT.lastIndexOf("/") + 1);
|
|
2458
2533
|
}
|
|
2534
|
+
/** Selects an mcasset.cloud version, updates the vanilla source, and clears in-memory caches. */
|
|
2459
2535
|
static setVersion(version) {
|
|
2460
2536
|
this.ROOT = `https://assets.mcasset.cloud/${version}`;
|
|
2461
2537
|
const source = new HostedAssetSource(this.ROOT, { retryDefaults: false });
|
|
@@ -2489,6 +2565,13 @@ var init_AssetLoader = __esm({
|
|
|
2489
2565
|
return scope ? `${scope}
|
|
2490
2566
|
${key}` : key;
|
|
2491
2567
|
}
|
|
2568
|
+
/**
|
|
2569
|
+
* Registers a source at the highest priority.
|
|
2570
|
+
* Call {@link Caching.clear} after changing sources to discard previously loaded assets.
|
|
2571
|
+
*
|
|
2572
|
+
* @param key - Name used to replace or remove this source.
|
|
2573
|
+
* @param override - Removes the first source with this name before adding the new one.
|
|
2574
|
+
*/
|
|
2492
2575
|
static addSource(key, source, override = true) {
|
|
2493
2576
|
if (override) {
|
|
2494
2577
|
const existing = this.removeSource(key);
|
|
@@ -2499,6 +2582,7 @@ ${key}` : key;
|
|
|
2499
2582
|
this._SOURCES.unshift({ key, source });
|
|
2500
2583
|
console.log(p4, "Added AssetSource", key);
|
|
2501
2584
|
}
|
|
2585
|
+
/** Removes and returns the first source with this name. Call {@link Caching.clear} to reload assets. */
|
|
2502
2586
|
static removeSource(key) {
|
|
2503
2587
|
const index = this._SOURCES.findIndex((s) => s.key === key);
|
|
2504
2588
|
if (index != -1) {
|
|
@@ -2509,6 +2593,7 @@ ${key}` : key;
|
|
|
2509
2593
|
}
|
|
2510
2594
|
return void 0;
|
|
2511
2595
|
}
|
|
2596
|
+
/** Loads from all sources and returns defined results in priority order. Any source failure rejects the call. */
|
|
2512
2597
|
static async getAll(key, parser) {
|
|
2513
2598
|
const sources = [...this._SOURCES];
|
|
2514
2599
|
const results = [];
|
|
@@ -2553,6 +2638,7 @@ ${key}` : key;
|
|
|
2553
2638
|
return void 0;
|
|
2554
2639
|
}
|
|
2555
2640
|
};
|
|
2641
|
+
/** Default asset base URL. Use {@link setVersion} to select a Minecraft version. */
|
|
2556
2642
|
_AssetLoader.ROOT = DEFAULT_ROOT;
|
|
2557
2643
|
_AssetLoader._SOURCES = [];
|
|
2558
2644
|
/** Used when a registered source cannot identify its content, so nothing persists past this session. */
|
|
@@ -2577,6 +2663,7 @@ var init_ModelTextures = __esm({
|
|
|
2577
2663
|
static get PERSISTENT_META_CACHE() {
|
|
2578
2664
|
return this._persistentMetaCache ?? (this._persistentMetaCache = PersistentCache.open("minerender-texturemeta"));
|
|
2579
2665
|
}
|
|
2666
|
+
/** Loads and decodes a texture into a readable canvas, or returns `undefined` when missing. */
|
|
2580
2667
|
static async get(key) {
|
|
2581
2668
|
const keyStr = key.serialize();
|
|
2582
2669
|
const pending = this.preload(key);
|
|
@@ -2594,6 +2681,7 @@ var init_ModelTextures = __esm({
|
|
|
2594
2681
|
throw err;
|
|
2595
2682
|
}
|
|
2596
2683
|
}
|
|
2684
|
+
/** Fetches and caches encoded texture bytes without decoding the pixels. */
|
|
2597
2685
|
static async preload(key) {
|
|
2598
2686
|
const keyStr = key.serialize();
|
|
2599
2687
|
return Caching.textureAssetCache.get(keyStr, (k) => {
|
|
@@ -2604,6 +2692,7 @@ var init_ModelTextures = __esm({
|
|
|
2604
2692
|
});
|
|
2605
2693
|
});
|
|
2606
2694
|
}
|
|
2695
|
+
/** Loads a texture's `.mcmeta` file, or returns `undefined` when no metadata file exists. */
|
|
2607
2696
|
static async getMeta(key) {
|
|
2608
2697
|
if (!key.extension || !key.extension.endsWith(".mcmeta")) {
|
|
2609
2698
|
key = Object.assign(new AssetKey("", ""), key);
|
|
@@ -2620,6 +2709,7 @@ var init_ModelTextures = __esm({
|
|
|
2620
2709
|
});
|
|
2621
2710
|
});
|
|
2622
2711
|
}
|
|
2712
|
+
/** Clears persisted texture metadata. Use {@link Caching.clear} to discard in-memory textures and metadata. */
|
|
2623
2713
|
static async clearCache() {
|
|
2624
2714
|
await this.PERSISTENT_META_CACHE.clear();
|
|
2625
2715
|
}
|
|
@@ -2686,6 +2776,7 @@ var init_Ticker = __esm({
|
|
|
2686
2776
|
}
|
|
2687
2777
|
return handle;
|
|
2688
2778
|
}
|
|
2779
|
+
/** Starts or resumes the shared tick loop. Repeated calls have no effect. */
|
|
2689
2780
|
static start() {
|
|
2690
2781
|
if (this.interval) return;
|
|
2691
2782
|
this.interval = this.schedule(() => {
|
|
@@ -2708,6 +2799,7 @@ var init_Ticker = __esm({
|
|
|
2708
2799
|
_Ticker.fiveSecondTicks = 0;
|
|
2709
2800
|
}, 1e3 * 5);
|
|
2710
2801
|
}
|
|
2802
|
+
/** Pauses the loop while retaining callbacks for a later {@link start}. */
|
|
2711
2803
|
static stop() {
|
|
2712
2804
|
if (this.interval) clearInterval(this.interval);
|
|
2713
2805
|
if (this.oneSecondTicksTracker) clearInterval(this.oneSecondTicksTracker);
|
|
@@ -2716,12 +2808,14 @@ var init_Ticker = __esm({
|
|
|
2716
2808
|
this.oneSecondTicksTracker = void 0;
|
|
2717
2809
|
this.fiveSecondTicksTracker = void 0;
|
|
2718
2810
|
}
|
|
2811
|
+
/** Registers a callback, starts the loop if needed, and returns an ID for {@link remove}. */
|
|
2719
2812
|
static add(tick) {
|
|
2720
2813
|
this.start();
|
|
2721
2814
|
const c = this.counter++;
|
|
2722
2815
|
this._tickers.set(c, tick);
|
|
2723
2816
|
return c;
|
|
2724
2817
|
}
|
|
2818
|
+
/** Removes a callback by ID and stops the timers when no callbacks remain. */
|
|
2725
2819
|
static remove(c) {
|
|
2726
2820
|
if (typeof c === "number") this._tickers.delete(c);
|
|
2727
2821
|
if (!this._tickers.size) this.stop();
|
|
@@ -2735,6 +2829,7 @@ var init_Ticker = __esm({
|
|
|
2735
2829
|
static get tpsFiveSeconds() {
|
|
2736
2830
|
return this.fiveSecondTps;
|
|
2737
2831
|
}
|
|
2832
|
+
/** Stops the loop and removes all registered callbacks. */
|
|
2738
2833
|
static dispose() {
|
|
2739
2834
|
this.stop();
|
|
2740
2835
|
this._tickers.clear();
|
|
@@ -2789,6 +2884,7 @@ var init_TextureAtlas = __esm({
|
|
|
2789
2884
|
}
|
|
2790
2885
|
};
|
|
2791
2886
|
}
|
|
2887
|
+
/** Copies pixels for a texture variable from its current atlas rectangle. */
|
|
2792
2888
|
getData(texture) {
|
|
2793
2889
|
const pos = this.positions[texture];
|
|
2794
2890
|
const size = this.sizes[texture];
|
|
@@ -3066,6 +3162,7 @@ var init_UVMapper = __esm({
|
|
|
3066
3162
|
}
|
|
3067
3163
|
uv.needsUpdate = true;
|
|
3068
3164
|
}
|
|
3165
|
+
/** Returns the shared atlas for a keyed, merged model, creating it on first use. */
|
|
3069
3166
|
static async getAtlas(model) {
|
|
3070
3167
|
const keyStr = model.key.serialize();
|
|
3071
3168
|
return Caching.modelTextureAtlasCache.get(keyStr, (k) => {
|
|
@@ -3136,6 +3233,11 @@ var init_UVMapper = __esm({
|
|
|
3136
3233
|
}
|
|
3137
3234
|
return [tl, tr, bl, br];
|
|
3138
3235
|
}
|
|
3236
|
+
/**
|
|
3237
|
+
* Combines model textures and animation metadata into an atlas.
|
|
3238
|
+
* Mapped UVs are stored on copies of the model's elements, available through the returned atlas.
|
|
3239
|
+
* Returns `undefined` for models without a texture map.
|
|
3240
|
+
*/
|
|
3139
3241
|
static async createAtlas(originalModel) {
|
|
3140
3242
|
const textureMap = {};
|
|
3141
3243
|
const metaMap = {};
|
|
@@ -3500,6 +3602,7 @@ var init_Entities = __esm({
|
|
|
3500
3602
|
init_MineRenderError();
|
|
3501
3603
|
init_ModelTextures();
|
|
3502
3604
|
Entities = class {
|
|
3605
|
+
/** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */
|
|
3503
3606
|
static async getEntityList() {
|
|
3504
3607
|
const collect = async (path) => {
|
|
3505
3608
|
const prefix2 = path ? `${path}/` : "";
|
|
@@ -3517,6 +3620,7 @@ var init_Entities = __esm({
|
|
|
3517
3620
|
const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
|
|
3518
3621
|
return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
3519
3622
|
}
|
|
3623
|
+
/** Returns selectable geometry-layer names, or an empty list when the model is missing. */
|
|
3520
3624
|
static async getLayerList(modelKey) {
|
|
3521
3625
|
return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
|
|
3522
3626
|
}
|
|
@@ -3524,6 +3628,15 @@ var init_Entities = __esm({
|
|
|
3524
3628
|
static async getPassList(modelKey) {
|
|
3525
3629
|
return (await this.getModelFile(modelKey))?.passes ?? [];
|
|
3526
3630
|
}
|
|
3631
|
+
/**
|
|
3632
|
+
* Loads the layers and textures to pass to {@link MineRenderScene.addEntity}.
|
|
3633
|
+
* By default, selects `main`, unconditional passes, and passes enabled by `options.when`.
|
|
3634
|
+
*
|
|
3635
|
+
* @param modelKey - Dataset model, such as `new BasicAssetKey("minecraft", "zombie")`.
|
|
3636
|
+
* @param textureKey - Texture override for the first selected layer.
|
|
3637
|
+
* @param options - Layer selection, conditional passes, and per-layer texture overrides.
|
|
3638
|
+
* @returns The selected model, or `undefined` when its dataset file is missing.
|
|
3639
|
+
*/
|
|
3527
3640
|
static async getEntity(modelKey, textureKey, options) {
|
|
3528
3641
|
const model = await this.getModelFile(modelKey);
|
|
3529
3642
|
if (!model) return void 0;
|
|
@@ -3569,6 +3682,7 @@ var init_Entities = __esm({
|
|
|
3569
3682
|
const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
|
|
3570
3683
|
return file?.animations;
|
|
3571
3684
|
}
|
|
3685
|
+
/** Finds a fallback texture using the model path, its directory, and vanilla variant data. */
|
|
3572
3686
|
static async resolveTexture(modelKey) {
|
|
3573
3687
|
const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
|
|
3574
3688
|
const root = isAssetKey(modelKey) ? modelKey.root : void 0;
|
|
@@ -3729,12 +3843,14 @@ var init_EntityAnimationPlayer = __esm({
|
|
|
3729
3843
|
this._animation = void 0;
|
|
3730
3844
|
this._time = 0;
|
|
3731
3845
|
}
|
|
3846
|
+
/** Applies the pose at an absolute playback time. Returns `false` when no clip is active. */
|
|
3732
3847
|
setTime(seconds) {
|
|
3733
3848
|
if (!this._animation) return false;
|
|
3734
3849
|
this._time = seconds;
|
|
3735
3850
|
this.apply();
|
|
3736
3851
|
return true;
|
|
3737
3852
|
}
|
|
3853
|
+
/** Advances playback by elapsed seconds multiplied by the speed passed to {@link play}. */
|
|
3738
3854
|
advance(deltaSeconds) {
|
|
3739
3855
|
return this.setTime(this._time + deltaSeconds * this.speed);
|
|
3740
3856
|
}
|
|
@@ -3772,6 +3888,7 @@ var init_InstanceReference = __esm({
|
|
|
3772
3888
|
if (!this.instanceable.isInstanceActive(this.index, this)) throw new MineRenderError("Instance has been removed");
|
|
3773
3889
|
return this.instanceable;
|
|
3774
3890
|
}
|
|
3891
|
+
/** Releases this placement's slot for reuse. Repeated calls have no effect. */
|
|
3775
3892
|
removeFromScene() {
|
|
3776
3893
|
if (this.instanceable.isInstanceActive(this.index, this)) this.instanceable.removeInstanceAt(this.index);
|
|
3777
3894
|
}
|
|
@@ -3784,9 +3901,11 @@ var init_InstanceReference = __esm({
|
|
|
3784
3901
|
setMatrix(matrix) {
|
|
3785
3902
|
this.activeInstanceable.setMatrixAt(this.index, matrix);
|
|
3786
3903
|
}
|
|
3904
|
+
/** Hides or restores this placement while preserving its transform and allocated slot. */
|
|
3787
3905
|
setVisible(visible) {
|
|
3788
3906
|
this.activeInstanceable.setInstanceVisibleAt(this.index, visible);
|
|
3789
3907
|
}
|
|
3908
|
+
/** Updates the supplied transform components. Positions use scene units and rotations use radians. */
|
|
3790
3909
|
setPositionRotationScale(position, rotation, scale) {
|
|
3791
3910
|
this.activeInstanceable.setPositionRotationScaleAt(this.index, position, rotation, scale);
|
|
3792
3911
|
}
|
|
@@ -3855,6 +3974,7 @@ var init_SceneObject = __esm({
|
|
|
3855
3974
|
}
|
|
3856
3975
|
async init() {
|
|
3857
3976
|
}
|
|
3977
|
+
/** Marks ancestor scenes for redraw and emits a `change` event. */
|
|
3858
3978
|
notifyDirty() {
|
|
3859
3979
|
this.traverseAncestors((parent) => {
|
|
3860
3980
|
const scene = parent;
|
|
@@ -3890,15 +4010,17 @@ var init_SceneObject = __esm({
|
|
|
3890
4010
|
return obj;
|
|
3891
4011
|
}
|
|
3892
4012
|
/**
|
|
3893
|
-
*
|
|
4013
|
+
* Finds a named part, such as `head`, without the internal `group:` prefix.
|
|
4014
|
+
* Returns `undefined` when the group does not exist.
|
|
3894
4015
|
*/
|
|
3895
4016
|
getGroupByName(name) {
|
|
3896
4017
|
return this.getObjectByName(`group:${name}`);
|
|
3897
4018
|
}
|
|
3898
4019
|
/**
|
|
3899
|
-
*
|
|
3900
|
-
* @param name name
|
|
3901
|
-
* @param visible
|
|
4020
|
+
* Changes a named group's visibility and requests a redraw.
|
|
4021
|
+
* @param name - Part name without the `group:` prefix.
|
|
4022
|
+
* @param visible - Visibility to assign. Omit it to toggle the current value.
|
|
4023
|
+
* @returns The resulting visibility, or `false` if the group does not exist.
|
|
3902
4024
|
*/
|
|
3903
4025
|
toggleGroupVisibility(name, visible) {
|
|
3904
4026
|
return this.toggleObjectVisibility(this.getGroupByName(name), visible);
|
|
@@ -3949,15 +4071,16 @@ var init_SceneObject = __esm({
|
|
|
3949
4071
|
return mesh;
|
|
3950
4072
|
}
|
|
3951
4073
|
/**
|
|
3952
|
-
*
|
|
4074
|
+
* Finds a named mesh without the internal `mesh:` prefix, or returns `undefined`.
|
|
3953
4075
|
*/
|
|
3954
4076
|
getMeshByName(name) {
|
|
3955
4077
|
return this.getObjectByName(`mesh:${name}`);
|
|
3956
4078
|
}
|
|
3957
4079
|
/**
|
|
3958
|
-
*
|
|
3959
|
-
* @param name name
|
|
3960
|
-
* @param visible
|
|
4080
|
+
* Changes a named mesh's visibility and requests a redraw.
|
|
4081
|
+
* @param name - Mesh name without the `mesh:` prefix.
|
|
4082
|
+
* @param visible - Visibility to assign. Omit it to toggle the current value.
|
|
4083
|
+
* @returns The resulting visibility, or `false` if the mesh does not exist.
|
|
3961
4084
|
*/
|
|
3962
4085
|
toggleMeshVisibility(name, visible) {
|
|
3963
4086
|
return this.toggleObjectVisibility(this.getMeshByName(name), visible);
|
|
@@ -4003,12 +4126,14 @@ var init_SceneObject = __esm({
|
|
|
4003
4126
|
get isInstanced() {
|
|
4004
4127
|
return this._isInstanced;
|
|
4005
4128
|
}
|
|
4129
|
+
/** Number of live placements, excluding released instance slots. */
|
|
4006
4130
|
get instanceCounter() {
|
|
4007
4131
|
return this._instanceCounter;
|
|
4008
4132
|
}
|
|
4009
4133
|
constructInstanceReference(i) {
|
|
4010
4134
|
return new InstanceReference(this, i);
|
|
4011
4135
|
}
|
|
4136
|
+
/** Allocates a placement of this instanced object, reusing a released slot when available. */
|
|
4012
4137
|
nextInstance() {
|
|
4013
4138
|
const mesh = this.instanceMesh;
|
|
4014
4139
|
if (!mesh) throw new MineRenderError("Object is not instanced");
|
|
@@ -4155,6 +4280,7 @@ var init_SceneObject = __esm({
|
|
|
4155
4280
|
vector.setFromMatrixScale(matrix);
|
|
4156
4281
|
return vector;
|
|
4157
4282
|
}
|
|
4283
|
+
/** Updates supplied transform components. For a shared model, affects every live instance. */
|
|
4158
4284
|
setPositionRotationScale(position, rotation, scale) {
|
|
4159
4285
|
if (this.isInstanced) {
|
|
4160
4286
|
for (const i of this.activeInstanceIndices()) {
|
|
@@ -4173,6 +4299,7 @@ var init_SceneObject = __esm({
|
|
|
4173
4299
|
}
|
|
4174
4300
|
this.notifyDirty();
|
|
4175
4301
|
}
|
|
4302
|
+
/** Sets position in scene units. For a shared model, updates every live instance. */
|
|
4176
4303
|
setPosition(position) {
|
|
4177
4304
|
if (this.isInstanced) {
|
|
4178
4305
|
for (const i of this.activeInstanceIndices()) {
|
|
@@ -4190,6 +4317,7 @@ var init_SceneObject = __esm({
|
|
|
4190
4317
|
return this.position;
|
|
4191
4318
|
}
|
|
4192
4319
|
}
|
|
4320
|
+
/** Sets rotation in radians. For a shared model, updates every live instance. */
|
|
4193
4321
|
setRotation(rotation) {
|
|
4194
4322
|
if (this.isInstanced) {
|
|
4195
4323
|
for (const i of this.activeInstanceIndices()) {
|
|
@@ -4207,6 +4335,7 @@ var init_SceneObject = __esm({
|
|
|
4207
4335
|
return this.rotation;
|
|
4208
4336
|
}
|
|
4209
4337
|
}
|
|
4338
|
+
/** Sets scale factors. For a shared model, updates every live instance. */
|
|
4210
4339
|
setScale(scale) {
|
|
4211
4340
|
if (this.isInstanced) {
|
|
4212
4341
|
for (const i of this.activeInstanceIndices()) {
|
|
@@ -4244,6 +4373,7 @@ var init_SceneObject = __esm({
|
|
|
4244
4373
|
this.notifyDirty();
|
|
4245
4374
|
super.dispose();
|
|
4246
4375
|
}
|
|
4376
|
+
/** Releases instance slots and removes children, disposing children that implement Disposable. */
|
|
4247
4377
|
disposeAndRemoveAllChildren() {
|
|
4248
4378
|
if (this.instanceMesh) {
|
|
4249
4379
|
if (this._scene) this._scene.stats.instanceCount -= this.instanceReferences.size;
|
|
@@ -4266,6 +4396,7 @@ var init_SceneObject = __esm({
|
|
|
4266
4396
|
}
|
|
4267
4397
|
this.notifyDirty();
|
|
4268
4398
|
}
|
|
4399
|
+
/** Detaches the object from its parent and requests a redraw. */
|
|
4269
4400
|
removeFromScene() {
|
|
4270
4401
|
this.notifyDirty();
|
|
4271
4402
|
this.removeFromParent();
|
|
@@ -4421,12 +4552,15 @@ var init_EntityObject = __esm({
|
|
|
4421
4552
|
if (this.animationPlayers.length) this.notifyDirty();
|
|
4422
4553
|
}
|
|
4423
4554
|
//</editor-fold>
|
|
4555
|
+
/** Finds a selected draw by its layer key, such as `main` or `main#2`, or returns `undefined`. */
|
|
4424
4556
|
getLayerGroup(name) {
|
|
4425
4557
|
return super.getGroupByName(`layer:${name}`);
|
|
4426
4558
|
}
|
|
4559
|
+
/** Finds a part name without `group:`. Supply `layerName` to restrict the search to one draw. */
|
|
4427
4560
|
getGroupByName(name, layerName) {
|
|
4428
4561
|
return layerName === void 0 ? super.getGroupByName(name) : this.getLayerGroup(layerName)?.getObjectByName(`group:${name}`);
|
|
4429
4562
|
}
|
|
4563
|
+
/** Finds a mesh name without `mesh:`. Supply `layerName` to restrict the search to one draw. */
|
|
4430
4564
|
getMeshByName(name, layerName) {
|
|
4431
4565
|
return layerName === void 0 ? super.getMeshByName(name) : this.getLayerGroup(layerName)?.getObjectByName(`mesh:${name}`);
|
|
4432
4566
|
}
|
|
@@ -5090,6 +5224,7 @@ var init_ModelCulling = __esm({
|
|
|
5090
5224
|
import_three23 = require("three");
|
|
5091
5225
|
init_CubeFace();
|
|
5092
5226
|
ModelCulling = class {
|
|
5227
|
+
/** Rotates a world-direction bit mask into model space. Bits follow {@link CUBE_FACES}. */
|
|
5093
5228
|
static toLocalMask(worldMask, rotation) {
|
|
5094
5229
|
let localMask = 0;
|
|
5095
5230
|
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
@@ -5100,6 +5235,7 @@ var init_ModelCulling = __esm({
|
|
|
5100
5235
|
}
|
|
5101
5236
|
return localMask;
|
|
5102
5237
|
}
|
|
5238
|
+
/** Whether a model fills one block with opaque faces and can hide adjacent block faces. */
|
|
5103
5239
|
static isOpaqueFullCube(atlas) {
|
|
5104
5240
|
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
5105
5241
|
const element = atlas.model.elements[0];
|
|
@@ -6105,6 +6241,7 @@ var Meshes = class _Meshes {
|
|
|
6105
6241
|
static createBox(key) {
|
|
6106
6242
|
return new import_three6.Mesh(Geometries.getBox(key.geometry), Materials.getImage(key.material));
|
|
6107
6243
|
}
|
|
6244
|
+
/** Returns a shared Mesh object. Use {@link createBox} for a mesh with its own transform and parent. */
|
|
6108
6245
|
static getBox(key) {
|
|
6109
6246
|
const keyStr = serializeMeshKey(key);
|
|
6110
6247
|
return Caching.boxMeshCache.get(keyStr, (k) => {
|
|
@@ -6217,6 +6354,7 @@ init_AssetParsers();
|
|
|
6217
6354
|
init_ModelTextures();
|
|
6218
6355
|
init_Caching();
|
|
6219
6356
|
var Fonts = class {
|
|
6357
|
+
/** Combines font definitions in source-priority order. Unsupported Unihex and TrueType providers are skipped. */
|
|
6220
6358
|
static async get(key = "minecraft:default") {
|
|
6221
6359
|
const fontKey = typeof key === "string" ? AssetKey.parse("font", key) : key;
|
|
6222
6360
|
return await Caching.fontCache.get(fontKey.serialize(), () => this.load(fontKey, []));
|
|
@@ -9392,6 +9530,13 @@ var GuiHelper = class {
|
|
|
9392
9530
|
});
|
|
9393
9531
|
return layers;
|
|
9394
9532
|
}
|
|
9533
|
+
/**
|
|
9534
|
+
* Calculates a slot's top-left position in GUI pixels.
|
|
9535
|
+
* @param slot - Zero-based slot index, or `[column, row]`.
|
|
9536
|
+
* @param origin - Position of the first slot.
|
|
9537
|
+
* @param offset - Horizontal and vertical spacing between slot origins, in pixels.
|
|
9538
|
+
* @param rowSize - Slots per row when `slot` is an index.
|
|
9539
|
+
*/
|
|
9395
9540
|
static inventorySlot(slot, origin = [0, 0], offset = [18, 18], rowSize = 9) {
|
|
9396
9541
|
const [column, row] = typeof slot === "number" ? [slot % rowSize, Math.floor(slot / rowSize)] : slot;
|
|
9397
9542
|
return [origin[0] + column * offset[0], origin[1] + row * offset[1]];
|
|
@@ -10049,6 +10194,7 @@ var SceneStatsDisplay = class {
|
|
|
10049
10194
|
appendTo(el) {
|
|
10050
10195
|
el.append(this.statsContainer);
|
|
10051
10196
|
}
|
|
10197
|
+
/** Stops the refresh timer and removes the panel from the page. */
|
|
10052
10198
|
dispose() {
|
|
10053
10199
|
clearInterval(this.interval);
|
|
10054
10200
|
this.interval = void 0;
|
|
@@ -10073,6 +10219,7 @@ var InstanceManager = class {
|
|
|
10073
10219
|
this.isInstanceManager = true;
|
|
10074
10220
|
this.instanceCache = {};
|
|
10075
10221
|
}
|
|
10222
|
+
/** Allocates a new placement of a cached model, or returns `undefined` if the key is unknown. */
|
|
10076
10223
|
async get(key) {
|
|
10077
10224
|
if (key in this.instanceCache) {
|
|
10078
10225
|
console.debug(p9, "key in cache", key);
|
|
@@ -10080,6 +10227,7 @@ var InstanceManager = class {
|
|
|
10080
10227
|
}
|
|
10081
10228
|
return void 0;
|
|
10082
10229
|
}
|
|
10230
|
+
/** Allocates a placement, calling the supplier once when the shared model is first needed. */
|
|
10083
10231
|
async getOrCreate(key, supplier) {
|
|
10084
10232
|
if (key in this.instanceCache) {
|
|
10085
10233
|
return await this.get(key);
|
|
@@ -10096,6 +10244,7 @@ var InstanceManager = class {
|
|
|
10096
10244
|
throw error;
|
|
10097
10245
|
}
|
|
10098
10246
|
}
|
|
10247
|
+
/** Forgets cached models without disposing them or releasing their existing placements. */
|
|
10099
10248
|
reset() {
|
|
10100
10249
|
for (let instanceCacheKey in this.instanceCache) {
|
|
10101
10250
|
delete this.instanceCache[instanceCacheKey];
|
|
@@ -10141,6 +10290,7 @@ function matchesCondition(condition, state) {
|
|
|
10141
10290
|
});
|
|
10142
10291
|
}
|
|
10143
10292
|
var BlockStateResolver = class {
|
|
10293
|
+
/** Loads vanilla property defaults, falling back to preview values inferred from the blockstate file. */
|
|
10144
10294
|
static async defaults(blockState) {
|
|
10145
10295
|
const defaults = blockState.key ? await BlockStates.getDefaultState(blockState.key) : void 0;
|
|
10146
10296
|
const state = {};
|
|
@@ -10160,9 +10310,11 @@ var BlockStateResolver = class {
|
|
|
10160
10310
|
}
|
|
10161
10311
|
return state;
|
|
10162
10312
|
}
|
|
10313
|
+
/** Selects matching models. Supply `choose` to control selection within each alternatives array. */
|
|
10163
10314
|
static select(blockState, state, choose = this.choose) {
|
|
10164
10315
|
return this.matching(blockState, state).map(choose);
|
|
10165
10316
|
}
|
|
10317
|
+
/** Returns matching model groups before choosing weighted alternatives. */
|
|
10166
10318
|
static matching(blockState, state) {
|
|
10167
10319
|
const out = [];
|
|
10168
10320
|
if (blockState.variants) {
|
|
@@ -10186,6 +10338,7 @@ var BlockStateResolver = class {
|
|
|
10186
10338
|
}
|
|
10187
10339
|
return out;
|
|
10188
10340
|
}
|
|
10341
|
+
/** Selects a random alternative using positive integer weights, each defaulting to 1. */
|
|
10189
10342
|
static choose(variants) {
|
|
10190
10343
|
if (!Array.isArray(variants)) return variants;
|
|
10191
10344
|
if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
|
|
@@ -10203,6 +10356,7 @@ var BlockStateResolver = class {
|
|
|
10203
10356
|
}
|
|
10204
10357
|
return variants[variants.length - 1];
|
|
10205
10358
|
}
|
|
10359
|
+
/** Converts blockstate rotations in degrees into the Euler rotation used by model rendering. */
|
|
10206
10360
|
static rotation(variant) {
|
|
10207
10361
|
const rotation = new import_three29.Euler();
|
|
10208
10362
|
if (typeof variant.x !== "undefined") {
|
|
@@ -10484,6 +10638,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
10484
10638
|
}
|
|
10485
10639
|
this.notifyDirty();
|
|
10486
10640
|
}
|
|
10641
|
+
/** Selected property values. Use {@link setState} to change properties and rebuild the rendered models. */
|
|
10487
10642
|
get state() {
|
|
10488
10643
|
return this._state;
|
|
10489
10644
|
}
|
|
@@ -10583,6 +10738,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
10583
10738
|
obj.setPosition(this.position);
|
|
10584
10739
|
return obj;
|
|
10585
10740
|
}
|
|
10741
|
+
/** Clears selected properties and rebuilds models without reapplying property defaults. */
|
|
10586
10742
|
async resetState() {
|
|
10587
10743
|
this._previousState = this._state;
|
|
10588
10744
|
this._state = {};
|
|
@@ -12486,6 +12642,11 @@ function compoundList(tags, name) {
|
|
|
12486
12642
|
// src/model/multiblock/StructureParser.ts
|
|
12487
12643
|
init_MineRenderError();
|
|
12488
12644
|
var StructureParser = class {
|
|
12645
|
+
/**
|
|
12646
|
+
* Parses decoded NBT, omitting air blocks.
|
|
12647
|
+
* @param _nbt - Structure data decoded by {@link NBTHelper.fromBuffer}.
|
|
12648
|
+
* @param paletteIndex - Palette to select when the structure has several. Defaults to 0.
|
|
12649
|
+
*/
|
|
12489
12650
|
static async parse(_nbt, paletteIndex) {
|
|
12490
12651
|
const nbt = _nbt.value;
|
|
12491
12652
|
let palette;
|
|
@@ -13320,6 +13481,7 @@ var SkinImage = class {
|
|
|
13320
13481
|
// src/skin/SkinTextures.ts
|
|
13321
13482
|
init_Textures();
|
|
13322
13483
|
var SkinTextures = class {
|
|
13484
|
+
/** Loads a skin URL. Pass `legacy` to override layout detection from the image dimensions. */
|
|
13323
13485
|
static async get(src, legacy) {
|
|
13324
13486
|
const image = await SkinImage.getData(src);
|
|
13325
13487
|
const scale = image.width / 64;
|
|
@@ -13493,6 +13655,14 @@ var SkinObject = class extends SceneObject {
|
|
|
13493
13655
|
}
|
|
13494
13656
|
}
|
|
13495
13657
|
}
|
|
13658
|
+
/**
|
|
13659
|
+
* Loads a skin texture, detecting slim arms and legacy layouts by default.
|
|
13660
|
+
* To override detection, set `slim` or `legacy` in the options passed to
|
|
13661
|
+
* `new SkinObject(options)` or `scene.addSkin(src, options)`.
|
|
13662
|
+
* Use {@link setSlim} or {@link setLegacy} to change these settings later.
|
|
13663
|
+
*
|
|
13664
|
+
* @param src - URL of the skin texture.
|
|
13665
|
+
*/
|
|
13496
13666
|
async setSkinTexture(src) {
|
|
13497
13667
|
if (typeof src === "undefined") return;
|
|
13498
13668
|
this.skinTextureSrc = src;
|
|
@@ -13641,6 +13811,7 @@ var _MineRenderScene = class _MineRenderScene extends import_three34.Scene {
|
|
|
13641
13811
|
this.stats.sceneObjectCount += change;
|
|
13642
13812
|
}
|
|
13643
13813
|
}
|
|
13814
|
+
/** Initializes each object before attaching it to the scene. */
|
|
13644
13815
|
async initAndAdd(...object2) {
|
|
13645
13816
|
this.dirty = true;
|
|
13646
13817
|
for (let obj of object2) {
|
|
@@ -13676,13 +13847,33 @@ var _MineRenderScene = class _MineRenderScene extends import_three34.Scene {
|
|
|
13676
13847
|
return obj;
|
|
13677
13848
|
}
|
|
13678
13849
|
}
|
|
13850
|
+
/**
|
|
13851
|
+
* Adds a model loaded with {@link Models.getMerged}.
|
|
13852
|
+
* Set `options.instanceMeshes` to `false` to create a separate ModelObject.
|
|
13853
|
+
*
|
|
13854
|
+
* @param parent - Object to attach the model to. Defaults to this scene.
|
|
13855
|
+
* @returns The model, or a reference to one placement of a shared model.
|
|
13856
|
+
*/
|
|
13679
13857
|
async addModel(model, options, parent = this) {
|
|
13680
13858
|
options = { ...options, tints: await ItemTints.get(model, options?.tints) };
|
|
13681
13859
|
return this.addSceneObject(model, () => new ModelObject(model, options), options, parent);
|
|
13682
13860
|
}
|
|
13861
|
+
/**
|
|
13862
|
+
* Adds the models selected by a blockstate loaded with {@link BlockStates.get}.
|
|
13863
|
+
* Set `options.initialState` to choose block properties such as `facing` or `axis`.
|
|
13864
|
+
* Use the returned object's `setPosition` method to move all of its model parts.
|
|
13865
|
+
*/
|
|
13683
13866
|
async addBlock(blockState, options, parent = this) {
|
|
13684
13867
|
return this.addSceneObject(blockState, () => new BlockObject(blockState, options), options, parent);
|
|
13685
13868
|
}
|
|
13869
|
+
/**
|
|
13870
|
+
* Loads a skin and adds an initialized player model.
|
|
13871
|
+
*
|
|
13872
|
+
* @param skin - Texture URL, such as one returned by {@link Skins.fromUuidOrUsername}.
|
|
13873
|
+
* Omit it to assign a texture later with {@link SkinObject.setSkinTexture}.
|
|
13874
|
+
* @param options - Player settings, including `slim` and `legacy` detection overrides.
|
|
13875
|
+
* @param parent - Object to attach the player to. Defaults to this scene.
|
|
13876
|
+
*/
|
|
13686
13877
|
async addSkin(skin, options, parent = this) {
|
|
13687
13878
|
this.dirty = true;
|
|
13688
13879
|
const obj = new SkinObject(options);
|
|
@@ -13694,9 +13885,14 @@ var _MineRenderScene = class _MineRenderScene extends import_three34.Scene {
|
|
|
13694
13885
|
parent.add(obj);
|
|
13695
13886
|
return obj;
|
|
13696
13887
|
}
|
|
13888
|
+
/** Adds an entity loaded with {@link Entities.getEntity}, using its selected layers and textures. */
|
|
13697
13889
|
async addEntity(entity, options, parent = this) {
|
|
13698
13890
|
return this.addSceneObject(entity, () => new EntityObject(entity, options), options, parent);
|
|
13699
13891
|
}
|
|
13892
|
+
/**
|
|
13893
|
+
* Adds GUI layers in draw order. One GUI pixel equals one scene unit.
|
|
13894
|
+
* Layer positions start at the top left, with positive GUI y pointing down.
|
|
13895
|
+
*/
|
|
13700
13896
|
async addGui(layers, options, parent = this) {
|
|
13701
13897
|
const obj = new GuiObject(layers, options);
|
|
13702
13898
|
obj.scene = this;
|
|
@@ -14513,6 +14709,7 @@ var _Renderer = class _Renderer {
|
|
|
14513
14709
|
get element() {
|
|
14514
14710
|
return this._element;
|
|
14515
14711
|
}
|
|
14712
|
+
/** Attaches the canvas to an element and sizes it to that element's dimensions. */
|
|
14516
14713
|
appendTo(element) {
|
|
14517
14714
|
if (this._disposed) return;
|
|
14518
14715
|
this._element = element;
|
|
@@ -14540,6 +14737,7 @@ var _Renderer = class _Renderer {
|
|
|
14540
14737
|
events.add(changeEvent2);
|
|
14541
14738
|
dispatcher.addEventListener(changeEvent2, this._changeListener);
|
|
14542
14739
|
}
|
|
14740
|
+
/** Updates the camera and canvas size. Width and height are in CSS pixels. */
|
|
14543
14741
|
resize(width, height) {
|
|
14544
14742
|
if (this._disposed) return;
|
|
14545
14743
|
if (isPerspectiveCamera(this.camera)) {
|
|
@@ -14578,12 +14776,14 @@ var _Renderer = class _Renderer {
|
|
|
14578
14776
|
if (this._frameCallbacks.get(callback) === subscription) this._frameCallbacks.delete(callback);
|
|
14579
14777
|
};
|
|
14580
14778
|
}
|
|
14779
|
+
/** Starts or resumes the animation loop and registered frame callbacks. */
|
|
14581
14780
|
start() {
|
|
14582
14781
|
if (this._disposed) return;
|
|
14583
14782
|
this.stop();
|
|
14584
14783
|
this._running = true;
|
|
14585
14784
|
if (!this._inAnimationLoop) this.renderer.setAnimationLoop(this._animationLoop);
|
|
14586
14785
|
}
|
|
14786
|
+
/** Pauses rendering and frame callbacks. Call {@link start} to resume. */
|
|
14587
14787
|
stop() {
|
|
14588
14788
|
if (this._disposed) return;
|
|
14589
14789
|
this._running = false;
|
|
@@ -14692,12 +14892,15 @@ var _Renderer = class _Renderer {
|
|
|
14692
14892
|
const canvas = trim ? trimCanvas(this.renderer.domElement) : this.renderer.domElement;
|
|
14693
14893
|
return canvas.toDataURL(mime, quality);
|
|
14694
14894
|
}
|
|
14895
|
+
/** Exports visible scene meshes as OBJ text, without texture images. */
|
|
14695
14896
|
toObj() {
|
|
14696
14897
|
return SceneExporter.toObj(this.scene);
|
|
14697
14898
|
}
|
|
14899
|
+
/** Exports visible scene meshes as PLY. Set `options.binary` for an ArrayBuffer. */
|
|
14698
14900
|
toPLY(options) {
|
|
14699
14901
|
return SceneExporter.toPLY(this.scene, options);
|
|
14700
14902
|
}
|
|
14903
|
+
/** Exports a static textured scene in the browser. Set `options.binary` for GLB output. */
|
|
14701
14904
|
toGLTF(options) {
|
|
14702
14905
|
return SceneExporter.toGLTF(this.scene, options);
|
|
14703
14906
|
}
|
|
@@ -14779,12 +14982,14 @@ init_request();
|
|
|
14779
14982
|
init_Requests();
|
|
14780
14983
|
var Skins = class {
|
|
14781
14984
|
//<editor-fold desc="Skins">
|
|
14985
|
+
/** Returns a skin URL for {@link MineRenderScene.addSkin}, or `undefined` if name lookup fails. */
|
|
14782
14986
|
static async fromUuidOrUsername(uuidOrUsername) {
|
|
14783
14987
|
if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
|
|
14784
14988
|
return this.fromUuid(uuidOrUsername);
|
|
14785
14989
|
}
|
|
14786
14990
|
return this.fromUsername(uuidOrUsername);
|
|
14787
14991
|
}
|
|
14992
|
+
/** Builds a proxy URL for a UUID without downloading or checking the skin. */
|
|
14788
14993
|
static async fromUuid(uuid) {
|
|
14789
14994
|
return this.getMcProxySkinUrl(uuid);
|
|
14790
14995
|
}
|
|
@@ -14796,6 +15001,7 @@ var Skins = class {
|
|
|
14796
15001
|
return void 0;
|
|
14797
15002
|
});
|
|
14798
15003
|
}
|
|
15004
|
+
/** Looks up a saved MineSkin skin and returns its texture URL, or `undefined` on lookup failure. */
|
|
14799
15005
|
static async fromMineSkin(mineskinId) {
|
|
14800
15006
|
return this.getMineSkin(mineskinId).then((mineskin) => {
|
|
14801
15007
|
if (mineskin) {
|
|
@@ -14806,12 +15012,14 @@ var Skins = class {
|
|
|
14806
15012
|
}
|
|
14807
15013
|
//</editor-fold>
|
|
14808
15014
|
//<editor-fold desc="Capes">
|
|
15015
|
+
/** Resolves a player's Minecraft cape URL for {@link SkinObject.setCapeTexture}. */
|
|
14809
15016
|
static async capeFromUuidOrUsername(uuidOrUsername) {
|
|
14810
15017
|
if (uuidOrUsername.length === 32 || uuidOrUsername.length === 36) {
|
|
14811
15018
|
return this.capeFromUuid(uuidOrUsername);
|
|
14812
15019
|
}
|
|
14813
15020
|
return this.capeFromUsername(uuidOrUsername);
|
|
14814
15021
|
}
|
|
15022
|
+
/** Builds a proxy URL without checking whether the player has a cape. */
|
|
14815
15023
|
static async capeFromUuid(uuid) {
|
|
14816
15024
|
return this.getMcProxyCapeUrl(uuid);
|
|
14817
15025
|
}
|
|
@@ -14966,16 +15174,19 @@ var ChunkData = class _ChunkData {
|
|
|
14966
15174
|
this.freeIds = [];
|
|
14967
15175
|
this.nbt = /* @__PURE__ */ new Map();
|
|
14968
15176
|
}
|
|
15177
|
+
/** Returns a detached copy of a cell, or `undefined` for air. Indices range from 0 to 4095. */
|
|
14969
15178
|
get(index) {
|
|
14970
15179
|
_ChunkData.validateIndex(index);
|
|
14971
15180
|
const entry = this.palette[this.indices[index]];
|
|
14972
15181
|
return entry ? _ChunkData.copyBlock(entry.state, this.nbt.get(index)) : void 0;
|
|
14973
15182
|
}
|
|
15183
|
+
/** Captures a cell's data and returns a copy-producing reader that survives later cell changes. */
|
|
14974
15184
|
snapshot(index) {
|
|
14975
15185
|
_ChunkData.validateIndex(index);
|
|
14976
15186
|
const entry = this.palette[this.indices[index]];
|
|
14977
15187
|
return entry ? _ChunkData.copyBlock.bind(void 0, entry.state, this.nbt.get(index)) : void 0;
|
|
14978
15188
|
}
|
|
15189
|
+
/** Copies block data into a cell. An omitted block or an air block clears the cell. */
|
|
14979
15190
|
set(index, block) {
|
|
14980
15191
|
_ChunkData.validateIndex(index);
|
|
14981
15192
|
let state;
|
|
@@ -15040,15 +15251,23 @@ var ChunkData = class _ChunkData {
|
|
|
15040
15251
|
|
|
15041
15252
|
// src/world/AnvilParser.ts
|
|
15042
15253
|
var AnvilParser = class {
|
|
15254
|
+
/** Lists occupied chunk positions within the region, using local coordinates from 0 to 31. */
|
|
15043
15255
|
static getChunkList(data) {
|
|
15044
15256
|
return this.locations(this.bytes(data)).map(({ x, z }) => ({ x, z }));
|
|
15045
15257
|
}
|
|
15258
|
+
/** Decodes all stored chunks. Gzip, zlib, and uncompressed payloads are supported. */
|
|
15046
15259
|
static async parse(data) {
|
|
15047
15260
|
const bytes = this.bytes(data);
|
|
15048
15261
|
const chunks = [];
|
|
15049
15262
|
for (const location of this.locations(bytes)) chunks.push(await this.readChunk(bytes, location));
|
|
15050
15263
|
return { chunks };
|
|
15051
15264
|
}
|
|
15265
|
+
/**
|
|
15266
|
+
* Decodes one chunk for {@link MineRenderWorld.placeChunk}.
|
|
15267
|
+
* @param localX - Chunk x within the region, from 0 to 31.
|
|
15268
|
+
* @param localZ - Chunk z within the region, from 0 to 31.
|
|
15269
|
+
* @returns The chunk with absolute coordinates, or `undefined` if the region has no chunk there.
|
|
15270
|
+
*/
|
|
15052
15271
|
static async parseChunk(data, localX, localZ) {
|
|
15053
15272
|
if (![localX, localZ].every((value) => Number.isInteger(value) && value >= 0 && value < 32)) {
|
|
15054
15273
|
throw new RangeError("Region-local chunk coordinates must be integers from 0 to 31");
|
|
@@ -15253,6 +15472,7 @@ var SectionModels = class {
|
|
|
15253
15472
|
this.templates = /* @__PURE__ */ new Set();
|
|
15254
15473
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("maxAtlasSize must be a positive integer");
|
|
15255
15474
|
}
|
|
15475
|
+
/** Returns a cube template, or `undefined` when the block requires an individual render object. */
|
|
15256
15476
|
async get(blockState, properties = {}) {
|
|
15257
15477
|
if (!blockState.variants || blockState.multipart) return void 0;
|
|
15258
15478
|
let states = this.states.get(blockState);
|
|
@@ -15306,6 +15526,7 @@ var SectionModels = class {
|
|
|
15306
15526
|
}
|
|
15307
15527
|
return { variants, templates };
|
|
15308
15528
|
}
|
|
15529
|
+
/** Disposes prepared geometry and clears this world's template caches. */
|
|
15309
15530
|
clear() {
|
|
15310
15531
|
for (const template of this.templates) template.geometry.dispose();
|
|
15311
15532
|
this.templates.clear();
|
|
@@ -15356,6 +15577,13 @@ var MineRenderWorld = class {
|
|
|
15356
15577
|
this.validatePosBounds(posOrX);
|
|
15357
15578
|
await this.getChunkAt(posOrX)?.setBlockVisibleAt(posOrX, yOrVisible);
|
|
15358
15579
|
}
|
|
15580
|
+
/**
|
|
15581
|
+
* Places a structure's blocks at their stored positions, then refreshes neighboring faces.
|
|
15582
|
+
* Entity NBT is retained by the structure but is not rendered.
|
|
15583
|
+
*
|
|
15584
|
+
* @param useBatches - Uses bounded batches by default. Set to `false` for sequential placement.
|
|
15585
|
+
* @param executor - Optional queue for batched placement. The caller remains responsible for stopping it.
|
|
15586
|
+
*/
|
|
15359
15587
|
async placeMultiBlock(multiblock, useBatches = true, executor) {
|
|
15360
15588
|
const changes = /* @__PURE__ */ new Map();
|
|
15361
15589
|
try {
|
|
@@ -15452,6 +15680,7 @@ var MineRenderWorld = class {
|
|
|
15452
15680
|
});
|
|
15453
15681
|
}
|
|
15454
15682
|
}
|
|
15683
|
+
/** Removes all chunks and releases their block placements and section meshes. */
|
|
15455
15684
|
async clear() {
|
|
15456
15685
|
await this.culling;
|
|
15457
15686
|
const chunks = [...this._chunks.values()];
|
|
@@ -15537,9 +15766,11 @@ var MineRenderWorld = class {
|
|
|
15537
15766
|
}
|
|
15538
15767
|
return chunk;
|
|
15539
15768
|
}
|
|
15769
|
+
/** Returns the loaded chunk containing a world block position, without creating a chunk. */
|
|
15540
15770
|
getChunkAt(pos) {
|
|
15541
15771
|
return this._chunks.get(this.worldPosToChunkKey(pos));
|
|
15542
15772
|
}
|
|
15773
|
+
/** Converts block coordinates to scene units by multiplying each component by 16. */
|
|
15543
15774
|
static worldToScenePosition(pos) {
|
|
15544
15775
|
return new import_three39.Vector3(
|
|
15545
15776
|
pos.x * 16,
|
|
@@ -15547,6 +15778,7 @@ var MineRenderWorld = class {
|
|
|
15547
15778
|
pos.z * 16
|
|
15548
15779
|
);
|
|
15549
15780
|
}
|
|
15781
|
+
/** Converts scene units to block coordinates without rounding to an integer block. */
|
|
15550
15782
|
static sceneToWorldPosition(pos) {
|
|
15551
15783
|
return new import_three39.Vector3(
|
|
15552
15784
|
pos.x / 16,
|
|
@@ -15579,6 +15811,7 @@ var SectionMesh = class _SectionMesh extends import_three40.Group {
|
|
|
15579
15811
|
super(...arguments);
|
|
15580
15812
|
this.ownedMeshes = [];
|
|
15581
15813
|
}
|
|
15814
|
+
/** Builds section-local meshes from visible cube faces. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
15582
15815
|
static build(entries, maxAtlasSize = 2048) {
|
|
15583
15816
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
15584
15817
|
const visible = entries.filter((entry) => entry.template.cullFaces.some((direction) => !(entry.cullMask & direction)));
|
|
@@ -15723,7 +15956,7 @@ var Chunk = class _Chunk {
|
|
|
15723
15956
|
return this.setBlockInChunkAt(pos, block, worldPos);
|
|
15724
15957
|
}
|
|
15725
15958
|
/**
|
|
15726
|
-
*
|
|
15959
|
+
* Places a block at integer chunk-local coordinates from 0 to 15.
|
|
15727
15960
|
*/
|
|
15728
15961
|
async setBlockInChunkAt(pos, block, worldPos, onBlocksChanged = this.onBlocksChanged) {
|
|
15729
15962
|
if (typeof worldPos === "undefined") {
|
|
@@ -15772,6 +16005,7 @@ var Chunk = class _Chunk {
|
|
|
15772
16005
|
await onBlocksChanged?.([worldPos]);
|
|
15773
16006
|
}
|
|
15774
16007
|
}
|
|
16008
|
+
/** Changes visibility at world block coordinates while preserving the block's data. */
|
|
15775
16009
|
async setBlockVisibleAt(pos, visible) {
|
|
15776
16010
|
const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
|
|
15777
16011
|
const block = this.renderedBlocks.get(index);
|
|
@@ -15825,6 +16059,7 @@ var Chunk = class _Chunk {
|
|
|
15825
16059
|
this.scene.dirty = true;
|
|
15826
16060
|
this.meshDirty = false;
|
|
15827
16061
|
}
|
|
16062
|
+
/** Removes stored blocks and their render objects, then notifies the owning world of changed positions. */
|
|
15828
16063
|
async clear(onBlocksChanged = this.onBlocksChanged) {
|
|
15829
16064
|
const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
15830
16065
|
new import_three41.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
@@ -15845,6 +16080,7 @@ var Chunk = class _Chunk {
|
|
|
15845
16080
|
static isAir(block) {
|
|
15846
16081
|
return ChunkData.isAir(block);
|
|
15847
16082
|
}
|
|
16083
|
+
/** Maps chunk-local coordinates from 0 to 15 to a storage index, with x varying fastest, then z, then y. */
|
|
15848
16084
|
static chunkPosToBlockIndex(pos) {
|
|
15849
16085
|
if ([pos.x, pos.y, pos.z].some((value) => !Number.isInteger(value) || value < 0 || value >= 16)) {
|
|
15850
16086
|
throw new RangeError("Block coordinates must be integers from 0 to 15 within a chunk");
|