minerender 2.1.0-alpha.7 → 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 +5 -1
- package/dist/browser/index.d.ts +5 -1
- package/dist/browser/index.js +86 -48
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +86 -48
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +86 -48
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +4 -0
- package/dist/node/index.d.ts +4 -0
- package/dist/node/index.js +88 -49
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +88 -49
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/node/index.d.mts
CHANGED
|
@@ -853,6 +853,7 @@ declare class EntityObject extends SceneObject {
|
|
|
853
853
|
constructor(entity: EntityModel, options?: Partial<EntityObjectOptions>);
|
|
854
854
|
init(): Promise<void>;
|
|
855
855
|
dispose(): void;
|
|
856
|
+
private get textureKey();
|
|
856
857
|
protected loadTextures(): Promise<void>;
|
|
857
858
|
protected createMeshes(force?: boolean): void;
|
|
858
859
|
protected applyTextures(): Promise<void>;
|
|
@@ -1512,6 +1513,9 @@ declare class Skins {
|
|
|
1512
1513
|
}
|
|
1513
1514
|
|
|
1514
1515
|
declare class TextureLoader {
|
|
1516
|
+
private static readonly failedTextures;
|
|
1517
|
+
/** Reports whether image loading failed, so cached textures can be retried. */
|
|
1518
|
+
static hasFailed(texture: Texture): boolean;
|
|
1515
1519
|
protected static createTexture(): Texture;
|
|
1516
1520
|
static loadInBackground(src: string, format?: PixelFormat, rotation?: number): Texture;
|
|
1517
1521
|
static load(src: string, format?: PixelFormat, rotation?: number): Texture;
|
package/dist/node/index.d.ts
CHANGED
|
@@ -853,6 +853,7 @@ declare class EntityObject extends SceneObject {
|
|
|
853
853
|
constructor(entity: EntityModel, options?: Partial<EntityObjectOptions>);
|
|
854
854
|
init(): Promise<void>;
|
|
855
855
|
dispose(): void;
|
|
856
|
+
private get textureKey();
|
|
856
857
|
protected loadTextures(): Promise<void>;
|
|
857
858
|
protected createMeshes(force?: boolean): void;
|
|
858
859
|
protected applyTextures(): Promise<void>;
|
|
@@ -1512,6 +1513,9 @@ declare class Skins {
|
|
|
1512
1513
|
}
|
|
1513
1514
|
|
|
1514
1515
|
declare class TextureLoader {
|
|
1516
|
+
private static readonly failedTextures;
|
|
1517
|
+
/** Reports whether image loading failed, so cached textures can be retried. */
|
|
1518
|
+
static hasFailed(texture: Texture): boolean;
|
|
1515
1519
|
protected static createTexture(): Texture;
|
|
1516
1520
|
static loadInBackground(src: string, format?: PixelFormat, rotation?: number): Texture;
|
|
1517
1521
|
static load(src: string, format?: PixelFormat, rotation?: number): Texture;
|
package/dist/node/index.js
CHANGED
|
@@ -874,29 +874,41 @@ var ImageLoader = class _ImageLoader {
|
|
|
874
874
|
static async loadAsync(src) {
|
|
875
875
|
return new Promise((resolve, reject) => {
|
|
876
876
|
const image = this._createImage();
|
|
877
|
-
image.src = src;
|
|
878
877
|
image.onload = () => resolve(image);
|
|
879
|
-
image.onerror = (err) => reject(err);
|
|
878
|
+
image.onerror = (err) => reject(err instanceof Error ? err : new Error("Failed to decode image"));
|
|
879
|
+
image.src = src;
|
|
880
880
|
});
|
|
881
881
|
}
|
|
882
882
|
static loadElement(src, onload, onerr) {
|
|
883
883
|
const image = this._createImage();
|
|
884
|
-
image.src = src;
|
|
885
884
|
if (onload)
|
|
886
885
|
image.onload = onload;
|
|
887
886
|
if (onerr)
|
|
888
887
|
image.onerror = onerr;
|
|
888
|
+
image.src = src;
|
|
889
889
|
return image;
|
|
890
890
|
}
|
|
891
891
|
static async loadData(src) {
|
|
892
892
|
console.debug(p2, "loadData", src);
|
|
893
|
-
|
|
893
|
+
const image = await this.loadCanvasData(src);
|
|
894
|
+
return image.data.getImageData(0, 0, image.width, image.height);
|
|
894
895
|
}
|
|
895
896
|
static async loadCanvasData(src) {
|
|
896
|
-
|
|
897
|
+
const keyStr = serializeImageKey({ src });
|
|
898
|
+
const info = this.getInfo(src);
|
|
899
|
+
const cached = Caching.rawImageCache.getIfPresent(keyStr);
|
|
900
|
+
try {
|
|
901
|
+
return await this.infoToCanvasData(await info);
|
|
902
|
+
} catch (err) {
|
|
903
|
+
if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {
|
|
904
|
+
Caching.rawImageCache.invalidate(keyStr);
|
|
905
|
+
}
|
|
906
|
+
throw err;
|
|
907
|
+
}
|
|
897
908
|
}
|
|
898
909
|
static async infoToCanvasData(info) {
|
|
899
|
-
const
|
|
910
|
+
const type = info.type === "jpg" ? "jpeg" : info.type ?? "png";
|
|
911
|
+
const image = await _ImageLoader.loadAsync(`data:image/${type};base64,${info.data.toString("base64")}`);
|
|
900
912
|
const canvas = createCanvas2(info.width, info.height);
|
|
901
913
|
const context = canvas.getContext("2d");
|
|
902
914
|
context.drawImage(image, 0, 0);
|
|
@@ -907,11 +919,8 @@ var ImageLoader = class _ImageLoader {
|
|
|
907
919
|
};
|
|
908
920
|
}
|
|
909
921
|
static async infoToData(info) {
|
|
910
|
-
const image = await
|
|
911
|
-
|
|
912
|
-
const context = canvas.getContext("2d");
|
|
913
|
-
context.drawImage(image, 0, 0);
|
|
914
|
-
return context.getImageData(0, 0, canvas.width, canvas.height);
|
|
922
|
+
const image = await this.infoToCanvasData(info);
|
|
923
|
+
return image.data.getImageData(0, 0, image.width, image.height);
|
|
915
924
|
}
|
|
916
925
|
static async getData(src) {
|
|
917
926
|
const keyStr = serializeImageKey({ src });
|
|
@@ -926,13 +935,17 @@ var ImageLoader = class _ImageLoader {
|
|
|
926
935
|
});
|
|
927
936
|
}
|
|
928
937
|
static async processResponse(response) {
|
|
929
|
-
|
|
938
|
+
var _a;
|
|
939
|
+
const src = (_a = response.config) == null ? void 0 : _a.url;
|
|
930
940
|
const data = import_buffer.Buffer.from(response.data);
|
|
931
941
|
const { width, height, type } = Env.provider.imageSize(data);
|
|
942
|
+
if (!width || !height) {
|
|
943
|
+
throw new Error("Invalid or unsupported image dimensions");
|
|
944
|
+
}
|
|
932
945
|
return {
|
|
933
946
|
src,
|
|
934
|
-
width
|
|
935
|
-
height
|
|
947
|
+
width,
|
|
948
|
+
height,
|
|
936
949
|
type,
|
|
937
950
|
data
|
|
938
951
|
};
|
|
@@ -949,15 +962,7 @@ var ImageLoader = class _ImageLoader {
|
|
|
949
962
|
return Requests.genericRequest({
|
|
950
963
|
url: src,
|
|
951
964
|
responseType: "arraybuffer"
|
|
952
|
-
}).then(this.processResponse)
|
|
953
|
-
return {
|
|
954
|
-
src,
|
|
955
|
-
width: 0,
|
|
956
|
-
height: 0,
|
|
957
|
-
type: void 0,
|
|
958
|
-
data: import_buffer.Buffer.from([0])
|
|
959
|
-
};
|
|
960
|
-
});
|
|
965
|
+
}).then(this.processResponse);
|
|
961
966
|
}
|
|
962
967
|
static async getInfo(src) {
|
|
963
968
|
const keyStr = serializeImageKey({ src });
|
|
@@ -979,16 +984,22 @@ var ImageLoader = class _ImageLoader {
|
|
|
979
984
|
|
|
980
985
|
// src/texture/TextureLoader.ts
|
|
981
986
|
var TextureLoader = class {
|
|
987
|
+
/** Reports whether image loading failed, so cached textures can be retried. */
|
|
988
|
+
static hasFailed(texture) {
|
|
989
|
+
return this.failedTextures.has(texture);
|
|
990
|
+
}
|
|
982
991
|
static createTexture() {
|
|
983
992
|
return new import_three4.Texture();
|
|
984
993
|
}
|
|
985
994
|
static loadInBackground(src, format = import_three4.RGBAFormat, rotation = 0) {
|
|
986
995
|
const texture = this.createTexture();
|
|
987
996
|
texture.colorSpace = THREE.SRGBColorSpace;
|
|
988
|
-
const image = ImageLoader.loadElement(src)
|
|
989
|
-
image.onload = function() {
|
|
997
|
+
const image = ImageLoader.loadElement(src, () => {
|
|
990
998
|
texture.needsUpdate = true;
|
|
991
|
-
}
|
|
999
|
+
}, (error) => {
|
|
1000
|
+
this.failedTextures.add(texture);
|
|
1001
|
+
console.warn("Failed to load texture", src, error);
|
|
1002
|
+
});
|
|
992
1003
|
texture.image = image;
|
|
993
1004
|
texture.format = format;
|
|
994
1005
|
texture.rotation = rotation;
|
|
@@ -998,14 +1009,18 @@ var TextureLoader = class {
|
|
|
998
1009
|
const texture = new import_three4.Texture();
|
|
999
1010
|
texture.colorSpace = THREE.SRGBColorSpace;
|
|
1000
1011
|
ImageLoader.getData(src).then((image) => {
|
|
1001
|
-
texture.needsUpdate = true;
|
|
1002
1012
|
texture.image = image;
|
|
1013
|
+
texture.needsUpdate = true;
|
|
1014
|
+
}).catch((error) => {
|
|
1015
|
+
this.failedTextures.add(texture);
|
|
1016
|
+
console.warn("Failed to load texture", src, error);
|
|
1003
1017
|
});
|
|
1004
1018
|
texture.format = format;
|
|
1005
1019
|
texture.rotation = rotation;
|
|
1006
1020
|
return Textures.initTextureProps(texture);
|
|
1007
1021
|
}
|
|
1008
1022
|
};
|
|
1023
|
+
TextureLoader.failedTextures = /* @__PURE__ */ new WeakSet();
|
|
1009
1024
|
|
|
1010
1025
|
// src/texture/Textures.ts
|
|
1011
1026
|
var THREE2 = __toESM(require("three"));
|
|
@@ -1029,6 +1044,10 @@ var Textures = class _Textures {
|
|
|
1029
1044
|
}
|
|
1030
1045
|
static getImage(key) {
|
|
1031
1046
|
const keyStr = serializeTextureKey(key);
|
|
1047
|
+
const cached = Caching.textureCache.peek(keyStr);
|
|
1048
|
+
if (cached && TextureLoader.hasFailed(cached)) {
|
|
1049
|
+
Caching.textureCache.invalidate(keyStr);
|
|
1050
|
+
}
|
|
1032
1051
|
return Caching.textureCache.get(keyStr, (k) => {
|
|
1033
1052
|
return _Textures.createImage(key);
|
|
1034
1053
|
});
|
|
@@ -1172,7 +1191,12 @@ var _Materials = class _Materials {
|
|
|
1172
1191
|
return this.createBasicCanvasMaterial(canvas, transparent, shade);
|
|
1173
1192
|
}
|
|
1174
1193
|
static getImage(key) {
|
|
1194
|
+
var _a;
|
|
1175
1195
|
const keyStr = serializeMaterialKey(key);
|
|
1196
|
+
const map = (_a = Caching.materialCache.peek(keyStr)) == null ? void 0 : _a.map;
|
|
1197
|
+
if (map && TextureLoader.hasFailed(map)) {
|
|
1198
|
+
Caching.materialCache.invalidate(keyStr);
|
|
1199
|
+
}
|
|
1176
1200
|
return Caching.materialCache.get(keyStr, (k) => {
|
|
1177
1201
|
return _Materials.createImage(key);
|
|
1178
1202
|
});
|
|
@@ -1830,11 +1854,21 @@ var ModelTextures = class {
|
|
|
1830
1854
|
return this._persistentMetaCache ??= PersistentCache.open("minerender-texturemeta");
|
|
1831
1855
|
}
|
|
1832
1856
|
static async get(key) {
|
|
1833
|
-
const
|
|
1834
|
-
|
|
1835
|
-
|
|
1857
|
+
const keyStr = key.serialize();
|
|
1858
|
+
const pending = this.preload(key);
|
|
1859
|
+
const cached = Caching.textureAssetCache.getIfPresent(keyStr);
|
|
1860
|
+
try {
|
|
1861
|
+
const asset = await pending;
|
|
1862
|
+
if (asset) {
|
|
1863
|
+
return await ImageLoader.infoToCanvasData(asset);
|
|
1864
|
+
}
|
|
1865
|
+
return void 0;
|
|
1866
|
+
} catch (err) {
|
|
1867
|
+
if (cached && Caching.textureAssetCache.getIfPresent(keyStr) === cached) {
|
|
1868
|
+
Caching.textureAssetCache.invalidate(keyStr);
|
|
1869
|
+
}
|
|
1870
|
+
throw err;
|
|
1836
1871
|
}
|
|
1837
|
-
return void 0;
|
|
1838
1872
|
}
|
|
1839
1873
|
static async preload(key) {
|
|
1840
1874
|
const keyStr = key.serialize();
|
|
@@ -3028,9 +3062,9 @@ var EntityObject = class extends SceneObject {
|
|
|
3028
3062
|
dispose() {
|
|
3029
3063
|
super.dispose();
|
|
3030
3064
|
}
|
|
3031
|
-
|
|
3065
|
+
get textureKey() {
|
|
3032
3066
|
var _a;
|
|
3033
|
-
|
|
3067
|
+
return new AssetKey(
|
|
3034
3068
|
((_a = this.entity.key) == null ? void 0 : _a.namespace) ?? DEFAULT_NAMESPACE,
|
|
3035
3069
|
this.entity.key.path,
|
|
3036
3070
|
//TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
|
|
@@ -3038,7 +3072,10 @@ var EntityObject = class extends SceneObject {
|
|
|
3038
3072
|
"entity",
|
|
3039
3073
|
"assets",
|
|
3040
3074
|
".png"
|
|
3041
|
-
)
|
|
3075
|
+
);
|
|
3076
|
+
}
|
|
3077
|
+
async loadTextures() {
|
|
3078
|
+
this.imageData = await ModelTextures.get(this.textureKey);
|
|
3042
3079
|
}
|
|
3043
3080
|
//TODO: abstract this, since extracted model data can be used for entities, blocks, players
|
|
3044
3081
|
createMeshes(force = false) {
|
|
@@ -3071,21 +3108,23 @@ var EntityObject = class extends SceneObject {
|
|
|
3071
3108
|
this.meshesCreated = true;
|
|
3072
3109
|
}
|
|
3073
3110
|
async applyTextures() {
|
|
3074
|
-
|
|
3075
|
-
const
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
this.
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3111
|
+
const assetKeyStr = this.textureKey.serialize();
|
|
3112
|
+
const keyStr = `entity:${assetKeyStr}`;
|
|
3113
|
+
let mat = Caching.materialCache.getIfPresent(keyStr);
|
|
3114
|
+
if (!mat) {
|
|
3115
|
+
const pending = this.loadTextures();
|
|
3116
|
+
const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
|
|
3117
|
+
await pending;
|
|
3118
|
+
if (!this.imageData) return;
|
|
3119
|
+
const canvas = this.imageData.data.canvas;
|
|
3120
|
+
const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
|
|
3121
|
+
mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
|
|
3122
|
+
this.imageData = void 0;
|
|
3123
|
+
}
|
|
3124
|
+
this.iterateAllMeshes((mesh) => {
|
|
3125
|
+
mesh.material = mat;
|
|
3126
|
+
});
|
|
3127
|
+
this.notifyDirty();
|
|
3089
3128
|
}
|
|
3090
3129
|
};
|
|
3091
3130
|
EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
|