minerender 2.1.0-beta.6 → 2.1.0-beta.7
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/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 +3 -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 +1 -1
- package/dist/browser/esm/assets/Entities.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/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/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 +64 -11
- 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/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/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/_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 +64 -11
- package/dist/browser/index.js +3071 -2956
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +6095 -5975
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +64 -11
- package/dist/node/index.d.ts +64 -11
- package/dist/node/index.js +3095 -2978
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +3087 -2971
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/assets/Assets.ts"],"sourcesContent":["import { Models } from \"./Models\";\nimport { Model } from \"../model/Model\";\nimport { Maybe } from \"../util/util\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { BlockStates } from \"./BlockStates\";\nimport { AssetKey, AssetType } from \"./AssetKey\";\n\
|
|
1
|
+
{"version":3,"sources":["../../../../src/assets/Assets.ts"],"sourcesContent":["import { Models } from \"./Models\";\nimport { Model } from \"../model/Model\";\nimport { Maybe } from \"../util/util\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { BlockStates } from \"./BlockStates\";\nimport { AssetKey, AssetType } from \"./AssetKey\";\n\n/** Convenience accessors for model and blockstate loading. */\nexport class Assets {\n\n /**\n * @deprecated\n */\n public static parseAssetKey(assetType: AssetType, str: string, origin?: AssetKey): AssetKey {\n return AssetKey.parse(assetType, str, origin);\n }\n\n /** Loads a model with its parent chain resolved. See {@link Models.getMerged}. */\n public static async getModel(key: AssetKey): Promise<Maybe<Model>> {\n return Models.getMerged(key);\n }\n\n /** Loads a blockstate definition. See {@link BlockStates.get}. */\n public static async getBlockState(key: AssetKey): Promise<Maybe<BlockState>> {\n return BlockStates.get(key);\n }\n\n}\n"],"mappings":";AAAA,SAAS,cAAc;AAIvB,SAAS,mBAAmB;AAC5B,SAAS,gBAA2B;AAG7B,IAAM,SAAN,MAAa;AAAA;AAAA;AAAA;AAAA,EAKhB,OAAc,cAAc,WAAsB,KAAa,QAA6B;AACxF,WAAO,SAAS,MAAM,WAAW,KAAK,MAAM;AAAA,EAChD;AAAA;AAAA,EAGA,aAAoB,SAAS,KAAsC;AAC/D,WAAO,OAAO,UAAU,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,aAAoB,cAAc,KAA2C;AACzE,WAAO,YAAY,IAAI,GAAG;AAAA,EAC9B;AAEJ;","names":[]}
|
|
@@ -4,6 +4,8 @@ import { AssetKey } from "./AssetKey.mjs";
|
|
|
4
4
|
import { AssetLoader } from "./AssetLoader.mjs";
|
|
5
5
|
import { AssetParser } from "./source/index.mjs";
|
|
6
6
|
import { Caching } from "../cache/Caching.mjs";
|
|
7
|
+
import { logger } from "../util/log.mjs";
|
|
8
|
+
var log = logger("BlockEntities");
|
|
7
9
|
var BlockEntities = class {
|
|
8
10
|
/**
|
|
9
11
|
* Loads the block index of a version. Versions and sources without one yield an empty index, and so does
|
|
@@ -17,7 +19,7 @@ var BlockEntities = class {
|
|
|
17
19
|
try {
|
|
18
20
|
return await AssetLoader.get(key, AssetParser.JSON) ?? {};
|
|
19
21
|
} catch (error) {
|
|
20
|
-
|
|
22
|
+
log.warn("Could not load the block entity index; block entities are drawn as plain block models", error);
|
|
21
23
|
return {};
|
|
22
24
|
}
|
|
23
25
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/assets/BlockEntities.ts"],"sourcesContent":["import { Matrix4 } from \"three\";\nimport { AssetKey } from \"./AssetKey\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { AssetParser } from \"./source\";\nimport { Caching } from \"../cache/Caching\";\nimport type { MinecraftAsset } from \"../MinecraftAsset\";\nimport type { BlockStateProperties } from \"../model/block/BlockStateProperties\";\nimport type { TripleArray } from \"../model/Model\";\nimport type { Maybe } from \"../util\";\n\n/** One model drawn by a block-entity renderer. */\nexport interface BlockEntityPart {\n model: string;\n /** Model layer; defaults to \"main\". */\n layer?: string;\n /** Set only when the texture differs from the layer's default. */\n textureLocation?: string;\n /** Blockstate multipart syntax: every property must match, and \"a|b\" matches either value. */\n when?: Record<string, string>;\n}\n\n/** Degrees per property value, or degrees per unit of a numeric property. */\nexport type BlockEntityRotation = { property: string; degrees: Record<string, number> } | { property: string; step: number };\n\n/** Models and state-dependent placement for one block ID in the block-entity index. */\nexport interface BlockEntityEntry {\n parts: BlockEntityPart[];\n rotation?: BlockEntityRotation;\n /** Offset in model units, applied before the rotation. */\n translation?: TripleArray;\n}\n\n/** The dataset's `blocks.json`: block ID to the models its block-entity renderer draws. */\nexport type BlockEntityIndex = MinecraftAsset & { [block: string]: BlockEntityEntry };\n\n/** Parts and placement selected by {@link BlockEntities.resolve} for a block's properties. */\nexport interface ResolvedBlockEntity {\n parts: BlockEntityPart[];\n /** Degrees counter-clockwise seen from above, about the block's vertical centre axis. */\n rotation: number;\n translation: TripleArray;\n}\n\n/** Resolves blockstate properties into the entity models used to draw chests, beds, and other block entities. */\nexport class BlockEntities {\n\n /**\n * Loads the block index of a version. Versions and sources without one yield an empty index, and so does\n * a failed load: the index is optional, and blocks must not retry or fail with it one by one. The empty\n * result is cached like any other; `Caching.clear()` or `AssetLoader.setVersion()` forces a new attempt.\n */\n public static async getIndex(root?: string): Promise<BlockEntityIndex> {\n // The index sits next to the namespace directories, at <root>/entity-models/blocks.json.\n const key = new AssetKey(\"entity-models\", \"blocks\", undefined, undefined, undefined, \".json\", root);\n key.rootType = undefined!;\n const index = await Caching.blockEntityIndexCache.get(key.serialize(), async () => {\n try {\n return await AssetLoader.get<BlockEntityIndex>(key, AssetParser.JSON) ?? {};\n } catch (error) {\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/assets/BlockEntities.ts"],"sourcesContent":["import { Matrix4 } from \"three\";\nimport { AssetKey } from \"./AssetKey\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { AssetParser } from \"./source\";\nimport { Caching } from \"../cache/Caching\";\nimport type { MinecraftAsset } from \"../MinecraftAsset\";\nimport type { BlockStateProperties } from \"../model/block/BlockStateProperties\";\nimport type { TripleArray } from \"../model/Model\";\nimport type { Maybe } from \"../util\";\nimport { logger } from \"../util/log\";\n\nconst log = logger(\"BlockEntities\");\n\n/** One model drawn by a block-entity renderer. */\nexport interface BlockEntityPart {\n model: string;\n /** Model layer; defaults to \"main\". */\n layer?: string;\n /** Set only when the texture differs from the layer's default. */\n textureLocation?: string;\n /** Blockstate multipart syntax: every property must match, and \"a|b\" matches either value. */\n when?: Record<string, string>;\n}\n\n/** Degrees per property value, or degrees per unit of a numeric property. */\nexport type BlockEntityRotation = { property: string; degrees: Record<string, number> } | { property: string; step: number };\n\n/** Models and state-dependent placement for one block ID in the block-entity index. */\nexport interface BlockEntityEntry {\n parts: BlockEntityPart[];\n rotation?: BlockEntityRotation;\n /** Offset in model units, applied before the rotation. */\n translation?: TripleArray;\n}\n\n/** The dataset's `blocks.json`: block ID to the models its block-entity renderer draws. */\nexport type BlockEntityIndex = MinecraftAsset & { [block: string]: BlockEntityEntry };\n\n/** Parts and placement selected by {@link BlockEntities.resolve} for a block's properties. */\nexport interface ResolvedBlockEntity {\n parts: BlockEntityPart[];\n /** Degrees counter-clockwise seen from above, about the block's vertical centre axis. */\n rotation: number;\n translation: TripleArray;\n}\n\n/** Resolves blockstate properties into the entity models used to draw chests, beds, and other block entities. */\nexport class BlockEntities {\n\n /**\n * Loads the block index of a version. Versions and sources without one yield an empty index, and so does\n * a failed load: the index is optional, and blocks must not retry or fail with it one by one. The empty\n * result is cached like any other; `Caching.clear()` or `AssetLoader.setVersion()` forces a new attempt.\n */\n public static async getIndex(root?: string): Promise<BlockEntityIndex> {\n // The index sits next to the namespace directories, at <root>/entity-models/blocks.json.\n const key = new AssetKey(\"entity-models\", \"blocks\", undefined, undefined, undefined, \".json\", root);\n key.rootType = undefined!;\n const index = await Caching.blockEntityIndexCache.get(key.serialize(), async () => {\n try {\n return await AssetLoader.get<BlockEntityIndex>(key, AssetParser.JSON) ?? {};\n } catch (error) {\n log.warn(\"Could not load the block entity index; block entities are drawn as plain block models\", error);\n return {};\n }\n });\n return index ?? {};\n }\n\n /** The index entry of a block ID such as `minecraft:chest`. */\n public static entry(index: BlockEntityIndex, block: string): Maybe<BlockEntityEntry> {\n const entry = Object.prototype.hasOwnProperty.call(index, block) ? index[block] : undefined;\n return Array.isArray(entry?.parts) ? entry : undefined;\n }\n\n /** Selects the parts and placement for a block ID such as `minecraft:chest`; undefined when nothing is drawn. */\n public static resolve(index: BlockEntityIndex, block: string, state: BlockStateProperties = {}): Maybe<ResolvedBlockEntity> {\n const entry = this.entry(index, block);\n if (!entry) return undefined;\n // Default block states may hold booleans, numbers and upper-case enum names.\n const value = (property: string) => String(state[property]).toLowerCase();\n const parts = entry.parts.filter(part => Object.entries(part.when ?? {})\n .every(([property, values]) => String(values).split(\"|\").includes(value(property))));\n if (!parts.length) return undefined;\n let rotation = 0;\n if (entry.rotation) {\n const selected = value(entry.rotation.property);\n rotation = \"degrees\" in entry.rotation ? entry.rotation.degrees[selected] : Number(selected) * entry.rotation.step;\n if (!Number.isFinite(rotation)) rotation = 0;\n }\n return { parts, rotation, translation: entry.translation ?? [0, 0, 0] };\n }\n\n /** Placement in block space (0..16 per axis), applied on top of the model's own transform. */\n public static matrix(resolved: ResolvedBlockEntity, matrix: Matrix4 = new Matrix4()): Matrix4 {\n return matrix.makeTranslation(8, 0, 8)\n .multiply(new Matrix4().makeRotationY(resolved.rotation * Math.PI / 180))\n .multiply(new Matrix4().makeTranslation(resolved.translation[0] - 8, resolved.translation[1], resolved.translation[2] - 8));\n }\n\n}\n"],"mappings":";AAAA,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,eAAe;AAKxB,SAAS,cAAc;AAEvB,IAAM,MAAM,OAAO,eAAe;AAoC3B,IAAM,gBAAN,MAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOvB,aAAoB,SAAS,MAA0C;AAEnE,UAAM,MAAM,IAAI,SAAS,iBAAiB,UAAU,QAAW,QAAW,QAAW,SAAS,IAAI;AAClG,QAAI,WAAW;AACf,UAAM,QAAQ,MAAM,QAAQ,sBAAsB,IAAI,IAAI,UAAU,GAAG,YAAY;AAC/E,UAAI;AACA,eAAO,MAAM,YAAY,IAAsB,KAAK,YAAY,IAAI,KAAK,CAAC;AAAA,MAC9E,SAAS,OAAO;AACZ,YAAI,KAAK,yFAAyF,KAAK;AACvG,eAAO,CAAC;AAAA,MACZ;AAAA,IACJ,CAAC;AACD,WAAO,SAAS,CAAC;AAAA,EACrB;AAAA;AAAA,EAGA,OAAc,MAAM,OAAyB,OAAwC;AACjF,UAAM,QAAQ,OAAO,UAAU,eAAe,KAAK,OAAO,KAAK,IAAI,MAAM,KAAK,IAAI;AAClF,WAAO,MAAM,QAAQ,OAAO,KAAK,IAAI,QAAQ;AAAA,EACjD;AAAA;AAAA,EAGA,OAAc,QAAQ,OAAyB,OAAe,QAA8B,CAAC,GAA+B;AACxH,UAAM,QAAQ,KAAK,MAAM,OAAO,KAAK;AACrC,QAAI,CAAC,MAAO,QAAO;AAEnB,UAAM,QAAQ,CAAC,aAAqB,OAAO,MAAM,QAAQ,CAAC,EAAE,YAAY;AACxE,UAAM,QAAQ,MAAM,MAAM,OAAO,UAAQ,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,EAClE,MAAM,CAAC,CAAC,UAAU,MAAM,MAAM,OAAO,MAAM,EAAE,MAAM,GAAG,EAAE,SAAS,MAAM,QAAQ,CAAC,CAAC,CAAC;AACvF,QAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,QAAI,WAAW;AACf,QAAI,MAAM,UAAU;AAChB,YAAM,WAAW,MAAM,MAAM,SAAS,QAAQ;AAC9C,iBAAW,aAAa,MAAM,WAAW,MAAM,SAAS,QAAQ,QAAQ,IAAI,OAAO,QAAQ,IAAI,MAAM,SAAS;AAC9G,UAAI,CAAC,OAAO,SAAS,QAAQ,EAAG,YAAW;AAAA,IAC/C;AACA,WAAO,EAAE,OAAO,UAAU,aAAa,MAAM,eAAe,CAAC,GAAG,GAAG,CAAC,EAAE;AAAA,EAC1E;AAAA;AAAA,EAGA,OAAc,OAAO,UAA+B,SAAkB,IAAI,QAAQ,GAAY;AAC1F,WAAO,OAAO,gBAAgB,GAAG,GAAG,CAAC,EAChC,SAAS,IAAI,QAAQ,EAAE,cAAc,SAAS,WAAW,KAAK,KAAK,GAAG,CAAC,EACvE,SAAS,IAAI,QAAQ,EAAE,gBAAgB,SAAS,YAAY,CAAC,IAAI,GAAG,SAAS,YAAY,CAAC,GAAG,SAAS,YAAY,CAAC,IAAI,CAAC,CAAC;AAAA,EAClI;AAEJ;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/assets/BlockStates.ts
|
|
2
2
|
import { Caching } from "../cache/Caching.mjs";
|
|
3
3
|
import { AssetLoader } from "./AssetLoader.mjs";
|
|
4
|
-
import { DEFAULT_NAMESPACE } from "./
|
|
4
|
+
import { DEFAULT_NAMESPACE } from "./AssetDefaults.mjs";
|
|
5
5
|
import { AssetKey } from "./AssetKey.mjs";
|
|
6
6
|
import { PersistentCache } from "../cache/PersistentCache.mjs";
|
|
7
7
|
import { AssetParser } from "./source/parser/AssetParsers.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/assets/BlockStates.ts"],"sourcesContent":["import { Maybe } from \"../util/util\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { Caching } from \"../cache/Caching\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"./
|
|
1
|
+
{"version":3,"sources":["../../../../src/assets/BlockStates.ts"],"sourcesContent":["import { Maybe } from \"../util/util\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport { Caching } from \"../cache/Caching\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"./AssetDefaults\";\nimport { BlockStatePropertyDefaults } from \"../model/block/BlockStateProperties\";\nimport { AssetKey } from \"./AssetKey\";\nimport { PersistentCache } from \"../cache/PersistentCache\";\nimport { AssetParser } from \"./source/parser/AssetParsers\";\nimport { ListAsset } from \"../ListAsset\";\nimport { MinecraftAsset } from \"../MinecraftAsset\";\nimport { Renames } from \"./Renames\";\nimport { MineRenderData } from \"./MineRenderData\";\n\n/** Loads blockstate definitions and the property defaults used to select block models. */\nexport class BlockStates {\n\n private static _persistentCache: PersistentCache | undefined;\n\n private static get PERSISTENT_CACHE(): PersistentCache {\n return this._persistentCache ??= PersistentCache.open(\"minerender-blockstates\");\n }\n\n // BlockState names are hardcoded\n /** Returns blockstate filenames from the selected version's `_list.json`, or an empty list. */\n public static async getList(): Promise<string[]> {\n const key = new AssetKey(\n DEFAULT_NAMESPACE,\n \"_list\",\n \"blockstates\",\n undefined,\n \"assets\",\n \".json\",\n AssetLoader.ROOT\n );\n return Caching.listAssetCache.get(key.serialize(), () => {\n return AssetLoader.get<ListAsset>(key, AssetParser.LIST);\n }).then(r => r?.files ?? []);\n }\n\n public static async getDefaultStates(root?: string): Promise<Maybe<DefaultBlockStates>> {\n return MineRenderData.get(\"blockStates\", root);\n }\n\n /** Looks up vanilla property definitions for the key's block path, or returns `undefined`. */\n public static async getDefaultState(key: AssetKey): Promise<Maybe<BlockStatePropertyDefaults>> {\n const defaultStates = await this.getDefaultStates(key.root);\n if (!defaultStates) {\n return undefined;\n }\n return defaultStates[key.toNamespacedString()] as BlockStatePropertyDefaults;\n }\n\n /** Loads a cached blockstate definition for {@link MineRenderScene.addBlock}, or returns `undefined`. */\n public static async get(key: AssetKey): Promise<Maybe<BlockState>> {\n if (!key.assetType) {\n key.assetType = \"blockstates\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n // An ID from an older version loads its replacement. The registry fallback can select a table\n // newer than the assets, so a missing replacement keeps the original ID.\n const renamed = await Renames.key(\"blocks\", key);\n const replacement = renamed && await this.get(renamed);\n if (replacement) return replacement;\n const keyStr = key.serialize();\n return Caching.blockStateCache.get(keyStr, k => {\n return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), k1 => {\n return AssetLoader.get<BlockState>(key, AssetParser.BLOCKSTATE);\n })\n }).then(asset => {\n if (asset) {\n asset.key = key;\n }\n return asset;\n })\n }\n\n public static getAll(keys: AssetKey[] | Iterable<AssetKey>): Promise<Maybe<BlockState>[]> {\n const promises: Promise<Maybe<BlockState>>[] = [];\n for (let key of keys) {\n promises.push(this.get(key));\n }\n return Promise.all(promises);\n }\n\n /** Clears persisted blockstates. Use {@link Caching.clear} to also discard in-memory assets. */\n public static async clearCache() {\n await this.PERSISTENT_CACHE.clear();\n }\n\n}\n\nexport class DefaultBlockStates implements MinecraftAsset {\n [k: string]: BlockStatePropertyDefaults;\n}\n"],"mappings":";AAEA,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAElC,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAG5B,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAGxB,IAAM,cAAN,MAAkB;AAAA,EAIrB,WAAmB,mBAAoC;AACnD,WAAO,KAAK,qBAAL,KAAK,mBAAqB,gBAAgB,KAAK,wBAAwB;AAAA,EAClF;AAAA;AAAA;AAAA,EAIA,aAAoB,UAA6B;AAC7C,UAAM,MAAM,IAAI;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,IAChB;AACA,WAAO,QAAQ,eAAe,IAAI,IAAI,UAAU,GAAG,MAAM;AACrD,aAAO,YAAY,IAAe,KAAK,YAAY,IAAI;AAAA,IAC3D,CAAC,EAAE,KAAK,OAAK,GAAG,SAAS,CAAC,CAAC;AAAA,EAC/B;AAAA,EAEA,aAAoB,iBAAiB,MAAmD;AACpF,WAAO,eAAe,IAAI,eAAe,IAAI;AAAA,EACjD;AAAA;AAAA,EAGA,aAAoB,gBAAgB,KAA2D;AAC3F,UAAM,gBAAgB,MAAM,KAAK,iBAAiB,IAAI,IAAI;AAC1D,QAAI,CAAC,eAAe;AAChB,aAAO;AAAA,IACX;AACA,WAAO,cAAc,IAAI,mBAAmB,CAAC;AAAA,EACjD;AAAA;AAAA,EAGA,aAAoB,IAAI,KAA2C;AAC/D,QAAI,CAAC,IAAI,WAAW;AAChB,UAAI,YAAY;AAAA,IACpB;AACA,QAAI,CAAC,IAAI,WAAW;AAChB,UAAI,YAAY;AAAA,IACpB;AAGA,UAAM,UAAU,MAAM,QAAQ,IAAI,UAAU,GAAG;AAC/C,UAAM,cAAc,WAAW,MAAM,KAAK,IAAI,OAAO;AACrD,QAAI,YAAa,QAAO;AACxB,UAAM,SAAS,IAAI,UAAU;AAC7B,WAAO,QAAQ,gBAAgB,IAAI,QAAQ,OAAK;AAC5C,aAAO,KAAK,iBAAiB,UAAU,YAAY,cAAc,MAAM,GAAG,QAAM;AAC5E,eAAO,YAAY,IAAgB,KAAK,YAAY,UAAU;AAAA,MAClE,CAAC;AAAA,IACL,CAAC,EAAE,KAAK,WAAS;AACb,UAAI,OAAO;AACP,cAAM,MAAM;AAAA,MAChB;AACA,aAAO;AAAA,IACX,CAAC;AAAA,EACL;AAAA,EAEA,OAAc,OAAO,MAAqE;AACtF,UAAM,WAAyC,CAAC;AAChD,aAAS,OAAO,MAAM;AAClB,eAAS,KAAK,KAAK,IAAI,GAAG,CAAC;AAAA,IAC/B;AACA,WAAO,QAAQ,IAAI,QAAQ;AAAA,EAC/B;AAAA;AAAA,EAGA,aAAoB,aAAa;AAC7B,UAAM,KAAK,iBAAiB,MAAM;AAAA,EACtC;AAEJ;AAEO,IAAM,qBAAN,MAAmD;AAE1D;","names":[]}
|
|
@@ -3,7 +3,7 @@ import { AssetKey, isAssetKey } from "./AssetKey.mjs";
|
|
|
3
3
|
import { AssetLoader } from "./AssetLoader.mjs";
|
|
4
4
|
import { AssetParser } from "./source/index.mjs";
|
|
5
5
|
import { Caching } from "../cache/Caching.mjs";
|
|
6
|
-
import { DEFAULT_NAMESPACE } from "./
|
|
6
|
+
import { DEFAULT_NAMESPACE } from "./AssetDefaults.mjs";
|
|
7
7
|
import { MineRenderError } from "../error/MineRenderError.mjs";
|
|
8
8
|
import { ModelTextures } from "./ModelTextures.mjs";
|
|
9
9
|
var Entities = class {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/assets/Entities.ts"],"sourcesContent":["import { AssetKey, BasicAssetKey, isAssetKey } from \"./AssetKey\";\nimport type { EntityLayer, EntityModel, EntityModelFile, EntityModelPass } from \"../entity/EntityModel\";\nimport type { EntityAnimation, EntityAnimationFile } from \"../entity/EntityAnimation\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { AssetParser } from \"./source\";\nimport { Maybe } from \"../util\";\nimport { Caching } from \"../cache/Caching\";\nimport { DEFAULT_NAMESPACE } from \"./Assets\";\nimport type { ListAsset } from \"../ListAsset\";\nimport { MineRenderError } from \"../error/MineRenderError\";\nimport { ModelTextures } from \"./ModelTextures\";\nimport type { MinecraftAsset } from \"../MinecraftAsset\";\n\n/** Loads entity and block-entity geometry, texture selections, and animation clips from the dataset. */\nexport class Entities {\n\n /** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */\n public static async getEntityList(): Promise<string[]> {\n const collect = async (path: string): Promise<string[]> => {\n const prefix = path ? `${path}/` : \"\";\n const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix}_list`, undefined, undefined, \"entity-models\", \".json\");\n const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get<ListAsset>(key, AssetParser.LIST));\n if (!list) return [];\n const files = list.files.filter(file => file.endsWith(\".json\") && file !== \"_list.json\")\n .map(file => `${prefix}${file.slice(0, -5)}`);\n const children = await Promise.all(list.directories.map(directory => collect(`${prefix}${directory}`)));\n return [...files, ...children.flat()];\n };\n return collect(\"\");\n }\n\n private static async getModelFile(modelKey: BasicAssetKey): Promise<Maybe<EntityModelFile>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models\", \".json\", isAssetKey(modelKey) ? modelKey.root : undefined);\n return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get<EntityModelFile>(key, AssetParser.JSON));\n }\n\n /** Returns selectable geometry-layer names, or an empty list when the model is missing. */\n public static async getLayerList(modelKey: BasicAssetKey): Promise<string[]> {\n return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});\n }\n\n /** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */\n public static async getPassList(modelKey: BasicAssetKey): Promise<EntityModelPass[]> {\n return (await this.getModelFile(modelKey))?.passes ?? [];\n }\n\n /**\n * Loads the layers and textures to pass to {@link MineRenderScene.addEntity}.\n * By default, selects `main`, unconditional passes, and passes enabled by `options.when`.\n *\n * @param modelKey - Dataset model, such as `new BasicAssetKey(\"minecraft\", \"zombie\")`.\n * @param textureKey - Texture override for the first selected layer.\n * @param options - Layer selection, conditional passes, and per-layer texture overrides.\n * @returns The selected model, or `undefined` when its dataset file is missing.\n */\n public static async getEntity(modelKey: BasicAssetKey, textureKey?: BasicAssetKey, options?: EntityModelOptions): Promise<Maybe<EntityModel>> {\n const model = await this.getModelFile(modelKey);\n if (!model) return undefined;\n // Without an explicit selection, draw what vanilla draws: main, then the passes enabled for the requested state.\n const passes = options?.layers || options?.layer !== undefined ? [] :\n (model.passes ?? []).filter(pass => pass.when === undefined || options?.when?.includes(pass.when));\n const draws: EntityModelPass[] = [...new Set(options?.layers ?? [options?.layer ?? \"main\"])].map(layer => ({ layer }));\n if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);\n draws.push(...passes);\n const names: string[] = [];\n const selected = draws.map(pass => {\n const layer = model.layers[pass.layer];\n if (!layer) {\n throw new MineRenderError(`Entity ${model.id} has no layer \"${pass.layer}\". Available layers: ${Object.keys(model.layers).join(\", \")}`);\n }\n // A pass may draw geometry that is already selected with another texture.\n let name = pass.layer;\n for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;\n names.push(name);\n return { name, layer, pass };\n });\n const layers: Record<string, EntityLayer> = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {\n const override = options?.textures?.[name] ?? (index === 0 ? textureKey : undefined);\n const textureLocation = pass.textureLocation ?? layer.textureLocation;\n let texture: Maybe<AssetKey>;\n if (override) {\n const path = isAssetKey(override) ? override.getFullPath() : override.path;\n texture = isAssetKey(override) && override.assetType === \"textures\" && path.startsWith(\"entity/\")\n ? override\n : new AssetKey(override.namespace, path, \"textures\", \"entity\", \"assets\", \".png\", isAssetKey(override) ? override.root : undefined);\n } else if (textureLocation !== undefined) {\n texture = AssetKey.parse(\"textures\", textureLocation.replace(/^([^:]+:)?textures\\//, \"$1\"));\n if (isAssetKey(modelKey)) texture.root = modelKey.root;\n } else {\n texture = await this.resolveTexture(modelKey);\n }\n const render = pass.render ?? layer.render;\n return [name, { key: override ?? modelKey, texture, layer, ...(render && { render }), ...(pass.tint && { tint: pass.tint }) }];\n })));\n return { ...layers[names[0]], id: model.id, layers, ...(model.transform && { transform: model.transform }) };\n }\n\n /**\n * Native and sampled vanilla clips by name, or undefined when the model or selected version has none.\n */\n public static async getAnimations(modelKey: BasicAssetKey): Promise<Maybe<Record<string, EntityAnimation>>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models/animations\", \".json\", isAssetKey(modelKey) ? modelKey.root : undefined);\n const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get<EntityAnimationFile>(key, AssetParser.JSON));\n return file?.animations;\n }\n\n /** Finds a fallback texture using the model path, its directory, and vanilla variant data. */\n public static async resolveTexture(modelKey: BasicAssetKey): Promise<Maybe<AssetKey>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const root = isAssetKey(modelKey) ? modelKey.root : undefined;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models\", \".json\", root);\n return Caching.entityTextureCache.get(key.serialize(), async () => {\n const name = path.split(\"/\").pop()!;\n for (const candidate of [path, `${path}/${name}`]) {\n const texture = new AssetKey(modelKey.namespace, candidate, \"textures\", \"entity\", \"assets\", \".png\", root);\n if (await ModelTextures.get(texture)) return texture;\n }\n const listKey = new AssetKey(modelKey.namespace, \"_list\", `${name}_variant`, undefined, \"data\", \".json\", root);\n const list = await AssetLoader.get<ListAsset>(listKey, AssetParser.LIST);\n const files = list?.files.filter(file => file.endsWith(\".json\") && file !== \"_list.json\");\n const file = files?.find(file => file === \"temperate.json\") ?? files?.[0];\n if (!file) return undefined;\n const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, undefined, \"data\", \".json\", root);\n const variant = await AssetLoader.get<EntityVariant>(variantKey, AssetParser.JSON);\n const assets = variant?.assets;\n const textureId = variant?.asset_id ?? (typeof assets?.wild === \"string\" ? assets.wild :\n Object.values(assets ?? {}).find(value => typeof value === \"string\"));\n if (typeof textureId !== \"string\") return undefined;\n const texture = AssetKey.parse(\"textures\", textureId);\n texture.root = root;\n return texture;\n });\n }\n\n /** @deprecated Use getEntityList(); block entities share the entity dataset. */\n public static getBlockList(): Promise<string[]> {\n return this.getEntityList();\n }\n\n /** @deprecated Use getEntity(); block entities share the entity dataset. */\n public static getBlock(modelKey: BasicAssetKey, textureKey?: BasicAssetKey, options?: EntityModelOptions): Promise<Maybe<EntityModel>> {\n return this.getEntity(modelKey, textureKey, options);\n }\n\n}\n\n/** Selection settings passed as the third argument to {@link Entities.getEntity}. */\nexport interface EntityModelOptions {\n /** Selects one geometry layer without dataset passes. `layers` takes precedence when supplied. */\n layer?: string;\n /** Layer names in draw order; an explicit selection draws exactly these layers and no dataset passes. */\n layers?: string[];\n /**\n * Entity states that enable the dataset's conditional passes, e.g. `[\"powered\"]` for a charged creeper.\n * Without `layer`/`layers`, `main` and every unconditional pass are always drawn.\n */\n when?: string[];\n /** Per-layer texture overrides, keyed like `EntityModel.layers`. The positional texture key applies to the first selected layer. */\n textures?: Record<string, BasicAssetKey>;\n}\n\ninterface EntityVariant extends MinecraftAsset {\n asset_id?: string;\n assets?: Record<string, unknown>;\n}\n"],"mappings":"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","names":["texture","file"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/assets/Entities.ts"],"sourcesContent":["import { AssetKey, BasicAssetKey, isAssetKey } from \"./AssetKey\";\nimport type { EntityLayer, EntityModel, EntityModelFile, EntityModelPass } from \"../entity/EntityModel\";\nimport type { EntityAnimation, EntityAnimationFile } from \"../entity/EntityAnimation\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { AssetParser } from \"./source\";\nimport { Maybe } from \"../util\";\nimport { Caching } from \"../cache/Caching\";\nimport { DEFAULT_NAMESPACE } from \"./AssetDefaults\";\nimport type { ListAsset } from \"../ListAsset\";\nimport { MineRenderError } from \"../error/MineRenderError\";\nimport { ModelTextures } from \"./ModelTextures\";\nimport type { MinecraftAsset } from \"../MinecraftAsset\";\n\n/** Loads entity and block-entity geometry, texture selections, and animation clips from the dataset. */\nexport class Entities {\n\n /** Lists model paths in the `minecraft` namespace, including subdirectories and excluding `.json`. */\n public static async getEntityList(): Promise<string[]> {\n const collect = async (path: string): Promise<string[]> => {\n const prefix = path ? `${path}/` : \"\";\n const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix}_list`, undefined, undefined, \"entity-models\", \".json\");\n const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get<ListAsset>(key, AssetParser.LIST));\n if (!list) return [];\n const files = list.files.filter(file => file.endsWith(\".json\") && file !== \"_list.json\")\n .map(file => `${prefix}${file.slice(0, -5)}`);\n const children = await Promise.all(list.directories.map(directory => collect(`${prefix}${directory}`)));\n return [...files, ...children.flat()];\n };\n return collect(\"\");\n }\n\n private static async getModelFile(modelKey: BasicAssetKey): Promise<Maybe<EntityModelFile>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models\", \".json\", isAssetKey(modelKey) ? modelKey.root : undefined);\n return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get<EntityModelFile>(key, AssetParser.JSON));\n }\n\n /** Returns selectable geometry-layer names, or an empty list when the model is missing. */\n public static async getLayerList(modelKey: BasicAssetKey): Promise<string[]> {\n return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});\n }\n\n /** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */\n public static async getPassList(modelKey: BasicAssetKey): Promise<EntityModelPass[]> {\n return (await this.getModelFile(modelKey))?.passes ?? [];\n }\n\n /**\n * Loads the layers and textures to pass to {@link MineRenderScene.addEntity}.\n * By default, selects `main`, unconditional passes, and passes enabled by `options.when`.\n *\n * @param modelKey - Dataset model, such as `new BasicAssetKey(\"minecraft\", \"zombie\")`.\n * @param textureKey - Texture override for the first selected layer.\n * @param options - Layer selection, conditional passes, and per-layer texture overrides.\n * @returns The selected model, or `undefined` when its dataset file is missing.\n */\n public static async getEntity(modelKey: BasicAssetKey, textureKey?: BasicAssetKey, options?: EntityModelOptions): Promise<Maybe<EntityModel>> {\n const model = await this.getModelFile(modelKey);\n if (!model) return undefined;\n // Without an explicit selection, draw what vanilla draws: main, then the passes enabled for the requested state.\n const passes = options?.layers || options?.layer !== undefined ? [] :\n (model.passes ?? []).filter(pass => pass.when === undefined || options?.when?.includes(pass.when));\n const draws: EntityModelPass[] = [...new Set(options?.layers ?? [options?.layer ?? \"main\"])].map(layer => ({ layer }));\n if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);\n draws.push(...passes);\n const names: string[] = [];\n const selected = draws.map(pass => {\n const layer = model.layers[pass.layer];\n if (!layer) {\n throw new MineRenderError(`Entity ${model.id} has no layer \"${pass.layer}\". Available layers: ${Object.keys(model.layers).join(\", \")}`);\n }\n // A pass may draw geometry that is already selected with another texture.\n let name = pass.layer;\n for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;\n names.push(name);\n return { name, layer, pass };\n });\n const layers: Record<string, EntityLayer> = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {\n const override = options?.textures?.[name] ?? (index === 0 ? textureKey : undefined);\n const textureLocation = pass.textureLocation ?? layer.textureLocation;\n let texture: Maybe<AssetKey>;\n if (override) {\n const path = isAssetKey(override) ? override.getFullPath() : override.path;\n texture = isAssetKey(override) && override.assetType === \"textures\" && path.startsWith(\"entity/\")\n ? override\n : new AssetKey(override.namespace, path, \"textures\", \"entity\", \"assets\", \".png\", isAssetKey(override) ? override.root : undefined);\n } else if (textureLocation !== undefined) {\n texture = AssetKey.parse(\"textures\", textureLocation.replace(/^([^:]+:)?textures\\//, \"$1\"));\n if (isAssetKey(modelKey)) texture.root = modelKey.root;\n } else {\n texture = await this.resolveTexture(modelKey);\n }\n const render = pass.render ?? layer.render;\n return [name, { key: override ?? modelKey, texture, layer, ...(render && { render }), ...(pass.tint && { tint: pass.tint }) }];\n })));\n return { ...layers[names[0]], id: model.id, layers, ...(model.transform && { transform: model.transform }) };\n }\n\n /**\n * Native and sampled vanilla clips by name, or undefined when the model or selected version has none.\n */\n public static async getAnimations(modelKey: BasicAssetKey): Promise<Maybe<Record<string, EntityAnimation>>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models/animations\", \".json\", isAssetKey(modelKey) ? modelKey.root : undefined);\n const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get<EntityAnimationFile>(key, AssetParser.JSON));\n return file?.animations;\n }\n\n /** Finds a fallback texture using the model path, its directory, and vanilla variant data. */\n public static async resolveTexture(modelKey: BasicAssetKey): Promise<Maybe<AssetKey>> {\n const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;\n const root = isAssetKey(modelKey) ? modelKey.root : undefined;\n const key = new AssetKey(modelKey.namespace, path, undefined, undefined, \"entity-models\", \".json\", root);\n return Caching.entityTextureCache.get(key.serialize(), async () => {\n const name = path.split(\"/\").pop()!;\n for (const candidate of [path, `${path}/${name}`]) {\n const texture = new AssetKey(modelKey.namespace, candidate, \"textures\", \"entity\", \"assets\", \".png\", root);\n if (await ModelTextures.get(texture)) return texture;\n }\n const listKey = new AssetKey(modelKey.namespace, \"_list\", `${name}_variant`, undefined, \"data\", \".json\", root);\n const list = await AssetLoader.get<ListAsset>(listKey, AssetParser.LIST);\n const files = list?.files.filter(file => file.endsWith(\".json\") && file !== \"_list.json\");\n const file = files?.find(file => file === \"temperate.json\") ?? files?.[0];\n if (!file) return undefined;\n const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, undefined, \"data\", \".json\", root);\n const variant = await AssetLoader.get<EntityVariant>(variantKey, AssetParser.JSON);\n const assets = variant?.assets;\n const textureId = variant?.asset_id ?? (typeof assets?.wild === \"string\" ? assets.wild :\n Object.values(assets ?? {}).find(value => typeof value === \"string\"));\n if (typeof textureId !== \"string\") return undefined;\n const texture = AssetKey.parse(\"textures\", textureId);\n texture.root = root;\n return texture;\n });\n }\n\n /** @deprecated Use getEntityList(); block entities share the entity dataset. */\n public static getBlockList(): Promise<string[]> {\n return this.getEntityList();\n }\n\n /** @deprecated Use getEntity(); block entities share the entity dataset. */\n public static getBlock(modelKey: BasicAssetKey, textureKey?: BasicAssetKey, options?: EntityModelOptions): Promise<Maybe<EntityModel>> {\n return this.getEntity(modelKey, textureKey, options);\n }\n\n}\n\n/** Selection settings passed as the third argument to {@link Entities.getEntity}. */\nexport interface EntityModelOptions {\n /** Selects one geometry layer without dataset passes. `layers` takes precedence when supplied. */\n layer?: string;\n /** Layer names in draw order; an explicit selection draws exactly these layers and no dataset passes. */\n layers?: string[];\n /**\n * Entity states that enable the dataset's conditional passes, e.g. `[\"powered\"]` for a charged creeper.\n * Without `layer`/`layers`, `main` and every unconditional pass are always drawn.\n */\n when?: string[];\n /** Per-layer texture overrides, keyed like `EntityModel.layers`. The positional texture key applies to the first selected layer. */\n textures?: Record<string, BasicAssetKey>;\n}\n\ninterface EntityVariant extends MinecraftAsset {\n asset_id?: string;\n assets?: Record<string, unknown>;\n}\n"],"mappings":"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","names":["texture","file"]}
|
|
@@ -3,7 +3,7 @@ import { Renames } from "./Renames.mjs";
|
|
|
3
3
|
import { Caching } from "../cache/Caching.mjs";
|
|
4
4
|
import { ModelMerger } from "../model/ModelMerger.mjs";
|
|
5
5
|
import { AssetLoader } from "./AssetLoader.mjs";
|
|
6
|
-
import { DEFAULT_NAMESPACE } from "./
|
|
6
|
+
import { DEFAULT_NAMESPACE } from "./AssetDefaults.mjs";
|
|
7
7
|
import { PersistentCache } from "../cache/PersistentCache.mjs";
|
|
8
8
|
import { AssetKey, isAssetKey, isResourceLocation } from "./AssetKey.mjs";
|
|
9
9
|
import { AssetParser } from "./source/parser/AssetParsers.mjs";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/assets/Models.ts"],"sourcesContent":["import { Renames } from \"./Renames\";\nimport { ItemModel, ItemTintSource, Model, SpecialItemRenderer } from \"../model/Model\";\nimport { Caching } from \"../cache/Caching\";\nimport { Maybe } from \"../util/util\";\nimport { ModelMerger } from \"../model/ModelMerger\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"./Assets\";\nimport { PersistentCache } from \"../cache/PersistentCache\";\nimport { AssetKey, isAssetKey, isResourceLocation } from \"./AssetKey\";\nimport { ListAsset } from \"../ListAsset\";\nimport { AssetParser } from \"./source/parser/AssetParsers\";\nimport { DisplayPosition } from \"../model/DisplayPosition\";\nimport { DYE_COLORS } from \"./BannerPatterns\";\nimport { ItemDefaults } from \"../model/ItemDefaults\";\nimport { MineRenderData } from \"./MineRenderData\";\nimport { ItemTints } from \"../model/ItemTints\";\n\n/** Caller-supplied item-preview state passed to {@link Models.getMerged}. */\nexport interface ItemModelContext {\n /** Context used by display-context selectors, overriding `properties`. Defaults to GUI. */\n displayContext?: DisplayPosition | \"none\";\n /** Explicit property overrides. Nodes with the same ID share one override, regardless of their parameters. */\n properties?: Record<string, boolean | string | number>;\n /** Supplied component JSON by ID, overriding built-in defaults. Component selectors compare structural JSON values. */\n components?: Record<string, unknown>;\n /** Stack count, as a nonnegative integer. Defaults to 1; items without listed defaults stack to 64. */\n count?: number;\n /** Item-model keys by reference-node ID, such as `minecraft:bundle/selected_item`. Unset references draw nothing. */\n itemReferences?: Record<string, AssetKey>;\n}\n\n/** Loads and caches Java block/item models, including inherited geometry and textures. */\nexport class Models {\n\n // Bump when the shape of cached item models changes.\n private static readonly ITEM_CACHE_VERSION = \"item-v8\";\n private static _persistentCache: PersistentCache | undefined;\n\n // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading\n // the library, and would require an EnvProvider before any entry has had a chance to register\n private static get PERSISTENT_CACHE(): PersistentCache {\n return this._persistentCache ??= PersistentCache.open(\"minerender-models\");\n }\n\n /** Lists item filenames from the asset source's `_list.json`, with a legacy model-directory fallback. */\n public static async getItemList(): Promise<string[]> {\n const key = new AssetKey(DEFAULT_NAMESPACE, \"_list\", \"items\");\n const legacyKey = new AssetKey(DEFAULT_NAMESPACE, \"_list\", \"models\", \"item\");\n return Caching.listAssetCache.get(key.serialize(), async () => {\n return (await AssetLoader.getFirst<ListAsset>([key, legacyKey], AssetParser.LIST))?.asset;\n }).then(r => r?.files ?? []);\n }\n\n public static async loadAndMerge(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n const model = key.type === \"item\" ? await this.getItemModel(key, context) : await this.getRaw(key);\n if (!model) {\n return undefined;\n }\n const merged = await ModelMerger.mergeWithParents(model);\n return merged;\n }\n\n private static async getItemModel(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n const preview = this.snapshotContext(key, context);\n const dataKey = await this.applyDefaults(key, preview);\n return this.getPreparedItemModel(key, preview, dataKey);\n }\n\n private static async getPreparedItemModel(key: AssetKey, preview: Required<ItemModelContext>, dataKey: string): Promise<Maybe<Model>> {\n const itemId = `${key.namespace}:${key.path}`;\n const itemKey = new AssetKey(key.namespace, key.path, \"items\", undefined, key.rootType, \".json\", key.root);\n const cacheKey = itemKey.serialize() + this.contextKey(preview) + dataKey;\n const model = await this.PERSISTENT_CACHE.getOrLoad(`${this.ITEM_CACHE_VERSION}:${AssetLoader.persistentKey(cacheKey)}`, async () => {\n const result = await AssetLoader.getFirst<Model & { model?: ItemModelNode }>([itemKey, key], AssetParser.JSON);\n if (!result) return undefined;\n if (result.key.assetType !== \"items\") return { ...result.asset, key, itemId, components: preview.components } as ItemModel;\n\n const load = async (selected: SelectedItemModel): Promise<ItemModel> => {\n if (\"parts\" in selected) {\n return { key, itemId, parts: await Promise.all(selected.parts.map(load)) };\n }\n if (\"item\" in selected) {\n // Referenced items start with their own default stack state and references.\n const model = await this.getItemModel(selected.item, { displayContext: preview.displayContext });\n if (!model) throw new Error(`Item ${key.toNamespacedString()} references missing item ${selected.item.toNamespacedString()}`);\n return model as ItemModel;\n }\n const modelKey = AssetKey.parse(\"models\", selected.model);\n modelKey.root = key.root;\n const model = await this.getRaw(modelKey);\n if (!model) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);\n // Relative texture paths belong to the referenced model's namespace.\n return { ...model, itemId, components: preview.components, ...(selected.special && { special: selected.special }), ...(selected.tints && { tints: selected.tints }) } as ItemModel;\n };\n const model = await load(this.selectItemModel(result.asset.model, key, preview));\n return model;\n });\n const restore = (model: ItemModel): ItemModel => ({\n ...model, key: Object.assign(new AssetKey(\"\", \"\"), model.key),\n ...(model.parts && { parts: model.parts.map(restore) })\n });\n return model ? restore(model) : undefined;\n }\n\n private static contextIdentifier(id: string): string {\n if (!isResourceLocation(id)) {\n throw new Error(`Invalid item-preview identifier: ${id}`);\n }\n return id.includes(\":\") ? id : `minecraft:${id}`;\n }\n\n /** @internal */\n public static componentValue(components: Record<string, unknown>, id: string): unknown {\n const normalized = this.contextIdentifier(id);\n const short = normalized.replace(/^minecraft:/, \"\");\n if (short !== normalized && Object.prototype.hasOwnProperty.call(components, short)\n && Object.prototype.hasOwnProperty.call(components, normalized)) {\n throw new Error(`Duplicate item-preview component: ${normalized}`);\n }\n return Object.prototype.hasOwnProperty.call(components, short) ? components[short] : components[normalized];\n }\n\n private static snapshotContext(key: AssetKey, context: ItemModelContext): Required<ItemModelContext> {\n const displayContext = context.displayContext ?? DisplayPosition.GUI;\n if (displayContext !== \"none\" && !Object.values(DisplayPosition).includes(displayContext)) {\n throw new Error(`Unsupported item display context: ${displayContext}`);\n }\n for (const map of [context.properties, context.components, context.itemReferences]) {\n if (map !== undefined && (!map || typeof map !== \"object\" || Array.isArray(map))) {\n throw new Error(\"Item-preview properties, components, and references must be objects keyed by identifier\");\n }\n }\n const count = context.count === undefined ? 1 : context.count;\n if (!Number.isSafeInteger(count) || count < 0) throw new Error(\"Item-preview count must be a nonnegative safe integer\");\n const properties: Required<ItemModelContext>[\"properties\"] = {};\n for (const [id, value] of Object.entries(context.properties ?? {})) {\n const property = this.contextIdentifier(id);\n if (![\"boolean\", \"string\", \"number\"].includes(typeof value) || typeof value === \"number\" && !Number.isFinite(value)) {\n throw new Error(`Item-preview property ${property} must be a boolean, string, or finite number`);\n }\n if (Object.prototype.hasOwnProperty.call(properties, property)) throw new Error(`Duplicate item-preview property: ${property}`);\n properties[property] = value;\n }\n const components: Record<string, unknown> = {};\n for (const [id, value] of Object.entries(context.components ?? {})) {\n const component = this.contextIdentifier(id);\n if (Object.prototype.hasOwnProperty.call(components, component)) throw new Error(`Duplicate item-preview component: ${component}`);\n components[component] = this.snapshotJson(value);\n }\n const itemReferences: Record<string, AssetKey> = {};\n for (const [id, value] of Object.entries(context.itemReferences ?? {})) {\n const reference = this.contextIdentifier(id);\n if (!isAssetKey(value) || value.assetType !== \"models\" || value.type !== \"item\") {\n throw new Error(`Item-preview reference ${reference} must be an item-model AssetKey`);\n }\n this.contextIdentifier(`${value.namespace}:${value.path}`);\n if (Object.prototype.hasOwnProperty.call(itemReferences, reference)) throw new Error(`Duplicate item-preview reference: ${reference}`);\n itemReferences[reference] = Object.assign(new AssetKey(\"\", \"\"), value, { root: value.root ?? key.root });\n }\n return { displayContext, properties, components, count, itemReferences };\n }\n\n private static async applyDefaults(key: AssetKey, preview: Required<ItemModelContext>): Promise<string> {\n if (key.type !== \"item\") return \"\";\n const resolved = await MineRenderData.resolve(key.root);\n const defaults = await ItemDefaults.get(`${key.namespace}:${key.path}`, key.root);\n preview.components = { ...defaults, ...preview.components };\n if (resolved.manifest.dataVersion < 3337 && key.namespace === DEFAULT_NAMESPACE\n && [\"potion\", \"splash_potion\", \"lingering_potion\"].includes(key.path)\n && !Object.prototype.hasOwnProperty.call(preview.components, \"minecraft:enchantment_glint_override\")\n && await ItemTints.hasPotionEffects(preview.components[\"minecraft:potion_contents\"], key.root)) {\n preview.components[\"minecraft:enchantment_glint_override\"] = true;\n }\n return `|data:${resolved.root}:${resolved.manifest.datasets.itemDefaults?.sha256}:${resolved.manifest.datasets.potionColors?.sha256}`;\n }\n\n private static contextKey(context: Required<ItemModelContext>): string {\n const itemReferences = Object.fromEntries(Object.entries(context.itemReferences).map(([id, key]) => [id, key.serialize()]));\n return `|${this.ITEM_CACHE_VERSION}:${JSON.stringify(this.snapshotJson({ ...context, itemReferences }))}`;\n }\n\n private static snapshotJson(value: unknown, ancestors = new Set<object>()): unknown {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\" || typeof value === \"number\" && Number.isFinite(value)) return value;\n if (typeof value !== \"object\" || ancestors.has(value) || !Array.isArray(value)\n && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {\n throw new Error(\"Item-preview components must contain finite JSON values without circular references\");\n }\n ancestors.add(value);\n const copy = Array.isArray(value) ? Array.from(value, entry => this.snapshotJson(entry, ancestors))\n : Object.fromEntries(Object.keys(value).sort().map(key => [key, this.snapshotJson((value as Record<string, unknown>)[key], ancestors)]));\n ancestors.delete(value);\n return copy;\n }\n\n private static propertyValue(node: ItemModelNode, context: Required<ItemModelContext>): unknown {\n const kind = node.type.replace(/^minecraft:/, \"\");\n const property = node.property ? this.contextIdentifier(node.property) : undefined;\n if (kind === \"select\" && property === \"minecraft:display_context\") return context.displayContext;\n if (property && Object.prototype.hasOwnProperty.call(context.properties, property)) return context.properties[property];\n const fallback = kind === \"condition\" ? false : kind === \"range_dispatch\" ? 0 : undefined;\n const component = (id: string) => context.components[this.contextIdentifier(id)];\n if (property === \"minecraft:custom_model_data\") {\n const index = node.index ?? 0;\n if (!Number.isSafeInteger(index) || index < 0) throw new Error(\"Item-model custom_model_data index must be a nonnegative integer\");\n const data = component(\"custom_model_data\");\n if (data === undefined) return fallback;\n if (!data || typeof data !== \"object\" || Array.isArray(data)) throw new Error(\"Item-preview custom_model_data must be an object\");\n const field = kind === \"condition\" ? \"flags\" : kind === \"select\" ? \"strings\" : \"floats\";\n const values = (data as Record<string, unknown>)[field];\n if (values === undefined) return fallback;\n if (!Array.isArray(values)) throw new Error(`Item-preview custom_model_data.${field} must be an array`);\n return index < values.length ? values[index] : fallback;\n }\n if (kind === \"condition\" && property === \"minecraft:has_component\") {\n if (node.ignore_default) throw new Error(\"Item-preview has_component with ignore_default requires an explicit properties override; default component comparisons are unsupported\");\n return Object.prototype.hasOwnProperty.call(context.components, this.contextIdentifier(node.component!));\n }\n if (kind === \"select\") {\n switch (property) {\n case \"minecraft:component\": return component(node.component!);\n case \"minecraft:block_state\": {\n const state = component(\"block_state\");\n if (state === undefined) return undefined;\n if (!state || typeof state !== \"object\" || Array.isArray(state)) throw new Error(\"Item-preview block_state must be an object\");\n if (typeof node.block_state_property !== \"string\") throw new Error(\"Item-model block_state requires block_state_property\");\n return Object.prototype.hasOwnProperty.call(state, node.block_state_property)\n ? (state as Record<string, unknown>)[node.block_state_property] : undefined;\n }\n case \"minecraft:charge_type\": {\n const projectiles = component(\"charged_projectiles\");\n if (projectiles === undefined) return \"none\";\n if (!Array.isArray(projectiles)) throw new Error(\"Item-preview charged_projectiles must be an array of item stacks\");\n const ids = projectiles.map(stack => {\n if (!stack || typeof stack !== \"object\" || Array.isArray(stack)) throw new Error(\"Item-preview charged_projectiles must contain item-stack objects\");\n return this.contextIdentifier((stack as { id: string }).id);\n });\n return !ids.length ? \"none\" : ids.includes(\"minecraft:firework_rocket\") ? \"rocket\" : \"arrow\";\n }\n }\n }\n if (kind === \"range_dispatch\" && (property === \"minecraft:damage\" || property === \"minecraft:count\")) {\n const damage = property === \"minecraft:damage\";\n const maximumComponent = component(damage ? \"max_damage\" : \"max_stack_size\");\n const maximum = maximumComponent === undefined ? damage ? 0 : 1 : maximumComponent;\n const damageComponent = component(\"damage\");\n const value = damage ? damageComponent === undefined ? 0 : damageComponent : context.count;\n if (typeof value !== \"number\" || typeof maximum !== \"number\" || maximum < 0) throw new Error(`Item-preview ${property} requires numeric components and a nonnegative maximum`);\n const clamped = Math.max(0, Math.min(maximum, value));\n return node.normalize === false ? clamped : clamped / maximum;\n }\n return fallback;\n }\n\n private static selectItemModel(node: ItemModelNode | undefined, key: AssetKey, context: Required<ItemModelContext>): SelectedItemModel {\n if (!node || typeof node.type !== \"string\") {\n throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);\n }\n switch (node.type.replace(/^minecraft:/, \"\")) {\n case \"composite\":\n if (Array.isArray(node.models)) return { parts: node.models.map(child => this.selectItemModel(child, key, context)) };\n break;\n case \"bundle/selected_item\": {\n const item = context.itemReferences[\"minecraft:bundle/selected_item\"];\n return item ? { item } : { parts: [] };\n }\n case \"model\":\n if (typeof node.model === \"string\" && node.model) return { model: node.model, tints: node.tints };\n break;\n case \"special\": {\n if (!node.base || !node.model || typeof node.model !== \"object\") break;\n const special = node.model;\n switch (special.type) {\n case \"copper_golem_statue\":\n case \"minecraft:copper_golem_statue\":\n if (isResourceLocation(special.texture)\n && [\"standing\", \"sitting\", \"running\", \"star\"].includes(special.pose)) return { model: node.base, special };\n break;\n case \"banner\":\n case \"minecraft:banner\":\n if (typeof special.color === \"string\" && Object.prototype.hasOwnProperty.call(DYE_COLORS, special.color)) return { model: node.base, special };\n break;\n case \"shield\":\n case \"minecraft:shield\":\n case \"trident\":\n case \"minecraft:trident\":\n case \"conduit\":\n case \"minecraft:conduit\":\n case \"decorated_pot\":\n case \"minecraft:decorated_pot\":\n case \"player_head\":\n case \"minecraft:player_head\":\n return { model: node.base, special };\n case \"shulker_box\":\n case \"minecraft:shulker_box\":\n if (typeof special.texture === \"string\" && special.texture\n && (special.openness === undefined || typeof special.openness === \"number\" && Number.isFinite(special.openness))\n && (special.orientation === undefined || [\"down\", \"up\", \"north\", \"south\", \"west\", \"east\"].includes(special.orientation))) {\n return { model: node.base, special };\n }\n break;\n case \"chest\":\n case \"minecraft:chest\":\n case \"bed\":\n case \"minecraft:bed\":\n if (typeof special.texture === \"string\" && special.texture) return { model: node.base, special };\n break;\n case \"head\":\n case \"minecraft:head\":\n if (typeof special.kind === \"string\" && special.kind) return { model: node.base, special };\n break;\n }\n throw new Error(`Unsupported special item renderer ${special.type} for ${key.toNamespacedString()}`);\n }\n case \"condition\": {\n const value = this.propertyValue(node, context);\n if (typeof value !== \"boolean\") throw new Error(`Item-preview condition ${node.property} requires a boolean`);\n return this.selectItemModel(value ? node.on_true : node.on_false, key, context);\n }\n case \"select\": {\n const value = this.propertyValue(node, context);\n const component = node.property && this.contextIdentifier(node.property) === \"minecraft:component\";\n if (!component && value !== undefined && typeof value !== \"string\") throw new Error(`Item-preview selector ${node.property} requires a string`);\n const matches = (candidate: unknown) => component\n ? JSON.stringify(this.snapshotJson(candidate)) === JSON.stringify(this.snapshotJson(value)) : candidate === value;\n const selected = value === undefined ? undefined\n : node.cases?.find(entry => matches(entry.when) || Array.isArray(entry.when) && entry.when.some(matches))?.model;\n return this.selectItemModel(selected ?? node.fallback, key, context);\n }\n case \"range_dispatch\": {\n const value = this.propertyValue(node, context);\n if (typeof value !== \"number\") throw new Error(`Item-preview range ${node.property} requires a number`);\n if (Number.isNaN(value)) return this.selectItemModel(node.fallback, key, context);\n const scaled = value * (node.scale ?? 1);\n if (!Number.isFinite(scaled)) throw new Error(`Item-preview range ${node.property} requires a finite value and scale`);\n const selected = node.entries?.reduce<{ threshold: number; model: ItemModelNode } | undefined>((match, entry) => {\n return entry.threshold <= scaled && (!match || entry.threshold >= match.threshold) ? entry : match;\n }, undefined);\n return this.selectItemModel(selected?.model ?? node.fallback, key, context);\n }\n }\n throw new Error(`Unsupported item model ${node?.type ?? \"definition\"} for ${key.toNamespacedString()}`);\n }\n\n /** Loads one model file without resolving its parents. Returns `undefined` when the file is missing. */\n public static async getRaw(key: AssetKey): Promise<Maybe<Model>> {\n if (!key.assetType) {\n key.assetType = \"models\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n const keyStr = key.serialize();\n //TODO: maybe add the asset source to the key\n return Caching.rawModelCache.get(keyStr, k => {\n return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), k1 => {\n return AssetLoader.get<Model>(key, AssetParser.MODEL);\n })\n }).then(asset => {\n if (asset) {\n asset.key = key;\n }\n return asset;\n })\n }\n\n /**\n * Loads a model and resolves its parent chain. Returns `undefined` when the model is missing.\n * Item keys default to GUI context and a stack count of 1. Unresolved conditions are false and numeric properties are zero.\n * Versioned stack-size, durability, and glint defaults apply unless components override them.\n * Pass `context` to supply component values, property overrides, and item references for a preview.\n * Composite items retain independently merged children in `ItemModel.parts`.\n *\n * @param key - Model key, for example `AssetKey.parse(\"models\", \"minecraft:item/diamond_sword\")`.\n */\n public static async getMerged(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n if (!key.assetType) {\n key.assetType = \"models\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n const preview = this.snapshotContext(key, context);\n if (key.type === \"item\") {\n const renamed = await Renames.key(\"items\", key);\n const replacement = renamed && await this.getMerged(renamed, preview);\n if (replacement) return replacement;\n }\n const dataKey = await this.applyDefaults(key, preview);\n const keyStr = AssetLoader.persistentKey(key.serialize() + (key.type === \"item\" ? this.contextKey(preview) + dataKey : \"\"));\n const model = await Caching.mergedModelCache.get(keyStr, async () => {\n //TODO: persistent cache\n const raw = key.type === \"item\" ? await this.getPreparedItemModel(key, preview, dataKey) : await this.getRaw(key);\n const merged = raw ? await ModelMerger.mergeWithParents(raw) : undefined;\n return merged;\n });\n return model;\n }\n\n /** Alias for {@link getMerged}. */\n public static async get(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n return this.getMerged(key, context);\n }\n\n /** Clears persisted models. Use {@link Caching.clear} to also discard in-memory assets. */\n public static async clearCache() {\n return this.PERSISTENT_CACHE.clear();\n }\n\n}\n\ninterface ItemModelNode {\n type: string;\n model?: string | SpecialItemRenderer;\n tints?: ItemTintSource[];\n base?: string;\n property?: string;\n index?: number;\n component?: string;\n ignore_default?: boolean;\n normalize?: boolean;\n block_state_property?: string;\n on_false?: ItemModelNode;\n on_true?: ItemModelNode;\n fallback?: ItemModelNode;\n cases?: Array<{ when: unknown; model: ItemModelNode }>;\n entries?: Array<{ threshold: number; model: ItemModelNode }>;\n scale?: number;\n models?: ItemModelNode[];\n}\n\ntype SelectedItemModel = { model: string; special?: SpecialItemRenderer; tints?: ItemTintSource[] }\n | { parts: SelectedItemModel[] }\n | { item: AssetKey };\n"],"mappings":"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","names":["model"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/assets/Models.ts"],"sourcesContent":["import { Renames } from \"./Renames\";\nimport { ItemModel, ItemTintSource, Model, SpecialItemRenderer } from \"../model/Model\";\nimport { Caching } from \"../cache/Caching\";\nimport { Maybe } from \"../util/util\";\nimport { ModelMerger } from \"../model/ModelMerger\";\nimport { AssetLoader } from \"./AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"./AssetDefaults\";\nimport { PersistentCache } from \"../cache/PersistentCache\";\nimport { AssetKey, isAssetKey, isResourceLocation } from \"./AssetKey\";\nimport { ListAsset } from \"../ListAsset\";\nimport { AssetParser } from \"./source/parser/AssetParsers\";\nimport { DisplayPosition } from \"../model/DisplayPosition\";\nimport { DYE_COLORS } from \"./BannerPatterns\";\nimport { ItemDefaults } from \"../model/ItemDefaults\";\nimport { MineRenderData } from \"./MineRenderData\";\nimport { ItemTints } from \"../model/ItemTints\";\n\n/** Caller-supplied item-preview state passed to {@link Models.getMerged}. */\nexport interface ItemModelContext {\n /** Context used by display-context selectors, overriding `properties`. Defaults to GUI. */\n displayContext?: DisplayPosition | \"none\";\n /** Explicit property overrides. Nodes with the same ID share one override, regardless of their parameters. */\n properties?: Record<string, boolean | string | number>;\n /** Supplied component JSON by ID, overriding built-in defaults. Component selectors compare structural JSON values. */\n components?: Record<string, unknown>;\n /** Stack count, as a nonnegative integer. Defaults to 1; items without listed defaults stack to 64. */\n count?: number;\n /** Item-model keys by reference-node ID, such as `minecraft:bundle/selected_item`. Unset references draw nothing. */\n itemReferences?: Record<string, AssetKey>;\n}\n\n/** Loads and caches Java block/item models, including inherited geometry and textures. */\nexport class Models {\n\n // Bump when the shape of cached item models changes.\n private static readonly ITEM_CACHE_VERSION = \"item-v8\";\n private static _persistentCache: PersistentCache | undefined;\n\n // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading\n // the library, and would require an EnvProvider before any entry has had a chance to register\n private static get PERSISTENT_CACHE(): PersistentCache {\n return this._persistentCache ??= PersistentCache.open(\"minerender-models\");\n }\n\n /** Lists item filenames from the asset source's `_list.json`, with a legacy model-directory fallback. */\n public static async getItemList(): Promise<string[]> {\n const key = new AssetKey(DEFAULT_NAMESPACE, \"_list\", \"items\");\n const legacyKey = new AssetKey(DEFAULT_NAMESPACE, \"_list\", \"models\", \"item\");\n return Caching.listAssetCache.get(key.serialize(), async () => {\n return (await AssetLoader.getFirst<ListAsset>([key, legacyKey], AssetParser.LIST))?.asset;\n }).then(r => r?.files ?? []);\n }\n\n public static async loadAndMerge(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n const model = key.type === \"item\" ? await this.getItemModel(key, context) : await this.getRaw(key);\n if (!model) {\n return undefined;\n }\n const merged = await ModelMerger.mergeWithParents(model);\n return merged;\n }\n\n private static async getItemModel(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n const preview = this.snapshotContext(key, context);\n const dataKey = await this.applyDefaults(key, preview);\n return this.getPreparedItemModel(key, preview, dataKey);\n }\n\n private static async getPreparedItemModel(key: AssetKey, preview: Required<ItemModelContext>, dataKey: string): Promise<Maybe<Model>> {\n const itemId = `${key.namespace}:${key.path}`;\n const itemKey = new AssetKey(key.namespace, key.path, \"items\", undefined, key.rootType, \".json\", key.root);\n const cacheKey = itemKey.serialize() + this.contextKey(preview) + dataKey;\n const model = await this.PERSISTENT_CACHE.getOrLoad(`${this.ITEM_CACHE_VERSION}:${AssetLoader.persistentKey(cacheKey)}`, async () => {\n const result = await AssetLoader.getFirst<Model & { model?: ItemModelNode }>([itemKey, key], AssetParser.JSON);\n if (!result) return undefined;\n if (result.key.assetType !== \"items\") return { ...result.asset, key, itemId, components: preview.components } as ItemModel;\n\n const load = async (selected: SelectedItemModel): Promise<ItemModel> => {\n if (\"parts\" in selected) {\n return { key, itemId, parts: await Promise.all(selected.parts.map(load)) };\n }\n if (\"item\" in selected) {\n // Referenced items start with their own default stack state and references.\n const model = await this.getItemModel(selected.item, { displayContext: preview.displayContext });\n if (!model) throw new Error(`Item ${key.toNamespacedString()} references missing item ${selected.item.toNamespacedString()}`);\n return model as ItemModel;\n }\n const modelKey = AssetKey.parse(\"models\", selected.model);\n modelKey.root = key.root;\n const model = await this.getRaw(modelKey);\n if (!model) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);\n // Relative texture paths belong to the referenced model's namespace.\n return { ...model, itemId, components: preview.components, ...(selected.special && { special: selected.special }), ...(selected.tints && { tints: selected.tints }) } as ItemModel;\n };\n const model = await load(this.selectItemModel(result.asset.model, key, preview));\n return model;\n });\n const restore = (model: ItemModel): ItemModel => ({\n ...model, key: Object.assign(new AssetKey(\"\", \"\"), model.key),\n ...(model.parts && { parts: model.parts.map(restore) })\n });\n return model ? restore(model) : undefined;\n }\n\n private static contextIdentifier(id: string): string {\n if (!isResourceLocation(id)) {\n throw new Error(`Invalid item-preview identifier: ${id}`);\n }\n return id.includes(\":\") ? id : `minecraft:${id}`;\n }\n\n /** @internal */\n public static componentValue(components: Record<string, unknown>, id: string): unknown {\n const normalized = this.contextIdentifier(id);\n const short = normalized.replace(/^minecraft:/, \"\");\n if (short !== normalized && Object.prototype.hasOwnProperty.call(components, short)\n && Object.prototype.hasOwnProperty.call(components, normalized)) {\n throw new Error(`Duplicate item-preview component: ${normalized}`);\n }\n return Object.prototype.hasOwnProperty.call(components, short) ? components[short] : components[normalized];\n }\n\n private static snapshotContext(key: AssetKey, context: ItemModelContext): Required<ItemModelContext> {\n const displayContext = context.displayContext ?? DisplayPosition.GUI;\n if (displayContext !== \"none\" && !Object.values(DisplayPosition).includes(displayContext)) {\n throw new Error(`Unsupported item display context: ${displayContext}`);\n }\n for (const map of [context.properties, context.components, context.itemReferences]) {\n if (map !== undefined && (!map || typeof map !== \"object\" || Array.isArray(map))) {\n throw new Error(\"Item-preview properties, components, and references must be objects keyed by identifier\");\n }\n }\n const count = context.count === undefined ? 1 : context.count;\n if (!Number.isSafeInteger(count) || count < 0) throw new Error(\"Item-preview count must be a nonnegative safe integer\");\n const properties: Required<ItemModelContext>[\"properties\"] = {};\n for (const [id, value] of Object.entries(context.properties ?? {})) {\n const property = this.contextIdentifier(id);\n if (![\"boolean\", \"string\", \"number\"].includes(typeof value) || typeof value === \"number\" && !Number.isFinite(value)) {\n throw new Error(`Item-preview property ${property} must be a boolean, string, or finite number`);\n }\n if (Object.prototype.hasOwnProperty.call(properties, property)) throw new Error(`Duplicate item-preview property: ${property}`);\n properties[property] = value;\n }\n const components: Record<string, unknown> = {};\n for (const [id, value] of Object.entries(context.components ?? {})) {\n const component = this.contextIdentifier(id);\n if (Object.prototype.hasOwnProperty.call(components, component)) throw new Error(`Duplicate item-preview component: ${component}`);\n components[component] = this.snapshotJson(value);\n }\n const itemReferences: Record<string, AssetKey> = {};\n for (const [id, value] of Object.entries(context.itemReferences ?? {})) {\n const reference = this.contextIdentifier(id);\n if (!isAssetKey(value) || value.assetType !== \"models\" || value.type !== \"item\") {\n throw new Error(`Item-preview reference ${reference} must be an item-model AssetKey`);\n }\n this.contextIdentifier(`${value.namespace}:${value.path}`);\n if (Object.prototype.hasOwnProperty.call(itemReferences, reference)) throw new Error(`Duplicate item-preview reference: ${reference}`);\n itemReferences[reference] = Object.assign(new AssetKey(\"\", \"\"), value, { root: value.root ?? key.root });\n }\n return { displayContext, properties, components, count, itemReferences };\n }\n\n private static async applyDefaults(key: AssetKey, preview: Required<ItemModelContext>): Promise<string> {\n if (key.type !== \"item\") return \"\";\n const resolved = await MineRenderData.resolve(key.root);\n const defaults = await ItemDefaults.get(`${key.namespace}:${key.path}`, key.root);\n preview.components = { ...defaults, ...preview.components };\n if (resolved.manifest.dataVersion < 3337 && key.namespace === DEFAULT_NAMESPACE\n && [\"potion\", \"splash_potion\", \"lingering_potion\"].includes(key.path)\n && !Object.prototype.hasOwnProperty.call(preview.components, \"minecraft:enchantment_glint_override\")\n && await ItemTints.hasPotionEffects(preview.components[\"minecraft:potion_contents\"], key.root)) {\n preview.components[\"minecraft:enchantment_glint_override\"] = true;\n }\n return `|data:${resolved.root}:${resolved.manifest.datasets.itemDefaults?.sha256}:${resolved.manifest.datasets.potionColors?.sha256}`;\n }\n\n private static contextKey(context: Required<ItemModelContext>): string {\n const itemReferences = Object.fromEntries(Object.entries(context.itemReferences).map(([id, key]) => [id, key.serialize()]));\n return `|${this.ITEM_CACHE_VERSION}:${JSON.stringify(this.snapshotJson({ ...context, itemReferences }))}`;\n }\n\n private static snapshotJson(value: unknown, ancestors = new Set<object>()): unknown {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\" || typeof value === \"number\" && Number.isFinite(value)) return value;\n if (typeof value !== \"object\" || ancestors.has(value) || !Array.isArray(value)\n && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {\n throw new Error(\"Item-preview components must contain finite JSON values without circular references\");\n }\n ancestors.add(value);\n const copy = Array.isArray(value) ? Array.from(value, entry => this.snapshotJson(entry, ancestors))\n : Object.fromEntries(Object.keys(value).sort().map(key => [key, this.snapshotJson((value as Record<string, unknown>)[key], ancestors)]));\n ancestors.delete(value);\n return copy;\n }\n\n private static propertyValue(node: ItemModelNode, context: Required<ItemModelContext>): unknown {\n const kind = node.type.replace(/^minecraft:/, \"\");\n const property = node.property ? this.contextIdentifier(node.property) : undefined;\n if (kind === \"select\" && property === \"minecraft:display_context\") return context.displayContext;\n if (property && Object.prototype.hasOwnProperty.call(context.properties, property)) return context.properties[property];\n const fallback = kind === \"condition\" ? false : kind === \"range_dispatch\" ? 0 : undefined;\n const component = (id: string) => context.components[this.contextIdentifier(id)];\n if (property === \"minecraft:custom_model_data\") {\n const index = node.index ?? 0;\n if (!Number.isSafeInteger(index) || index < 0) throw new Error(\"Item-model custom_model_data index must be a nonnegative integer\");\n const data = component(\"custom_model_data\");\n if (data === undefined) return fallback;\n if (!data || typeof data !== \"object\" || Array.isArray(data)) throw new Error(\"Item-preview custom_model_data must be an object\");\n const field = kind === \"condition\" ? \"flags\" : kind === \"select\" ? \"strings\" : \"floats\";\n const values = (data as Record<string, unknown>)[field];\n if (values === undefined) return fallback;\n if (!Array.isArray(values)) throw new Error(`Item-preview custom_model_data.${field} must be an array`);\n return index < values.length ? values[index] : fallback;\n }\n if (kind === \"condition\" && property === \"minecraft:has_component\") {\n if (node.ignore_default) throw new Error(\"Item-preview has_component with ignore_default requires an explicit properties override; default component comparisons are unsupported\");\n return Object.prototype.hasOwnProperty.call(context.components, this.contextIdentifier(node.component!));\n }\n if (kind === \"select\") {\n switch (property) {\n case \"minecraft:component\": return component(node.component!);\n case \"minecraft:block_state\": {\n const state = component(\"block_state\");\n if (state === undefined) return undefined;\n if (!state || typeof state !== \"object\" || Array.isArray(state)) throw new Error(\"Item-preview block_state must be an object\");\n if (typeof node.block_state_property !== \"string\") throw new Error(\"Item-model block_state requires block_state_property\");\n return Object.prototype.hasOwnProperty.call(state, node.block_state_property)\n ? (state as Record<string, unknown>)[node.block_state_property] : undefined;\n }\n case \"minecraft:charge_type\": {\n const projectiles = component(\"charged_projectiles\");\n if (projectiles === undefined) return \"none\";\n if (!Array.isArray(projectiles)) throw new Error(\"Item-preview charged_projectiles must be an array of item stacks\");\n const ids = projectiles.map(stack => {\n if (!stack || typeof stack !== \"object\" || Array.isArray(stack)) throw new Error(\"Item-preview charged_projectiles must contain item-stack objects\");\n return this.contextIdentifier((stack as { id: string }).id);\n });\n return !ids.length ? \"none\" : ids.includes(\"minecraft:firework_rocket\") ? \"rocket\" : \"arrow\";\n }\n }\n }\n if (kind === \"range_dispatch\" && (property === \"minecraft:damage\" || property === \"minecraft:count\")) {\n const damage = property === \"minecraft:damage\";\n const maximumComponent = component(damage ? \"max_damage\" : \"max_stack_size\");\n const maximum = maximumComponent === undefined ? damage ? 0 : 1 : maximumComponent;\n const damageComponent = component(\"damage\");\n const value = damage ? damageComponent === undefined ? 0 : damageComponent : context.count;\n if (typeof value !== \"number\" || typeof maximum !== \"number\" || maximum < 0) throw new Error(`Item-preview ${property} requires numeric components and a nonnegative maximum`);\n const clamped = Math.max(0, Math.min(maximum, value));\n return node.normalize === false ? clamped : clamped / maximum;\n }\n return fallback;\n }\n\n private static selectItemModel(node: ItemModelNode | undefined, key: AssetKey, context: Required<ItemModelContext>): SelectedItemModel {\n if (!node || typeof node.type !== \"string\") {\n throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);\n }\n switch (node.type.replace(/^minecraft:/, \"\")) {\n case \"composite\":\n if (Array.isArray(node.models)) return { parts: node.models.map(child => this.selectItemModel(child, key, context)) };\n break;\n case \"bundle/selected_item\": {\n const item = context.itemReferences[\"minecraft:bundle/selected_item\"];\n return item ? { item } : { parts: [] };\n }\n case \"model\":\n if (typeof node.model === \"string\" && node.model) return { model: node.model, tints: node.tints };\n break;\n case \"special\": {\n if (!node.base || !node.model || typeof node.model !== \"object\") break;\n const special = node.model;\n switch (special.type) {\n case \"copper_golem_statue\":\n case \"minecraft:copper_golem_statue\":\n if (isResourceLocation(special.texture)\n && [\"standing\", \"sitting\", \"running\", \"star\"].includes(special.pose)) return { model: node.base, special };\n break;\n case \"banner\":\n case \"minecraft:banner\":\n if (typeof special.color === \"string\" && Object.prototype.hasOwnProperty.call(DYE_COLORS, special.color)) return { model: node.base, special };\n break;\n case \"shield\":\n case \"minecraft:shield\":\n case \"trident\":\n case \"minecraft:trident\":\n case \"conduit\":\n case \"minecraft:conduit\":\n case \"decorated_pot\":\n case \"minecraft:decorated_pot\":\n case \"player_head\":\n case \"minecraft:player_head\":\n return { model: node.base, special };\n case \"shulker_box\":\n case \"minecraft:shulker_box\":\n if (typeof special.texture === \"string\" && special.texture\n && (special.openness === undefined || typeof special.openness === \"number\" && Number.isFinite(special.openness))\n && (special.orientation === undefined || [\"down\", \"up\", \"north\", \"south\", \"west\", \"east\"].includes(special.orientation))) {\n return { model: node.base, special };\n }\n break;\n case \"chest\":\n case \"minecraft:chest\":\n case \"bed\":\n case \"minecraft:bed\":\n if (typeof special.texture === \"string\" && special.texture) return { model: node.base, special };\n break;\n case \"head\":\n case \"minecraft:head\":\n if (typeof special.kind === \"string\" && special.kind) return { model: node.base, special };\n break;\n }\n throw new Error(`Unsupported special item renderer ${special.type} for ${key.toNamespacedString()}`);\n }\n case \"condition\": {\n const value = this.propertyValue(node, context);\n if (typeof value !== \"boolean\") throw new Error(`Item-preview condition ${node.property} requires a boolean`);\n return this.selectItemModel(value ? node.on_true : node.on_false, key, context);\n }\n case \"select\": {\n const value = this.propertyValue(node, context);\n const component = node.property && this.contextIdentifier(node.property) === \"minecraft:component\";\n if (!component && value !== undefined && typeof value !== \"string\") throw new Error(`Item-preview selector ${node.property} requires a string`);\n const matches = (candidate: unknown) => component\n ? JSON.stringify(this.snapshotJson(candidate)) === JSON.stringify(this.snapshotJson(value)) : candidate === value;\n const selected = value === undefined ? undefined\n : node.cases?.find(entry => matches(entry.when) || Array.isArray(entry.when) && entry.when.some(matches))?.model;\n return this.selectItemModel(selected ?? node.fallback, key, context);\n }\n case \"range_dispatch\": {\n const value = this.propertyValue(node, context);\n if (typeof value !== \"number\") throw new Error(`Item-preview range ${node.property} requires a number`);\n if (Number.isNaN(value)) return this.selectItemModel(node.fallback, key, context);\n const scaled = value * (node.scale ?? 1);\n if (!Number.isFinite(scaled)) throw new Error(`Item-preview range ${node.property} requires a finite value and scale`);\n const selected = node.entries?.reduce<{ threshold: number; model: ItemModelNode } | undefined>((match, entry) => {\n return entry.threshold <= scaled && (!match || entry.threshold >= match.threshold) ? entry : match;\n }, undefined);\n return this.selectItemModel(selected?.model ?? node.fallback, key, context);\n }\n }\n throw new Error(`Unsupported item model ${node?.type ?? \"definition\"} for ${key.toNamespacedString()}`);\n }\n\n /** Loads one model file without resolving its parents. Returns `undefined` when the file is missing. */\n public static async getRaw(key: AssetKey): Promise<Maybe<Model>> {\n if (!key.assetType) {\n key.assetType = \"models\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n const keyStr = key.serialize();\n //TODO: maybe add the asset source to the key\n return Caching.rawModelCache.get(keyStr, k => {\n return this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(keyStr), k1 => {\n return AssetLoader.get<Model>(key, AssetParser.MODEL);\n })\n }).then(asset => {\n if (asset) {\n asset.key = key;\n }\n return asset;\n })\n }\n\n /**\n * Loads a model and resolves its parent chain. Returns `undefined` when the model is missing.\n * Item keys default to GUI context and a stack count of 1. Unresolved conditions are false and numeric properties are zero.\n * Versioned stack-size, durability, and glint defaults apply unless components override them.\n * Pass `context` to supply component values, property overrides, and item references for a preview.\n * Composite items retain independently merged children in `ItemModel.parts`.\n *\n * @param key - Model key, for example `AssetKey.parse(\"models\", \"minecraft:item/diamond_sword\")`.\n */\n public static async getMerged(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n if (!key.assetType) {\n key.assetType = \"models\";\n }\n if (!key.extension) {\n key.extension = \".json\";\n }\n const preview = this.snapshotContext(key, context);\n if (key.type === \"item\") {\n const renamed = await Renames.key(\"items\", key);\n const replacement = renamed && await this.getMerged(renamed, preview);\n if (replacement) return replacement;\n }\n const dataKey = await this.applyDefaults(key, preview);\n const keyStr = AssetLoader.persistentKey(key.serialize() + (key.type === \"item\" ? this.contextKey(preview) + dataKey : \"\"));\n const model = await Caching.mergedModelCache.get(keyStr, async () => {\n //TODO: persistent cache\n const raw = key.type === \"item\" ? await this.getPreparedItemModel(key, preview, dataKey) : await this.getRaw(key);\n const merged = raw ? await ModelMerger.mergeWithParents(raw) : undefined;\n return merged;\n });\n return model;\n }\n\n /** Alias for {@link getMerged}. */\n public static async get(key: AssetKey, context: ItemModelContext = {}): Promise<Maybe<Model>> {\n return this.getMerged(key, context);\n }\n\n /** Clears persisted models. Use {@link Caching.clear} to also discard in-memory assets. */\n public static async clearCache() {\n return this.PERSISTENT_CACHE.clear();\n }\n\n}\n\ninterface ItemModelNode {\n type: string;\n model?: string | SpecialItemRenderer;\n tints?: ItemTintSource[];\n base?: string;\n property?: string;\n index?: number;\n component?: string;\n ignore_default?: boolean;\n normalize?: boolean;\n block_state_property?: string;\n on_false?: ItemModelNode;\n on_true?: ItemModelNode;\n fallback?: ItemModelNode;\n cases?: Array<{ when: unknown; model: ItemModelNode }>;\n entries?: Array<{ threshold: number; model: ItemModelNode }>;\n scale?: number;\n models?: ItemModelNode[];\n}\n\ntype SelectedItemModel = { model: string; special?: SpecialItemRenderer; tints?: ItemTintSource[] }\n | { parts: SelectedItemModel[] }\n | { item: AssetKey };\n"],"mappings":"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","names":["model"]}
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
import { TextWriter, Uint8ArrayReader, ZipReader } from "@zip.js/zip.js";
|
|
3
3
|
import { AssetKey } from "../AssetKey.mjs";
|
|
4
4
|
import { AssetLoader } from "../AssetLoader.mjs";
|
|
5
|
-
import { DEFAULT_NAMESPACE } from "../
|
|
5
|
+
import { DEFAULT_NAMESPACE } from "../AssetDefaults.mjs";
|
|
6
6
|
import { Caching } from "../../cache/Caching.mjs";
|
|
7
7
|
import { AssetParser } from "../source/parser/AssetParsers.mjs";
|
|
8
8
|
import { createCanvas } from "../../canvas/CanvasCompat.mjs";
|
|
9
|
+
import { logger } from "../../util/log.mjs";
|
|
10
|
+
var log = logger("Unihex");
|
|
9
11
|
var ATLAS_SIZE = 512;
|
|
10
12
|
var GLYPH_HEIGHT = 16;
|
|
11
13
|
var UnihexAtlas = class {
|
|
@@ -93,7 +95,7 @@ async function parseUnihex(key) {
|
|
|
93
95
|
}
|
|
94
96
|
return { indices, rows, metrics };
|
|
95
97
|
} catch (error) {
|
|
96
|
-
|
|
98
|
+
log.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
97
99
|
return void 0;
|
|
98
100
|
}
|
|
99
101
|
}
|
|
@@ -112,7 +114,7 @@ async function loadUnihex(provider, fontKey, characters) {
|
|
|
112
114
|
return { ...override, from, to };
|
|
113
115
|
});
|
|
114
116
|
} catch (error) {
|
|
115
|
-
|
|
117
|
+
log.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
|
|
116
118
|
return glyphs;
|
|
117
119
|
}
|
|
118
120
|
const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
|
|
@@ -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 \"../Assets\";\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 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/assets/index.ts"],"sourcesContent":["// autogenerated\nexport * from './AssetKey';\nexport * from './AssetLoader';\nexport * from './Assets';\nexport * from './BannerPatterns';\nexport * from './Biomes';\nexport * from './BlockEntities';\nexport * from './BlockStates';\nexport * from './DecoratedPots';\nexport * from './Entities';\nexport * from './Fonts';\nexport * from './MineRenderData';\nexport * from './ModelTextures';\nexport * from './Models';\nexport * from './Renames';\nexport * from './source';\n"],"mappings":";AACA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/assets/index.ts"],"sourcesContent":["// autogenerated\nexport * from './AssetDefaults';\nexport * from './AssetKey';\nexport * from './AssetLoader';\nexport * from './Assets';\nexport * from './BannerPatterns';\nexport * from './Biomes';\nexport * from './BlockEntities';\nexport * from './BlockStates';\nexport * from './DecoratedPots';\nexport * from './Entities';\nexport * from './Fonts';\nexport * from './MineRenderData';\nexport * from './ModelTextures';\nexport * from './Models';\nexport * from './Renames';\nexport * from './source';\n"],"mappings":";AACA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -1,16 +1,16 @@
|
|
|
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";
|
|
7
|
-
import { DEFAULT_NAMESPACE } from "../
|
|
7
|
+
import { DEFAULT_NAMESPACE } from "../AssetDefaults.mjs";
|
|
8
8
|
import { RequestError, Requests } from "../../request/index.mjs";
|
|
9
9
|
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);
|