minerender 2.1.0-alpha.6 → 2.1.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.d.mts +15 -11
- package/dist/browser/index.d.ts +15 -11
- package/dist/browser/index.js +93 -54
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +93 -54
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +1340 -1088
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +14 -10
- package/dist/node/index.d.ts +14 -10
- package/dist/node/index.js +95 -55
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +95 -55
- package/dist/node/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/browser/index.mjs
CHANGED
|
@@ -422,8 +422,8 @@ var Caching = class {
|
|
|
422
422
|
/**
|
|
423
423
|
* Clears every cache and stops its expiry timer.
|
|
424
424
|
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
425
|
+
* Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.
|
|
426
|
+
* Use {@link shutdown} to also stop requests and the shared Ticker.
|
|
427
427
|
*/
|
|
428
428
|
static end() {
|
|
429
429
|
for (const cache of this.all) {
|
|
@@ -671,13 +671,14 @@ var _Requests = class _Requests {
|
|
|
671
671
|
}
|
|
672
672
|
static get queueSizes() {
|
|
673
673
|
return {
|
|
674
|
-
generic: this.genericQueue.size,
|
|
675
|
-
mcAsset: this.mcAssetRequestQueue.size
|
|
674
|
+
generic: this.genericQueue.size + this.genericQueue.activeSize,
|
|
675
|
+
mcAsset: this.mcAssetRequestQueue.size + this.mcAssetRequestQueue.activeSize
|
|
676
676
|
};
|
|
677
677
|
}
|
|
678
678
|
/**
|
|
679
|
-
*
|
|
680
|
-
*
|
|
679
|
+
* Permanently stops both queues and rejects waiting and future requests.
|
|
680
|
+
* Requests already running can finish. Idle queues hold no timer, so Node can exit without
|
|
681
|
+
* this cleanup. See {@link shutdown}.
|
|
681
682
|
*/
|
|
682
683
|
static end() {
|
|
683
684
|
this.genericQueue.end();
|
|
@@ -757,29 +758,41 @@ var ImageLoader = class _ImageLoader {
|
|
|
757
758
|
static async loadAsync(src) {
|
|
758
759
|
return new Promise((resolve, reject) => {
|
|
759
760
|
const image = this._createImage();
|
|
760
|
-
image.src = src;
|
|
761
761
|
image.onload = () => resolve(image);
|
|
762
|
-
image.onerror = (err) => reject(err);
|
|
762
|
+
image.onerror = (err) => reject(err instanceof Error ? err : new Error("Failed to decode image"));
|
|
763
|
+
image.src = src;
|
|
763
764
|
});
|
|
764
765
|
}
|
|
765
766
|
static loadElement(src, onload, onerr) {
|
|
766
767
|
const image = this._createImage();
|
|
767
|
-
image.src = src;
|
|
768
768
|
if (onload)
|
|
769
769
|
image.onload = onload;
|
|
770
770
|
if (onerr)
|
|
771
771
|
image.onerror = onerr;
|
|
772
|
+
image.src = src;
|
|
772
773
|
return image;
|
|
773
774
|
}
|
|
774
775
|
static async loadData(src) {
|
|
775
776
|
console.debug(p2, "loadData", src);
|
|
776
|
-
|
|
777
|
+
const image = await this.loadCanvasData(src);
|
|
778
|
+
return image.data.getImageData(0, 0, image.width, image.height);
|
|
777
779
|
}
|
|
778
780
|
static async loadCanvasData(src) {
|
|
779
|
-
|
|
781
|
+
const keyStr = serializeImageKey({ src });
|
|
782
|
+
const info = this.getInfo(src);
|
|
783
|
+
const cached = Caching.rawImageCache.getIfPresent(keyStr);
|
|
784
|
+
try {
|
|
785
|
+
return await this.infoToCanvasData(await info);
|
|
786
|
+
} catch (err) {
|
|
787
|
+
if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {
|
|
788
|
+
Caching.rawImageCache.invalidate(keyStr);
|
|
789
|
+
}
|
|
790
|
+
throw err;
|
|
791
|
+
}
|
|
780
792
|
}
|
|
781
793
|
static async infoToCanvasData(info) {
|
|
782
|
-
const
|
|
794
|
+
const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
|
|
795
|
+
const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
|
|
783
796
|
const canvas = createCanvas(info.width, info.height);
|
|
784
797
|
const context = canvas.getContext("2d");
|
|
785
798
|
context.drawImage(image, 0, 0);
|
|
@@ -790,11 +803,8 @@ var ImageLoader = class _ImageLoader {
|
|
|
790
803
|
};
|
|
791
804
|
}
|
|
792
805
|
static async infoToData(info) {
|
|
793
|
-
const image = await
|
|
794
|
-
|
|
795
|
-
const context = canvas.getContext("2d");
|
|
796
|
-
context.drawImage(image, 0, 0);
|
|
797
|
-
return context.getImageData(0, 0, canvas.width, canvas.height);
|
|
806
|
+
const image = await this.infoToCanvasData(info);
|
|
807
|
+
return image.data.getImageData(0, 0, image.width, image.height);
|
|
798
808
|
}
|
|
799
809
|
static async getData(src) {
|
|
800
810
|
const keyStr = serializeImageKey({ src });
|
|
@@ -809,13 +819,16 @@ var ImageLoader = class _ImageLoader {
|
|
|
809
819
|
});
|
|
810
820
|
}
|
|
811
821
|
static async processResponse(response) {
|
|
812
|
-
const src = response.config
|
|
822
|
+
const src = response.config?.url;
|
|
813
823
|
const data = Buffer2.from(response.data);
|
|
814
824
|
const { width, height, type } = Env.provider.imageSize(data);
|
|
825
|
+
if (!width || !height) {
|
|
826
|
+
throw new Error("Invalid or unsupported image dimensions");
|
|
827
|
+
}
|
|
815
828
|
return {
|
|
816
829
|
src,
|
|
817
|
-
width
|
|
818
|
-
height
|
|
830
|
+
width,
|
|
831
|
+
height,
|
|
819
832
|
type,
|
|
820
833
|
data
|
|
821
834
|
};
|
|
@@ -832,15 +845,7 @@ var ImageLoader = class _ImageLoader {
|
|
|
832
845
|
return Requests.genericRequest({
|
|
833
846
|
url: src,
|
|
834
847
|
responseType: "arraybuffer"
|
|
835
|
-
}).then(this.processResponse)
|
|
836
|
-
return {
|
|
837
|
-
src,
|
|
838
|
-
width: 0,
|
|
839
|
-
height: 0,
|
|
840
|
-
type: void 0,
|
|
841
|
-
data: Buffer2.from([0])
|
|
842
|
-
};
|
|
843
|
-
});
|
|
848
|
+
}).then(this.processResponse);
|
|
844
849
|
}
|
|
845
850
|
static async getInfo(src) {
|
|
846
851
|
const keyStr = serializeImageKey({ src });
|
|
@@ -862,16 +867,22 @@ var ImageLoader = class _ImageLoader {
|
|
|
862
867
|
|
|
863
868
|
// src/texture/TextureLoader.ts
|
|
864
869
|
var TextureLoader = class {
|
|
870
|
+
/** Reports whether image loading failed, so cached textures can be retried. */
|
|
871
|
+
static hasFailed(texture) {
|
|
872
|
+
return this.failedTextures.has(texture);
|
|
873
|
+
}
|
|
865
874
|
static createTexture() {
|
|
866
875
|
return new Texture();
|
|
867
876
|
}
|
|
868
877
|
static loadInBackground(src, format = RGBAFormat, rotation = 0) {
|
|
869
878
|
const texture = this.createTexture();
|
|
870
879
|
texture.colorSpace = THREE.SRGBColorSpace;
|
|
871
|
-
const image = ImageLoader.loadElement(src)
|
|
872
|
-
image.onload = function() {
|
|
880
|
+
const image = ImageLoader.loadElement(src, () => {
|
|
873
881
|
texture.needsUpdate = true;
|
|
874
|
-
}
|
|
882
|
+
}, (error) => {
|
|
883
|
+
this.failedTextures.add(texture);
|
|
884
|
+
console.warn("Failed to load texture", src, error);
|
|
885
|
+
});
|
|
875
886
|
texture.image = image;
|
|
876
887
|
texture.format = format;
|
|
877
888
|
texture.rotation = rotation;
|
|
@@ -881,14 +892,18 @@ var TextureLoader = class {
|
|
|
881
892
|
const texture = new Texture();
|
|
882
893
|
texture.colorSpace = THREE.SRGBColorSpace;
|
|
883
894
|
ImageLoader.getData(src).then((image) => {
|
|
884
|
-
texture.needsUpdate = true;
|
|
885
895
|
texture.image = image;
|
|
896
|
+
texture.needsUpdate = true;
|
|
897
|
+
}).catch((error) => {
|
|
898
|
+
this.failedTextures.add(texture);
|
|
899
|
+
console.warn("Failed to load texture", src, error);
|
|
886
900
|
});
|
|
887
901
|
texture.format = format;
|
|
888
902
|
texture.rotation = rotation;
|
|
889
903
|
return Textures.initTextureProps(texture);
|
|
890
904
|
}
|
|
891
905
|
};
|
|
906
|
+
TextureLoader.failedTextures = /* @__PURE__ */ new WeakSet();
|
|
892
907
|
|
|
893
908
|
// src/texture/Textures.ts
|
|
894
909
|
import * as THREE2 from "three";
|
|
@@ -912,6 +927,10 @@ var Textures = class _Textures {
|
|
|
912
927
|
}
|
|
913
928
|
static getImage(key) {
|
|
914
929
|
const keyStr = serializeTextureKey(key);
|
|
930
|
+
const cached = Caching.textureCache.peek(keyStr);
|
|
931
|
+
if (cached && TextureLoader.hasFailed(cached)) {
|
|
932
|
+
Caching.textureCache.invalidate(keyStr);
|
|
933
|
+
}
|
|
915
934
|
return Caching.textureCache.get(keyStr, (k) => {
|
|
916
935
|
return _Textures.createImage(key);
|
|
917
936
|
});
|
|
@@ -1056,6 +1075,10 @@ var _Materials = class _Materials {
|
|
|
1056
1075
|
}
|
|
1057
1076
|
static getImage(key) {
|
|
1058
1077
|
const keyStr = serializeMaterialKey(key);
|
|
1078
|
+
const map = Caching.materialCache.peek(keyStr)?.map;
|
|
1079
|
+
if (map && TextureLoader.hasFailed(map)) {
|
|
1080
|
+
Caching.materialCache.invalidate(keyStr);
|
|
1081
|
+
}
|
|
1059
1082
|
return Caching.materialCache.get(keyStr, (k) => {
|
|
1060
1083
|
return _Materials.createImage(key);
|
|
1061
1084
|
});
|
|
@@ -1713,11 +1736,21 @@ var ModelTextures = class {
|
|
|
1713
1736
|
return this._persistentMetaCache ?? (this._persistentMetaCache = PersistentCache.open("minerender-texturemeta"));
|
|
1714
1737
|
}
|
|
1715
1738
|
static async get(key) {
|
|
1716
|
-
const
|
|
1717
|
-
|
|
1718
|
-
|
|
1739
|
+
const keyStr = key.serialize();
|
|
1740
|
+
const pending = this.preload(key);
|
|
1741
|
+
const cached = Caching.textureAssetCache.getIfPresent(keyStr);
|
|
1742
|
+
try {
|
|
1743
|
+
const asset = await pending;
|
|
1744
|
+
if (asset) {
|
|
1745
|
+
return await ImageLoader.infoToCanvasData(asset);
|
|
1746
|
+
}
|
|
1747
|
+
return void 0;
|
|
1748
|
+
} catch (err) {
|
|
1749
|
+
if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
|
|
1750
|
+
Caching.textureAssetCache.invalidate(keyStr);
|
|
1751
|
+
}
|
|
1752
|
+
throw err;
|
|
1719
1753
|
}
|
|
1720
|
-
return void 0;
|
|
1721
1754
|
}
|
|
1722
1755
|
static async preload(key) {
|
|
1723
1756
|
const keyStr = key.serialize();
|
|
@@ -2908,8 +2941,8 @@ var EntityObject = class extends SceneObject {
|
|
|
2908
2941
|
dispose() {
|
|
2909
2942
|
super.dispose();
|
|
2910
2943
|
}
|
|
2911
|
-
|
|
2912
|
-
|
|
2944
|
+
get textureKey() {
|
|
2945
|
+
return new AssetKey(
|
|
2913
2946
|
this.entity.key?.namespace ?? DEFAULT_NAMESPACE,
|
|
2914
2947
|
this.entity.key.path,
|
|
2915
2948
|
//TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
|
|
@@ -2917,7 +2950,10 @@ var EntityObject = class extends SceneObject {
|
|
|
2917
2950
|
"entity",
|
|
2918
2951
|
"assets",
|
|
2919
2952
|
".png"
|
|
2920
|
-
)
|
|
2953
|
+
);
|
|
2954
|
+
}
|
|
2955
|
+
async loadTextures() {
|
|
2956
|
+
this.imageData = await ModelTextures.get(this.textureKey);
|
|
2921
2957
|
}
|
|
2922
2958
|
//TODO: abstract this, since extracted model data can be used for entities, blocks, players
|
|
2923
2959
|
createMeshes(force = false) {
|
|
@@ -2950,20 +2986,23 @@ var EntityObject = class extends SceneObject {
|
|
|
2950
2986
|
this.meshesCreated = true;
|
|
2951
2987
|
}
|
|
2952
2988
|
async applyTextures() {
|
|
2953
|
-
const
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2989
|
+
const assetKeyStr = this.textureKey.serialize();
|
|
2990
|
+
const keyStr = `entity:${assetKeyStr}`;
|
|
2991
|
+
let mat = Caching.materialCache.getIfPresent(keyStr);
|
|
2992
|
+
if (!mat) {
|
|
2993
|
+
const pending = this.loadTextures();
|
|
2994
|
+
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
|
|
2995
|
+
await pending;
|
|
2996
|
+
if (!this.imageData) return;
|
|
2997
|
+
const canvas = this.imageData.data.canvas;
|
|
2998
|
+
const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
|
|
2999
|
+
mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
3000
|
+
this.imageData = void 0;
|
|
3001
|
+
}
|
|
3002
|
+
this.iterateAllMeshes((mesh) => {
|
|
3003
|
+
mesh.material = mat;
|
|
3004
|
+
});
|
|
3005
|
+
this.notifyDirty();
|
|
2967
3006
|
}
|
|
2968
3007
|
};
|
|
2969
3008
|
EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
|