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/node/index.mjs
CHANGED
|
@@ -1319,7 +1319,7 @@ var Models = class _Models {
|
|
|
1319
1319
|
}
|
|
1320
1320
|
static async getItemModel(key) {
|
|
1321
1321
|
const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
|
|
1322
|
-
const model = await this.PERSISTENT_CACHE.getOrLoad(itemKey.serialize(), async () => {
|
|
1322
|
+
const model = await this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(itemKey.serialize()), async () => {
|
|
1323
1323
|
const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
|
|
1324
1324
|
if (!result) return void 0;
|
|
1325
1325
|
if (result.key.assetType !== "items") return { ...result.asset, key };
|
|
@@ -1365,7 +1365,7 @@ var Models = class _Models {
|
|
|
1365
1365
|
}
|
|
1366
1366
|
const keyStr = key.serialize();
|
|
1367
1367
|
return Caching.rawModelCache.get(keyStr, (k) => {
|
|
1368
|
-
return this.PERSISTENT_CACHE.getOrLoad(keyStr, (k1) => {
|
|
1368
|
+
return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1369
1369
|
return AssetLoader.get(key, "model" /* MODEL */);
|
|
1370
1370
|
});
|
|
1371
1371
|
}).then((asset) => {
|
|
@@ -1437,7 +1437,7 @@ var BlockStates = class {
|
|
|
1437
1437
|
}
|
|
1438
1438
|
const keyStr = key.serialize();
|
|
1439
1439
|
return Caching.blockStateCache.get(keyStr, (k) => {
|
|
1440
|
-
return this.PERSISTENT_CACHE.getOrLoad(keyStr, (k1) => {
|
|
1440
|
+
return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1441
1441
|
return AssetLoader.get(key, "blockstate" /* BLOCKSTATE */);
|
|
1442
1442
|
});
|
|
1443
1443
|
}).then((asset) => {
|
|
@@ -1483,6 +1483,14 @@ var Assets = class {
|
|
|
1483
1483
|
var AssetSource = class {
|
|
1484
1484
|
constructor() {
|
|
1485
1485
|
}
|
|
1486
|
+
/**
|
|
1487
|
+
* Identifies this source's content across sessions for persistent caching. Sources that
|
|
1488
|
+
* cannot tell whether their content changed (an unnamed archive, for example) return
|
|
1489
|
+
* undefined, which keeps their results out of long-lived caches.
|
|
1490
|
+
*/
|
|
1491
|
+
get cacheId() {
|
|
1492
|
+
return void 0;
|
|
1493
|
+
}
|
|
1486
1494
|
};
|
|
1487
1495
|
var AssetLoadError = class extends Error {
|
|
1488
1496
|
constructor(source, key, path, cause) {
|
|
@@ -1771,6 +1779,9 @@ var HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
1771
1779
|
get root() {
|
|
1772
1780
|
return this._root;
|
|
1773
1781
|
}
|
|
1782
|
+
get cacheId() {
|
|
1783
|
+
return `hosted:${this._root}`;
|
|
1784
|
+
}
|
|
1774
1785
|
get options() {
|
|
1775
1786
|
return this._options;
|
|
1776
1787
|
}
|
|
@@ -1786,9 +1797,10 @@ var HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
1786
1797
|
// src/assets/source/archive/BrowserArchiveProxy.ts
|
|
1787
1798
|
import { BlobReader, BlobWriter, ZipReader } from "@zip.js/zip.js";
|
|
1788
1799
|
var BrowserArchiveProxy = class {
|
|
1789
|
-
constructor(blob) {
|
|
1800
|
+
constructor(blob, id) {
|
|
1790
1801
|
this._blob = blob;
|
|
1791
1802
|
this._reader = new ZipReader(new BlobReader(this._blob));
|
|
1803
|
+
this.id = id ?? (typeof File !== "undefined" && blob instanceof File ? `${blob.name}:${blob.size}:${blob.lastModified}` : void 0);
|
|
1792
1804
|
}
|
|
1793
1805
|
async getEntries() {
|
|
1794
1806
|
return (await this._reader.getEntries()).map((e) => {
|
|
@@ -1813,6 +1825,10 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
|
1813
1825
|
static blob(blob) {
|
|
1814
1826
|
return new _ArchiveAssetSource(new BrowserArchiveProxy(blob));
|
|
1815
1827
|
}
|
|
1828
|
+
get cacheId() {
|
|
1829
|
+
const id = this._archiveProxy.id;
|
|
1830
|
+
return id === void 0 ? void 0 : `archive:${id}`;
|
|
1831
|
+
}
|
|
1816
1832
|
async getEntries() {
|
|
1817
1833
|
return this._archiveProxy.getEntries();
|
|
1818
1834
|
}
|
|
@@ -1855,6 +1871,7 @@ var ArchiveAssetSource = class _ArchiveAssetSource extends AssetSource {
|
|
|
1855
1871
|
|
|
1856
1872
|
// src/assets/AssetLoader.ts
|
|
1857
1873
|
var p4 = prefix("AssetLoader");
|
|
1874
|
+
var FALLBACK_ROOT = "https://raw.githubusercontent.com/InventivetalentDev/minerender-fallback-assets/master";
|
|
1858
1875
|
var AssetLoader = class {
|
|
1859
1876
|
static {
|
|
1860
1877
|
this.ROOT = DEFAULT_ROOT;
|
|
@@ -1862,6 +1879,10 @@ var AssetLoader = class {
|
|
|
1862
1879
|
static {
|
|
1863
1880
|
this._SOURCES = [];
|
|
1864
1881
|
}
|
|
1882
|
+
static {
|
|
1883
|
+
/** Used when a registered source cannot identify its content, so nothing persists past this session. */
|
|
1884
|
+
this.SESSION_SCOPE = `session:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
1885
|
+
}
|
|
1865
1886
|
static get version() {
|
|
1866
1887
|
return this.ROOT.substring(this.ROOT.lastIndexOf("/") + 1);
|
|
1867
1888
|
}
|
|
@@ -1876,6 +1897,28 @@ var AssetLoader = class {
|
|
|
1876
1897
|
}
|
|
1877
1898
|
Caching.clear();
|
|
1878
1899
|
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Scope for persistent cache keys. Empty with only the default vanilla sources, so their
|
|
1902
|
+
* entries stay valid across sessions; otherwise it names every added source (resource packs,
|
|
1903
|
+
* mirrors) so their results never masquerade as vanilla assets after a reload.
|
|
1904
|
+
*/
|
|
1905
|
+
static get persistentScope() {
|
|
1906
|
+
const parts = [];
|
|
1907
|
+
for (const { key, source } of this._SOURCES) {
|
|
1908
|
+
const id = source.cacheId;
|
|
1909
|
+
if (key === "mcassets" && id === `hosted:${this.ROOT}`) continue;
|
|
1910
|
+
if (key === "mcassets-fallback" && id === `hosted:${FALLBACK_ROOT}`) continue;
|
|
1911
|
+
if (id === void 0) return this.SESSION_SCOPE;
|
|
1912
|
+
parts.push(`${key}=${id}`);
|
|
1913
|
+
}
|
|
1914
|
+
return parts.join("|");
|
|
1915
|
+
}
|
|
1916
|
+
/** Prefixes a persistent cache key with the current source scope. */
|
|
1917
|
+
static persistentKey(key) {
|
|
1918
|
+
const scope = this.persistentScope;
|
|
1919
|
+
return scope ? `${scope}
|
|
1920
|
+
${key}` : key;
|
|
1921
|
+
}
|
|
1879
1922
|
static addSource(key, source, override = true) {
|
|
1880
1923
|
if (override) {
|
|
1881
1924
|
const existing = this.removeSource(key);
|
|
@@ -1897,7 +1940,7 @@ var AssetLoader = class {
|
|
|
1897
1940
|
return void 0;
|
|
1898
1941
|
}
|
|
1899
1942
|
static {
|
|
1900
|
-
this.addSource("mcassets-fallback", new HostedAssetSource(
|
|
1943
|
+
this.addSource("mcassets-fallback", new HostedAssetSource(FALLBACK_ROOT, { retryDefaults: false }));
|
|
1901
1944
|
this.addSource("mcassets", new HostedAssetSource(this.ROOT, { retryDefaults: false }));
|
|
1902
1945
|
}
|
|
1903
1946
|
static async getAll(key, parser) {
|
|
@@ -1979,7 +2022,7 @@ var ModelTextures = class {
|
|
|
1979
2022
|
}
|
|
1980
2023
|
const keyStr = key.serialize();
|
|
1981
2024
|
return Caching.textureMetaCache.get(keyStr, (k) => {
|
|
1982
|
-
return this.PERSISTENT_META_CACHE.getOrLoad(keyStr, (k1) => {
|
|
2025
|
+
return this.PERSISTENT_META_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), (k1) => {
|
|
1983
2026
|
return AssetLoader.get(key, "meta" /* META */).then((asset) => {
|
|
1984
2027
|
if (asset)
|
|
1985
2028
|
asset.key = key;
|
|
@@ -4659,7 +4702,9 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
4659
4702
|
if (typeof variant.y !== "undefined") {
|
|
4660
4703
|
rotation.y = toRadians(clampRotationDegrees(typeof variant.x !== "undefined" ? variant.y : 360 - variant.y));
|
|
4661
4704
|
}
|
|
4662
|
-
const
|
|
4705
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
4706
|
+
modelKey.root = this.blockState.key?.root;
|
|
4707
|
+
const model = await Models.getMerged(modelKey);
|
|
4663
4708
|
const options = {
|
|
4664
4709
|
...this.options,
|
|
4665
4710
|
tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints) : this.options.tints,
|
|
@@ -5451,56 +5496,12 @@ var baseSkinCoordinates = {
|
|
|
5451
5496
|
}
|
|
5452
5497
|
},
|
|
5453
5498
|
cape: {
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
48
|
|
5461
|
-
]
|
|
5462
|
-
},
|
|
5463
|
-
west: {
|
|
5464
|
-
uv: [
|
|
5465
|
-
8,
|
|
5466
|
-
36,
|
|
5467
|
-
12,
|
|
5468
|
-
48
|
|
5469
|
-
]
|
|
5470
|
-
},
|
|
5471
|
-
north: {
|
|
5472
|
-
uv: [
|
|
5473
|
-
4,
|
|
5474
|
-
36,
|
|
5475
|
-
8,
|
|
5476
|
-
48
|
|
5477
|
-
]
|
|
5478
|
-
},
|
|
5479
|
-
south: {
|
|
5480
|
-
uv: [
|
|
5481
|
-
12,
|
|
5482
|
-
36,
|
|
5483
|
-
16,
|
|
5484
|
-
48
|
|
5485
|
-
]
|
|
5486
|
-
},
|
|
5487
|
-
up: {
|
|
5488
|
-
uv: [
|
|
5489
|
-
4,
|
|
5490
|
-
32,
|
|
5491
|
-
8,
|
|
5492
|
-
36
|
|
5493
|
-
]
|
|
5494
|
-
},
|
|
5495
|
-
down: {
|
|
5496
|
-
uv: [
|
|
5497
|
-
8,
|
|
5498
|
-
32,
|
|
5499
|
-
12,
|
|
5500
|
-
36
|
|
5501
|
-
],
|
|
5502
|
-
rotation: 180
|
|
5503
|
-
}
|
|
5499
|
+
east: { uv: [0, 1, 1, 17] },
|
|
5500
|
+
west: { uv: [11, 1, 12, 17] },
|
|
5501
|
+
north: { uv: [1, 1, 11, 17] },
|
|
5502
|
+
south: { uv: [12, 1, 22, 17] },
|
|
5503
|
+
up: { uv: [11, 1, 1, 0] },
|
|
5504
|
+
down: { uv: [21, 0, 11, 1] }
|
|
5504
5505
|
}
|
|
5505
5506
|
};
|
|
5506
5507
|
var classicSkinTextureCoordinates = {
|
|
@@ -5583,7 +5584,7 @@ var slimSkinGeometries = {
|
|
|
5583
5584
|
var import_ts_deepmerge7 = __toESM(require_dist());
|
|
5584
5585
|
|
|
5585
5586
|
// src/skin/SkinTextures.ts
|
|
5586
|
-
import { DataTexture, DoubleSide as DoubleSide2, MeshBasicMaterial as MeshBasicMaterial3, SRGBColorSpace as SRGBColorSpace3 } from "three";
|
|
5587
|
+
import { DataTexture, DoubleSide as DoubleSide2, FrontSide as FrontSide2, MeshBasicMaterial as MeshBasicMaterial3, SRGBColorSpace as SRGBColorSpace3 } from "three";
|
|
5587
5588
|
var SkinTextures = class {
|
|
5588
5589
|
static async get(src, legacy) {
|
|
5589
5590
|
const image = await ImageLoader.getData(src);
|
|
@@ -5599,14 +5600,27 @@ var SkinTextures = class {
|
|
|
5599
5600
|
const key = `skin:${serializeImageKey({ src })}:${isLegacy}`;
|
|
5600
5601
|
const material = Caching.materialCache.get(key, () => {
|
|
5601
5602
|
const pixels = isLegacy ? this.normalizeLegacy(image, scale) : new Uint8Array(image.data);
|
|
5602
|
-
|
|
5603
|
-
texture.colorSpace = SRGBColorSpace3;
|
|
5604
|
-
texture.flipY = true;
|
|
5605
|
-
texture.needsUpdate = true;
|
|
5606
|
-
return new MeshBasicMaterial3({ map: texture, transparent: true, side: DoubleSide2, alphaTest: 0.5 });
|
|
5603
|
+
return this.createMaterial(pixels, image.width, image.width);
|
|
5607
5604
|
});
|
|
5608
5605
|
return { material, slim, legacy: isLegacy };
|
|
5609
5606
|
}
|
|
5607
|
+
static async getCape(src) {
|
|
5608
|
+
const image = await ImageLoader.getData(src);
|
|
5609
|
+
const scale = image.width / 64;
|
|
5610
|
+
if (!Number.isInteger(scale) || scale < 1 || image.height !== image.width / 2) {
|
|
5611
|
+
throw new MineRenderError(`Invalid cape dimensions ${image.width}x${image.height}; expected 64x32 or an integer-scaled equivalent`);
|
|
5612
|
+
}
|
|
5613
|
+
return Caching.materialCache.get(`cape:${serializeImageKey({ src })}`, () => {
|
|
5614
|
+
return this.createMaterial(new Uint8Array(image.data), image.width, image.height, false);
|
|
5615
|
+
});
|
|
5616
|
+
}
|
|
5617
|
+
static createMaterial(pixels, width, height, transparent = true) {
|
|
5618
|
+
const texture = Textures.initTextureProps(new DataTexture(pixels, width, height));
|
|
5619
|
+
texture.colorSpace = SRGBColorSpace3;
|
|
5620
|
+
texture.flipY = true;
|
|
5621
|
+
texture.needsUpdate = true;
|
|
5622
|
+
return new MeshBasicMaterial3({ map: texture, transparent, side: transparent ? DoubleSide2 : FrontSide2, alphaTest: transparent ? 0.5 : 0 });
|
|
5623
|
+
}
|
|
5610
5624
|
static isSlim(image, scale) {
|
|
5611
5625
|
for (const [x, y] of [[46, 52], [54, 20]]) {
|
|
5612
5626
|
for (let row = y * scale; row < (y + 12) * scale; row++) {
|
|
@@ -5669,6 +5683,7 @@ var SkinObject = class extends SceneObject {
|
|
|
5669
5683
|
this.slim = false;
|
|
5670
5684
|
this.detectedSlim = false;
|
|
5671
5685
|
this.skinLoad = 0;
|
|
5686
|
+
this.capeLoad = 0;
|
|
5672
5687
|
this.options = (0, import_ts_deepmerge7.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
|
|
5673
5688
|
this.slim = this.options.slim ?? false;
|
|
5674
5689
|
}
|
|
@@ -5738,6 +5753,7 @@ var SkinObject = class extends SceneObject {
|
|
|
5738
5753
|
this.detectedSlim = texture.slim;
|
|
5739
5754
|
this.updateSlim(this.options.slim ?? this.detectedSlim);
|
|
5740
5755
|
for (const part of SKIN_PARTS) {
|
|
5756
|
+
if (part === "cape" /* CAPE */) continue;
|
|
5741
5757
|
const mesh = this.getMeshByName(part);
|
|
5742
5758
|
if (mesh) {
|
|
5743
5759
|
mesh.material = texture.material;
|
|
@@ -5745,7 +5761,34 @@ var SkinObject = class extends SceneObject {
|
|
|
5745
5761
|
}
|
|
5746
5762
|
this.notifyDirty();
|
|
5747
5763
|
}
|
|
5748
|
-
|
|
5764
|
+
/** Load a vanilla cape texture, or pass undefined to remove the cape. */
|
|
5765
|
+
async setCapeTexture(src) {
|
|
5766
|
+
const load = ++this.capeLoad;
|
|
5767
|
+
if (src === void 0) {
|
|
5768
|
+
const group = this.getGroupByName("cape" /* CAPE */);
|
|
5769
|
+
if (group) this.remove(group);
|
|
5770
|
+
this.notifyDirty();
|
|
5771
|
+
return;
|
|
5772
|
+
}
|
|
5773
|
+
const material = await SkinTextures.getCape(src);
|
|
5774
|
+
if (load !== this.capeLoad) return;
|
|
5775
|
+
const mesh = this.getMeshByName("cape" /* CAPE */);
|
|
5776
|
+
if (mesh) {
|
|
5777
|
+
mesh.material = material;
|
|
5778
|
+
} else {
|
|
5779
|
+
const group = this.createAndAddGroup("cape" /* CAPE */, 0, 24, 2);
|
|
5780
|
+
group.rotation.set(toRadians(-6), Math.PI, 0);
|
|
5781
|
+
const geometry = this._getBoxGeometryFromDimensions(
|
|
5782
|
+
classicSkinGeometries.cape,
|
|
5783
|
+
classicSkinTextureCoordinates.cape,
|
|
5784
|
+
[64, 32],
|
|
5785
|
+
[64, 32]
|
|
5786
|
+
);
|
|
5787
|
+
const cape = this.createAndAddMesh("cape" /* CAPE */, group, geometry, material);
|
|
5788
|
+
cape.position.set(0, -8, -0.5);
|
|
5789
|
+
}
|
|
5790
|
+
this.notifyDirty();
|
|
5791
|
+
}
|
|
5749
5792
|
/** Select the arm model, or pass undefined to use texture detection. */
|
|
5750
5793
|
setSlim(slim) {
|
|
5751
5794
|
this.options.slim = slim;
|
|
@@ -5773,6 +5816,7 @@ var SkinObject = class extends SceneObject {
|
|
|
5773
5816
|
}
|
|
5774
5817
|
dispose() {
|
|
5775
5818
|
this.skinLoad++;
|
|
5819
|
+
this.capeLoad++;
|
|
5776
5820
|
super.dispose();
|
|
5777
5821
|
}
|
|
5778
5822
|
//TODO: layer toggles
|