minerender 2.1.0-alpha.136 → 2.1.0-alpha.138
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/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/assets/AssetLoader.mjs +4 -4
- package/dist/browser/esm/assets/AssetLoader.mjs.map +1 -1
- package/dist/browser/esm/assets/BlockEntities.mjs +3 -1
- package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
- package/dist/browser/esm/assets/_fonts/Unihex.mjs +4 -2
- package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -1
- package/dist/browser/esm/assets/source/HostedAssetSource.mjs +6 -7
- package/dist/browser/esm/assets/source/HostedAssetSource.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/image/ImageLoader.mjs +3 -3
- package/dist/browser/esm/image/ImageLoader.mjs.map +1 -1
- package/dist/browser/esm/index.browser.d.mts +49 -7
- 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/block/scene/BlockObject.mjs +3 -1
- package/dist/browser/esm/model/block/scene/BlockObject.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/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/skin/Skins.mjs +6 -4
- package/dist/browser/esm/skin/Skins.mjs.map +1 -1
- package/dist/browser/esm/texture/TextureLoader.mjs +4 -2
- package/dist/browser/esm/texture/TextureLoader.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/world/Chunk.mjs +8 -5
- package/dist/browser/esm/world/Chunk.mjs.map +1 -1
- package/dist/browser/esm/world/MineRenderWorld.mjs +96 -54
- package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
- package/dist/browser/esm/world/WorldStreamer.mjs +21 -20
- package/dist/browser/esm/world/WorldStreamer.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 +49 -7
- package/dist/browser/index.js +566 -461
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +2101 -1994
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +49 -7
- package/dist/node/index.d.ts +49 -7
- package/dist/node/index.js +566 -459
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +537 -431
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/assets/_fonts/Unihex.ts"],"sourcesContent":["import { TextWriter, Uint8ArrayReader, ZipReader } from \"@zip.js/zip.js\";\nimport { AssetKey } from \"../AssetKey\";\nimport { AssetLoader } from \"../AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"../AssetDefaults\";\nimport { Caching } from \"../../cache/Caching\";\nimport { AssetParser } from \"../source/parser/AssetParsers\";\nimport { createCanvas, type CompatCanvas } from \"../../canvas/CanvasCompat\";\nimport type { BitmapGlyph } from \"../Fonts\";\nimport type { BinaryAsset } from \"../source/HostedAssetSource\";\n\nexport interface UnihexProvider {\n type: \"unihex\" | \"minecraft:unihex\";\n hex_file: string;\n size_overrides?: { from: string; to: string; left: number; right: number }[];\n}\n\ninterface HexGlyph {\n rows: Uint32Array;\n bitWidth: number;\n left: number;\n right: number;\n}\n\nexport interface UnihexFile {\n indices: Int32Array;\n rows: Uint32Array;\n metrics: Uint8Array;\n}\n\nconst ATLAS_SIZE = 512;\nconst GLYPH_HEIGHT = 16;\n\n/** Packs glyphs into shared pages only when their pixels or source rectangles are requested. */\nclass UnihexAtlas {\n private image?: CompatCanvas;\n private x = 0;\n private y = 0;\n\n public draw(glyph: HexGlyph): { image: CompatCanvas; x: number; y: number } {\n const width = glyph.right - glyph.left + 1;\n if (this.image && this.x + width > this.image.width) {\n this.x = 0;\n this.y += GLYPH_HEIGHT;\n }\n if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {\n this.image = createCanvas(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);\n this.x = 0;\n this.y = 0;\n }\n const context = this.image.getContext(\"2d\") as CanvasRenderingContext2D;\n const pixels = context.createImageData(width, GLYPH_HEIGHT);\n for (let y = 0; y < GLYPH_HEIGHT; y++) {\n for (let x = 0; x < width; x++) {\n const column = glyph.left + x;\n if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> (glyph.bitWidth - column - 1) & 1)) continue;\n pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);\n }\n }\n const result = { image: this.image, x: this.x, y: this.y };\n context.putImageData(pixels, this.x, this.y);\n this.x += width;\n return result;\n }\n}\n\nfunction readHex(text: string, filename: string, glyphs: Map<number, HexGlyph>): void {\n const lines = text.split(\"\\n\");\n if (lines[lines.length - 1] === \"\") lines.pop();\n lines.forEach((line, index) => {\n const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);\n if (!match || ![32, 64, 96, 128].includes(match[2].length)) {\n throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);\n }\n const codepoint = parseInt(match[1], 16);\n if (codepoint > 0x10ffff) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);\n const bitWidth = match[2].length / 4;\n const rowLength = bitWidth / 4;\n const rows = new Uint32Array(GLYPH_HEIGHT);\n let mask = 0;\n for (let y = 0; y < GLYPH_HEIGHT; y++) {\n rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);\n mask |= rows[y];\n }\n let left = 0, right = bitWidth;\n if (mask) {\n while (!(mask >>> (bitWidth - left - 1) & 1)) left++;\n right = bitWidth - 1;\n while (!(mask >>> (bitWidth - right - 1) & 1)) right--;\n }\n glyphs.set(codepoint, { rows, bitWidth, left, right });\n });\n}\n\nconst atlases = new WeakMap<UnihexProvider, UnihexAtlas>();\n\nasync function parseUnihex(key: AssetKey): Promise<UnihexFile | undefined> {\n try {\n const asset = await AssetLoader.get<BinaryAsset>(key, AssetParser.BINARY);\n if (!asset) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);\n const records = new Map<number, HexGlyph>();\n const reader = new ZipReader(new Uint8ArrayReader(asset.data), { useWebWorkers: false, useCompressionStream: false });\n try {\n for (const entry of await reader.getEntries()) {\n if (!entry.directory && entry.filename.endsWith(\".hex\")) {\n readHex(await entry.getData!(new TextWriter(), { checkSignature: true }), entry.filename, records);\n }\n }\n } finally {\n await reader.close();\n }\n const indices = new Int32Array(0x110000).fill(-1);\n const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);\n let index = 0;\n for (const [codepoint, record] of records) {\n indices[codepoint] = index;\n rows.set(record.rows, index * GLYPH_HEIGHT);\n metrics.set([record.bitWidth, record.left, record.right], index * 3);\n index++;\n }\n return { indices, rows, metrics };\n } catch (error) {\n console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);\n return undefined;\n }\n}\n\n/** Resolves Unihex characters with vanilla metrics and lazily rasterized, half-resolution glyphs. */\nexport async function loadUnihex(provider: UnihexProvider, fontKey: AssetKey, characters: string): Promise<Map<string, BitmapGlyph>> {\n const origin = new AssetKey(DEFAULT_NAMESPACE, \"\", undefined, undefined, \"assets\", \"\", fontKey.root);\n const key = AssetKey.parse(\"font\", provider.hex_file, origin);\n // Archive references already include their directory beneath the namespace root.\n key.assetType = undefined;\n const glyphs = new Map<string, BitmapGlyph>();\n let overrides;\n try {\n overrides = (provider.size_overrides ?? []).map(override => {\n const from = override.from.codePointAt(0), to = override.to.codePointAt(0);\n if ([...override.from].length !== 1 || [...override.to].length !== 1 || from! >= to!\n || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {\n throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);\n }\n return { ...override, from: from!, to: to! };\n });\n } catch (error) {\n console.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);\n return glyphs;\n }\n const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));\n if (!file) return glyphs;\n let atlas = atlases.get(provider);\n if (!atlas) { atlas = new UnihexAtlas(); atlases.set(provider, atlas); }\n for (const character of characters) {\n const codepoint = character.codePointAt(0)!, index = file.indices[codepoint];\n if (index < 0) continue;\n const record = { rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),\n bitWidth: file.metrics[index * 3], left: file.metrics[index * 3 + 1], right: file.metrics[index * 3 + 2] };\n const override = overrides.find(range => codepoint >= range.from && codepoint <= range.to);\n if (override) { record.left = override.left; record.right = override.right; }\n const width = record.right - record.left + 1;\n let rendered: ReturnType<UnihexAtlas[\"draw\"]> | undefined;\n const render = () => rendered ??= atlas!.draw(record);\n glyphs.set(character, {\n get image() { return render().image; },\n get x() { return render().x; },\n get y() { return render().y; },\n width, height: GLYPH_HEIGHT, scale: 0.5, ascent: 7, advance: Math.floor(width / 2) + 1,\n boldOffset: 0.5, shadowOffset: 0.5\n });\n }\n return glyphs;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/assets/_fonts/Unihex.ts"],"sourcesContent":["import { TextWriter, Uint8ArrayReader, ZipReader } from \"@zip.js/zip.js\";\nimport { AssetKey } from \"../AssetKey\";\nimport { AssetLoader } from \"../AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"../AssetDefaults\";\nimport { Caching } from \"../../cache/Caching\";\nimport { AssetParser } from \"../source/parser/AssetParsers\";\nimport { createCanvas, type CompatCanvas } from \"../../canvas/CanvasCompat\";\nimport type { BitmapGlyph } from \"../Fonts\";\nimport type { BinaryAsset } from \"../source/HostedAssetSource\";\nimport { logger } from \"../../util/log\";\n\nconst log = logger(\"Unihex\");\n\nexport interface UnihexProvider {\n type: \"unihex\" | \"minecraft:unihex\";\n hex_file: string;\n size_overrides?: { from: string; to: string; left: number; right: number }[];\n}\n\ninterface HexGlyph {\n rows: Uint32Array;\n bitWidth: number;\n left: number;\n right: number;\n}\n\nexport interface UnihexFile {\n indices: Int32Array;\n rows: Uint32Array;\n metrics: Uint8Array;\n}\n\nconst ATLAS_SIZE = 512;\nconst GLYPH_HEIGHT = 16;\n\n/** Packs glyphs into shared pages only when their pixels or source rectangles are requested. */\nclass UnihexAtlas {\n private image?: CompatCanvas;\n private x = 0;\n private y = 0;\n\n public draw(glyph: HexGlyph): { image: CompatCanvas; x: number; y: number } {\n const width = glyph.right - glyph.left + 1;\n if (this.image && this.x + width > this.image.width) {\n this.x = 0;\n this.y += GLYPH_HEIGHT;\n }\n if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {\n this.image = createCanvas(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);\n this.x = 0;\n this.y = 0;\n }\n const context = this.image.getContext(\"2d\") as CanvasRenderingContext2D;\n const pixels = context.createImageData(width, GLYPH_HEIGHT);\n for (let y = 0; y < GLYPH_HEIGHT; y++) {\n for (let x = 0; x < width; x++) {\n const column = glyph.left + x;\n if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> (glyph.bitWidth - column - 1) & 1)) continue;\n pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);\n }\n }\n const result = { image: this.image, x: this.x, y: this.y };\n context.putImageData(pixels, this.x, this.y);\n this.x += width;\n return result;\n }\n}\n\nfunction readHex(text: string, filename: string, glyphs: Map<number, HexGlyph>): void {\n const lines = text.split(\"\\n\");\n if (lines[lines.length - 1] === \"\") lines.pop();\n lines.forEach((line, index) => {\n const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);\n if (!match || ![32, 64, 96, 128].includes(match[2].length)) {\n throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);\n }\n const codepoint = parseInt(match[1], 16);\n if (codepoint > 0x10ffff) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);\n const bitWidth = match[2].length / 4;\n const rowLength = bitWidth / 4;\n const rows = new Uint32Array(GLYPH_HEIGHT);\n let mask = 0;\n for (let y = 0; y < GLYPH_HEIGHT; y++) {\n rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);\n mask |= rows[y];\n }\n let left = 0, right = bitWidth;\n if (mask) {\n while (!(mask >>> (bitWidth - left - 1) & 1)) left++;\n right = bitWidth - 1;\n while (!(mask >>> (bitWidth - right - 1) & 1)) right--;\n }\n glyphs.set(codepoint, { rows, bitWidth, left, right });\n });\n}\n\nconst atlases = new WeakMap<UnihexProvider, UnihexAtlas>();\n\nasync function parseUnihex(key: AssetKey): Promise<UnihexFile | undefined> {\n try {\n const asset = await AssetLoader.get<BinaryAsset>(key, AssetParser.BINARY);\n if (!asset) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);\n const records = new Map<number, HexGlyph>();\n const reader = new ZipReader(new Uint8ArrayReader(asset.data), { useWebWorkers: false, useCompressionStream: false });\n try {\n for (const entry of await reader.getEntries()) {\n if (!entry.directory && entry.filename.endsWith(\".hex\")) {\n readHex(await entry.getData!(new TextWriter(), { checkSignature: true }), entry.filename, records);\n }\n }\n } finally {\n await reader.close();\n }\n const indices = new Int32Array(0x110000).fill(-1);\n const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);\n let index = 0;\n for (const [codepoint, record] of records) {\n indices[codepoint] = index;\n rows.set(record.rows, index * GLYPH_HEIGHT);\n metrics.set([record.bitWidth, record.left, record.right], index * 3);\n index++;\n }\n return { indices, rows, metrics };\n } catch (error) {\n log.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);\n return undefined;\n }\n}\n\n/** Resolves Unihex characters with vanilla metrics and lazily rasterized, half-resolution glyphs. */\nexport async function loadUnihex(provider: UnihexProvider, fontKey: AssetKey, characters: string): Promise<Map<string, BitmapGlyph>> {\n const origin = new AssetKey(DEFAULT_NAMESPACE, \"\", undefined, undefined, \"assets\", \"\", fontKey.root);\n const key = AssetKey.parse(\"font\", provider.hex_file, origin);\n // Archive references already include their directory beneath the namespace root.\n key.assetType = undefined;\n const glyphs = new Map<string, BitmapGlyph>();\n let overrides;\n try {\n overrides = (provider.size_overrides ?? []).map(override => {\n const from = override.from.codePointAt(0), to = override.to.codePointAt(0);\n if ([...override.from].length !== 1 || [...override.to].length !== 1 || from! >= to!\n || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {\n throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);\n }\n return { ...override, from: from!, to: to! };\n });\n } catch (error) {\n log.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);\n return glyphs;\n }\n const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));\n if (!file) return glyphs;\n let atlas = atlases.get(provider);\n if (!atlas) { atlas = new UnihexAtlas(); atlases.set(provider, atlas); }\n for (const character of characters) {\n const codepoint = character.codePointAt(0)!, index = file.indices[codepoint];\n if (index < 0) continue;\n const record = { rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),\n bitWidth: file.metrics[index * 3], left: file.metrics[index * 3 + 1], right: file.metrics[index * 3 + 2] };\n const override = overrides.find(range => codepoint >= range.from && codepoint <= range.to);\n if (override) { record.left = override.left; record.right = override.right; }\n const width = record.right - record.left + 1;\n let rendered: ReturnType<UnihexAtlas[\"draw\"]> | undefined;\n const render = () => rendered ??= atlas!.draw(record);\n glyphs.set(character, {\n get image() { return render().image; },\n get x() { return render().x; },\n get y() { return render().y; },\n width, height: GLYPH_HEIGHT, scale: 0.5, ascent: 7, advance: Math.floor(width / 2) + 1,\n boldOffset: 0.5, shadowOffset: 0.5\n });\n }\n return glyphs;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/assets/source/HostedAssetSource.ts
|
|
2
2
|
import { AssetLoadError, AssetSource } from "./AssetSource.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { logger } from "../../util/log.mjs";
|
|
4
4
|
import { NBTHelper } from "../../nbt/index.mjs";
|
|
5
5
|
import { ImageLoader } from "../../image/index.mjs";
|
|
6
6
|
import { AssetKey } from "../AssetKey.mjs";
|
|
@@ -10,7 +10,7 @@ import { AssetLoader } from "../AssetLoader.mjs";
|
|
|
10
10
|
import { AssetParser } from "./parser/index.mjs";
|
|
11
11
|
import { merge } from "../../util/_internal/merge.mjs";
|
|
12
12
|
var BINARY_TIMEOUT = 6e4;
|
|
13
|
-
var
|
|
13
|
+
var log = logger("HostedAssetSource");
|
|
14
14
|
var DEFAULT_OPTIONS = {
|
|
15
15
|
retryDefaults: true
|
|
16
16
|
};
|
|
@@ -22,14 +22,14 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
22
22
|
return direct;
|
|
23
23
|
}
|
|
24
24
|
if (key.namespace !== DEFAULT_NAMESPACE) {
|
|
25
|
-
|
|
25
|
+
log.debug("Retrying", key, "with default namespace");
|
|
26
26
|
const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);
|
|
27
27
|
const namespaced = await this.load(namespaceKey, parser);
|
|
28
28
|
if (typeof namespaced !== "undefined") {
|
|
29
29
|
return namespaced;
|
|
30
30
|
}
|
|
31
31
|
if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
|
|
32
|
-
|
|
32
|
+
log.debug("Retrying", key, "with default root+namespace");
|
|
33
33
|
const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
|
|
34
34
|
const namespacedRooted = await this.load(namespacedRootedKey, parser);
|
|
35
35
|
if (typeof namespacedRooted !== "undefined") {
|
|
@@ -37,7 +37,7 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
} else if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
|
|
40
|
-
|
|
40
|
+
log.debug("Retrying", key, "with default root");
|
|
41
41
|
const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
|
|
42
42
|
const rooted = await this.load(rootKey, parser);
|
|
43
43
|
if (typeof rooted !== "undefined") {
|
|
@@ -47,9 +47,8 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
|
|
|
47
47
|
return void 0;
|
|
48
48
|
}
|
|
49
49
|
async load(key, parser) {
|
|
50
|
-
console.info(p, "Loading", key);
|
|
51
50
|
const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
|
|
52
|
-
|
|
51
|
+
log.debug("Loading", url);
|
|
53
52
|
const request = { url };
|
|
54
53
|
try {
|
|
55
54
|
parser.config(request);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/assets/source/HostedAssetSource.ts"],"sourcesContent":["import { AssetLoadError, AssetSource } from \"./AssetSource\";\nimport { BlockState, Model, TextureAsset } from \"../../model\";\nimport type { RequestConfig, RequestResponse } from \"../../request\";\nimport { Maybe, prefix } from \"../../util\";\nimport { MinecraftTextureMeta } from \"../../MinecraftTextureMeta\";\nimport { NBTAsset, NBTHelper } from \"../../nbt\";\nimport { ImageLoader } from \"../../image\";\nimport { ListAsset } from \"../../ListAsset\";\nimport { MinecraftAsset } from \"../../MinecraftAsset\";\nimport { AssetKey } from \"../AssetKey\";\nimport { DEFAULT_NAMESPACE } from \"../AssetDefaults\";\nimport { RequestError, Requests } from \"../../request\";\nimport { AssetLoader } from \"../AssetLoader\";\nimport { AssetParser } from \"./parser\";\nimport { ResponseParser } from \"./parser\";\nimport { merge } from \"../../util/_internal/merge\";\n\nconst BINARY_TIMEOUT = 60_000;\n\nconst p = prefix(\"HostedAssetSource\");\n\nconst DEFAULT_OPTIONS: HostedAssetSourceOptions = {\n retryDefaults: true\n}\n\n/** Loads assets over HTTP from a Minecraft directory tree rooted at the constructor's URL. */\nexport class HostedAssetSource extends AssetSource {\n\n static readonly MODEL: ResponseParser<Model> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<Model> {\n return response.data as Model;\n }\n }\n static readonly BLOCKSTATE: ResponseParser<BlockState> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<BlockState> {\n return response.data as BlockState;\n }\n }\n static readonly META: ResponseParser<MinecraftTextureMeta> = {\n config(request: RequestConfig) {\n // request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): Maybe<MinecraftTextureMeta> {\n return response.data as MinecraftTextureMeta;\n }\n }\n static readonly NBT: ResponseParser<NBTAsset> = {\n config(request: RequestConfig) {\n request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): Promise<Maybe<NBTAsset>> {\n return NBTHelper.fromBuffer(response.data);\n }\n }\n static readonly IMAGE: ResponseParser<TextureAsset> = {\n config(request: RequestConfig) {\n request.responseType = \"arraybuffer\";\n },\n async parse(response: RequestResponse): Promise<Maybe<TextureAsset>> {\n return await ImageLoader.processResponse(response) as TextureAsset;\n }\n }\n static readonly LIST: ResponseParser<ListAsset> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<ListAsset> {\n return response.data as ListAsset;\n }\n }\n static readonly JSON: ResponseParser<any> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<any> {\n return response.data;\n }\n }\n static readonly BINARY: ResponseParser<BinaryAsset> = {\n config(request: RequestConfig) {\n request.timeout = BINARY_TIMEOUT;\n request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): BinaryAsset {\n return { data: new Uint8Array(response.data as ArrayBuffer) };\n }\n }\n\n static readonly PARSER_MAP: Map<AssetParser, ResponseParser<any>> = new Map<AssetParser, ResponseParser<any>>([\n [AssetParser.MODEL, HostedAssetSource.MODEL],\n [AssetParser.BLOCKSTATE, HostedAssetSource.BLOCKSTATE],\n [AssetParser.META, HostedAssetSource.META],\n [AssetParser.NBT, HostedAssetSource.NBT],\n [AssetParser.IMAGE, HostedAssetSource.IMAGE],\n [AssetParser.LIST, HostedAssetSource.LIST],\n [AssetParser.JSON, HostedAssetSource.JSON],\n [AssetParser.BINARY, HostedAssetSource.BINARY],\n ]);\n\n /** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */\n public async loadOrRetryWithDefaults<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>> {\n const direct = await this.load<T>(key, parser);\n if (typeof direct !== \"undefined\") {\n return direct;\n }\n if (key.namespace !== DEFAULT_NAMESPACE) {\n console.info(p, \"Retrying\", key, \"with default namespace\");\n // Try on the same host but with default minecraft: namespace\n const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);\n const namespaced = await this.load<T>(namespaceKey, parser);\n if (typeof namespaced !== \"undefined\") {\n return namespaced;\n }\n if ((typeof key.root !== \"undefined\" && key.root !== AssetLoader.ROOT) || (typeof this.root !== \"undefined\" && this.root !== AssetLoader.ROOT)) {\n console.info(p, \"Retrying\", key, \"with default root+namespace\");\n // Try both defaults\n const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);\n const namespacedRooted = await this.load<T>(namespacedRootedKey, parser);\n if (typeof namespacedRooted !== \"undefined\") {\n return namespacedRooted;\n }\n }\n } else if ((typeof key.root !== \"undefined\" && key.root !== AssetLoader.ROOT) || (typeof this.root !== \"undefined\" && this.root !== AssetLoader.ROOT)) {\n console.info(p, \"Retrying\", key, \"with default root\");\n // Try on default root\n const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);\n const rooted = await this.load<T>(rootKey, parser);\n if (typeof rooted !== \"undefined\") {\n return rooted;\n }\n }\n return undefined;\n }\n\n\n protected async load<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>> {\n console.info(p, \"Loading\", key);\n const url = `${ this.assetBasePath(key) }${ key.type !== undefined ? key.type + '/' : '' }${ key.path }${ key.extension }`;\n console.debug(p, url);\n const request: RequestConfig = { url };\n try {\n parser.config(request);\n let response: RequestResponse;\n try {\n response = await Requests.mcAssetRequest(request);\n } catch (cause) {\n // HTTP 404 is the only request failure that permits source fallback.\n if (cause instanceof RequestError && cause.response?.status === 404) {\n return undefined;\n }\n throw cause;\n }\n if (response.data === undefined) {\n throw new Error(\"Asset response has no data\");\n }\n return await parser.parse(response);\n } catch (cause) {\n throw new AssetLoadError(this, key, request.url, cause);\n }\n }\n\n public assetBasePath(key: AssetKey) {\n return `${ key.root ?? this.root ?? AssetLoader.ROOT }/${ key.rootType !== undefined ? key.rootType + '/' : '' }${ key.namespace !== undefined ? key.namespace + '/' : '' }${ key.assetType !== undefined ? key.assetType + '/' : '' }`;\n }\n\n private readonly _root: string;\n private readonly _options: HostedAssetSourceOptions;\n\n /**\n * Creates a hosted source for {@link AssetLoader.addSource}.\n * Set `options.retryDefaults` to `false` to restrict lookups to the requested namespace and root.\n */\n public constructor(root: string, options?: Partial<HostedAssetSourceOptions>) {\n super();\n this._root = root;\n this._options = merge({}, DEFAULT_OPTIONS, options ?? {});\n }\n\n public get root(): string {\n return this._root;\n }\n\n public get cacheId(): string {\n return `hosted:${this._root}`;\n }\n\n public get options(): HostedAssetSourceOptions {\n return this._options;\n }\n\n public get<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser): Promise<Maybe<T>> {\n const responseParser = HostedAssetSource.PARSER_MAP.get(parser) as ResponseParser<T>;\n if (this.options.retryDefaults && !(key.rootType === undefined && key.namespace === \"minerender-data\")) {\n return this.loadOrRetryWithDefaults(key, responseParser);\n }\n return this.load(key, responseParser);\n }\n\n}\n\ninterface HostedAssetSourceOptions {\n retryDefaults: boolean;\n}\n\n/** Encoded asset bytes loaded without JSON or image decoding. */\nexport interface BinaryAsset extends MinecraftAsset {\n data: Uint8Array;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/assets/source/HostedAssetSource.ts"],"sourcesContent":["import { AssetLoadError, AssetSource } from \"./AssetSource\";\nimport { BlockState, Model, TextureAsset } from \"../../model\";\nimport type { RequestConfig, RequestResponse } from \"../../request\";\nimport { Maybe } from \"../../util\";\nimport { logger } from \"../../util/log\";\nimport { MinecraftTextureMeta } from \"../../MinecraftTextureMeta\";\nimport { NBTAsset, NBTHelper } from \"../../nbt\";\nimport { ImageLoader } from \"../../image\";\nimport { ListAsset } from \"../../ListAsset\";\nimport { MinecraftAsset } from \"../../MinecraftAsset\";\nimport { AssetKey } from \"../AssetKey\";\nimport { DEFAULT_NAMESPACE } from \"../AssetDefaults\";\nimport { RequestError, Requests } from \"../../request\";\nimport { AssetLoader } from \"../AssetLoader\";\nimport { AssetParser } from \"./parser\";\nimport { ResponseParser } from \"./parser\";\nimport { merge } from \"../../util/_internal/merge\";\n\nconst BINARY_TIMEOUT = 60_000;\n\nconst log = logger(\"HostedAssetSource\");\n\nconst DEFAULT_OPTIONS: HostedAssetSourceOptions = {\n retryDefaults: true\n}\n\n/** Loads assets over HTTP from a Minecraft directory tree rooted at the constructor's URL. */\nexport class HostedAssetSource extends AssetSource {\n\n static readonly MODEL: ResponseParser<Model> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<Model> {\n return response.data as Model;\n }\n }\n static readonly BLOCKSTATE: ResponseParser<BlockState> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<BlockState> {\n return response.data as BlockState;\n }\n }\n static readonly META: ResponseParser<MinecraftTextureMeta> = {\n config(request: RequestConfig) {\n // request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): Maybe<MinecraftTextureMeta> {\n return response.data as MinecraftTextureMeta;\n }\n }\n static readonly NBT: ResponseParser<NBTAsset> = {\n config(request: RequestConfig) {\n request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): Promise<Maybe<NBTAsset>> {\n return NBTHelper.fromBuffer(response.data);\n }\n }\n static readonly IMAGE: ResponseParser<TextureAsset> = {\n config(request: RequestConfig) {\n request.responseType = \"arraybuffer\";\n },\n async parse(response: RequestResponse): Promise<Maybe<TextureAsset>> {\n return await ImageLoader.processResponse(response) as TextureAsset;\n }\n }\n static readonly LIST: ResponseParser<ListAsset> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<ListAsset> {\n return response.data as ListAsset;\n }\n }\n static readonly JSON: ResponseParser<any> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<any> {\n return response.data;\n }\n }\n static readonly BINARY: ResponseParser<BinaryAsset> = {\n config(request: RequestConfig) {\n request.timeout = BINARY_TIMEOUT;\n request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): BinaryAsset {\n return { data: new Uint8Array(response.data as ArrayBuffer) };\n }\n }\n\n static readonly PARSER_MAP: Map<AssetParser, ResponseParser<any>> = new Map<AssetParser, ResponseParser<any>>([\n [AssetParser.MODEL, HostedAssetSource.MODEL],\n [AssetParser.BLOCKSTATE, HostedAssetSource.BLOCKSTATE],\n [AssetParser.META, HostedAssetSource.META],\n [AssetParser.NBT, HostedAssetSource.NBT],\n [AssetParser.IMAGE, HostedAssetSource.IMAGE],\n [AssetParser.LIST, HostedAssetSource.LIST],\n [AssetParser.JSON, HostedAssetSource.JSON],\n [AssetParser.BINARY, HostedAssetSource.BINARY],\n ]);\n\n /** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */\n public async loadOrRetryWithDefaults<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>> {\n const direct = await this.load<T>(key, parser);\n if (typeof direct !== \"undefined\") {\n return direct;\n }\n if (key.namespace !== DEFAULT_NAMESPACE) {\n log.debug(\"Retrying\", key, \"with default namespace\");\n // Try on the same host but with default minecraft: namespace\n const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);\n const namespaced = await this.load<T>(namespaceKey, parser);\n if (typeof namespaced !== \"undefined\") {\n return namespaced;\n }\n if ((typeof key.root !== \"undefined\" && key.root !== AssetLoader.ROOT) || (typeof this.root !== \"undefined\" && this.root !== AssetLoader.ROOT)) {\n log.debug(\"Retrying\", key, \"with default root+namespace\");\n // Try both defaults\n const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);\n const namespacedRooted = await this.load<T>(namespacedRootedKey, parser);\n if (typeof namespacedRooted !== \"undefined\") {\n return namespacedRooted;\n }\n }\n } else if ((typeof key.root !== \"undefined\" && key.root !== AssetLoader.ROOT) || (typeof this.root !== \"undefined\" && this.root !== AssetLoader.ROOT)) {\n log.debug(\"Retrying\", key, \"with default root\");\n // Try on default root\n const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);\n const rooted = await this.load<T>(rootKey, parser);\n if (typeof rooted !== \"undefined\") {\n return rooted;\n }\n }\n return undefined;\n }\n\n\n protected async load<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>> {\n const url = `${ this.assetBasePath(key) }${ key.type !== undefined ? key.type + '/' : '' }${ key.path }${ key.extension }`;\n log.debug(\"Loading\", url);\n const request: RequestConfig = { url };\n try {\n parser.config(request);\n let response: RequestResponse;\n try {\n response = await Requests.mcAssetRequest(request);\n } catch (cause) {\n // HTTP 404 is the only request failure that permits source fallback.\n if (cause instanceof RequestError && cause.response?.status === 404) {\n return undefined;\n }\n throw cause;\n }\n if (response.data === undefined) {\n throw new Error(\"Asset response has no data\");\n }\n return await parser.parse(response);\n } catch (cause) {\n throw new AssetLoadError(this, key, request.url, cause);\n }\n }\n\n public assetBasePath(key: AssetKey) {\n return `${ key.root ?? this.root ?? AssetLoader.ROOT }/${ key.rootType !== undefined ? key.rootType + '/' : '' }${ key.namespace !== undefined ? key.namespace + '/' : '' }${ key.assetType !== undefined ? key.assetType + '/' : '' }`;\n }\n\n private readonly _root: string;\n private readonly _options: HostedAssetSourceOptions;\n\n /**\n * Creates a hosted source for {@link AssetLoader.addSource}.\n * Set `options.retryDefaults` to `false` to restrict lookups to the requested namespace and root.\n */\n public constructor(root: string, options?: Partial<HostedAssetSourceOptions>) {\n super();\n this._root = root;\n this._options = merge({}, DEFAULT_OPTIONS, options ?? {});\n }\n\n public get root(): string {\n return this._root;\n }\n\n public get cacheId(): string {\n return `hosted:${this._root}`;\n }\n\n public get options(): HostedAssetSourceOptions {\n return this._options;\n }\n\n public get<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser): Promise<Maybe<T>> {\n const responseParser = HostedAssetSource.PARSER_MAP.get(parser) as ResponseParser<T>;\n if (this.options.retryDefaults && !(key.rootType === undefined && key.namespace === \"minerender-data\")) {\n return this.loadOrRetryWithDefaults(key, responseParser);\n }\n return this.load(key, responseParser);\n }\n\n}\n\ninterface HostedAssetSourceOptions {\n retryDefaults: boolean;\n}\n\n/** Encoded asset bytes loaded without JSON or image decoding. */\nexport interface BinaryAsset extends MinecraftAsset {\n data: Uint8Array;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/env/browser/BrowserCache.ts
|
|
2
2
|
import { PersistentCache } from "../../cache/PersistentCache.mjs";
|
|
3
|
-
import {
|
|
4
|
-
var
|
|
3
|
+
import { logger } from "../../util/log.mjs";
|
|
4
|
+
var log = logger("BrowserCache");
|
|
5
5
|
var BrowserCache = class extends PersistentCache {
|
|
6
6
|
constructor(backing) {
|
|
7
7
|
super(backing);
|
|
@@ -12,7 +12,7 @@ var BrowserCache = class extends PersistentCache {
|
|
|
12
12
|
return true;
|
|
13
13
|
} catch (error) {
|
|
14
14
|
this.memory = /* @__PURE__ */ new Map();
|
|
15
|
-
|
|
15
|
+
log.warn("Could not open browser storage; using an in-memory store", error);
|
|
16
16
|
return false;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/env/browser/BrowserCache.ts"],"sourcesContent":["import { PersistentCache } from \"../../cache/PersistentCache\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../../src/env/browser/BrowserCache.ts"],"sourcesContent":["import { PersistentCache } from \"../../cache/PersistentCache\";\nimport { logger } from \"../../util/log\";\n\nconst log = logger(\"BrowserCache\");\n\n/**\n * {@link PersistentCache} backed by localforage (IndexedDB / WebSQL / localStorage).\n * Uses an in-memory store when browser storage cannot be opened.\n */\nexport class BrowserCache extends PersistentCache<LocalForage> {\n\n private initialized?: Promise<boolean>;\n private memory?: Map<string, unknown>;\n\n constructor(backing: LocalForage) {\n super(backing);\n }\n\n private async initialize(): Promise<boolean> {\n try {\n await this.backing.ready();\n return true;\n } catch (error) {\n this.memory = new Map();\n log.warn(\"Could not open browser storage; using an in-memory store\", error);\n return false;\n }\n }\n\n private async run<T>(operation: () => Promise<T>, fallback: (memory: Map<string, unknown>) => T): Promise<T> {\n if (await (this.initialized ??= this.initialize())) return operation();\n return fallback(this.memory!);\n }\n\n get<T>(key: string): Promise<T> {\n return this.run(() => this.backing.getItem<T>(key), memory => memory.get(key) as T) as Promise<T>;\n }\n\n put<T>(key: string, value: T): Promise<T> {\n return this.run(() => this.backing.setItem<T>(key, value), memory => {\n memory.set(key, value);\n return value;\n });\n }\n\n delete<T>(key: string): Promise<void> {\n return this.run(() => this.backing.removeItem(key), memory => { memory.delete(key); });\n }\n\n clear(): Promise<void> {\n return this.run(() => this.backing.clear(), memory => memory.clear());\n }\n\n length(): Promise<number> {\n return this.run(() => this.backing.length(), memory => memory.size);\n }\n\n keys(): Promise<string[]> {\n return this.run(() => this.backing.keys(), memory => [...memory.keys()]);\n }\n\n forEach<T>(callback: (v: T, k: string) => void): Promise<void> {\n return this.run(() => this.backing.iterate<T, void>((value, key) => {\n callback(value, key);\n }), memory => memory.forEach((value, key) => callback(value as T, key)));\n }\n\n}\n"],"mappings":";AAAA,SAAS,uBAAuB;AAChC,SAAS,cAAc;AAEvB,IAAM,MAAM,OAAO,cAAc;AAM1B,IAAM,eAAN,cAA2B,gBAA6B;AAAA,EAK3D,YAAY,SAAsB;AAC9B,UAAM,OAAO;AAAA,EACjB;AAAA,EAEA,MAAc,aAA+B;AACzC,QAAI;AACA,YAAM,KAAK,QAAQ,MAAM;AACzB,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,WAAK,SAAS,oBAAI,IAAI;AACtB,UAAI,KAAK,4DAA4D,KAAK;AAC1E,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEA,MAAc,IAAO,WAA6B,UAA2D;AACzG,QAAI,OAAO,KAAK,gBAAL,KAAK,cAAgB,KAAK,WAAW,IAAI,QAAO,UAAU;AACrE,WAAO,SAAS,KAAK,MAAO;AAAA,EAChC;AAAA,EAEA,IAAO,KAAyB;AAC5B,WAAO,KAAK,IAAI,MAAM,KAAK,QAAQ,QAAW,GAAG,GAAG,YAAU,OAAO,IAAI,GAAG,CAAM;AAAA,EACtF;AAAA,EAEA,IAAO,KAAa,OAAsB;AACtC,WAAO,KAAK,IAAI,MAAM,KAAK,QAAQ,QAAW,KAAK,KAAK,GAAG,YAAU;AACjE,aAAO,IAAI,KAAK,KAAK;AACrB,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EAEA,OAAU,KAA4B;AAClC,WAAO,KAAK,IAAI,MAAM,KAAK,QAAQ,WAAW,GAAG,GAAG,YAAU;AAAE,aAAO,OAAO,GAAG;AAAA,IAAG,CAAC;AAAA,EACzF;AAAA,EAEA,QAAuB;AACnB,WAAO,KAAK,IAAI,MAAM,KAAK,QAAQ,MAAM,GAAG,YAAU,OAAO,MAAM,CAAC;AAAA,EACxE;AAAA,EAEA,SAA0B;AACtB,WAAO,KAAK,IAAI,MAAM,KAAK,QAAQ,OAAO,GAAG,YAAU,OAAO,IAAI;AAAA,EACtE;AAAA,EAEA,OAA0B;AACtB,WAAO,KAAK,IAAI,MAAM,KAAK,QAAQ,KAAK,GAAG,YAAU,CAAC,GAAG,OAAO,KAAK,CAAC,CAAC;AAAA,EAC3E;AAAA,EAEA,QAAW,UAAoD;AAC3D,WAAO,KAAK,IAAI,MAAM,KAAK,QAAQ,QAAiB,CAAC,OAAO,QAAQ;AAChE,eAAS,OAAO,GAAG;AAAA,IACvB,CAAC,GAAG,YAAU,OAAO,QAAQ,CAAC,OAAO,QAAQ,SAAS,OAAY,GAAG,CAAC,CAAC;AAAA,EAC3E;AAEJ;","names":[]}
|
|
@@ -6,8 +6,8 @@ import { Env } from "../Env.mjs";
|
|
|
6
6
|
import { Requests } from "../request/Requests.mjs";
|
|
7
7
|
import { WrappedImage } from "../WrappedImage.mjs";
|
|
8
8
|
import { base64ToBytes, bytesToBase64 } from "../util/_internal/base64.mjs";
|
|
9
|
-
import {
|
|
10
|
-
var
|
|
9
|
+
import { logger } from "../util/log.mjs";
|
|
10
|
+
var log = logger("ImageLoader");
|
|
11
11
|
var ImageLoader = class _ImageLoader {
|
|
12
12
|
static _createImage() {
|
|
13
13
|
return createImage();
|
|
@@ -32,7 +32,7 @@ var ImageLoader = class _ImageLoader {
|
|
|
32
32
|
return image;
|
|
33
33
|
}
|
|
34
34
|
static async loadData(src) {
|
|
35
|
-
|
|
35
|
+
log.debug("loadData", src);
|
|
36
36
|
const image = await this.loadCanvasData(src);
|
|
37
37
|
return image.data.getImageData(0, 0, image.width, image.height);
|
|
38
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/image/ImageLoader.ts"],"sourcesContent":["import { CompatImage, createCanvas, createImage } from \"../canvas/CanvasCompat\";\nimport { serializeImageKey } from \"../cache/CacheKey\";\nimport { Caching } from \"../cache/Caching\";\nimport type { RequestResponse } from \"../request/Requests\";\nimport { Env } from \"../Env\";\nimport { Requests } from \"../request/Requests\";\nimport { WrappedImage } from \"../WrappedImage\";\nimport { ExtractableImageData } from \"../ExtractableImageData\";\nimport { base64ToBytes, bytesToBase64 } from \"../util/_internal/base64\";\nimport { prefix } from \"../util/log\";\n\nconst p = prefix(\"ImageLoader\");\n\n/** Encoded image bytes with dimensions and format detected from the file header. */\nexport interface ImageInfo {\n src?: string;\n width: number;\n height: number;\n type?: string;\n data: Uint8Array;\n}\n\n/** Fetches and decodes images through the active browser or Node environment provider. */\nexport class ImageLoader {\n\n protected static _createImage(): CompatImage {\n return createImage();\n }\n\n /** Resolves when an image URL has decoded, or rejects if decoding fails. */\n public static async loadAsync(src: string): Promise<CompatImage> {\n return new Promise<CompatImage>((resolve, reject) => {\n const image = this._createImage();\n image.onload = () => resolve(image);\n image.onerror = (err: Error) => reject(err instanceof Error ? err : new Error(\"Failed to decode image\"));\n // Node images can finish decoding synchronously when src is assigned.\n image.src = src;\n });\n }\n\n /** Returns an image immediately. Use the callbacks to observe loading, or await {@link loadAsync}. */\n public static loadElement(src: string, onload?: () => void, onerr?: (err: Error) => void): CompatImage {\n const image = this._createImage();\n if (onload)\n image.onload = onload;\n if (onerr)\n image.onerror = onerr;\n image.src = src;\n return image;\n }\n\n public static async loadData(src: string): Promise<ImageData> {\n console.debug(p, \"loadData\", src);\n const image = await this.loadCanvasData(src);\n return image.data.getImageData(0, 0, image.width, image.height);\n }\n\n public static async loadCanvasData(src: string): Promise<ExtractableImageData> {\n const keyStr = serializeImageKey({ src });\n const info = this.getInfo(src);\n const cached = Caching.rawImageCache.getIfPresent(keyStr);\n try {\n return await this.infoToCanvasData(await info);\n } catch (err) {\n // A valid header can still contain corrupt pixels. Retry the fetch after a decode\n // failure, without evicting a replacement inserted while this load was pending.\n if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {\n Caching.rawImageCache.invalidate(keyStr);\n }\n throw err;\n }\n }\n\n /** Decodes the supplied bytes into a canvas without fetching the source URL again. */\n public static async infoToCanvasData(info: ImageInfo): Promise<ExtractableImageData> {\n const type = info.type === \"jpg\" ? \"jpeg\" : info.type ?? \"png\";\n // Both browser and Node images accept data URLs; src remains provenance, not a second fetch.\n const image = await ImageLoader.loadAsync(`data:image/${type};base64,${bytesToBase64(info.data)}`);\n const canvas = createCanvas(info.width, info.height);\n const context = canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n context.drawImage(image as CanvasImageSource, 0, 0);\n return {\n data: context,\n width: info.width,\n height: info.height\n }\n }\n\n\n public static async infoToData(info: ImageInfo): Promise<ImageData> {\n const image = await this.infoToCanvasData(info);\n return image.data.getImageData(0, 0, image.width, image.height);\n }\n\n /** Returns cached RGBA pixels for an image URL or data URL. Failed loads can be retried. */\n public static async getData(src: string): Promise<ImageData> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.imageDataCache.get(keyStr, k => {\n return ImageLoader.loadData(src);\n }))!;\n }\n\n /** Returns a cached canvas context and dimensions for an image URL or data URL. */\n public static async getCanvasData(src: string): Promise<ExtractableImageData> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.canvasImageDataCache.get(keyStr, k => {\n return ImageLoader.loadCanvasData(src);\n }))!;\n }\n\n public static async processResponse(response: Pick<RequestResponse<ArrayBuffer>, \"data\" | \"url\">): Promise<ImageInfo> {\n const src = response.url;\n const data = new Uint8Array(response.data);\n const { width, height, type } = Env.provider.imageSize(data);\n if (!width || !height) {\n throw new Error(\"Invalid or unsupported image dimensions\");\n }\n return {\n src,\n width,\n height,\n type,\n data: data\n }\n }\n\n\n public static async loadInfo(src: string): Promise<ImageInfo> {\n if (/^data:/i.test(src.trimStart())) {\n const url = new URL(src);\n url.hash = \"\";\n const comma = url.href.indexOf(\",\");\n if (comma < 0) {\n throw new Error(\"Invalid image data URL\");\n }\n // Percent escapes represent image bytes, which need not be valid UTF-8.\n const bytes = url.href.slice(comma + 1).replace(/%([\\da-f]{2})/gi,\n (_, hex: string) => String.fromCharCode(parseInt(hex, 16)));\n const data = /; *base64 *$/i.test(url.href.slice(5, comma))\n ? base64ToBytes(bytes)\n : Uint8Array.from(bytes, char => char.charCodeAt(0));\n return this.processResponse({\n url: src,\n data: data.buffer\n });\n }\n\n return Requests.genericRequest({\n url: src,\n responseType: \"arraybuffer\"\n })\n .then(this.processResponse);\n }\n\n public static async getInfo(src: string): Promise<ImageInfo> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.rawImageCache.get(keyStr, k => {\n return ImageLoader.loadInfo(src);\n }))!;\n }\n\n public static async loadWrapped(src: string): Promise<WrappedImage> {\n const data = await this.getCanvasData(src);\n return new WrappedImage(data);\n }\n\n public static async getWrapped(src: string): Promise<WrappedImage> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.wrappedImageCache.get(keyStr, k => {\n return ImageLoader.loadWrapped(src);\n }))!;\n }\n\n\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/image/ImageLoader.ts"],"sourcesContent":["import { CompatImage, createCanvas, createImage } from \"../canvas/CanvasCompat\";\nimport { serializeImageKey } from \"../cache/CacheKey\";\nimport { Caching } from \"../cache/Caching\";\nimport type { RequestResponse } from \"../request/Requests\";\nimport { Env } from \"../Env\";\nimport { Requests } from \"../request/Requests\";\nimport { WrappedImage } from \"../WrappedImage\";\nimport { ExtractableImageData } from \"../ExtractableImageData\";\nimport { base64ToBytes, bytesToBase64 } from \"../util/_internal/base64\";\nimport { logger } from \"../util/log\";\n\nconst log = logger(\"ImageLoader\");\n\n/** Encoded image bytes with dimensions and format detected from the file header. */\nexport interface ImageInfo {\n src?: string;\n width: number;\n height: number;\n type?: string;\n data: Uint8Array;\n}\n\n/** Fetches and decodes images through the active browser or Node environment provider. */\nexport class ImageLoader {\n\n protected static _createImage(): CompatImage {\n return createImage();\n }\n\n /** Resolves when an image URL has decoded, or rejects if decoding fails. */\n public static async loadAsync(src: string): Promise<CompatImage> {\n return new Promise<CompatImage>((resolve, reject) => {\n const image = this._createImage();\n image.onload = () => resolve(image);\n image.onerror = (err: Error) => reject(err instanceof Error ? err : new Error(\"Failed to decode image\"));\n // Node images can finish decoding synchronously when src is assigned.\n image.src = src;\n });\n }\n\n /** Returns an image immediately. Use the callbacks to observe loading, or await {@link loadAsync}. */\n public static loadElement(src: string, onload?: () => void, onerr?: (err: Error) => void): CompatImage {\n const image = this._createImage();\n if (onload)\n image.onload = onload;\n if (onerr)\n image.onerror = onerr;\n image.src = src;\n return image;\n }\n\n public static async loadData(src: string): Promise<ImageData> {\n log.debug(\"loadData\", src);\n const image = await this.loadCanvasData(src);\n return image.data.getImageData(0, 0, image.width, image.height);\n }\n\n public static async loadCanvasData(src: string): Promise<ExtractableImageData> {\n const keyStr = serializeImageKey({ src });\n const info = this.getInfo(src);\n const cached = Caching.rawImageCache.getIfPresent(keyStr);\n try {\n return await this.infoToCanvasData(await info);\n } catch (err) {\n // A valid header can still contain corrupt pixels. Retry the fetch after a decode\n // failure, without evicting a replacement inserted while this load was pending.\n if (cached && Caching.rawImageCache.getIfPresent(keyStr) === cached) {\n Caching.rawImageCache.invalidate(keyStr);\n }\n throw err;\n }\n }\n\n /** Decodes the supplied bytes into a canvas without fetching the source URL again. */\n public static async infoToCanvasData(info: ImageInfo): Promise<ExtractableImageData> {\n const type = info.type === \"jpg\" ? \"jpeg\" : info.type ?? \"png\";\n // Both browser and Node images accept data URLs; src remains provenance, not a second fetch.\n const image = await ImageLoader.loadAsync(`data:image/${type};base64,${bytesToBase64(info.data)}`);\n const canvas = createCanvas(info.width, info.height);\n const context = canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n context.drawImage(image as CanvasImageSource, 0, 0);\n return {\n data: context,\n width: info.width,\n height: info.height\n }\n }\n\n\n public static async infoToData(info: ImageInfo): Promise<ImageData> {\n const image = await this.infoToCanvasData(info);\n return image.data.getImageData(0, 0, image.width, image.height);\n }\n\n /** Returns cached RGBA pixels for an image URL or data URL. Failed loads can be retried. */\n public static async getData(src: string): Promise<ImageData> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.imageDataCache.get(keyStr, k => {\n return ImageLoader.loadData(src);\n }))!;\n }\n\n /** Returns a cached canvas context and dimensions for an image URL or data URL. */\n public static async getCanvasData(src: string): Promise<ExtractableImageData> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.canvasImageDataCache.get(keyStr, k => {\n return ImageLoader.loadCanvasData(src);\n }))!;\n }\n\n public static async processResponse(response: Pick<RequestResponse<ArrayBuffer>, \"data\" | \"url\">): Promise<ImageInfo> {\n const src = response.url;\n const data = new Uint8Array(response.data);\n const { width, height, type } = Env.provider.imageSize(data);\n if (!width || !height) {\n throw new Error(\"Invalid or unsupported image dimensions\");\n }\n return {\n src,\n width,\n height,\n type,\n data: data\n }\n }\n\n\n public static async loadInfo(src: string): Promise<ImageInfo> {\n if (/^data:/i.test(src.trimStart())) {\n const url = new URL(src);\n url.hash = \"\";\n const comma = url.href.indexOf(\",\");\n if (comma < 0) {\n throw new Error(\"Invalid image data URL\");\n }\n // Percent escapes represent image bytes, which need not be valid UTF-8.\n const bytes = url.href.slice(comma + 1).replace(/%([\\da-f]{2})/gi,\n (_, hex: string) => String.fromCharCode(parseInt(hex, 16)));\n const data = /; *base64 *$/i.test(url.href.slice(5, comma))\n ? base64ToBytes(bytes)\n : Uint8Array.from(bytes, char => char.charCodeAt(0));\n return this.processResponse({\n url: src,\n data: data.buffer\n });\n }\n\n return Requests.genericRequest({\n url: src,\n responseType: \"arraybuffer\"\n })\n .then(this.processResponse);\n }\n\n public static async getInfo(src: string): Promise<ImageInfo> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.rawImageCache.get(keyStr, k => {\n return ImageLoader.loadInfo(src);\n }))!;\n }\n\n public static async loadWrapped(src: string): Promise<WrappedImage> {\n const data = await this.getCanvasData(src);\n return new WrappedImage(data);\n }\n\n public static async getWrapped(src: string): Promise<WrappedImage> {\n const keyStr = serializeImageKey({ src });\n return (await Caching.wrappedImageCache.get(keyStr, k => {\n return ImageLoader.loadWrapped(src);\n }))!;\n }\n\n\n}\n"],"mappings":"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","names":[]}
|
|
@@ -933,6 +933,34 @@ declare class BatchedExecutor {
|
|
|
933
933
|
}
|
|
934
934
|
type Task<T = unknown> = () => T | Promise<T>;
|
|
935
935
|
|
|
936
|
+
/** Severity of a log message, from most to least verbose. */
|
|
937
|
+
type LogLevel = "debug" | "info" | "warn" | "error";
|
|
938
|
+
/** The lowest level that is printed, or `"silent"` to print nothing. */
|
|
939
|
+
type LogThreshold = LogLevel | "silent";
|
|
940
|
+
/** Receives each message that passes the threshold. `args` are the logger call's arguments, without a tag. */
|
|
941
|
+
type LogHandler = (level: LogLevel, namespace: string, args: unknown[]) => void;
|
|
942
|
+
interface LoggingOptions {
|
|
943
|
+
/** Threshold for namespaces without an override. Starts at `"warn"`. */
|
|
944
|
+
level?: LogThreshold;
|
|
945
|
+
/** Thresholds by logger name, such as `{ UVMapper: "debug" }`. Replaces earlier overrides. */
|
|
946
|
+
namespaces?: Record<string, LogThreshold>;
|
|
947
|
+
}
|
|
948
|
+
interface Logger {
|
|
949
|
+
debug(...args: unknown[]): void;
|
|
950
|
+
info(...args: unknown[]): void;
|
|
951
|
+
warn(...args: unknown[]): void;
|
|
952
|
+
error(...args: unknown[]): void;
|
|
953
|
+
}
|
|
954
|
+
/** Global log settings for every MineRender logger. */
|
|
955
|
+
declare class Logging {
|
|
956
|
+
/** Updates the given settings and keeps the others. */
|
|
957
|
+
static configure(options: LoggingOptions): void;
|
|
958
|
+
/** Sends messages to `handler` instead of the console. Call without an argument to restore console output. */
|
|
959
|
+
static setHandler(handler?: LogHandler): void;
|
|
960
|
+
}
|
|
961
|
+
/** Creates a logger whose messages are tagged and filtered as `namespace`. */
|
|
962
|
+
declare function logger(namespace: string): Logger;
|
|
963
|
+
/** @deprecated Use {@link logger}. */
|
|
936
964
|
declare function prefix(prefix?: string): string;
|
|
937
965
|
|
|
938
966
|
/** Rotates geometry in place around the element's origin. The supplied angle is in degrees. */
|
|
@@ -944,8 +972,11 @@ declare function addWireframeToObject(obj: Object3D, color?: number, w?: number)
|
|
|
944
972
|
/** Adds edge and axis helpers to a mesh and returns a function that disposes their resources. */
|
|
945
973
|
declare function addWireframeToMesh(geo: BufferGeometry, mesh: Mesh, color?: number, w?: number): () => void;
|
|
946
974
|
|
|
975
|
+
/** @deprecated Unused by MineRender. */
|
|
947
976
|
declare function captureException(e: any, ...extra: any[]): void;
|
|
977
|
+
/** @deprecated Unused by MineRender. */
|
|
948
978
|
declare function timingStart(marker: string): void;
|
|
979
|
+
/** @deprecated Unused by MineRender. */
|
|
949
980
|
declare function timingEnd(marker: string): void;
|
|
950
981
|
|
|
951
982
|
declare function sha1(str: string): string;
|
|
@@ -4035,7 +4066,7 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
4035
4066
|
private ambientOcclusionCells?;
|
|
4036
4067
|
private readonly blockChanges;
|
|
4037
4068
|
private biomeChange?;
|
|
4038
|
-
constructor(scene: MineRenderScene, x: number, y: number, z: number, onBlocksChanged?: ((positions: Vector3[]) => Promise<void>) | undefined, sectionModels?: SectionModels | undefined, neighborCell?: ((x: number, y: number, z: number) => number) | undefined, biomeAt?: ((x: number, y: number, z: number) => Maybe<string>) | undefined, onBiomesChanged?: ((biomes?: readonly string[]) => Promise<void>) | undefined, lightAt?: ((x: number, y: number, z: number) => number) | undefined, onLightCleared?: (() => Promise<void>) | undefined, ambientLight?: number, biomeBlend?: (() => BiomeBlend | undefined) | undefined);
|
|
4069
|
+
constructor(scene: MineRenderScene, x: number, y: number, z: number, onBlocksChanged?: ((positions: Vector3[], deferCulling?: boolean) => Promise<void>) | undefined, sectionModels?: SectionModels | undefined, neighborCell?: ((x: number, y: number, z: number) => number) | undefined, biomeAt?: ((x: number, y: number, z: number) => Maybe<string>) | undefined, onBiomesChanged?: ((biomes?: readonly string[]) => Promise<void>) | undefined, lightAt?: ((x: number, y: number, z: number) => number) | undefined, onLightCleared?: (() => Promise<void>) | undefined, ambientLight?: number, biomeBlend?: (() => BiomeBlend | undefined) | undefined);
|
|
4039
4070
|
/** Finds the nearest owned block hit across sections, testing each shared mesh once. */
|
|
4040
4071
|
static raycast<SectionMeshing extends boolean>(chunks: Iterable<Chunk<SectionMeshing>>, raycaster: Raycaster): WorldBlockIntersection | undefined;
|
|
4041
4072
|
getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo<SectionMeshing>>;
|
|
@@ -4047,11 +4078,14 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
4047
4078
|
getBiomeAt(pos: TripleArray): Maybe<string>;
|
|
4048
4079
|
/** Copies 64 biome IDs in x + z * 4 + y * 16 order and refreshes placed blocks. Omit the array to clear biome data. */
|
|
4049
4080
|
setBiomes(biomes?: readonly string[]): Promise<void>;
|
|
4050
|
-
/**
|
|
4081
|
+
/**
|
|
4082
|
+
* Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects.
|
|
4083
|
+
* The owning world can defer neighbor culling until all affected chunks are refreshed.
|
|
4084
|
+
*/
|
|
4051
4085
|
refreshBiomes(columns?: readonly {
|
|
4052
4086
|
x: number;
|
|
4053
4087
|
z: number;
|
|
4054
|
-
}[]): Promise<void>;
|
|
4088
|
+
}[], deferCulling?: boolean): Promise<void>;
|
|
4055
4089
|
private refreshBiomeBlocks;
|
|
4056
4090
|
/**
|
|
4057
4091
|
* Places a block at integer world block coordinates. Pass `undefined` to remove it.
|
|
@@ -4062,7 +4096,7 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
4062
4096
|
/**
|
|
4063
4097
|
* Places a block at integer chunk-local coordinates from 0 to 15.
|
|
4064
4098
|
*/
|
|
4065
|
-
setBlockInChunkAt(pos: Vector3, block?: Block, worldPos?: Vector3, onBlocksChanged?: ((positions: Vector3[]) => Promise<void>) | undefined): Promise<Maybe<BlockInfo<SectionMeshing>>>;
|
|
4099
|
+
setBlockInChunkAt(pos: Vector3, block?: Block, worldPos?: Vector3, onBlocksChanged?: ((positions: Vector3[], deferCulling?: boolean) => Promise<void>) | undefined): Promise<Maybe<BlockInfo<SectionMeshing>>>;
|
|
4066
4100
|
/** Places cells in input order and returns changed world positions without refreshing neighbors. */
|
|
4067
4101
|
placeBlocks(blocks: readonly {
|
|
4068
4102
|
index: number;
|
|
@@ -4227,6 +4261,14 @@ declare class MineRenderWorld<SectionMeshing extends boolean = false> {
|
|
|
4227
4261
|
* Coordinates match AnvilChunk.x/z, not block positions. Missing columns are ignored.
|
|
4228
4262
|
*/
|
|
4229
4263
|
unloadChunkColumn(x: number, z: number): Promise<void>;
|
|
4264
|
+
/**
|
|
4265
|
+
* Removes chunk columns together and refreshes surviving neighbors once.
|
|
4266
|
+
* Coordinates are absolute chunk columns. Duplicate and missing columns are ignored.
|
|
4267
|
+
*/
|
|
4268
|
+
unloadChunkColumns(positions: readonly {
|
|
4269
|
+
x: number;
|
|
4270
|
+
z: number;
|
|
4271
|
+
}[]): Promise<void>;
|
|
4230
4272
|
private clearChunkColumn;
|
|
4231
4273
|
private markSectionChanged;
|
|
4232
4274
|
/** Removes all chunks and releases their blocks, section meshes, and owned entities. */
|
|
@@ -4304,7 +4346,7 @@ declare class WorldStreamer {
|
|
|
4304
4346
|
private running?;
|
|
4305
4347
|
private disposal?;
|
|
4306
4348
|
private disposed;
|
|
4307
|
-
constructor(world: Pick<MineRenderWorld<boolean>, "placeChunk" | "
|
|
4349
|
+
constructor(world: Pick<MineRenderWorld<boolean>, "placeChunk" | "unloadChunkColumns">, source: WorldChunkSource, options?: WorldStreamerOptions);
|
|
4308
4350
|
/** Returns absolute coordinates of successfully placed columns, including retained columns. */
|
|
4309
4351
|
get loadedChunks(): readonly {
|
|
4310
4352
|
x: number;
|
|
@@ -4338,7 +4380,7 @@ declare class WorldStreamer {
|
|
|
4338
4380
|
dispose(): Promise<void>;
|
|
4339
4381
|
private drain;
|
|
4340
4382
|
private needsLoad;
|
|
4341
|
-
private
|
|
4383
|
+
private unloadMany;
|
|
4342
4384
|
private validateChunk;
|
|
4343
4385
|
private within;
|
|
4344
4386
|
private key;
|
|
@@ -4387,4 +4429,4 @@ declare class BrowserCache extends PersistentCache<LocalForage> {
|
|
|
4387
4429
|
*/
|
|
4388
4430
|
declare function probeImageSize(data: Uint8Array): ImageSizeInfo;
|
|
4389
4431
|
|
|
4390
|
-
export { AXES, type AnimationFrame, type AnimationMeta, type AnimatorFunction, type AnvilChunk, type AnvilEntityChunk, type AnvilExternalChunkReader, type AnvilParseOptions, AnvilParser, type AnvilRegion, type AnvilRegionReader, AnvilWorldSource, type AnvilWorldSourceOptions, ArchiveAssetSource, type ArchiveAssetSourceOptions, type ArchiveEntry, type ArchiveProxy, AssetKey, AssetLoadError, AssetLoader, AssetParser, AssetSource, type AssetType, Assets, Axis, BUILTIN_ENTITY, BUILTIN_GENERATED, type BannerPattern, type BannerPatternDraw, BannerPatterns, BasicAssetKey, type BasicMinecraftAsset, BatchedExecutor, type BedrockBone, type BedrockCube, type BedrockEntityDescription, type BedrockEntityFile, type BedrockGeometry, type BedrockGeometryFile, type BinaryAsset, type Biome, type BiomeColorKind, Biomes, type BitmapFont, type BitmapGlyph, type Block, BlockEntities, type BlockEntityEntry, type BlockEntityIndex, type BlockEntityPart, type BlockEntityRotation, type BlockFluidState, type BlockInfo, type BlockModel, type BlockModelTextures, BlockObject, type BlockObjectOptions, type BlockState, type BlockStateMultipart, type BlockStateProperties, type BlockStateProperty, type BlockStatePropertyDefaults, type BlockStatePropertyValue, BlockStateResolver, type BlockStateVariant, type BlockStateVariants, BlockStates, BlockTints, type BoxGeometryKey, BrowserArchiveProxy, BrowserCache, BrowserEnv, CUBE_FACES, CUBE_FACE_OFFSETS, type CacheKey, Caching, type CameraOptions, CanvasImage, type CapeLayout, Chunk, ChunkData, Colormaps, type CompatCanvas, type CompatImage, type ComposerOptions, type ControlsMode, type ControlsOptions, CubeFace, CubeFaceIndex, DEFAULT_ELEMENTS, DEFAULT_NAMESPACE, DEFAULT_ROOT, DEFAULT_UV, DISPLAY_POSITIONS, DYE_COLORS, type DebugOptions, type DecoratedPotSide, DecoratedPots, type DeepPartial, DefaultBlockStates, DisplayPosition, DisplayTransforms, type Disposable, type DoubleArray, type DyeColor, ENTITY_ANIMATION_CHANNELS, type ElementFace, type ElementRotation, Entities, type EntityAnimation, type EntityAnimationBone, type EntityAnimationChannel, type EntityAnimationFile, type EntityAnimationKeyframe, type EntityAnimationOptions, EntityAnimationPlayer, type EntityAnimationPose, type EntityLayer, type EntityModel, type EntityModelCube, type EntityModelFile, type EntityModelLayer, type EntityModelOptions, type EntityModelPart, type EntityModelPass, EntityObject, type EntityObjectOptions, type EntityRenderMode, type EntityTransformOp, Env, type EnvProvider, type ExtractableImageData, type FluidKind, FluidModelObject, type FluidQuads, type FluidRules, type FluidSample, type FluidSampler, type FlyAction, FlyControls, type FlyControlsEventMap, Fonts, type FrameCallback, type FromTo, GUI_CONTAINER_LAYOUTS, Geometries, type GuiBookButtonState, type GuiBookOptions, type GuiBossBarColor, type GuiBossBarOptions, type GuiContainerType, GuiHelper, type GuiItemLayer, type GuiLayer, GuiLight, GuiObject, type GuiObjectOptions, type GuiRecipe, type GuiRecipeIngredient, type GuiRecipeOptions, type GuiSpriteScaling, type GuiText, type GuiTextLayer, type GuiTextLayout, type GuiTextOptions, type GuiTextRun, type GuiTextStyle, type GuiTextureLayer, type GuiTooltipOptions, HostedAssetSource, type IModelTextures, ITEM_GENERATED, type ImageInfo, ImageLoader, type ImageSizeInfo, InstanceManager, InstanceReference, type Instanceable, ItemDefaults, ItemGlint, type ItemModel, type ItemModelContext, type ItemModelTextures, type ItemTintColor, type ItemTintSource, ItemTints, type ListAsset, LitematicaParser, type LitematicaRegion, type LitematicaStructure, type LoadedSceneDocument, type LoadedSceneObject, MapControls, type MaterialKey, Materials, type Maybe, type MeshKey, Meshes, MineRenderData, type MineRenderDataManifest, type MineRenderDatasets, MineRenderError, MineRenderScene, type MineRenderSceneOptions, MineRenderWorld, type MineRenderWorldOptions, type MinecraftAsset, MinecraftCubeTexture, MinecraftFaceUV, type MinecraftTextureMeta, type Model, ModelCulling, type ModelDisplay, type ModelElement, type ModelFaces, ModelGenerator, ModelMerger, ModelObject, type ModelObjectOptions, ModelTextures, Models, type MultiBlockBlock, type MultiBlockEntity, type MultiBlockStructure, type MultipartCondition, type NBTAsset, NBTHelper, OrbitControls, type PackFormat, PackFormats, PackMetadata, PersistentCache, PlayerHeadTextures, type PositionedGuiGlyph, type QuadArray, type RawImageKey, type RenameKind, Renames, type RenderOptions, Renderer, type RendererControls, type RendererFrame, type RendererOptions, type RendererSurface, type RequestConfig, RequestError, type RequestResponse, Requests, type ResolvedBlockEntity, type ResolvedMineRenderData, type ResponseParser, SCENE_DOCUMENT_MAX_BYTES, SKIN_PARTS, type SavedLightSample, type SceneBlockDefinition, type SceneDocument, SceneDocumentLoader, type SceneEntityDefinition, SceneExporter, type SceneGLTFExportOptions, type SceneGuiDefinition, type SceneGuiLayer, SceneInspector, type SceneItemContext, type SceneModelDefinition, SceneObject, type SceneObjectDefinition, type SceneObjectDefinitionBase, type SceneObjectOptions, type SceneSkinDefinition, type SceneSkinPosePart, SceneStats, SceneStatsDisplay, SchematicParser, type SchematicParserOptions, type SectionAtlasSize, type SectionFluidInput, type SectionFluidKind, type SectionFluids, type SectionGeometryInput, type SectionGeometryPage, type SectionLightData, SectionMesh, type SectionMeshEntry, type SectionMeshTemplate, SectionModels, type SectionTemplateData, SectionWorker, type Serializable, type SkinGeometries, SkinImage, SkinObject, type SkinObjectOptions, SkinPart, type SkinTexture, type SkinTextureCoordinates, SkinTextures, Skins, type SpecialItemPart, type SpecialItemRenderer, SpecialItems, SpongeSchematicParser, type StructureNBT, StructureParser, type TextureAsset, TextureAtlas, type TextureKey, TextureLoader, Textures, Ticker, type TickerFunction, TintColors, type Transformable, type TripleArray, UVMapper, type VideoExportOptions, VideoExporter, type WorldBlockIntersection, type WorldChunkSource, type WorldEntityIntersection, WorldStreamer, type WorldStreamerOptions, WrappedImage, addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation, applyGenericRotation, axisToVec3, base64decode, base64encode, buildFluidQuads, buildSectionGeometry, capeTextureSizes, captureException, changeEvent, clampRotationDegrees, classicSkinGeometries, classicSkinTextureCoordinates, computeMorphedAttributes, copySectionLight, createCanvas, createFluidGeometry, createGuiTextGeometry, createGuiTextureGeometry, createImage, decodeSceneDocument, encodeSceneDocument, entityAnimationTime, estimateBytesUsed, fluidKindOf, getBlockFluidState, getFluidKind, interleaveAttributes, isAssetKey, isBasicAssetKey, isBlockObject, isDisposable, isDoubleArray, isEntityObject, isFlyControls, isGuiObject, isInstanceManager, isInstanceReference, isInstanceable, isInstancedMesh, isMesh, isMineRenderScene, isModelObject, isObject3D, isOrthographicCamera, isPerspectiveCamera, isQuadArray, isResourceLocation, isSceneObject, isTransformable, isTripleArray, isVector3, layoutGuiText, md5, mergeBufferAttributes, mergeBufferGeometries, mergeVertices, parseSceneDocument, prefix, probeImageSize, registerBrowserEnv, resolveBlockFluidState, resolveLegacyBlock, resolveLegacyBlockState, sampleEntityAnimation, sampleEntityKeyframes, sampleFluid, sampleSectionLight, sectionGeometryTransferables, serializeBoxGeometryKey, serializeImageKey, serializeMaterialKey, serializeMeshKey, serializeTextureKey, sha1, sha256, sha512, shutdown, sleep, slimSkinGeometries, slimSkinTextureCoordinates, timingEnd, timingStart, toDegrees, toRadians, toTrianglesDrawMode, trimCanvas, validateAnimationWeights, yieldToEventLoop };
|
|
4432
|
+
export { AXES, type AnimationFrame, type AnimationMeta, type AnimatorFunction, type AnvilChunk, type AnvilEntityChunk, type AnvilExternalChunkReader, type AnvilParseOptions, AnvilParser, type AnvilRegion, type AnvilRegionReader, AnvilWorldSource, type AnvilWorldSourceOptions, ArchiveAssetSource, type ArchiveAssetSourceOptions, type ArchiveEntry, type ArchiveProxy, AssetKey, AssetLoadError, AssetLoader, AssetParser, AssetSource, type AssetType, Assets, Axis, BUILTIN_ENTITY, BUILTIN_GENERATED, type BannerPattern, type BannerPatternDraw, BannerPatterns, BasicAssetKey, type BasicMinecraftAsset, BatchedExecutor, type BedrockBone, type BedrockCube, type BedrockEntityDescription, type BedrockEntityFile, type BedrockGeometry, type BedrockGeometryFile, type BinaryAsset, type Biome, type BiomeColorKind, Biomes, type BitmapFont, type BitmapGlyph, type Block, BlockEntities, type BlockEntityEntry, type BlockEntityIndex, type BlockEntityPart, type BlockEntityRotation, type BlockFluidState, type BlockInfo, type BlockModel, type BlockModelTextures, BlockObject, type BlockObjectOptions, type BlockState, type BlockStateMultipart, type BlockStateProperties, type BlockStateProperty, type BlockStatePropertyDefaults, type BlockStatePropertyValue, BlockStateResolver, type BlockStateVariant, type BlockStateVariants, BlockStates, BlockTints, type BoxGeometryKey, BrowserArchiveProxy, BrowserCache, BrowserEnv, CUBE_FACES, CUBE_FACE_OFFSETS, type CacheKey, Caching, type CameraOptions, CanvasImage, type CapeLayout, Chunk, ChunkData, Colormaps, type CompatCanvas, type CompatImage, type ComposerOptions, type ControlsMode, type ControlsOptions, CubeFace, CubeFaceIndex, DEFAULT_ELEMENTS, DEFAULT_NAMESPACE, DEFAULT_ROOT, DEFAULT_UV, DISPLAY_POSITIONS, DYE_COLORS, type DebugOptions, type DecoratedPotSide, DecoratedPots, type DeepPartial, DefaultBlockStates, DisplayPosition, DisplayTransforms, type Disposable, type DoubleArray, type DyeColor, ENTITY_ANIMATION_CHANNELS, type ElementFace, type ElementRotation, Entities, type EntityAnimation, type EntityAnimationBone, type EntityAnimationChannel, type EntityAnimationFile, type EntityAnimationKeyframe, type EntityAnimationOptions, EntityAnimationPlayer, type EntityAnimationPose, type EntityLayer, type EntityModel, type EntityModelCube, type EntityModelFile, type EntityModelLayer, type EntityModelOptions, type EntityModelPart, type EntityModelPass, EntityObject, type EntityObjectOptions, type EntityRenderMode, type EntityTransformOp, Env, type EnvProvider, type ExtractableImageData, type FluidKind, FluidModelObject, type FluidQuads, type FluidRules, type FluidSample, type FluidSampler, type FlyAction, FlyControls, type FlyControlsEventMap, Fonts, type FrameCallback, type FromTo, GUI_CONTAINER_LAYOUTS, Geometries, type GuiBookButtonState, type GuiBookOptions, type GuiBossBarColor, type GuiBossBarOptions, type GuiContainerType, GuiHelper, type GuiItemLayer, type GuiLayer, GuiLight, GuiObject, type GuiObjectOptions, type GuiRecipe, type GuiRecipeIngredient, type GuiRecipeOptions, type GuiSpriteScaling, type GuiText, type GuiTextLayer, type GuiTextLayout, type GuiTextOptions, type GuiTextRun, type GuiTextStyle, type GuiTextureLayer, type GuiTooltipOptions, HostedAssetSource, type IModelTextures, ITEM_GENERATED, type ImageInfo, ImageLoader, type ImageSizeInfo, InstanceManager, InstanceReference, type Instanceable, ItemDefaults, ItemGlint, type ItemModel, type ItemModelContext, type ItemModelTextures, type ItemTintColor, type ItemTintSource, ItemTints, type ListAsset, LitematicaParser, type LitematicaRegion, type LitematicaStructure, type LoadedSceneDocument, type LoadedSceneObject, type LogHandler, type LogLevel, type LogThreshold, type Logger, Logging, type LoggingOptions, MapControls, type MaterialKey, Materials, type Maybe, type MeshKey, Meshes, MineRenderData, type MineRenderDataManifest, type MineRenderDatasets, MineRenderError, MineRenderScene, type MineRenderSceneOptions, MineRenderWorld, type MineRenderWorldOptions, type MinecraftAsset, MinecraftCubeTexture, MinecraftFaceUV, type MinecraftTextureMeta, type Model, ModelCulling, type ModelDisplay, type ModelElement, type ModelFaces, ModelGenerator, ModelMerger, ModelObject, type ModelObjectOptions, ModelTextures, Models, type MultiBlockBlock, type MultiBlockEntity, type MultiBlockStructure, type MultipartCondition, type NBTAsset, NBTHelper, OrbitControls, type PackFormat, PackFormats, PackMetadata, PersistentCache, PlayerHeadTextures, type PositionedGuiGlyph, type QuadArray, type RawImageKey, type RenameKind, Renames, type RenderOptions, Renderer, type RendererControls, type RendererFrame, type RendererOptions, type RendererSurface, type RequestConfig, RequestError, type RequestResponse, Requests, type ResolvedBlockEntity, type ResolvedMineRenderData, type ResponseParser, SCENE_DOCUMENT_MAX_BYTES, SKIN_PARTS, type SavedLightSample, type SceneBlockDefinition, type SceneDocument, SceneDocumentLoader, type SceneEntityDefinition, SceneExporter, type SceneGLTFExportOptions, type SceneGuiDefinition, type SceneGuiLayer, SceneInspector, type SceneItemContext, type SceneModelDefinition, SceneObject, type SceneObjectDefinition, type SceneObjectDefinitionBase, type SceneObjectOptions, type SceneSkinDefinition, type SceneSkinPosePart, SceneStats, SceneStatsDisplay, SchematicParser, type SchematicParserOptions, type SectionAtlasSize, type SectionFluidInput, type SectionFluidKind, type SectionFluids, type SectionGeometryInput, type SectionGeometryPage, type SectionLightData, SectionMesh, type SectionMeshEntry, type SectionMeshTemplate, SectionModels, type SectionTemplateData, SectionWorker, type Serializable, type SkinGeometries, SkinImage, SkinObject, type SkinObjectOptions, SkinPart, type SkinTexture, type SkinTextureCoordinates, SkinTextures, Skins, type SpecialItemPart, type SpecialItemRenderer, SpecialItems, SpongeSchematicParser, type StructureNBT, StructureParser, type TextureAsset, TextureAtlas, type TextureKey, TextureLoader, Textures, Ticker, type TickerFunction, TintColors, type Transformable, type TripleArray, UVMapper, type VideoExportOptions, VideoExporter, type WorldBlockIntersection, type WorldChunkSource, type WorldEntityIntersection, WorldStreamer, type WorldStreamerOptions, WrappedImage, addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation, applyGenericRotation, axisToVec3, base64decode, base64encode, buildFluidQuads, buildSectionGeometry, capeTextureSizes, captureException, changeEvent, clampRotationDegrees, classicSkinGeometries, classicSkinTextureCoordinates, computeMorphedAttributes, copySectionLight, createCanvas, createFluidGeometry, createGuiTextGeometry, createGuiTextureGeometry, createImage, decodeSceneDocument, encodeSceneDocument, entityAnimationTime, estimateBytesUsed, fluidKindOf, getBlockFluidState, getFluidKind, interleaveAttributes, isAssetKey, isBasicAssetKey, isBlockObject, isDisposable, isDoubleArray, isEntityObject, isFlyControls, isGuiObject, isInstanceManager, isInstanceReference, isInstanceable, isInstancedMesh, isMesh, isMineRenderScene, isModelObject, isObject3D, isOrthographicCamera, isPerspectiveCamera, isQuadArray, isResourceLocation, isSceneObject, isTransformable, isTripleArray, isVector3, layoutGuiText, logger, md5, mergeBufferAttributes, mergeBufferGeometries, mergeVertices, parseSceneDocument, prefix, probeImageSize, registerBrowserEnv, resolveBlockFluidState, resolveLegacyBlock, resolveLegacyBlockState, sampleEntityAnimation, sampleEntityKeyframes, sampleFluid, sampleSectionLight, sectionGeometryTransferables, serializeBoxGeometryKey, serializeImageKey, serializeMaterialKey, serializeMeshKey, serializeTextureKey, sha1, sha256, sha512, shutdown, sleep, slimSkinGeometries, slimSkinTextureCoordinates, timingEnd, timingStart, toDegrees, toRadians, toTrianglesDrawMode, trimCanvas, validateAnimationWeights, yieldToEventLoop };
|
|
@@ -3,9 +3,9 @@ import { Raycaster, Vector2 } from "three";
|
|
|
3
3
|
import { isSceneObject } from "../renderer/SceneObject.mjs";
|
|
4
4
|
import { toDegrees, toRadians } from "../util/util.mjs";
|
|
5
5
|
import { isTransformable } from "../Transformable.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { logger } from "../util/log.mjs";
|
|
7
7
|
import { isMesh } from "../util/three.mjs";
|
|
8
|
-
var
|
|
8
|
+
var log = logger("SceneInspector");
|
|
9
9
|
var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
|
|
10
10
|
var SceneInspector = class {
|
|
11
11
|
constructor(renderer) {
|
|
@@ -99,7 +99,7 @@ var SceneInspector = class {
|
|
|
99
99
|
}
|
|
100
100
|
selectObject(targetObject, targetIntersection, instance = this.getIntersectionInstance(targetIntersection)) {
|
|
101
101
|
this.selectedObject = targetObject;
|
|
102
|
-
|
|
102
|
+
log.debug("selected", targetObject);
|
|
103
103
|
this.redraw(targetObject, targetIntersection, instance);
|
|
104
104
|
}
|
|
105
105
|
redraw(targetObject, targetIntersection, instance) {
|