minerender 2.1.0-alpha.28 → 2.1.0-alpha.29
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 +27 -2
- package/dist/browser/index.d.ts +27 -2
- package/dist/browser/index.js +105 -63
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +106 -64
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +105 -63
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +27 -2
- package/dist/node/index.d.ts +27 -2
- package/dist/node/index.js +107 -63
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +108 -64
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/browser/index.mjs
CHANGED
|
@@ -1312,7 +1312,7 @@ var Models = class _Models {
|
|
|
1312
1312
|
}
|
|
1313
1313
|
static async getItemModel(key) {
|
|
1314
1314
|
const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
|
|
1315
|
-
const model = await this.PERSISTENT_CACHE.getOrLoad(itemKey.serialize(), async () => {
|
|
1315
|
+
const model = await this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(itemKey.serialize()), async () => {
|
|
1316
1316
|
const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
|
|
1317
1317
|
if (!result) return void 0;
|
|
1318
1318
|
if (result.key.assetType !== "items") return { ...result.asset, key };
|
|
@@ -1358,7 +1358,7 @@ var Models = class _Models {
|
|
|
1358
1358
|
}
|
|
1359
1359
|
const keyStr = key.serialize();
|
|
1360
1360
|
return Caching.rawModelCache.get(keyStr, (k) => {
|
|
1361
|
-
return this.PERSISTENT_CACHE.getOrLoad(keyStr, (k1) => {
|
|
1361
|
+
return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1362
1362
|
return AssetLoader.get(key, "model" /* MODEL */);
|
|
1363
1363
|
});
|
|
1364
1364
|
}).then((asset) => {
|
|
@@ -1430,7 +1430,7 @@ var BlockStates = class {
|
|
|
1430
1430
|
}
|
|
1431
1431
|
const keyStr = key.serialize();
|
|
1432
1432
|
return Caching.blockStateCache.get(keyStr, (k) => {
|
|
1433
|
-
return this.PERSISTENT_CACHE.getOrLoad(keyStr, (k1) => {
|
|
1433
|
+
return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1434
1434
|
return AssetLoader.get(key, "blockstate" /* BLOCKSTATE */);
|
|
1435
1435
|
});
|
|
1436
1436
|
}).then((asset) => {
|
|
@@ -1476,6 +1476,14 @@ var Assets = class {
|
|
|
1476
1476
|
var AssetSource = class {
|
|
1477
1477
|
constructor() {
|
|
1478
1478
|
}
|
|
1479
|
+
/**
|
|
1480
|
+
* Identifies this source's content across sessions for persistent caching. Sources that
|
|
1481
|
+
* cannot tell whether their content changed (an unnamed archive, for example) return
|
|
1482
|
+
* undefined, which keeps their results out of long-lived caches.
|
|
1483
|
+
*/
|
|
1484
|
+
get cacheId() {
|
|
1485
|
+
return void 0;
|
|
1486
|
+
}
|
|
1479
1487
|
};
|
|
1480
1488
|
var AssetLoadError = class extends Error {
|
|
1481
1489
|
constructor(source, key, path, cause) {
|
|
@@ -1688,6 +1696,9 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
1688
1696
|
get root() {
|
|
1689
1697
|
return this._root;
|
|
1690
1698
|
}
|
|
1699
|
+
get cacheId() {
|
|
1700
|
+
return `hosted:${this._root}`;
|
|
1701
|
+
}
|
|
1691
1702
|
get options() {
|
|
1692
1703
|
return this._options;
|
|
1693
1704
|
}
|
|
@@ -1764,9 +1775,10 @@ var HostedAssetSource = _HostedAssetSource;
|
|
|
1764
1775
|
// src/assets/source/archive/BrowserArchiveProxy.ts
|
|
1765
1776
|
import { BlobReader, BlobWriter, ZipReader } from "@zip.js/zip.js";
|
|
1766
1777
|
var BrowserArchiveProxy = class {
|
|
1767
|
-
constructor(blob) {
|
|
1778
|
+
constructor(blob, id) {
|
|
1768
1779
|
this._blob = blob;
|
|
1769
1780
|
this._reader = new ZipReader(new BlobReader(this._blob));
|
|
1781
|
+
this.id = id ?? (typeof File !== "undefined" && blob instanceof File ? `${blob.name}:${blob.size}:${blob.lastModified}` : void 0);
|
|
1770
1782
|
}
|
|
1771
1783
|
async getEntries() {
|
|
1772
1784
|
return (await this._reader.getEntries()).map((e) => {
|
|
@@ -1791,6 +1803,10 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
|
1791
1803
|
static blob(blob) {
|
|
1792
1804
|
return new _ArchiveAssetSource(new BrowserArchiveProxy(blob));
|
|
1793
1805
|
}
|
|
1806
|
+
get cacheId() {
|
|
1807
|
+
const id = this._archiveProxy.id;
|
|
1808
|
+
return id === void 0 ? void 0 : `archive:${id}`;
|
|
1809
|
+
}
|
|
1794
1810
|
async getEntries() {
|
|
1795
1811
|
return this._archiveProxy.getEntries();
|
|
1796
1812
|
}
|
|
@@ -1833,6 +1849,7 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
|
1833
1849
|
|
|
1834
1850
|
// src/assets/AssetLoader.ts
|
|
1835
1851
|
var p4 = prefix("AssetLoader");
|
|
1852
|
+
var FALLBACK_ROOT = "https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master";
|
|
1836
1853
|
var _AssetLoader = class _AssetLoader {
|
|
1837
1854
|
static get version() {
|
|
1838
1855
|
return this.ROOT.substring(this.ROOT.lastIndexOf("/") + 1);
|
|
@@ -1848,6 +1865,28 @@ var _AssetLoader = class _AssetLoader {
|
|
|
1848
1865
|
}
|
|
1849
1866
|
Caching.clear();
|
|
1850
1867
|
}
|
|
1868
|
+
/**
|
|
1869
|
+
* Scope for persistent cache keys. Empty with only the default vanilla sources, so their
|
|
1870
|
+
* entries stay valid across sessions; otherwise it names every added source (resource packs,
|
|
1871
|
+
* mirrors) so their results never masquerade as vanilla assets after a reload.
|
|
1872
|
+
*/
|
|
1873
|
+
static get persistentScope() {
|
|
1874
|
+
const parts = [];
|
|
1875
|
+
for (const { key, source } of this._SOURCES) {
|
|
1876
|
+
const id = source.cacheId;
|
|
1877
|
+
if (key === "mcassets" && id === `hosted:${this.ROOT}`) continue;
|
|
1878
|
+
if (key === "mcassets-fallback" && id === `hosted:${FALLBACK_ROOT}`) continue;
|
|
1879
|
+
if (id === void 0) return this.SESSION_SCOPE;
|
|
1880
|
+
parts.push(`${key}=${id}`);
|
|
1881
|
+
}
|
|
1882
|
+
return parts.join("|");
|
|
1883
|
+
}
|
|
1884
|
+
/** Prefixes a persistent cache key with the current source scope. */
|
|
1885
|
+
static persistentKey(key) {
|
|
1886
|
+
const scope = this.persistentScope;
|
|
1887
|
+
return scope ? `${scope}
|
|
1888
|
+
${key}` : key;
|
|
1889
|
+
}
|
|
1851
1890
|
static addSource(key, source, override = true) {
|
|
1852
1891
|
if (override) {
|
|
1853
1892
|
const existing = this.removeSource(key);
|
|
@@ -1909,7 +1948,9 @@ var _AssetLoader = class _AssetLoader {
|
|
|
1909
1948
|
};
|
|
1910
1949
|
_AssetLoader.ROOT = DEFAULT_ROOT;
|
|
1911
1950
|
_AssetLoader._SOURCES = [];
|
|
1912
|
-
|
|
1951
|
+
/** Used when a registered source cannot identify its content, so nothing persists past this session. */
|
|
1952
|
+
_AssetLoader.SESSION_SCOPE = `session:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
1953
|
+
_AssetLoader.addSource("mcassets-fallback", new HostedAssetSource(FALLBACK_ROOT, { retryDefaults: false }));
|
|
1913
1954
|
_AssetLoader.addSource("mcassets", new HostedAssetSource(_AssetLoader.ROOT, { retryDefaults: false }));
|
|
1914
1955
|
var AssetLoader = _AssetLoader;
|
|
1915
1956
|
|
|
@@ -1952,7 +1993,7 @@ var ModelTextures = class {
|
|
|
1952
1993
|
}
|
|
1953
1994
|
const keyStr = key.serialize();
|
|
1954
1995
|
return Caching.textureMetaCache.get(keyStr, (k) => {
|
|
1955
|
-
return this.PERSISTENT_META_CACHE.getOrLoad(keyStr, (k1) => {
|
|
1996
|
+
return this.PERSISTENT_META_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1956
1997
|
return AssetLoader.get(key, "meta" /* META */).then((asset) => {
|
|
1957
1998
|
if (asset)
|
|
1958
1999
|
asset.key = key;
|
|
@@ -4609,7 +4650,9 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4609
4650
|
if (typeof variant.y !== "undefined") {
|
|
4610
4651
|
rotation.y = toRadians(clampRotationDegrees(typeof variant.x !== "undefined" ? variant.y : 360 - variant.y));
|
|
4611
4652
|
}
|
|
4612
|
-
const
|
|
4653
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
4654
|
+
modelKey.root = this.blockState.key?.root;
|
|
4655
|
+
const model = await Models.getMerged(modelKey);
|
|
4613
4656
|
const options = {
|
|
4614
4657
|
...this.options,
|
|
4615
4658
|
tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints) : this.options.tints,
|
|
@@ -5405,56 +5448,12 @@ var baseSkinCoordinates = {
|
|
|
5405
5448
|
}
|
|
5406
5449
|
},
|
|
5407
5450
|
cape: {
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
48
|
|
5415
|
-
]
|
|
5416
|
-
},
|
|
5417
|
-
west: {
|
|
5418
|
-
uv: [
|
|
5419
|
-
8,
|
|
5420
|
-
36,
|
|
5421
|
-
12,
|
|
5422
|
-
48
|
|
5423
|
-
]
|
|
5424
|
-
},
|
|
5425
|
-
north: {
|
|
5426
|
-
uv: [
|
|
5427
|
-
4,
|
|
5428
|
-
36,
|
|
5429
|
-
8,
|
|
5430
|
-
48
|
|
5431
|
-
]
|
|
5432
|
-
},
|
|
5433
|
-
south: {
|
|
5434
|
-
uv: [
|
|
5435
|
-
12,
|
|
5436
|
-
36,
|
|
5437
|
-
16,
|
|
5438
|
-
48
|
|
5439
|
-
]
|
|
5440
|
-
},
|
|
5441
|
-
up: {
|
|
5442
|
-
uv: [
|
|
5443
|
-
4,
|
|
5444
|
-
32,
|
|
5445
|
-
8,
|
|
5446
|
-
36
|
|
5447
|
-
]
|
|
5448
|
-
},
|
|
5449
|
-
down: {
|
|
5450
|
-
uv: [
|
|
5451
|
-
8,
|
|
5452
|
-
32,
|
|
5453
|
-
12,
|
|
5454
|
-
36
|
|
5455
|
-
],
|
|
5456
|
-
rotation: 180
|
|
5457
|
-
}
|
|
5451
|
+
east: { uv: [0, 1, 1, 17] },
|
|
5452
|
+
west: { uv: [11, 1, 12, 17] },
|
|
5453
|
+
north: { uv: [1, 1, 11, 17] },
|
|
5454
|
+
south: { uv: [12, 1, 22, 17] },
|
|
5455
|
+
up: { uv: [11, 1, 1, 0] },
|
|
5456
|
+
down: { uv: [21, 0, 11, 1] }
|
|
5458
5457
|
}
|
|
5459
5458
|
};
|
|
5460
5459
|
var classicSkinTextureCoordinates = {
|
|
@@ -5537,7 +5536,7 @@ var slimSkinGeometries = {
|
|
|
5537
5536
|
var import_ts_deepmerge7 = __toESM(require_dist());
|
|
5538
5537
|
|
|
5539
5538
|
// src/skin/SkinTextures.ts
|
|
5540
|
-
import { DataTexture, DoubleSide as DoubleSide2, MeshBasicMaterial as MeshBasicMaterial3, SRGBColorSpace as SRGBColorSpace3 } from "three";
|
|
5539
|
+
import { DataTexture, DoubleSide as DoubleSide2, FrontSide as FrontSide2, MeshBasicMaterial as MeshBasicMaterial3, SRGBColorSpace as SRGBColorSpace3 } from "three";
|
|
5541
5540
|
var SkinTextures = class {
|
|
5542
5541
|
static async get(src, legacy) {
|
|
5543
5542
|
const image = await ImageLoader.getData(src);
|
|
@@ -5553,14 +5552,27 @@ var SkinTextures = class {
|
|
|
5553
5552
|
const key = `skin:${serializeImageKey({ src })}:${isLegacy}`;
|
|
5554
5553
|
const material = Caching.materialCache.get(key, () => {
|
|
5555
5554
|
const pixels = isLegacy ? this.normalizeLegacy(image, scale) : new Uint8Array(image.data);
|
|
5556
|
-
|
|
5557
|
-
texture.colorSpace = SRGBColorSpace3;
|
|
5558
|
-
texture.flipY = true;
|
|
5559
|
-
texture.needsUpdate = true;
|
|
5560
|
-
return new MeshBasicMaterial3({ map: texture, transparent: true, side: DoubleSide2, alphaTest: 0.5 });
|
|
5555
|
+
return this.createMaterial(pixels, image.width, image.width);
|
|
5561
5556
|
});
|
|
5562
5557
|
return { material, slim, legacy: isLegacy };
|
|
5563
5558
|
}
|
|
5559
|
+
static async getCape(src) {
|
|
5560
|
+
const image = await ImageLoader.getData(src);
|
|
5561
|
+
const scale = image.width / 64;
|
|
5562
|
+
if (!Number.isInteger(scale) || scale < 1 || image.height !== image.width / 2) {
|
|
5563
|
+
throw new MineRenderError(`Invalid cape dimensions ${image.width}x${image.height}; expected 64x32 or an integer-scaled equivalent`);
|
|
5564
|
+
}
|
|
5565
|
+
return Caching.materialCache.get(`cape:${serializeImageKey({ src })}`, () => {
|
|
5566
|
+
return this.createMaterial(new Uint8Array(image.data), image.width, image.height, false);
|
|
5567
|
+
});
|
|
5568
|
+
}
|
|
5569
|
+
static createMaterial(pixels, width, height, transparent = true) {
|
|
5570
|
+
const texture = Textures.initTextureProps(new DataTexture(pixels, width, height));
|
|
5571
|
+
texture.colorSpace = SRGBColorSpace3;
|
|
5572
|
+
texture.flipY = true;
|
|
5573
|
+
texture.needsUpdate = true;
|
|
5574
|
+
return new MeshBasicMaterial3({ map: texture, transparent, side: transparent ? DoubleSide2 : FrontSide2, alphaTest: transparent ? 0.5 : 0 });
|
|
5575
|
+
}
|
|
5564
5576
|
static isSlim(image, scale) {
|
|
5565
5577
|
for (const [x, y] of [[46, 52], [54, 20]]) {
|
|
5566
5578
|
for (let row = y * scale; row < (y + 12) * scale; row++) {
|
|
@@ -5623,6 +5635,7 @@ var SkinObject = class extends SceneObject {
|
|
|
5623
5635
|
this.slim = false;
|
|
5624
5636
|
this.detectedSlim = false;
|
|
5625
5637
|
this.skinLoad = 0;
|
|
5638
|
+
this.capeLoad = 0;
|
|
5626
5639
|
this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
|
|
5627
5640
|
this.slim = this.options.slim ?? false;
|
|
5628
5641
|
}
|
|
@@ -5692,6 +5705,7 @@ var SkinObject = class extends SceneObject {
|
|
|
5692
5705
|
this.detectedSlim = texture.slim;
|
|
5693
5706
|
this.updateSlim(this.options.slim ?? this.detectedSlim);
|
|
5694
5707
|
for (const part of SKIN_PARTS) {
|
|
5708
|
+
if (part === "cape" /* CAPE */) continue;
|
|
5695
5709
|
const mesh = this.getMeshByName(part);
|
|
5696
5710
|
if (mesh) {
|
|
5697
5711
|
mesh.material = texture.material;
|
|
@@ -5699,7 +5713,34 @@ var SkinObject = class extends SceneObject {
|
|
|
5699
5713
|
}
|
|
5700
5714
|
this.notifyDirty();
|
|
5701
5715
|
}
|
|
5702
|
-
|
|
5716
|
+
/** Load a vanilla cape texture, or pass undefined to remove the cape. */
|
|
5717
|
+
async setCapeTexture(src) {
|
|
5718
|
+
const load = ++this.capeLoad;
|
|
5719
|
+
if (src === void 0) {
|
|
5720
|
+
const group = this.getGroupByName("cape" /* CAPE */);
|
|
5721
|
+
if (group) this.remove(group);
|
|
5722
|
+
this.notifyDirty();
|
|
5723
|
+
return;
|
|
5724
|
+
}
|
|
5725
|
+
const material = await SkinTextures.getCape(src);
|
|
5726
|
+
if (load !== this.capeLoad) return;
|
|
5727
|
+
const mesh = this.getMeshByName("cape" /* CAPE */);
|
|
5728
|
+
if (mesh) {
|
|
5729
|
+
mesh.material = material;
|
|
5730
|
+
} else {
|
|
5731
|
+
const group = this.createAndAddGroup("cape" /* CAPE */, 0, 24, 2);
|
|
5732
|
+
group.rotation.set(toRadians(-6), Math.PI, 0);
|
|
5733
|
+
const geometry = this._getBoxGeometryFromDimensions(
|
|
5734
|
+
classicSkinGeometries.cape,
|
|
5735
|
+
classicSkinTextureCoordinates.cape,
|
|
5736
|
+
[64, 32],
|
|
5737
|
+
[64, 32]
|
|
5738
|
+
);
|
|
5739
|
+
const cape = this.createAndAddMesh("cape" /* CAPE */, group, geometry, material);
|
|
5740
|
+
cape.position.set(0, -8, -0.5);
|
|
5741
|
+
}
|
|
5742
|
+
this.notifyDirty();
|
|
5743
|
+
}
|
|
5703
5744
|
/** Select the arm model, or pass undefined to use texture detection. */
|
|
5704
5745
|
setSlim(slim) {
|
|
5705
5746
|
this.options.slim = slim;
|
|
@@ -5727,6 +5768,7 @@ var SkinObject = class extends SceneObject {
|
|
|
5727
5768
|
}
|
|
5728
5769
|
dispose() {
|
|
5729
5770
|
this.skinLoad++;
|
|
5771
|
+
this.capeLoad++;
|
|
5730
5772
|
super.dispose();
|
|
5731
5773
|
}
|
|
5732
5774
|
//TODO: layer toggles
|