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/node/index.mjs
CHANGED
|
@@ -385,8 +385,8 @@ var Caching = class {
|
|
|
385
385
|
/**
|
|
386
386
|
* Clears every cache and stops its expiry timer.
|
|
387
387
|
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
388
|
+
* Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.
|
|
389
|
+
* Use {@link shutdown} to also stop requests and the shared Ticker.
|
|
390
390
|
*/
|
|
391
391
|
static end() {
|
|
392
392
|
for (const cache of this.all) {
|
|
@@ -634,13 +634,14 @@ var _Requests = class _Requests {
|
|
|
634
634
|
}
|
|
635
635
|
static get queueSizes() {
|
|
636
636
|
return {
|
|
637
|
-
generic: this.genericQueue.size,
|
|
638
|
-
mcAsset: this.mcAssetRequestQueue.size
|
|
637
|
+
generic: this.genericQueue.size + this.genericQueue.activeSize,
|
|
638
|
+
mcAsset: this.mcAssetRequestQueue.size + this.mcAssetRequestQueue.activeSize
|
|
639
639
|
};
|
|
640
640
|
}
|
|
641
641
|
/**
|
|
642
|
-
*
|
|
643
|
-
*
|
|
642
|
+
* Permanently stops both queues and rejects waiting and future requests.
|
|
643
|
+
* Requests already running can finish. Idle queues hold no timer, so Node can exit without
|
|
644
|
+
* this cleanup. See {@link shutdown}.
|
|
644
645
|
*/
|
|
645
646
|
static end() {
|
|
646
647
|
this.genericQueue.end();
|
|
@@ -720,29 +721,41 @@ var ImageLoader = class _ImageLoader {
|
|
|
720
721
|
static async loadAsync(src) {
|
|
721
722
|
return new Promise((resolve, reject) => {
|
|
722
723
|
const image = this._createImage();
|
|
723
|
-
image.src = src;
|
|
724
724
|
image.onload = () => resolve(image);
|
|
725
|
-
image.onerror = (err) => reject(err);
|
|
725
|
+
image.onerror = (err) => reject(err instanceof Error ? err : new Error("Failed to decode image"));
|
|
726
|
+
image.src = src;
|
|
726
727
|
});
|
|
727
728
|
}
|
|
728
729
|
static loadElement(src, onload, onerr) {
|
|
729
730
|
const image = this._createImage();
|
|
730
|
-
image.src = src;
|
|
731
731
|
if (onload)
|
|
732
732
|
image.onload = onload;
|
|
733
733
|
if (onerr)
|
|
734
734
|
image.onerror = onerr;
|
|
735
|
+
image.src = src;
|
|
735
736
|
return image;
|
|
736
737
|
}
|
|
737
738
|
static async loadData(src) {
|
|
738
739
|
console.debug(p2, "loadData", src);
|
|
739
|
-
|
|
740
|
+
const image = await this.loadCanvasData(src);
|
|
741
|
+
return image.data.getImageData(0, 0, image.width, image.height);
|
|
740
742
|
}
|
|
741
743
|
static async loadCanvasData(src) {
|
|
742
|
-
|
|
744
|
+
const keyStr = serializeImageKey({ src });
|
|
745
|
+
const info = this.getInfo(src);
|
|
746
|
+
const cached = Caching.rawImageCache.getIfPresent(keyStr);
|
|
747
|
+
try {
|
|
748
|
+
return await this.infoToCanvasData(await info);
|
|
749
|
+
} catch (err) {
|
|
750
|
+
if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {
|
|
751
|
+
Caching.rawImageCache.invalidate(keyStr);
|
|
752
|
+
}
|
|
753
|
+
throw err;
|
|
754
|
+
}
|
|
743
755
|
}
|
|
744
756
|
static async infoToCanvasData(info) {
|
|
745
|
-
const
|
|
757
|
+
const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
|
|
758
|
+
const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
|
|
746
759
|
const canvas = createCanvas2(info.width, info.height);
|
|
747
760
|
const context = canvas.getContext("2d");
|
|
748
761
|
context.drawImage(image, 0, 0);
|
|
@@ -753,11 +766,8 @@ var ImageLoader = class _ImageLoader {
|
|
|
753
766
|
};
|
|
754
767
|
}
|
|
755
768
|
static async infoToData(info) {
|
|
756
|
-
const image = await
|
|
757
|
-
|
|
758
|
-
const context = canvas.getContext("2d");
|
|
759
|
-
context.drawImage(image, 0, 0);
|
|
760
|
-
return context.getImageData(0, 0, canvas.width, canvas.height);
|
|
769
|
+
const image = await this.infoToCanvasData(info);
|
|
770
|
+
return image.data.getImageData(0, 0, image.width, image.height);
|
|
761
771
|
}
|
|
762
772
|
static async getData(src) {
|
|
763
773
|
const keyStr = serializeImageKey({ src });
|
|
@@ -772,13 +782,17 @@ var ImageLoader = class _ImageLoader {
|
|
|
772
782
|
});
|
|
773
783
|
}
|
|
774
784
|
static async processResponse(response) {
|
|
775
|
-
|
|
785
|
+
var _a;
|
|
786
|
+
const src = (_a = response.config) == null ? void 0 : _a.url;
|
|
776
787
|
const data = Buffer2.from(response.data);
|
|
777
788
|
const { width, height, type } = Env.provider.imageSize(data);
|
|
789
|
+
if (!width || !height) {
|
|
790
|
+
throw new Error("Invalid or unsupported image dimensions");
|
|
791
|
+
}
|
|
778
792
|
return {
|
|
779
793
|
src,
|
|
780
|
-
width
|
|
781
|
-
height
|
|
794
|
+
width,
|
|
795
|
+
height,
|
|
782
796
|
type,
|
|
783
797
|
data
|
|
784
798
|
};
|
|
@@ -795,15 +809,7 @@ var ImageLoader = class _ImageLoader {
|
|
|
795
809
|
return Requests.genericRequest({
|
|
796
810
|
url: src,
|
|
797
811
|
responseType: "arraybuffer"
|
|
798
|
-
}).then(this.processResponse)
|
|
799
|
-
return {
|
|
800
|
-
src,
|
|
801
|
-
width: 0,
|
|
802
|
-
height: 0,
|
|
803
|
-
type: void 0,
|
|
804
|
-
data: Buffer2.from([0])
|
|
805
|
-
};
|
|
806
|
-
});
|
|
812
|
+
}).then(this.processResponse);
|
|
807
813
|
}
|
|
808
814
|
static async getInfo(src) {
|
|
809
815
|
const keyStr = serializeImageKey({ src });
|
|
@@ -825,16 +831,22 @@ var ImageLoader = class _ImageLoader {
|
|
|
825
831
|
|
|
826
832
|
// src/texture/TextureLoader.ts
|
|
827
833
|
var TextureLoader = class {
|
|
834
|
+
/** Reports whether image loading failed, so cached textures can be retried. */
|
|
835
|
+
static hasFailed(texture) {
|
|
836
|
+
return this.failedTextures.has(texture);
|
|
837
|
+
}
|
|
828
838
|
static createTexture() {
|
|
829
839
|
return new Texture();
|
|
830
840
|
}
|
|
831
841
|
static loadInBackground(src, format = RGBAFormat, rotation = 0) {
|
|
832
842
|
const texture = this.createTexture();
|
|
833
843
|
texture.colorSpace = THREE.SRGBColorSpace;
|
|
834
|
-
const image = ImageLoader.loadElement(src)
|
|
835
|
-
image.onload = function() {
|
|
844
|
+
const image = ImageLoader.loadElement(src, () => {
|
|
836
845
|
texture.needsUpdate = true;
|
|
837
|
-
}
|
|
846
|
+
}, (error) => {
|
|
847
|
+
this.failedTextures.add(texture);
|
|
848
|
+
console.warn("Failed to load texture", src, error);
|
|
849
|
+
});
|
|
838
850
|
texture.image = image;
|
|
839
851
|
texture.format = format;
|
|
840
852
|
texture.rotation = rotation;
|
|
@@ -844,14 +856,18 @@ var TextureLoader = class {
|
|
|
844
856
|
const texture = new Texture();
|
|
845
857
|
texture.colorSpace = THREE.SRGBColorSpace;
|
|
846
858
|
ImageLoader.getData(src).then((image) => {
|
|
847
|
-
texture.needsUpdate = true;
|
|
848
859
|
texture.image = image;
|
|
860
|
+
texture.needsUpdate = true;
|
|
861
|
+
}).catch((error) => {
|
|
862
|
+
this.failedTextures.add(texture);
|
|
863
|
+
console.warn("Failed to load texture", src, error);
|
|
849
864
|
});
|
|
850
865
|
texture.format = format;
|
|
851
866
|
texture.rotation = rotation;
|
|
852
867
|
return Textures.initTextureProps(texture);
|
|
853
868
|
}
|
|
854
869
|
};
|
|
870
|
+
TextureLoader.failedTextures = /* @__PURE__ */ new WeakSet();
|
|
855
871
|
|
|
856
872
|
// src/texture/Textures.ts
|
|
857
873
|
import * as THREE2 from "three";
|
|
@@ -875,6 +891,10 @@ var Textures = class _Textures {
|
|
|
875
891
|
}
|
|
876
892
|
static getImage(key) {
|
|
877
893
|
const keyStr = serializeTextureKey(key);
|
|
894
|
+
const cached = Caching.textureCache.peek(keyStr);
|
|
895
|
+
if (cached && TextureLoader.hasFailed(cached)) {
|
|
896
|
+
Caching.textureCache.invalidate(keyStr);
|
|
897
|
+
}
|
|
878
898
|
return Caching.textureCache.get(keyStr, (k) => {
|
|
879
899
|
return _Textures.createImage(key);
|
|
880
900
|
});
|
|
@@ -1018,7 +1038,12 @@ var _Materials = class _Materials {
|
|
|
1018
1038
|
return this.createBasicCanvasMaterial(canvas, transparent, shade);
|
|
1019
1039
|
}
|
|
1020
1040
|
static getImage(key) {
|
|
1041
|
+
var _a;
|
|
1021
1042
|
const keyStr = serializeMaterialKey(key);
|
|
1043
|
+
const map = (_a = Caching.materialCache.peek(keyStr)) == null ? void 0 : _a.map;
|
|
1044
|
+
if (map && TextureLoader.hasFailed(map)) {
|
|
1045
|
+
Caching.materialCache.invalidate(keyStr);
|
|
1046
|
+
}
|
|
1022
1047
|
return Caching.materialCache.get(keyStr, (k) => {
|
|
1023
1048
|
return _Materials.createImage(key);
|
|
1024
1049
|
});
|
|
@@ -1676,11 +1701,21 @@ var ModelTextures = class {
|
|
|
1676
1701
|
return this._persistentMetaCache ??= PersistentCache.open("minerender-texturemeta");
|
|
1677
1702
|
}
|
|
1678
1703
|
static async get(key) {
|
|
1679
|
-
const
|
|
1680
|
-
|
|
1681
|
-
|
|
1704
|
+
const keyStr = key.serialize();
|
|
1705
|
+
const pending = this.preload(key);
|
|
1706
|
+
const cached = Caching.textureAssetCache.getIfPresent(keyStr);
|
|
1707
|
+
try {
|
|
1708
|
+
const asset = await pending;
|
|
1709
|
+
if (asset) {
|
|
1710
|
+
return await ImageLoader.infoToCanvasData(asset);
|
|
1711
|
+
}
|
|
1712
|
+
return void 0;
|
|
1713
|
+
} catch (err) {
|
|
1714
|
+
if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
|
|
1715
|
+
Caching.textureAssetCache.invalidate(keyStr);
|
|
1716
|
+
}
|
|
1717
|
+
throw err;
|
|
1682
1718
|
}
|
|
1683
|
-
return void 0;
|
|
1684
1719
|
}
|
|
1685
1720
|
static async preload(key) {
|
|
1686
1721
|
const keyStr = key.serialize();
|
|
@@ -2874,9 +2909,9 @@ var EntityObject = class extends SceneObject {
|
|
|
2874
2909
|
dispose() {
|
|
2875
2910
|
super.dispose();
|
|
2876
2911
|
}
|
|
2877
|
-
|
|
2912
|
+
get textureKey() {
|
|
2878
2913
|
var _a;
|
|
2879
|
-
|
|
2914
|
+
return new AssetKey(
|
|
2880
2915
|
((_a = this.entity.key) == null ? void 0 : _a.namespace) ?? DEFAULT_NAMESPACE,
|
|
2881
2916
|
this.entity.key.path,
|
|
2882
2917
|
//TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
|
|
@@ -2884,7 +2919,10 @@ var EntityObject = class extends SceneObject {
|
|
|
2884
2919
|
"entity",
|
|
2885
2920
|
"assets",
|
|
2886
2921
|
".png"
|
|
2887
|
-
)
|
|
2922
|
+
);
|
|
2923
|
+
}
|
|
2924
|
+
async loadTextures() {
|
|
2925
|
+
this.imageData = await ModelTextures.get(this.textureKey);
|
|
2888
2926
|
}
|
|
2889
2927
|
//TODO: abstract this, since extracted model data can be used for entities, blocks, players
|
|
2890
2928
|
createMeshes(force = false) {
|
|
@@ -2917,21 +2955,23 @@ var EntityObject = class extends SceneObject {
|
|
|
2917
2955
|
this.meshesCreated = true;
|
|
2918
2956
|
}
|
|
2919
2957
|
async applyTextures() {
|
|
2920
|
-
|
|
2921
|
-
const
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
this.
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2958
|
+
const assetKeyStr = this.textureKey.serialize();
|
|
2959
|
+
const keyStr = `entity:${assetKeyStr}`;
|
|
2960
|
+
let mat = Caching.materialCache.getIfPresent(keyStr);
|
|
2961
|
+
if (!mat) {
|
|
2962
|
+
const pending = this.loadTextures();
|
|
2963
|
+
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
|
|
2964
|
+
await pending;
|
|
2965
|
+
if (!this.imageData) return;
|
|
2966
|
+
const canvas = this.imageData.data.canvas;
|
|
2967
|
+
const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
|
|
2968
|
+
mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
2969
|
+
this.imageData = void 0;
|
|
2970
|
+
}
|
|
2971
|
+
this.iterateAllMeshes((mesh) => {
|
|
2972
|
+
mesh.material = mat;
|
|
2973
|
+
});
|
|
2974
|
+
this.notifyDirty();
|
|
2935
2975
|
}
|
|
2936
2976
|
};
|
|
2937
2977
|
EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
|