minerender 2.1.0-beta.6 → 2.1.0-beta.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/README.md +10 -1
- package/dist/browser/esm/Materials.mjs +3 -1
- package/dist/browser/esm/Materials.mjs.map +1 -1
- package/dist/browser/esm/Ticker.mjs +3 -1
- package/dist/browser/esm/Ticker.mjs.map +1 -1
- package/dist/browser/esm/UVMapper.mjs +9 -9
- package/dist/browser/esm/UVMapper.mjs.map +1 -1
- package/dist/browser/esm/armor/Armor.mjs +84 -0
- package/dist/browser/esm/armor/Armor.mjs.map +1 -0
- package/dist/browser/esm/armor/index.mjs +3 -0
- package/dist/browser/esm/armor/index.mjs.map +1 -0
- package/dist/browser/esm/assets/AssetDefaults.mjs +8 -0
- package/dist/browser/esm/assets/AssetDefaults.mjs.map +1 -0
- package/dist/browser/esm/assets/AssetKey.mjs +1 -1
- package/dist/browser/esm/assets/AssetKey.mjs.map +1 -1
- package/dist/browser/esm/assets/AssetLoader.mjs +5 -5
- package/dist/browser/esm/assets/AssetLoader.mjs.map +1 -1
- package/dist/browser/esm/assets/Assets.mjs +1 -5
- package/dist/browser/esm/assets/Assets.mjs.map +1 -1
- package/dist/browser/esm/assets/BlockEntities.mjs +5 -1
- package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
- package/dist/browser/esm/assets/BlockStates.mjs +1 -1
- package/dist/browser/esm/assets/BlockStates.mjs.map +1 -1
- package/dist/browser/esm/assets/Entities.mjs +40 -12
- package/dist/browser/esm/assets/Entities.mjs.map +1 -1
- package/dist/browser/esm/assets/MineRenderData.mjs +8 -17
- package/dist/browser/esm/assets/MineRenderData.mjs.map +1 -1
- package/dist/browser/esm/assets/ModelTextures.mjs +13 -7
- package/dist/browser/esm/assets/ModelTextures.mjs.map +1 -1
- package/dist/browser/esm/assets/Models.mjs +1 -1
- package/dist/browser/esm/assets/Models.mjs.map +1 -1
- package/dist/browser/esm/assets/_fonts/Unihex.mjs +5 -3
- package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -1
- package/dist/browser/esm/assets/_versions/DatasetVersions.mjs +22 -0
- package/dist/browser/esm/assets/_versions/DatasetVersions.mjs.map +1 -0
- package/dist/browser/esm/assets/index.mjs +1 -0
- package/dist/browser/esm/assets/index.mjs.map +1 -1
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs +7 -8
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
- package/dist/browser/esm/cache/Caching.mjs +8 -0
- package/dist/browser/esm/cache/Caching.mjs.map +1 -1
- package/dist/browser/esm/entity/scene/EntityObject.mjs +31 -5
- package/dist/browser/esm/entity/scene/EntityObject.mjs.map +1 -1
- package/dist/browser/esm/env/browser/BrowserCache.mjs +3 -3
- package/dist/browser/esm/env/browser/BrowserCache.mjs.map +1 -1
- package/dist/browser/esm/env/browser/BrowserEnv.mjs +11 -4
- package/dist/browser/esm/env/browser/BrowserEnv.mjs.map +1 -1
- package/dist/browser/esm/image/ImageLoader.mjs +3 -3
- package/dist/browser/esm/image/ImageLoader.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +191 -22
- package/dist/browser/esm/index.browser.mjs.map +1 -1
- package/dist/browser/esm/index.mjs +1 -0
- package/dist/browser/esm/index.mjs.map +1 -1
- package/dist/browser/esm/inspector/SceneInspector.mjs +3 -3
- package/dist/browser/esm/inspector/SceneInspector.mjs.map +1 -1
- package/dist/browser/esm/instance/InstanceManager.mjs +4 -4
- package/dist/browser/esm/instance/InstanceManager.mjs.map +1 -1
- package/dist/browser/esm/model/ItemGlint.mjs +7 -6
- package/dist/browser/esm/model/ItemGlint.mjs.map +1 -1
- package/dist/browser/esm/model/block/scene/BlockObject.mjs +19 -6
- package/dist/browser/esm/model/block/scene/BlockObject.mjs.map +1 -1
- package/dist/browser/esm/model/multiblock/StructureParser.mjs +7 -4
- package/dist/browser/esm/model/multiblock/StructureParser.mjs.map +1 -1
- package/dist/browser/esm/model/scene/ModelObject.mjs +4 -4
- package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
- package/dist/browser/esm/nbt/NBTHelper.mjs +5 -2
- package/dist/browser/esm/nbt/NBTHelper.mjs.map +1 -1
- package/dist/browser/esm/renderer/Renderer.mjs +4 -2
- package/dist/browser/esm/renderer/Renderer.mjs.map +1 -1
- package/dist/browser/esm/renderer/SceneObject.mjs +0 -6
- package/dist/browser/esm/renderer/SceneObject.mjs.map +1 -1
- package/dist/browser/esm/request/Requests.mjs +3 -3
- package/dist/browser/esm/request/Requests.mjs.map +1 -1
- package/dist/browser/esm/scene/SceneDocument.mjs +35 -5
- package/dist/browser/esm/scene/SceneDocument.mjs.map +1 -1
- package/dist/browser/esm/scene/SceneDocumentLoader.mjs +14 -3
- package/dist/browser/esm/scene/SceneDocumentLoader.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinGeometries.mjs +4 -1
- package/dist/browser/esm/skin/SkinGeometries.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinPart.mjs +2 -0
- package/dist/browser/esm/skin/SkinPart.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinTextureCoordinates.mjs +11 -1
- package/dist/browser/esm/skin/SkinTextureCoordinates.mjs.map +1 -1
- package/dist/browser/esm/skin/SkinTextures.mjs +1 -1
- package/dist/browser/esm/skin/SkinTextures.mjs.map +1 -1
- package/dist/browser/esm/skin/Skins.mjs +6 -4
- package/dist/browser/esm/skin/Skins.mjs.map +1 -1
- package/dist/browser/esm/skin/scene/SkinObject.mjs +119 -7
- package/dist/browser/esm/skin/scene/SkinObject.mjs.map +1 -1
- package/dist/browser/esm/texture/PalettedTextures.mjs +46 -0
- package/dist/browser/esm/texture/PalettedTextures.mjs.map +1 -0
- package/dist/browser/esm/texture/TextureLoader.mjs +4 -2
- package/dist/browser/esm/texture/TextureLoader.mjs.map +1 -1
- package/dist/browser/esm/texture/index.mjs +1 -0
- package/dist/browser/esm/texture/index.mjs.map +1 -1
- package/dist/browser/esm/util/log.mjs +75 -0
- package/dist/browser/esm/util/log.mjs.map +1 -1
- package/dist/browser/esm/util/performance.mjs.map +1 -1
- package/dist/browser/esm/util/util.mjs +0 -2
- package/dist/browser/esm/util/util.mjs.map +1 -1
- package/dist/browser/esm/world/Chunk.mjs +70 -38
- package/dist/browser/esm/world/Chunk.mjs.map +1 -1
- package/dist/browser/esm/world/MineRenderWorld.mjs +187 -60
- package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
- package/dist/browser/esm/world/SectionMesh.mjs +65 -9
- package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
- package/dist/browser/esm/world/SectionModels.mjs +21 -15
- package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
- package/dist/browser/esm/world/SectionWorker.mjs +8 -2
- package/dist/browser/esm/world/SectionWorker.mjs.map +1 -1
- package/dist/browser/esm/world/WorldStreamer.mjs +129 -34
- package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
- package/dist/browser/esm/world/_culling/BlockCulling.mjs +1 -1
- package/dist/browser/esm/world/_culling/BlockCulling.mjs.map +1 -1
- package/dist/browser/esm/world/_entities/WorldEntities.mjs +3 -1
- package/dist/browser/esm/world/_entities/WorldEntities.mjs.map +1 -1
- package/dist/browser/index.d.ts +191 -22
- package/dist/browser/index.js +4461 -3648
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +13482 -12651
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +179 -21
- package/dist/node/index.d.ts +179 -21
- package/dist/node/index.js +4495 -3666
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +4412 -3586
- package/dist/node/index.mjs.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// src/texture/PalettedTextures.ts
|
|
2
|
+
import { ModelTextures } from "../assets/ModelTextures.mjs";
|
|
3
|
+
import { Caching } from "../cache/Caching.mjs";
|
|
4
|
+
import { CanvasImage } from "../canvas/CanvasImage.mjs";
|
|
5
|
+
import { MineRenderError } from "../error/MineRenderError.mjs";
|
|
6
|
+
var PalettedTextures = class {
|
|
7
|
+
/** Loads a texture with a palette permutation, sharing the resulting canvas between callers. */
|
|
8
|
+
static async get(texture, key, permutation) {
|
|
9
|
+
return Caching.canvasImageDataCache.get(`palette:${texture.serialize()}:${key.serialize()}:${permutation.serialize()}`, async () => {
|
|
10
|
+
const source = await ModelTextures.get(texture);
|
|
11
|
+
if (!source) return void 0;
|
|
12
|
+
const [palette, replacement] = await Promise.all([ModelTextures.get(key), ModelTextures.get(permutation)]);
|
|
13
|
+
if (!palette) throw new MineRenderError(`Missing palette ${key.toNamespacedString()}`);
|
|
14
|
+
if (!replacement) throw new MineRenderError(`Missing palette ${permutation.toNamespacedString()}`);
|
|
15
|
+
const pixels = source.data.getImageData(0, 0, source.width, source.height);
|
|
16
|
+
const colors = palette.data.getImageData(0, 0, palette.width, palette.height).data;
|
|
17
|
+
const replacements = replacement.data.getImageData(0, 0, replacement.width, replacement.height).data;
|
|
18
|
+
const image = new CanvasImage(source.width, source.height);
|
|
19
|
+
const output = image.context.createImageData(source.width, source.height);
|
|
20
|
+
output.data.set(this.permute(pixels.data, colors, replacements));
|
|
21
|
+
image.putData(output);
|
|
22
|
+
return { data: image.context, width: image.width, height: image.height };
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/** @internal */
|
|
26
|
+
static permute(pixels, key, permutation) {
|
|
27
|
+
if (key.length !== permutation.length) throw new MineRenderError("Palette images must have the same pixel count");
|
|
28
|
+
const mapping = /* @__PURE__ */ new Map();
|
|
29
|
+
for (let i = 0; i < key.length; i += 4) {
|
|
30
|
+
if (key[i + 3] !== 0) mapping.set(key[i] << 16 | key[i + 1] << 8 | key[i + 2], i);
|
|
31
|
+
}
|
|
32
|
+
const output = new Uint8ClampedArray(pixels);
|
|
33
|
+
for (let i = 0; i < pixels.length; i += 4) {
|
|
34
|
+
if (pixels[i + 3] === 0) continue;
|
|
35
|
+
const mapped = mapping.get(pixels[i] << 16 | pixels[i + 1] << 8 | pixels[i + 2]);
|
|
36
|
+
if (mapped === void 0) continue;
|
|
37
|
+
output.set(permutation.subarray(mapped, mapped + 3), i);
|
|
38
|
+
output[i + 3] = Math.floor(pixels[i + 3] * permutation[mapped + 3] / 255);
|
|
39
|
+
}
|
|
40
|
+
return output;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export {
|
|
44
|
+
PalettedTextures
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=PalettedTextures.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/texture/PalettedTextures.ts"],"sourcesContent":["import { AssetKey } from \"../assets/AssetKey\";\nimport { ModelTextures } from \"../assets/ModelTextures\";\nimport { Caching } from \"../cache/Caching\";\nimport { CanvasImage } from \"../canvas/CanvasImage\";\nimport { MineRenderError } from \"../error/MineRenderError\";\nimport type { ExtractableImageData } from \"../ExtractableImageData\";\nimport type { Maybe } from \"../util/util\";\n\n/** Recolours textures using indexed pairs of palette images. */\nexport class PalettedTextures {\n /** Loads a texture with a palette permutation, sharing the resulting canvas between callers. */\n public static async get(texture: AssetKey, key: AssetKey, permutation: AssetKey): Promise<Maybe<ExtractableImageData>> {\n return Caching.canvasImageDataCache.get(`palette:${texture.serialize()}:${key.serialize()}:${permutation.serialize()}`, async () => {\n const source = await ModelTextures.get(texture);\n if (!source) return undefined;\n const [palette, replacement] = await Promise.all([ModelTextures.get(key), ModelTextures.get(permutation)]);\n if (!palette) throw new MineRenderError(`Missing palette ${key.toNamespacedString()}`);\n if (!replacement) throw new MineRenderError(`Missing palette ${permutation.toNamespacedString()}`);\n const pixels = source.data.getImageData(0, 0, source.width, source.height);\n const colors = palette.data.getImageData(0, 0, palette.width, palette.height).data;\n const replacements = replacement.data.getImageData(0, 0, replacement.width, replacement.height).data;\n const image = new CanvasImage(source.width, source.height);\n const output = image.context.createImageData(source.width, source.height);\n output.data.set(this.permute(pixels.data, colors, replacements));\n image.putData(output);\n return { data: image.context as unknown as CanvasRenderingContext2D, width: image.width, height: image.height };\n });\n }\n\n /** @internal */\n public static permute(pixels: Uint8ClampedArray, key: Uint8ClampedArray, permutation: Uint8ClampedArray): Uint8ClampedArray {\n if (key.length !== permutation.length) throw new MineRenderError(\"Palette images must have the same pixel count\");\n const mapping = new Map<number, number>();\n for (let i = 0; i < key.length; i += 4) {\n if (key[i + 3] !== 0) mapping.set((key[i] << 16) | (key[i + 1] << 8) | key[i + 2], i);\n }\n const output = new Uint8ClampedArray(pixels);\n // PalettedPermutations.createPaletteMapping matches RGB and multiplies source and replacement alpha.\n for (let i = 0; i < pixels.length; i += 4) {\n if (pixels[i + 3] === 0) continue;\n const mapped = mapping.get((pixels[i] << 16) | (pixels[i + 1] << 8) | pixels[i + 2]);\n if (mapped === undefined) continue;\n output.set(permutation.subarray(mapped, mapped + 3), i);\n output[i + 3] = Math.floor(pixels[i + 3] * permutation[mapped + 3] / 255);\n }\n return output;\n }\n}\n"],"mappings":";AACA,SAAS,qBAAqB;AAC9B,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAKzB,IAAM,mBAAN,MAAuB;AAAA;AAAA,EAE1B,aAAoB,IAAI,SAAmB,KAAe,aAA6D;AACnH,WAAO,QAAQ,qBAAqB,IAAI,WAAW,QAAQ,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,YAAY,UAAU,CAAC,IAAI,YAAY;AAChI,YAAM,SAAS,MAAM,cAAc,IAAI,OAAO;AAC9C,UAAI,CAAC,OAAQ,QAAO;AACpB,YAAM,CAAC,SAAS,WAAW,IAAI,MAAM,QAAQ,IAAI,CAAC,cAAc,IAAI,GAAG,GAAG,cAAc,IAAI,WAAW,CAAC,CAAC;AACzG,UAAI,CAAC,QAAS,OAAM,IAAI,gBAAgB,mBAAmB,IAAI,mBAAmB,CAAC,EAAE;AACrF,UAAI,CAAC,YAAa,OAAM,IAAI,gBAAgB,mBAAmB,YAAY,mBAAmB,CAAC,EAAE;AACjG,YAAM,SAAS,OAAO,KAAK,aAAa,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM;AACzE,YAAM,SAAS,QAAQ,KAAK,aAAa,GAAG,GAAG,QAAQ,OAAO,QAAQ,MAAM,EAAE;AAC9E,YAAM,eAAe,YAAY,KAAK,aAAa,GAAG,GAAG,YAAY,OAAO,YAAY,MAAM,EAAE;AAChG,YAAM,QAAQ,IAAI,YAAY,OAAO,OAAO,OAAO,MAAM;AACzD,YAAM,SAAS,MAAM,QAAQ,gBAAgB,OAAO,OAAO,OAAO,MAAM;AACxE,aAAO,KAAK,IAAI,KAAK,QAAQ,OAAO,MAAM,QAAQ,YAAY,CAAC;AAC/D,YAAM,QAAQ,MAAM;AACpB,aAAO,EAAE,MAAM,MAAM,SAAgD,OAAO,MAAM,OAAO,QAAQ,MAAM,OAAO;AAAA,IAClH,CAAC;AAAA,EACL;AAAA;AAAA,EAGA,OAAc,QAAQ,QAA2B,KAAwB,aAAmD;AACxH,QAAI,IAAI,WAAW,YAAY,OAAQ,OAAM,IAAI,gBAAgB,+CAA+C;AAChH,UAAM,UAAU,oBAAI,IAAoB;AACxC,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,GAAG;AACpC,UAAI,IAAI,IAAI,CAAC,MAAM,EAAG,SAAQ,IAAK,IAAI,CAAC,KAAK,KAAO,IAAI,IAAI,CAAC,KAAK,IAAK,IAAI,IAAI,CAAC,GAAG,CAAC;AAAA,IACxF;AACA,UAAM,SAAS,IAAI,kBAAkB,MAAM;AAE3C,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;AACvC,UAAI,OAAO,IAAI,CAAC,MAAM,EAAG;AACzB,YAAM,SAAS,QAAQ,IAAK,OAAO,CAAC,KAAK,KAAO,OAAO,IAAI,CAAC,KAAK,IAAK,OAAO,IAAI,CAAC,CAAC;AACnF,UAAI,WAAW,OAAW;AAC1B,aAAO,IAAI,YAAY,SAAS,QAAQ,SAAS,CAAC,GAAG,CAAC;AACtD,aAAO,IAAI,CAAC,IAAI,KAAK,MAAM,OAAO,IAAI,CAAC,IAAI,YAAY,SAAS,CAAC,IAAI,GAAG;AAAA,IAC5E;AACA,WAAO;AAAA,EACX;AACJ;","names":[]}
|
|
@@ -3,6 +3,8 @@ import { RGBAFormat, Texture } from "three";
|
|
|
3
3
|
import * as THREE from "three";
|
|
4
4
|
import { ImageLoader } from "../image/ImageLoader.mjs";
|
|
5
5
|
import { Textures } from "./Textures.mjs";
|
|
6
|
+
import { logger } from "../util/log.mjs";
|
|
7
|
+
var log = logger("TextureLoader");
|
|
6
8
|
var TextureLoader = class {
|
|
7
9
|
/** Reports whether image loading failed, so cached textures can be retried. */
|
|
8
10
|
static hasFailed(texture) {
|
|
@@ -18,7 +20,7 @@ var TextureLoader = class {
|
|
|
18
20
|
texture.needsUpdate = true;
|
|
19
21
|
}, (error) => {
|
|
20
22
|
this.failedTextures.add(texture);
|
|
21
|
-
|
|
23
|
+
log.warn("Failed to load texture", src, error);
|
|
22
24
|
});
|
|
23
25
|
texture.image = image;
|
|
24
26
|
texture.format = format;
|
|
@@ -34,7 +36,7 @@ var TextureLoader = class {
|
|
|
34
36
|
texture.needsUpdate = true;
|
|
35
37
|
}).catch((error) => {
|
|
36
38
|
this.failedTextures.add(texture);
|
|
37
|
-
|
|
39
|
+
log.warn("Failed to load texture", src, error);
|
|
38
40
|
});
|
|
39
41
|
texture.format = format;
|
|
40
42
|
texture.rotation = rotation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/texture/TextureLoader.ts"],"sourcesContent":["import { PixelFormat, RGBAFormat, Texture } from \"three\";\nimport { Caching } from \"../cache/Caching\";\nimport * as THREE from \"three\";\nimport { ImageLoader } from \"../image/ImageLoader\";\nimport { createCanvas } from \"../canvas/CanvasCompat\";\nimport type { CanvasRenderingContext2D } from \"canvas\";\nimport { Textures } from \"./Textures\";\n\n/** Creates sRGB textures immediately and fills their pixels after asynchronous image loading. */\nexport class TextureLoader {\n\n private static readonly failedTextures = new WeakSet<Texture>();\n\n /** Reports whether image loading failed, so cached textures can be retried. */\n public static hasFailed(texture: Texture): boolean {\n return this.failedTextures.has(texture);\n }\n\n protected static createTexture(): Texture {\n return new Texture();\n }\n\n public static loadInBackground(src: string, format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = this.createTexture();\n texture.colorSpace = THREE.SRGBColorSpace;\n const image = ImageLoader.loadElement(src, () => {\n texture.needsUpdate = true;\n }, error => {\n this.failedTextures.add(texture);\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/texture/TextureLoader.ts"],"sourcesContent":["import { PixelFormat, RGBAFormat, Texture } from \"three\";\nimport { Caching } from \"../cache/Caching\";\nimport * as THREE from \"three\";\nimport { ImageLoader } from \"../image/ImageLoader\";\nimport { createCanvas } from \"../canvas/CanvasCompat\";\nimport type { CanvasRenderingContext2D } from \"canvas\";\nimport { Textures } from \"./Textures\";\nimport { logger } from \"../util/log\";\n\nconst log = logger(\"TextureLoader\");\n\n/** Creates sRGB textures immediately and fills their pixels after asynchronous image loading. */\nexport class TextureLoader {\n\n private static readonly failedTextures = new WeakSet<Texture>();\n\n /** Reports whether image loading failed, so cached textures can be retried. */\n public static hasFailed(texture: Texture): boolean {\n return this.failedTextures.has(texture);\n }\n\n protected static createTexture(): Texture {\n return new Texture();\n }\n\n public static loadInBackground(src: string, format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = this.createTexture();\n texture.colorSpace = THREE.SRGBColorSpace;\n const image = ImageLoader.loadElement(src, () => {\n texture.needsUpdate = true;\n }, error => {\n this.failedTextures.add(texture);\n log.warn(\"Failed to load texture\", src, error);\n });\n texture.image = image;\n texture.format = format;\n texture.rotation = rotation;\n\n return Textures.initTextureProps(texture);\n }\n\n /** Loads image pixels in the background. `rotation` is in radians. Check {@link hasFailed} for load failures. */\n public static load(src: string,format: PixelFormat = RGBAFormat, rotation: number = 0): Texture {\n const texture = new Texture();\n texture.colorSpace = THREE.SRGBColorSpace;\n ImageLoader.getData(src).then(image=>{\n texture.image = image;\n texture.needsUpdate = true;\n }).catch(error => {\n this.failedTextures.add(texture);\n log.warn(\"Failed to load texture\", src, error);\n });\n texture.format = format;\n texture.rotation = rotation;\n\n return Textures.initTextureProps(texture);\n }\n\n\n}\n"],"mappings":";AAAA,SAAsB,YAAY,eAAe;AAEjD,YAAY,WAAW;AACvB,SAAS,mBAAmB;AAG5B,SAAS,gBAAgB;AACzB,SAAS,cAAc;AAEvB,IAAM,MAAM,OAAO,eAAe;AAG3B,IAAM,gBAAN,MAAoB;AAAA;AAAA,EAKvB,OAAc,UAAU,SAA2B;AAC/C,WAAO,KAAK,eAAe,IAAI,OAAO;AAAA,EAC1C;AAAA,EAEA,OAAiB,gBAAyB;AACtC,WAAO,IAAI,QAAQ;AAAA,EACvB;AAAA,EAEA,OAAc,iBAAiB,KAAa,SAAsB,YAAY,WAAmB,GAAY;AACzG,UAAM,UAAU,KAAK,cAAc;AACnC,YAAQ,aAAmB;AAC3B,UAAM,QAAQ,YAAY,YAAY,KAAK,MAAM;AAC7C,cAAQ,cAAc;AAAA,IAC1B,GAAG,WAAS;AACR,WAAK,eAAe,IAAI,OAAO;AAC/B,UAAI,KAAK,0BAA0B,KAAK,KAAK;AAAA,IACjD,CAAC;AACD,YAAQ,QAAQ;AAChB,YAAQ,SAAS;AACjB,YAAQ,WAAW;AAEnB,WAAO,SAAS,iBAAiB,OAAO;AAAA,EAC5C;AAAA;AAAA,EAGA,OAAc,KAAK,KAAY,SAAsB,YAAY,WAAmB,GAAY;AAC5F,UAAM,UAAU,IAAI,QAAQ;AAC5B,YAAQ,aAAmB;AAC3B,gBAAY,QAAQ,GAAG,EAAE,KAAK,WAAO;AACjC,cAAQ,QAAQ;AAChB,cAAQ,cAAc;AAAA,IAC1B,CAAC,EAAE,MAAM,WAAS;AACd,WAAK,eAAe,IAAI,OAAO;AAC/B,UAAI,KAAK,0BAA0B,KAAK,KAAK;AAAA,IACjD,CAAC;AACD,YAAQ,SAAS;AACjB,YAAQ,WAAW;AAEnB,WAAO,SAAS,iBAAiB,OAAO;AAAA,EAC5C;AAGJ;AA/Ca,cAEe,iBAAiB,oBAAI,QAAiB;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/texture/index.ts"],"sourcesContent":["// autogenerated\nexport * from './Colormaps';\nexport * from './TextureAtlas';\nexport * from './TextureLoader';\nexport * from './Textures';\n"],"mappings":";AACA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/texture/index.ts"],"sourcesContent":["// autogenerated\nexport * from './Colormaps';\nexport * from './PalettedTextures';\nexport * from './TextureAtlas';\nexport * from './TextureLoader';\nexport * from './Textures';\n"],"mappings":";AACA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -1,4 +1,77 @@
|
|
|
1
1
|
// src/util/log.ts
|
|
2
|
+
var runtime = globalThis;
|
|
3
|
+
var levels = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };
|
|
4
|
+
var colors = { debug: 90, info: 36, warn: 33, error: 31 };
|
|
5
|
+
var threshold = "warn";
|
|
6
|
+
var namespaces;
|
|
7
|
+
var logHandler;
|
|
8
|
+
var tagStyle;
|
|
9
|
+
var switchRead = false;
|
|
10
|
+
var switchThreshold;
|
|
11
|
+
var switchNamespaces;
|
|
12
|
+
function readSwitch() {
|
|
13
|
+
switchRead = true;
|
|
14
|
+
let value;
|
|
15
|
+
if (typeof runtime.process?.versions?.node === "string") {
|
|
16
|
+
value = runtime.process.env?.MINERENDER_LOG;
|
|
17
|
+
} else {
|
|
18
|
+
try {
|
|
19
|
+
value = runtime.localStorage?.getItem("minerender:log");
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (value) {
|
|
24
|
+
for (const entry of value.split(",")) {
|
|
25
|
+
const separator = entry.indexOf("=");
|
|
26
|
+
const name = separator < 0 ? void 0 : entry.slice(0, separator).trim();
|
|
27
|
+
const setting = (separator < 0 ? entry : entry.slice(separator + 1)).trim();
|
|
28
|
+
if (!Object.prototype.hasOwnProperty.call(levels, setting) || name === "") continue;
|
|
29
|
+
if (name === void 0) {
|
|
30
|
+
switchThreshold = setting;
|
|
31
|
+
} else {
|
|
32
|
+
switchNamespaces ?? (switchNamespaces = /* @__PURE__ */ new Map());
|
|
33
|
+
switchNamespaces.set(name, setting);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
var Logging = class {
|
|
39
|
+
/** Updates the given settings and keeps the others. */
|
|
40
|
+
static configure(options) {
|
|
41
|
+
if (options.level !== void 0) threshold = options.level;
|
|
42
|
+
if (options.namespaces !== void 0) namespaces = new Map(Object.entries(options.namespaces));
|
|
43
|
+
}
|
|
44
|
+
/** Sends messages to `handler` instead of the console. Call without an argument to restore console output. */
|
|
45
|
+
static setHandler(handler) {
|
|
46
|
+
logHandler = handler;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
function logger(namespace) {
|
|
50
|
+
const write = (level, args) => {
|
|
51
|
+
if (!switchRead) readSwitch();
|
|
52
|
+
if (levels[level] < levels[switchNamespaces?.get(namespace) ?? switchThreshold ?? namespaces?.get(namespace) ?? threshold]) return;
|
|
53
|
+
if (logHandler) {
|
|
54
|
+
logHandler(level, namespace, args);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (tagStyle === void 0) {
|
|
58
|
+
tagStyle = typeof runtime.process?.versions?.node === "string" ? runtime.process.stdout?.isTTY === true ? "ansi" : "plain" : "browser";
|
|
59
|
+
}
|
|
60
|
+
if (tagStyle === "browser") {
|
|
61
|
+
console[level](`%cMineRender%c ${namespace}`, "background:#3c8527;color:#fff;border-radius:3px;padding:0 4px", "font-weight:bold", ...args);
|
|
62
|
+
} else {
|
|
63
|
+
const color = colors[level];
|
|
64
|
+
const tag = `[minerender:${namespace}]`;
|
|
65
|
+
console[level](tagStyle === "ansi" ? `\x1B[${color}m${tag}\x1B[0m` : tag, ...args);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
debug: (...args) => write("debug", args),
|
|
70
|
+
info: (...args) => write("info", args),
|
|
71
|
+
warn: (...args) => write("warn", args),
|
|
72
|
+
error: (...args) => write("error", args)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
2
75
|
var Reset = "\x1B[0m";
|
|
3
76
|
var FgGreen = "\x1B[32m";
|
|
4
77
|
var BgBlack = "\x1B[40m";
|
|
@@ -6,6 +79,8 @@ function prefix(prefix2) {
|
|
|
6
79
|
return `${FgGreen}MR${BgBlack}${prefix2 ?? ""}${Reset}`;
|
|
7
80
|
}
|
|
8
81
|
export {
|
|
82
|
+
Logging,
|
|
83
|
+
logger,
|
|
9
84
|
prefix
|
|
10
85
|
};
|
|
11
86
|
//# sourceMappingURL=log.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/util/log.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../../../src/util/log.ts"],"sourcesContent":["/** Severity of a log message, from most to least verbose. */\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\n/** The lowest level that is printed, or `\"silent\"` to print nothing. */\nexport type LogThreshold = LogLevel | \"silent\";\n\n/** Receives each message that passes the threshold. `args` are the logger call's arguments, without a tag. */\nexport type LogHandler = (level: LogLevel, namespace: string, args: unknown[]) => void;\n\nexport interface LoggingOptions {\n /** Threshold for namespaces without an override. Starts at `\"warn\"`. */\n level?: LogThreshold;\n /** Thresholds by logger name, such as `{ UVMapper: \"debug\" }`. Replaces earlier overrides. */\n namespaces?: Record<string, LogThreshold>;\n}\n\nexport interface Logger {\n debug(...args: unknown[]): void;\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\ntype Runtime = {\n process?: { versions?: { node?: string }; stdout?: { isTTY?: boolean }; env?: Record<string, string | undefined> };\n localStorage?: { getItem(key: string): string | null };\n};\n\nconst runtime = globalThis as Runtime;\nconst levels: Record<LogThreshold, number> = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };\nconst colors: Record<LogLevel, number> = { debug: 90, info: 36, warn: 33, error: 31 };\n\nlet threshold: LogThreshold = \"warn\";\nlet namespaces: Map<string, LogThreshold> | undefined;\nlet logHandler: LogHandler | undefined;\nlet tagStyle: \"plain\" | \"ansi\" | \"browser\" | undefined;\nlet switchRead = false;\nlet switchThreshold: LogThreshold | undefined;\nlet switchNamespaces: Map<string, LogThreshold> | undefined;\n\nfunction readSwitch(): void {\n switchRead = true;\n let value: string | null | undefined;\n if (typeof runtime.process?.versions?.node === \"string\") {\n value = runtime.process.env?.MINERENDER_LOG;\n } else {\n try {\n value = runtime.localStorage?.getItem(\"minerender:log\");\n } catch {\n // Sandboxed pages can deny access to storage.\n }\n }\n if (value) {\n for (const entry of value.split(\",\")) {\n const separator = entry.indexOf(\"=\");\n const name = separator < 0 ? undefined : entry.slice(0, separator).trim();\n const setting = (separator < 0 ? entry : entry.slice(separator + 1)).trim();\n if (!Object.prototype.hasOwnProperty.call(levels, setting) || name === \"\") continue;\n if (name === undefined) {\n switchThreshold = setting as LogThreshold;\n } else {\n switchNamespaces ??= new Map();\n switchNamespaces.set(name, setting as LogThreshold);\n }\n }\n }\n}\n\n/** Global log settings for every MineRender logger. */\nexport class Logging {\n /** Updates the given settings and keeps the others. */\n static configure(options: LoggingOptions): void {\n if (options.level !== undefined) threshold = options.level;\n if (options.namespaces !== undefined) namespaces = new Map(Object.entries(options.namespaces));\n }\n\n /** Sends messages to `handler` instead of the console. Call without an argument to restore console output. */\n static setHandler(handler?: LogHandler): void {\n logHandler = handler;\n }\n}\n\n/** Creates a logger whose messages are tagged and filtered as `namespace`. */\nexport function logger(namespace: string): Logger {\n const write = (level: LogLevel, args: unknown[]): void => {\n if (!switchRead) readSwitch();\n if (levels[level] < levels[switchNamespaces?.get(namespace) ?? switchThreshold ?? namespaces?.get(namespace) ?? threshold]) return;\n if (logHandler) {\n logHandler(level, namespace, args);\n return;\n }\n if (tagStyle === undefined) {\n tagStyle = typeof runtime.process?.versions?.node === \"string\"\n ? runtime.process.stdout?.isTTY === true ? \"ansi\" : \"plain\"\n : \"browser\";\n }\n if (tagStyle === \"browser\") {\n console[level](`%cMineRender%c ${namespace}`, \"background:#3c8527;color:#fff;border-radius:3px;padding:0 4px\", \"font-weight:bold\", ...args);\n } else {\n const color = colors[level];\n const tag = `[minerender:${namespace}]`;\n console[level](tagStyle === \"ansi\" ? `\\x1b[${color}m${tag}\\x1b[0m` : tag, ...args);\n }\n };\n return {\n debug: (...args) => write(\"debug\", args),\n info: (...args) => write(\"info\", args),\n warn: (...args) => write(\"warn\", args),\n error: (...args) => write(\"error\", args),\n };\n}\n\nconst Reset = \"\\x1b[0m\"\nconst FgGreen = \"\\x1b[32m\"\nconst BgBlack = \"\\x1b[40m\"\n\n/** @deprecated Use {@link logger}. */\nexport function prefix(prefix?: string): string {\n return `${ FgGreen }MR${ BgBlack }${ prefix ?? '' }${ Reset }`\n}\n"],"mappings":";AA4BA,IAAM,UAAU;AAChB,IAAM,SAAuC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,EAAE;AAC/F,IAAM,SAAmC,EAAE,OAAO,IAAI,MAAM,IAAI,MAAM,IAAI,OAAO,GAAG;AAEpF,IAAI,YAA0B;AAC9B,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI,aAAa;AACjB,IAAI;AACJ,IAAI;AAEJ,SAAS,aAAmB;AACxB,eAAa;AACb,MAAI;AACJ,MAAI,OAAO,QAAQ,SAAS,UAAU,SAAS,UAAU;AACrD,YAAQ,QAAQ,QAAQ,KAAK;AAAA,EACjC,OAAO;AACH,QAAI;AACA,cAAQ,QAAQ,cAAc,QAAQ,gBAAgB;AAAA,IAC1D,QAAQ;AAAA,IAER;AAAA,EACJ;AACA,MAAI,OAAO;AACP,eAAW,SAAS,MAAM,MAAM,GAAG,GAAG;AAClC,YAAM,YAAY,MAAM,QAAQ,GAAG;AACnC,YAAM,OAAO,YAAY,IAAI,SAAY,MAAM,MAAM,GAAG,SAAS,EAAE,KAAK;AACxE,YAAM,WAAW,YAAY,IAAI,QAAQ,MAAM,MAAM,YAAY,CAAC,GAAG,KAAK;AAC1E,UAAI,CAAC,OAAO,UAAU,eAAe,KAAK,QAAQ,OAAO,KAAK,SAAS,GAAI;AAC3E,UAAI,SAAS,QAAW;AACpB,0BAAkB;AAAA,MACtB,OAAO;AACH,gDAAqB,oBAAI,IAAI;AAC7B,yBAAiB,IAAI,MAAM,OAAuB;AAAA,MACtD;AAAA,IACJ;AAAA,EACJ;AACJ;AAGO,IAAM,UAAN,MAAc;AAAA;AAAA,EAEjB,OAAO,UAAU,SAA+B;AAC5C,QAAI,QAAQ,UAAU,OAAW,aAAY,QAAQ;AACrD,QAAI,QAAQ,eAAe,OAAW,cAAa,IAAI,IAAI,OAAO,QAAQ,QAAQ,UAAU,CAAC;AAAA,EACjG;AAAA;AAAA,EAGA,OAAO,WAAW,SAA4B;AAC1C,iBAAa;AAAA,EACjB;AACJ;AAGO,SAAS,OAAO,WAA2B;AAC9C,QAAM,QAAQ,CAAC,OAAiB,SAA0B;AACtD,QAAI,CAAC,WAAY,YAAW;AAC5B,QAAI,OAAO,KAAK,IAAI,OAAO,kBAAkB,IAAI,SAAS,KAAK,mBAAmB,YAAY,IAAI,SAAS,KAAK,SAAS,EAAG;AAC5H,QAAI,YAAY;AACZ,iBAAW,OAAO,WAAW,IAAI;AACjC;AAAA,IACJ;AACA,QAAI,aAAa,QAAW;AACxB,iBAAW,OAAO,QAAQ,SAAS,UAAU,SAAS,WAChD,QAAQ,QAAQ,QAAQ,UAAU,OAAO,SAAS,UAClD;AAAA,IACV;AACA,QAAI,aAAa,WAAW;AACxB,cAAQ,KAAK,EAAE,kBAAkB,SAAS,IAAI,iEAAiE,oBAAoB,GAAG,IAAI;AAAA,IAC9I,OAAO;AACH,YAAM,QAAQ,OAAO,KAAK;AAC1B,YAAM,MAAM,eAAe,SAAS;AACpC,cAAQ,KAAK,EAAE,aAAa,SAAS,QAAQ,KAAK,IAAI,GAAG,YAAY,KAAK,GAAG,IAAI;AAAA,IACrF;AAAA,EACJ;AACA,SAAO;AAAA,IACH,OAAO,IAAI,SAAS,MAAM,SAAS,IAAI;AAAA,IACvC,MAAM,IAAI,SAAS,MAAM,QAAQ,IAAI;AAAA,IACrC,MAAM,IAAI,SAAS,MAAM,QAAQ,IAAI;AAAA,IACrC,OAAO,IAAI,SAAS,MAAM,SAAS,IAAI;AAAA,EAC3C;AACJ;AAEA,IAAM,QAAQ;AACd,IAAM,UAAU;AAChB,IAAM,UAAU;AAGT,SAAS,OAAOA,SAAyB;AAC5C,SAAO,GAAI,OAAQ,KAAM,OAAQ,GAAIA,WAAU,EAAG,GAAI,KAAM;AAChE;","names":["prefix"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/util/performance.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../../../src/util/performance.ts"],"sourcesContent":["/** @deprecated Unused by MineRender. */\nexport function captureException(e: any, ...extra: any[]) {\n console.error(e, extra);\n //TODO\n}\n\n/** @deprecated Unused by MineRender. */\nexport function timingStart(marker: string) {\n console.time(marker);\n //TODO\n}\n\n/** @deprecated Unused by MineRender. */\nexport function timingEnd(marker: string) {\n console.timeEnd(marker);\n //TODO\n}\n"],"mappings":";AACO,SAAS,iBAAiB,MAAW,OAAc;AACtD,UAAQ,MAAM,GAAG,KAAK;AAE1B;AAGO,SAAS,YAAY,QAAgB;AACxC,UAAQ,KAAK,MAAM;AAEvB;AAGO,SAAS,UAAU,QAAgB;AACtC,UAAQ,QAAQ,MAAM;AAE1B;","names":[]}
|
|
@@ -28,8 +28,6 @@ async function sleep(timeout) {
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
function yieldToEventLoop() {
|
|
31
|
-
const scheduler = globalThis.scheduler;
|
|
32
|
-
if (scheduler?.yield) return scheduler.yield();
|
|
33
31
|
return new Promise((resolve) => {
|
|
34
32
|
if (typeof MessageChannel !== "undefined") {
|
|
35
33
|
const channel = new MessageChannel();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/util/util.ts"],"sourcesContent":["// Node ESM needs the explicit .js extension for the CommonJS hash module.\nimport MD5 from \"crypto-js/md5.js\";\nimport { Vector3 } from \"three\";\n\nexport const changeEvent = { type: 'change' as const };\n\nexport type Maybe<T> = T | undefined;\n\n// MD5 runs in both environments without pulling Node's crypto into the browser graph.\nexport function md5(str: string): string {\n return MD5(str).toString();\n}\n\nexport function base64encode(str: string): string {\n if (typeof btoa !== \"undefined\") {\n return btoa(str);\n }\n return Buffer.from(str).toString(\"base64\");\n}\n\nexport function base64decode(str: string): string {\n if (typeof atob !== \"undefined\") {\n return atob(str);\n }\n return Buffer.from(str, \"base64\").toString(\"ascii\");\n}\n\nexport function toRadians(degrees: number): number {\n return degrees * Math.PI / 180;\n}\n\nexport function toDegrees(radians: number): number {\n return radians * 180 / Math.PI;\n}\n\n/** Resolves after a delay in milliseconds. */\nexport async function sleep(timeout: number): Promise<void> {\n return new Promise(resolve => {\n setTimeout(() => resolve(), timeout);\n });\n}\n\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/util/util.ts"],"sourcesContent":["// Node ESM needs the explicit .js extension for the CommonJS hash module.\nimport MD5 from \"crypto-js/md5.js\";\nimport { Vector3 } from \"three\";\n\nexport const changeEvent = { type: 'change' as const };\n\nexport type Maybe<T> = T | undefined;\n\n// MD5 runs in both environments without pulling Node's crypto into the browser graph.\nexport function md5(str: string): string {\n return MD5(str).toString();\n}\n\nexport function base64encode(str: string): string {\n if (typeof btoa !== \"undefined\") {\n return btoa(str);\n }\n return Buffer.from(str).toString(\"base64\");\n}\n\nexport function base64decode(str: string): string {\n if (typeof atob !== \"undefined\") {\n return atob(str);\n }\n return Buffer.from(str, \"base64\").toString(\"ascii\");\n}\n\nexport function toRadians(degrees: number): number {\n return degrees * Math.PI / 180;\n}\n\nexport function toDegrees(radians: number): number {\n return radians * 180 / Math.PI;\n}\n\n/** Resolves after a delay in milliseconds. */\nexport async function sleep(timeout: number): Promise<void> {\n return new Promise(resolve => {\n setTimeout(() => resolve(), timeout);\n });\n}\n\n/**\n * Yields to the next macrotask without timer clamping when the platform supports it.\n * Not `scheduler.yield()`: Chrome runs its continuations ahead of rendering, so chained yields delay frames.\n */\nexport function yieldToEventLoop(): Promise<void> {\n return new Promise(resolve => {\n if (typeof MessageChannel !== \"undefined\") {\n const channel = new MessageChannel();\n channel.port1.onmessage = () => {\n channel.port1.close();\n channel.port2.close();\n resolve();\n };\n channel.port2.postMessage(undefined);\n } else {\n setTimeout(resolve, 0);\n }\n });\n}\n\n/** Reduces an angle modulo 360, retaining a negative sign for negative inputs. */\nexport function clampRotationDegrees(deg: number): number {\n return deg % 360;\n}\n\nexport function isVector3(obj: any): obj is Vector3 {\n return (<Vector3>obj).isVector3;\n}\n\nexport type DeepPartial<T> = {\n [P in keyof T]?: DeepPartial<T[P]>;\n};\n"],"mappings":";AACA,OAAO,SAAS;AAGT,IAAM,cAAc,EAAE,MAAM,SAAkB;AAK9C,SAAS,IAAI,KAAqB;AACrC,SAAO,IAAI,GAAG,EAAE,SAAS;AAC7B;AAEO,SAAS,aAAa,KAAqB;AAC9C,MAAI,OAAO,SAAS,aAAa;AAC7B,WAAO,KAAK,GAAG;AAAA,EACnB;AACA,SAAO,OAAO,KAAK,GAAG,EAAE,SAAS,QAAQ;AAC7C;AAEO,SAAS,aAAa,KAAqB;AAC9C,MAAI,OAAO,SAAS,aAAa;AAC7B,WAAO,KAAK,GAAG;AAAA,EACnB;AACA,SAAO,OAAO,KAAK,KAAK,QAAQ,EAAE,SAAS,OAAO;AACtD;AAEO,SAAS,UAAU,SAAyB;AAC/C,SAAO,UAAU,KAAK,KAAK;AAC/B;AAEO,SAAS,UAAU,SAAyB;AAC/C,SAAO,UAAU,MAAM,KAAK;AAChC;AAGA,eAAsB,MAAM,SAAgC;AACxD,SAAO,IAAI,QAAQ,aAAW;AAC1B,eAAW,MAAM,QAAQ,GAAG,OAAO;AAAA,EACvC,CAAC;AACL;AAMO,SAAS,mBAAkC;AAC9C,SAAO,IAAI,QAAQ,aAAW;AAC1B,QAAI,OAAO,mBAAmB,aAAa;AACvC,YAAM,UAAU,IAAI,eAAe;AACnC,cAAQ,MAAM,YAAY,MAAM;AAC5B,gBAAQ,MAAM,MAAM;AACpB,gBAAQ,MAAM,MAAM;AACpB,gBAAQ;AAAA,MACZ;AACA,cAAQ,MAAM,YAAY,MAAS;AAAA,IACvC,OAAO;AACH,iBAAW,SAAS,CAAC;AAAA,IACzB;AAAA,EACJ,CAAC;AACL;AAGO,SAAS,qBAAqB,KAAqB;AACtD,SAAO,MAAM;AACjB;AAEO,SAAS,UAAU,KAA0B;AAChD,SAAiB,IAAK;AAC1B;","names":[]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/world/Chunk.ts
|
|
2
|
+
import { BlockObject } from "../model/block/scene/BlockObject.mjs";
|
|
2
3
|
import { Color, Vector3 } from "three";
|
|
3
4
|
import { ChunkData } from "./ChunkData.mjs";
|
|
4
5
|
import { BlockStates } from "../assets/BlockStates.mjs";
|
|
@@ -134,11 +135,14 @@ var Chunk = class _Chunk {
|
|
|
134
135
|
this.biomes = copy;
|
|
135
136
|
return this.refreshBiomes();
|
|
136
137
|
}
|
|
137
|
-
/**
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects.
|
|
140
|
+
* The owning world can defer neighbor culling until all affected chunks are refreshed.
|
|
141
|
+
*/
|
|
142
|
+
refreshBiomes(columns, deferCulling = false) {
|
|
143
|
+
return this.changeBlocks(() => this.refreshBiomeBlocks(columns, deferCulling), true);
|
|
140
144
|
}
|
|
141
|
-
async refreshBiomeBlocks(columns) {
|
|
145
|
+
async refreshBiomeBlocks(columns, deferCulling = false) {
|
|
142
146
|
const blend = columns && this.biomeBlend?.();
|
|
143
147
|
const ownColumn = columns?.some((column) => column.x === this.x && column.z === this.z);
|
|
144
148
|
const affected = /* @__PURE__ */ new Map();
|
|
@@ -195,7 +199,7 @@ var Chunk = class _Chunk {
|
|
|
195
199
|
this.renderedBlocks.get(index)?.object?.setVisible(false);
|
|
196
200
|
}
|
|
197
201
|
const positions = blocks.map(({ index }) => new Vector3(...this.positionAt(index)));
|
|
198
|
-
if (this.onBlocksChanged) await this.onBlocksChanged(positions);
|
|
202
|
+
if (this.onBlocksChanged) await this.onBlocksChanged(positions, deferCulling);
|
|
199
203
|
else await this.rebuildSectionMesh();
|
|
200
204
|
}
|
|
201
205
|
}
|
|
@@ -266,8 +270,10 @@ var Chunk = class _Chunk {
|
|
|
266
270
|
if (rejected?.status === "rejected") throw rejected.reason;
|
|
267
271
|
}
|
|
268
272
|
const positions = [];
|
|
269
|
-
|
|
270
|
-
|
|
273
|
+
const jobs = /* @__PURE__ */ new Map();
|
|
274
|
+
let failureOrder = Infinity, failure;
|
|
275
|
+
for (const [order, { index, key, block }] of placements.entries()) {
|
|
276
|
+
jobs.delete(index);
|
|
271
277
|
this.hiddenBlocks.delete(index);
|
|
272
278
|
this.data.assign(index, this.data.intern(block), block?.nbt);
|
|
273
279
|
const readBlock = this.data.snapshot(index);
|
|
@@ -283,7 +289,6 @@ var Chunk = class _Chunk {
|
|
|
283
289
|
this.z * 16 + Math.floor(index / 16) % 16
|
|
284
290
|
);
|
|
285
291
|
positions.push(worldPos);
|
|
286
|
-
let object;
|
|
287
292
|
try {
|
|
288
293
|
if (!readBlock) continue;
|
|
289
294
|
const resolved = resolutions.get(key);
|
|
@@ -305,7 +310,7 @@ var Chunk = class _Chunk {
|
|
|
305
310
|
this.sectionBlocks.set(index, templates.map((template) => ({ index, template, cullMask: 0, biomeTint: context?.tint })));
|
|
306
311
|
this.meshDirty = true;
|
|
307
312
|
} else {
|
|
308
|
-
|
|
313
|
+
jobs.set(index, { order, readBlock, blockState, position: MineRenderWorld.worldToScenePosition(worldPos), options: {
|
|
309
314
|
mergeMeshes: true,
|
|
310
315
|
instanceMeshes: true,
|
|
311
316
|
maxInstanceCount: 2e3,
|
|
@@ -313,13 +318,12 @@ var Chunk = class _Chunk {
|
|
|
313
318
|
variantPosition,
|
|
314
319
|
biome: context?.biome,
|
|
315
320
|
biomePosition: this.biomePosition(index, blockState, stored)
|
|
316
|
-
});
|
|
317
|
-
|
|
321
|
+
} });
|
|
322
|
+
continue;
|
|
318
323
|
}
|
|
319
324
|
this.renderedBlocks.set(index, { get block() {
|
|
320
325
|
return readBlock();
|
|
321
|
-
}, object });
|
|
322
|
-
if (object) this.objectBlocks.add(index);
|
|
326
|
+
}, object: void 0 });
|
|
323
327
|
} catch (error) {
|
|
324
328
|
if (preserveDataOnFailure && readBlock) {
|
|
325
329
|
this.renderedBlocks.set(index, { get block() {
|
|
@@ -327,12 +331,35 @@ var Chunk = class _Chunk {
|
|
|
327
331
|
}, object: void 0 });
|
|
328
332
|
} else this.data.assign(index, 0);
|
|
329
333
|
this.fluidCells[index] = 0;
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
334
|
+
if (order < failureOrder) {
|
|
335
|
+
failureOrder = order;
|
|
336
|
+
failure = error;
|
|
337
|
+
}
|
|
333
338
|
}
|
|
334
339
|
}
|
|
335
|
-
|
|
340
|
+
const pending = [...jobs];
|
|
341
|
+
const objects = await Promise.allSettled(pending.map(([, job]) => this.createBlockObject(job.blockState, job.position, job.options)));
|
|
342
|
+
for (const [i, [index, { order, readBlock }]] of pending.entries()) {
|
|
343
|
+
const result = objects[i];
|
|
344
|
+
if (result.status === "fulfilled") {
|
|
345
|
+
this.renderedBlocks.set(index, { get block() {
|
|
346
|
+
return readBlock();
|
|
347
|
+
}, object: result.value });
|
|
348
|
+
this.objectBlocks.add(index);
|
|
349
|
+
} else {
|
|
350
|
+
if (preserveDataOnFailure) {
|
|
351
|
+
this.renderedBlocks.set(index, { get block() {
|
|
352
|
+
return readBlock();
|
|
353
|
+
}, object: void 0 });
|
|
354
|
+
} else this.data.assign(index, 0);
|
|
355
|
+
this.fluidCells[index] = 0;
|
|
356
|
+
if (order < failureOrder) {
|
|
357
|
+
failureOrder = order;
|
|
358
|
+
failure = result.reason;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (failureOrder < Infinity) throw failure;
|
|
336
363
|
return positions;
|
|
337
364
|
}
|
|
338
365
|
/** Replaces every cell from parsed section data. The caller refreshes neighbor culling. */
|
|
@@ -403,37 +430,42 @@ var Chunk = class _Chunk {
|
|
|
403
430
|
failed = true;
|
|
404
431
|
}
|
|
405
432
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
)
|
|
423
|
-
this.renderedBlocks.get(index).object = object;
|
|
433
|
+
const objects = await Promise.allSettled(perBlocks.map(({ index, blockState, biome }) => this.createBlockObject(blockState, new Vector3(
|
|
434
|
+
this.x * 256 + index % 16 * 16,
|
|
435
|
+
this.y * 256 + Math.floor(index / 256) * 16,
|
|
436
|
+
this.z * 256 + Math.floor(index / 16) % 16 * 16
|
|
437
|
+
), {
|
|
438
|
+
mergeMeshes: true,
|
|
439
|
+
instanceMeshes: true,
|
|
440
|
+
maxInstanceCount: 2e3,
|
|
441
|
+
initialState: this.data.stateAt(this.data.idAt(index)).properties,
|
|
442
|
+
variantPosition: this.positionAt(index),
|
|
443
|
+
biome,
|
|
444
|
+
biomePosition: this.biomePosition(index, blockState, this.data.stateAt(this.data.idAt(index)))
|
|
445
|
+
})));
|
|
446
|
+
for (const [i, { index }] of perBlocks.entries()) {
|
|
447
|
+
const result = objects[i];
|
|
448
|
+
if (result.status === "fulfilled") {
|
|
449
|
+
this.renderedBlocks.get(index).object = result.value;
|
|
424
450
|
this.objectBlocks.add(index);
|
|
425
|
-
}
|
|
451
|
+
} else {
|
|
426
452
|
this.data.assign(index, 0);
|
|
427
453
|
this.fluidCells[index] = 0;
|
|
428
454
|
this.renderedBlocks.delete(index);
|
|
429
455
|
this.objectBlocks.delete(index);
|
|
430
|
-
|
|
431
|
-
if (!failed) failure = error;
|
|
456
|
+
if (!failed) failure = result.reason;
|
|
432
457
|
failed = true;
|
|
433
458
|
}
|
|
434
459
|
}
|
|
435
460
|
if (failed) throw failure;
|
|
436
461
|
}
|
|
462
|
+
createBlockObject(blockState, position, options) {
|
|
463
|
+
return this.scene.addSceneObject(blockState, () => {
|
|
464
|
+
const object = new BlockObject(blockState, options);
|
|
465
|
+
object.position.copy(position);
|
|
466
|
+
return object;
|
|
467
|
+
}, options);
|
|
468
|
+
}
|
|
437
469
|
positionAt(index) {
|
|
438
470
|
return [this.x * 16 + index % 16, this.y * 16 + Math.floor(index / 256), this.z * 16 + Math.floor(index / 16) % 16];
|
|
439
471
|
}
|