minerender 2.1.0-beta.5 → 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.
Files changed (102) hide show
  1. package/dist/browser/esm/Materials.mjs +6 -3
  2. package/dist/browser/esm/Materials.mjs.map +1 -1
  3. package/dist/browser/esm/Ticker.mjs +3 -1
  4. package/dist/browser/esm/Ticker.mjs.map +1 -1
  5. package/dist/browser/esm/UVMapper.mjs +9 -9
  6. package/dist/browser/esm/UVMapper.mjs.map +1 -1
  7. package/dist/browser/esm/assets/AssetDefaults.mjs +8 -0
  8. package/dist/browser/esm/assets/AssetDefaults.mjs.map +1 -0
  9. package/dist/browser/esm/assets/AssetKey.mjs +1 -1
  10. package/dist/browser/esm/assets/AssetKey.mjs.map +1 -1
  11. package/dist/browser/esm/assets/AssetLoader.mjs +5 -5
  12. package/dist/browser/esm/assets/AssetLoader.mjs.map +1 -1
  13. package/dist/browser/esm/assets/Assets.mjs +1 -5
  14. package/dist/browser/esm/assets/Assets.mjs.map +1 -1
  15. package/dist/browser/esm/assets/BlockEntities.mjs +3 -1
  16. package/dist/browser/esm/assets/BlockEntities.mjs.map +1 -1
  17. package/dist/browser/esm/assets/BlockStates.mjs +1 -1
  18. package/dist/browser/esm/assets/BlockStates.mjs.map +1 -1
  19. package/dist/browser/esm/assets/Entities.mjs +1 -1
  20. package/dist/browser/esm/assets/Entities.mjs.map +1 -1
  21. package/dist/browser/esm/assets/Fonts.mjs +31 -4
  22. package/dist/browser/esm/assets/Fonts.mjs.map +1 -1
  23. package/dist/browser/esm/assets/Models.mjs +1 -1
  24. package/dist/browser/esm/assets/Models.mjs.map +1 -1
  25. package/dist/browser/esm/assets/_fonts/Unihex.mjs +168 -0
  26. package/dist/browser/esm/assets/_fonts/Unihex.mjs.map +1 -0
  27. package/dist/browser/esm/assets/index.mjs +1 -0
  28. package/dist/browser/esm/assets/index.mjs.map +1 -1
  29. package/dist/browser/esm/assets/source/HostedAssetSource.mjs +19 -9
  30. package/dist/browser/esm/assets/source/HostedAssetSource.mjs.map +1 -1
  31. package/dist/browser/esm/assets/source/parser/AssetParsers.mjs +1 -0
  32. package/dist/browser/esm/assets/source/parser/AssetParsers.mjs.map +1 -1
  33. package/dist/browser/esm/cache/Caching.mjs +2 -0
  34. package/dist/browser/esm/cache/Caching.mjs.map +1 -1
  35. package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs +62 -11
  36. package/dist/browser/esm/entity/scene/EntityAnimationPlayer.mjs.map +1 -1
  37. package/dist/browser/esm/entity/scene/EntityObject.mjs +53 -20
  38. package/dist/browser/esm/entity/scene/EntityObject.mjs.map +1 -1
  39. package/dist/browser/esm/env/browser/BrowserCache.mjs +3 -3
  40. package/dist/browser/esm/env/browser/BrowserCache.mjs.map +1 -1
  41. package/dist/browser/esm/env/browser/section.worker.mjs +5 -3
  42. package/dist/browser/esm/env/browser/section.worker.mjs.map +1 -1
  43. package/dist/browser/esm/gui/GuiText.mjs +4 -3
  44. package/dist/browser/esm/gui/GuiText.mjs.map +1 -1
  45. package/dist/browser/esm/image/ImageLoader.mjs +3 -3
  46. package/dist/browser/esm/image/ImageLoader.mjs.map +1 -1
  47. package/dist/browser/esm/index.browser.d.mts +115 -20
  48. package/dist/browser/esm/inspector/SceneInspector.mjs +3 -3
  49. package/dist/browser/esm/inspector/SceneInspector.mjs.map +1 -1
  50. package/dist/browser/esm/instance/InstanceManager.mjs +4 -4
  51. package/dist/browser/esm/instance/InstanceManager.mjs.map +1 -1
  52. package/dist/browser/esm/model/block/scene/BlockObject.mjs +3 -1
  53. package/dist/browser/esm/model/block/scene/BlockObject.mjs.map +1 -1
  54. package/dist/browser/esm/model/multiblock/StructureParser.mjs +7 -4
  55. package/dist/browser/esm/model/multiblock/StructureParser.mjs.map +1 -1
  56. package/dist/browser/esm/model/scene/ModelObject.mjs +8 -4
  57. package/dist/browser/esm/model/scene/ModelObject.mjs.map +1 -1
  58. package/dist/browser/esm/nbt/NBTHelper.mjs +5 -2
  59. package/dist/browser/esm/nbt/NBTHelper.mjs.map +1 -1
  60. package/dist/browser/esm/renderer/Renderer.mjs +4 -2
  61. package/dist/browser/esm/renderer/Renderer.mjs.map +1 -1
  62. package/dist/browser/esm/renderer/SceneObject.mjs +0 -6
  63. package/dist/browser/esm/renderer/SceneObject.mjs.map +1 -1
  64. package/dist/browser/esm/request/Requests.mjs +3 -3
  65. package/dist/browser/esm/request/Requests.mjs.map +1 -1
  66. package/dist/browser/esm/skin/Skins.mjs +6 -4
  67. package/dist/browser/esm/skin/Skins.mjs.map +1 -1
  68. package/dist/browser/esm/texture/TextureLoader.mjs +4 -2
  69. package/dist/browser/esm/texture/TextureLoader.mjs.map +1 -1
  70. package/dist/browser/esm/util/log.mjs +75 -0
  71. package/dist/browser/esm/util/log.mjs.map +1 -1
  72. package/dist/browser/esm/util/model.mjs +7 -7
  73. package/dist/browser/esm/util/model.mjs.map +1 -1
  74. package/dist/browser/esm/util/performance.mjs.map +1 -1
  75. package/dist/browser/esm/world/Chunk.mjs +8 -5
  76. package/dist/browser/esm/world/Chunk.mjs.map +1 -1
  77. package/dist/browser/esm/world/MineRenderWorld.mjs +96 -54
  78. package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
  79. package/dist/browser/esm/world/SectionGeometry.mjs +5 -3
  80. package/dist/browser/esm/world/SectionGeometry.mjs.map +1 -1
  81. package/dist/browser/esm/world/SectionMesh.mjs +4 -0
  82. package/dist/browser/esm/world/SectionMesh.mjs.map +1 -1
  83. package/dist/browser/esm/world/SectionModels.mjs +2 -2
  84. package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
  85. package/dist/browser/esm/world/WorldStreamer.mjs +21 -20
  86. package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
  87. package/dist/browser/esm/world/_culling/BlockCulling.mjs +1 -1
  88. package/dist/browser/esm/world/_culling/BlockCulling.mjs.map +1 -1
  89. package/dist/browser/esm/world/_entities/WorldEntities.mjs +3 -1
  90. package/dist/browser/esm/world/_entities/WorldEntities.mjs.map +1 -1
  91. package/dist/browser/index.d.ts +115 -20
  92. package/dist/browser/index.js +3449 -3025
  93. package/dist/browser/index.js.map +1 -1
  94. package/dist/bundle.js +13217 -12745
  95. package/dist/bundle.js.map +1 -1
  96. package/dist/node/index.d.mts +115 -20
  97. package/dist/node/index.d.ts +115 -20
  98. package/dist/node/index.js +3477 -3046
  99. package/dist/node/index.js.map +1 -1
  100. package/dist/node/index.mjs +3456 -3027
  101. package/dist/node/index.mjs.map +1 -1
  102. package/package.json +1 -1
@@ -0,0 +1,168 @@
1
+ // src/assets/_fonts/Unihex.ts
2
+ import { TextWriter, Uint8ArrayReader, ZipReader } from "@zip.js/zip.js";
3
+ import { AssetKey } from "../AssetKey.mjs";
4
+ import { AssetLoader } from "../AssetLoader.mjs";
5
+ import { DEFAULT_NAMESPACE } from "../AssetDefaults.mjs";
6
+ import { Caching } from "../../cache/Caching.mjs";
7
+ import { AssetParser } from "../source/parser/AssetParsers.mjs";
8
+ import { createCanvas } from "../../canvas/CanvasCompat.mjs";
9
+ import { logger } from "../../util/log.mjs";
10
+ var log = logger("Unihex");
11
+ var ATLAS_SIZE = 512;
12
+ var GLYPH_HEIGHT = 16;
13
+ var UnihexAtlas = class {
14
+ constructor() {
15
+ this.x = 0;
16
+ this.y = 0;
17
+ }
18
+ draw(glyph) {
19
+ const width = glyph.right - glyph.left + 1;
20
+ if (this.image && this.x + width > this.image.width) {
21
+ this.x = 0;
22
+ this.y += GLYPH_HEIGHT;
23
+ }
24
+ if (!this.image || this.y + GLYPH_HEIGHT > this.image.height || width > this.image.width) {
25
+ this.image = createCanvas(Math.max(ATLAS_SIZE, width), ATLAS_SIZE);
26
+ this.x = 0;
27
+ this.y = 0;
28
+ }
29
+ const context = this.image.getContext("2d");
30
+ const pixels = context.createImageData(width, GLYPH_HEIGHT);
31
+ for (let y = 0; y < GLYPH_HEIGHT; y++) {
32
+ for (let x = 0; x < width; x++) {
33
+ const column = glyph.left + x;
34
+ if (column < 0 || column >= glyph.bitWidth || !(glyph.rows[y] >>> glyph.bitWidth - column - 1 & 1)) continue;
35
+ pixels.data.fill(255, (y * width + x) * 4, (y * width + x + 1) * 4);
36
+ }
37
+ }
38
+ const result = { image: this.image, x: this.x, y: this.y };
39
+ context.putImageData(pixels, this.x, this.y);
40
+ this.x += width;
41
+ return result;
42
+ }
43
+ };
44
+ function readHex(text, filename, glyphs) {
45
+ const lines = text.split("\n");
46
+ if (lines[lines.length - 1] === "") lines.pop();
47
+ lines.forEach((line, index) => {
48
+ const match = /^([0-9A-F]{4,6}):([0-9A-F]+)$/.exec(line);
49
+ if (!match || ![32, 64, 96, 128].includes(match[2].length)) {
50
+ throw new Error(`Invalid Unihex record in ${filename} at line ${index + 1}`);
51
+ }
52
+ const codepoint = parseInt(match[1], 16);
53
+ if (codepoint > 1114111) throw new Error(`Invalid Unihex codepoint in ${filename} at line ${index + 1}`);
54
+ const bitWidth = match[2].length / 4;
55
+ const rowLength = bitWidth / 4;
56
+ const rows = new Uint32Array(GLYPH_HEIGHT);
57
+ let mask = 0;
58
+ for (let y = 0; y < GLYPH_HEIGHT; y++) {
59
+ rows[y] = parseInt(match[2].slice(y * rowLength, (y + 1) * rowLength), 16);
60
+ mask |= rows[y];
61
+ }
62
+ let left = 0, right = bitWidth;
63
+ if (mask) {
64
+ while (!(mask >>> bitWidth - left - 1 & 1)) left++;
65
+ right = bitWidth - 1;
66
+ while (!(mask >>> bitWidth - right - 1 & 1)) right--;
67
+ }
68
+ glyphs.set(codepoint, { rows, bitWidth, left, right });
69
+ });
70
+ }
71
+ var atlases = /* @__PURE__ */ new WeakMap();
72
+ async function parseUnihex(key) {
73
+ try {
74
+ const asset = await AssetLoader.get(key, AssetParser.BINARY);
75
+ if (!asset) throw new Error(`Could not load Unihex archive ${key.toNamespacedString()}`);
76
+ const records = /* @__PURE__ */ new Map();
77
+ const reader = new ZipReader(new Uint8ArrayReader(asset.data), { useWebWorkers: false, useCompressionStream: false });
78
+ try {
79
+ for (const entry of await reader.getEntries()) {
80
+ if (!entry.directory && entry.filename.endsWith(".hex")) {
81
+ readHex(await entry.getData(new TextWriter(), { checkSignature: true }), entry.filename, records);
82
+ }
83
+ }
84
+ } finally {
85
+ await reader.close();
86
+ }
87
+ const indices = new Int32Array(1114112).fill(-1);
88
+ const rows = new Uint32Array(records.size * GLYPH_HEIGHT), metrics = new Uint8Array(records.size * 3);
89
+ let index = 0;
90
+ for (const [codepoint, record] of records) {
91
+ indices[codepoint] = index;
92
+ rows.set(record.rows, index * GLYPH_HEIGHT);
93
+ metrics.set([record.bitWidth, record.left, record.right], index * 3);
94
+ index++;
95
+ }
96
+ return { indices, rows, metrics };
97
+ } catch (error) {
98
+ log.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
99
+ return void 0;
100
+ }
101
+ }
102
+ async function loadUnihex(provider, fontKey, characters) {
103
+ const origin = new AssetKey(DEFAULT_NAMESPACE, "", void 0, void 0, "assets", "", fontKey.root);
104
+ const key = AssetKey.parse("font", provider.hex_file, origin);
105
+ key.assetType = void 0;
106
+ const glyphs = /* @__PURE__ */ new Map();
107
+ let overrides;
108
+ try {
109
+ overrides = (provider.size_overrides ?? []).map((override) => {
110
+ const from = override.from.codePointAt(0), to = override.to.codePointAt(0);
111
+ if ([...override.from].length !== 1 || [...override.to].length !== 1 || from >= to || !Number.isInteger(override.left) || !Number.isInteger(override.right) || override.right < override.left) {
112
+ throw new Error(`Invalid Unihex size override in font ${fontKey.toNamespacedString()}`);
113
+ }
114
+ return { ...override, from, to };
115
+ });
116
+ } catch (error) {
117
+ log.warn(`Could not load Unihex file ${key.toNamespacedString()}`, error);
118
+ return glyphs;
119
+ }
120
+ const file = await Caching.unihexCache.get(key.serialize(), () => parseUnihex(key));
121
+ if (!file) return glyphs;
122
+ let atlas = atlases.get(provider);
123
+ if (!atlas) {
124
+ atlas = new UnihexAtlas();
125
+ atlases.set(provider, atlas);
126
+ }
127
+ for (const character of characters) {
128
+ const codepoint = character.codePointAt(0), index = file.indices[codepoint];
129
+ if (index < 0) continue;
130
+ const record = {
131
+ rows: file.rows.subarray(index * GLYPH_HEIGHT, (index + 1) * GLYPH_HEIGHT),
132
+ bitWidth: file.metrics[index * 3],
133
+ left: file.metrics[index * 3 + 1],
134
+ right: file.metrics[index * 3 + 2]
135
+ };
136
+ const override = overrides.find((range) => codepoint >= range.from && codepoint <= range.to);
137
+ if (override) {
138
+ record.left = override.left;
139
+ record.right = override.right;
140
+ }
141
+ const width = record.right - record.left + 1;
142
+ let rendered;
143
+ const render = () => rendered ?? (rendered = atlas.draw(record));
144
+ glyphs.set(character, {
145
+ get image() {
146
+ return render().image;
147
+ },
148
+ get x() {
149
+ return render().x;
150
+ },
151
+ get y() {
152
+ return render().y;
153
+ },
154
+ width,
155
+ height: GLYPH_HEIGHT,
156
+ scale: 0.5,
157
+ ascent: 7,
158
+ advance: Math.floor(width / 2) + 1,
159
+ boldOffset: 0.5,
160
+ shadowOffset: 0.5
161
+ });
162
+ }
163
+ return glyphs;
164
+ }
165
+ export {
166
+ loadUnihex
167
+ };
168
+ //# sourceMappingURL=Unihex.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/assets/_fonts/Unihex.ts"],"sourcesContent":["import { TextWriter, Uint8ArrayReader, ZipReader } from \"@zip.js/zip.js\";\nimport { AssetKey } from \"../AssetKey\";\nimport { AssetLoader } from \"../AssetLoader\";\nimport { DEFAULT_NAMESPACE } from \"../AssetDefaults\";\nimport { Caching } from \"../../cache/Caching\";\nimport { AssetParser } from \"../source/parser/AssetParsers\";\nimport { createCanvas, type CompatCanvas } from \"../../canvas/CanvasCompat\";\nimport type { BitmapGlyph } from \"../Fonts\";\nimport type { BinaryAsset } from \"../source/HostedAssetSource\";\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,4 +1,5 @@
1
1
  // src/assets/index.ts
2
+ export * from "./AssetDefaults.mjs";
2
3
  export * from "./AssetKey.mjs";
3
4
  export * from "./AssetLoader.mjs";
4
5
  export * from "./Assets.mjs";
@@ -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,15 +1,16 @@
1
1
  // src/assets/source/HostedAssetSource.ts
2
2
  import { AssetLoadError, AssetSource } from "./AssetSource.mjs";
3
- import { prefix } from "../../util/index.mjs";
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 "../Assets.mjs";
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
- var p = prefix("HostedAssetSource");
12
+ var BINARY_TIMEOUT = 6e4;
13
+ var log = logger("HostedAssetSource");
13
14
  var DEFAULT_OPTIONS = {
14
15
  retryDefaults: true
15
16
  };
@@ -21,14 +22,14 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
21
22
  return direct;
22
23
  }
23
24
  if (key.namespace !== DEFAULT_NAMESPACE) {
24
- console.info(p, "Retrying", key, "with default namespace");
25
+ log.debug("Retrying", key, "with default namespace");
25
26
  const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);
26
27
  const namespaced = await this.load(namespaceKey, parser);
27
28
  if (typeof namespaced !== "undefined") {
28
29
  return namespaced;
29
30
  }
30
31
  if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
31
- console.info(p, "Retrying", key, "with default root+namespace");
32
+ log.debug("Retrying", key, "with default root+namespace");
32
33
  const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
33
34
  const namespacedRooted = await this.load(namespacedRootedKey, parser);
34
35
  if (typeof namespacedRooted !== "undefined") {
@@ -36,7 +37,7 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
36
37
  }
37
38
  }
38
39
  } else if (typeof key.root !== "undefined" && key.root !== AssetLoader.ROOT || typeof this.root !== "undefined" && this.root !== AssetLoader.ROOT) {
39
- console.info(p, "Retrying", key, "with default root");
40
+ log.debug("Retrying", key, "with default root");
40
41
  const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);
41
42
  const rooted = await this.load(rootKey, parser);
42
43
  if (typeof rooted !== "undefined") {
@@ -46,9 +47,8 @@ var _HostedAssetSource = class _HostedAssetSource extends AssetSource {
46
47
  return void 0;
47
48
  }
48
49
  async load(key, parser) {
49
- console.info(p, "Loading", key);
50
50
  const url = `${this.assetBasePath(key)}${key.type !== void 0 ? key.type + "/" : ""}${key.path}${key.extension}`;
51
- console.debug(p, url);
51
+ log.debug("Loading", url);
52
52
  const request = { url };
53
53
  try {
54
54
  parser.config(request);
@@ -149,6 +149,15 @@ _HostedAssetSource.JSON = {
149
149
  return response.data;
150
150
  }
151
151
  };
152
+ _HostedAssetSource.BINARY = {
153
+ config(request) {
154
+ request.timeout = BINARY_TIMEOUT;
155
+ request.responseType = "arraybuffer";
156
+ },
157
+ parse(response) {
158
+ return { data: new Uint8Array(response.data) };
159
+ }
160
+ };
152
161
  _HostedAssetSource.PARSER_MAP = /* @__PURE__ */ new Map([
153
162
  [AssetParser.MODEL, _HostedAssetSource.MODEL],
154
163
  [AssetParser.BLOCKSTATE, _HostedAssetSource.BLOCKSTATE],
@@ -156,7 +165,8 @@ _HostedAssetSource.PARSER_MAP = /* @__PURE__ */ new Map([
156
165
  [AssetParser.NBT, _HostedAssetSource.NBT],
157
166
  [AssetParser.IMAGE, _HostedAssetSource.IMAGE],
158
167
  [AssetParser.LIST, _HostedAssetSource.LIST],
159
- [AssetParser.JSON, _HostedAssetSource.JSON]
168
+ [AssetParser.JSON, _HostedAssetSource.JSON],
169
+ [AssetParser.BINARY, _HostedAssetSource.BINARY]
160
170
  ]);
161
171
  var HostedAssetSource = _HostedAssetSource;
162
172
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/assets/source/HostedAssetSource.ts"],"sourcesContent":["import { AssetLoadError, AssetSource } from \"./AssetSource\";\nimport { BlockState, Model, TextureAsset } from \"../../model\";\nimport type { RequestConfig, RequestResponse } from \"../../request\";\nimport { Maybe, prefix } from \"../../util\";\nimport { MinecraftTextureMeta } from \"../../MinecraftTextureMeta\";\nimport { NBTAsset, NBTHelper } from \"../../nbt\";\nimport { ImageLoader } from \"../../image\";\nimport { ListAsset } from \"../../ListAsset\";\nimport { MinecraftAsset } from \"../../MinecraftAsset\";\nimport { AssetKey } from \"../AssetKey\";\nimport { DEFAULT_NAMESPACE } from \"../Assets\";\nimport { RequestError, Requests } from \"../../request\";\nimport { AssetLoader } from \"../AssetLoader\";\nimport { AssetParser } from \"./parser\";\nimport { ResponseParser } from \"./parser\";\nimport { merge } from \"../../util/_internal/merge\";\n\nconst p = prefix(\"HostedAssetSource\");\n\nconst DEFAULT_OPTIONS: HostedAssetSourceOptions = {\n retryDefaults: true\n}\n\n/** Loads assets over HTTP from a Minecraft directory tree rooted at the constructor's URL. */\nexport class HostedAssetSource extends AssetSource {\n\n static readonly MODEL: ResponseParser<Model> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<Model> {\n return response.data as Model;\n }\n }\n static readonly BLOCKSTATE: ResponseParser<BlockState> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<BlockState> {\n return response.data as BlockState;\n }\n }\n static readonly META: ResponseParser<MinecraftTextureMeta> = {\n config(request: RequestConfig) {\n // request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): Maybe<MinecraftTextureMeta> {\n return response.data as MinecraftTextureMeta;\n }\n }\n static readonly NBT: ResponseParser<NBTAsset> = {\n config(request: RequestConfig) {\n request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): Promise<Maybe<NBTAsset>> {\n return NBTHelper.fromBuffer(response.data);\n }\n }\n static readonly IMAGE: ResponseParser<TextureAsset> = {\n config(request: RequestConfig) {\n request.responseType = \"arraybuffer\";\n },\n async parse(response: RequestResponse): Promise<Maybe<TextureAsset>> {\n return await ImageLoader.processResponse(response) as TextureAsset;\n }\n }\n static readonly LIST: ResponseParser<ListAsset> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<ListAsset> {\n return response.data as ListAsset;\n }\n }\n static readonly JSON: ResponseParser<any> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<any> {\n return response.data;\n }\n }\n\n static readonly PARSER_MAP: Map<AssetParser, ResponseParser<any>> = new Map<AssetParser, ResponseParser<any>>([\n [AssetParser.MODEL, HostedAssetSource.MODEL],\n [AssetParser.BLOCKSTATE, HostedAssetSource.BLOCKSTATE],\n [AssetParser.META, HostedAssetSource.META],\n [AssetParser.NBT, HostedAssetSource.NBT],\n [AssetParser.IMAGE, HostedAssetSource.IMAGE],\n [AssetParser.LIST, HostedAssetSource.LIST],\n [AssetParser.JSON, HostedAssetSource.JSON],\n ]);\n\n /** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */\n public async loadOrRetryWithDefaults<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>> {\n const direct = await this.load<T>(key, parser);\n if (typeof direct !== \"undefined\") {\n return direct;\n }\n if (key.namespace !== DEFAULT_NAMESPACE) {\n console.info(p, \"Retrying\", key, \"with default namespace\");\n // Try on the same host but with default minecraft: namespace\n const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);\n const namespaced = await this.load<T>(namespaceKey, parser);\n if (typeof namespaced !== \"undefined\") {\n return namespaced;\n }\n if ((typeof key.root !== \"undefined\" && key.root !== AssetLoader.ROOT) || (typeof this.root !== \"undefined\" && this.root !== AssetLoader.ROOT)) {\n console.info(p, \"Retrying\", key, \"with default root+namespace\");\n // Try both defaults\n const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);\n const namespacedRooted = await this.load<T>(namespacedRootedKey, parser);\n if (typeof namespacedRooted !== \"undefined\") {\n return namespacedRooted;\n }\n }\n } else if ((typeof key.root !== \"undefined\" && key.root !== AssetLoader.ROOT) || (typeof this.root !== \"undefined\" && this.root !== AssetLoader.ROOT)) {\n console.info(p, \"Retrying\", key, \"with default root\");\n // Try on default root\n const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);\n const rooted = await this.load<T>(rootKey, parser);\n if (typeof rooted !== \"undefined\") {\n return rooted;\n }\n }\n return undefined;\n }\n\n\n protected async load<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>> {\n console.info(p, \"Loading\", key);\n const url = `${ this.assetBasePath(key) }${ key.type !== undefined ? key.type + '/' : '' }${ key.path }${ key.extension }`;\n console.debug(p, url);\n const request: RequestConfig = { url };\n try {\n parser.config(request);\n let response: RequestResponse;\n try {\n response = await Requests.mcAssetRequest(request);\n } catch (cause) {\n // HTTP 404 is the only request failure that permits source fallback.\n if (cause instanceof RequestError && cause.response?.status === 404) {\n return undefined;\n }\n throw cause;\n }\n if (response.data === undefined) {\n throw new Error(\"Asset response has no data\");\n }\n return await parser.parse(response);\n } catch (cause) {\n throw new AssetLoadError(this, key, request.url, cause);\n }\n }\n\n public assetBasePath(key: AssetKey) {\n return `${ key.root ?? this.root ?? AssetLoader.ROOT }/${ key.rootType !== undefined ? key.rootType + '/' : '' }${ key.namespace !== undefined ? key.namespace + '/' : '' }${ key.assetType !== undefined ? key.assetType + '/' : '' }`;\n }\n\n private readonly _root: string;\n private readonly _options: HostedAssetSourceOptions;\n\n /**\n * Creates a hosted source for {@link AssetLoader.addSource}.\n * Set `options.retryDefaults` to `false` to restrict lookups to the requested namespace and root.\n */\n public constructor(root: string, options?: Partial<HostedAssetSourceOptions>) {\n super();\n this._root = root;\n this._options = merge({}, DEFAULT_OPTIONS, options ?? {});\n }\n\n public get root(): string {\n return this._root;\n }\n\n public get cacheId(): string {\n return `hosted:${this._root}`;\n }\n\n public get options(): HostedAssetSourceOptions {\n return this._options;\n }\n\n public get<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser): Promise<Maybe<T>> {\n const responseParser = HostedAssetSource.PARSER_MAP.get(parser) as ResponseParser<T>;\n if (this.options.retryDefaults && !(key.rootType === undefined && key.namespace === \"minerender-data\")) {\n return this.loadOrRetryWithDefaults(key, responseParser);\n }\n return this.load(key, responseParser);\n }\n\n}\n\ninterface HostedAssetSourceOptions {\n retryDefaults: boolean;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../src/assets/source/HostedAssetSource.ts"],"sourcesContent":["import { AssetLoadError, AssetSource } from \"./AssetSource\";\nimport { BlockState, Model, TextureAsset } from \"../../model\";\nimport type { RequestConfig, RequestResponse } from \"../../request\";\nimport { Maybe } from \"../../util\";\nimport { logger } from \"../../util/log\";\nimport { MinecraftTextureMeta } from \"../../MinecraftTextureMeta\";\nimport { NBTAsset, NBTHelper } from \"../../nbt\";\nimport { ImageLoader } from \"../../image\";\nimport { ListAsset } from \"../../ListAsset\";\nimport { MinecraftAsset } from \"../../MinecraftAsset\";\nimport { AssetKey } from \"../AssetKey\";\nimport { DEFAULT_NAMESPACE } from \"../AssetDefaults\";\nimport { RequestError, Requests } from \"../../request\";\nimport { AssetLoader } from \"../AssetLoader\";\nimport { AssetParser } from \"./parser\";\nimport { ResponseParser } from \"./parser\";\nimport { merge } from \"../../util/_internal/merge\";\n\nconst BINARY_TIMEOUT = 60_000;\n\nconst log = logger(\"HostedAssetSource\");\n\nconst DEFAULT_OPTIONS: HostedAssetSourceOptions = {\n retryDefaults: true\n}\n\n/** Loads assets over HTTP from a Minecraft directory tree rooted at the constructor's URL. */\nexport class HostedAssetSource extends AssetSource {\n\n static readonly MODEL: ResponseParser<Model> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<Model> {\n return response.data as Model;\n }\n }\n static readonly BLOCKSTATE: ResponseParser<BlockState> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<BlockState> {\n return response.data as BlockState;\n }\n }\n static readonly META: ResponseParser<MinecraftTextureMeta> = {\n config(request: RequestConfig) {\n // request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): Maybe<MinecraftTextureMeta> {\n return response.data as MinecraftTextureMeta;\n }\n }\n static readonly NBT: ResponseParser<NBTAsset> = {\n config(request: RequestConfig) {\n request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): Promise<Maybe<NBTAsset>> {\n return NBTHelper.fromBuffer(response.data);\n }\n }\n static readonly IMAGE: ResponseParser<TextureAsset> = {\n config(request: RequestConfig) {\n request.responseType = \"arraybuffer\";\n },\n async parse(response: RequestResponse): Promise<Maybe<TextureAsset>> {\n return await ImageLoader.processResponse(response) as TextureAsset;\n }\n }\n static readonly LIST: ResponseParser<ListAsset> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<ListAsset> {\n return response.data as ListAsset;\n }\n }\n static readonly JSON: ResponseParser<any> = {\n config(request: RequestConfig) {\n },\n parse(response: RequestResponse): Maybe<any> {\n return response.data;\n }\n }\n static readonly BINARY: ResponseParser<BinaryAsset> = {\n config(request: RequestConfig) {\n request.timeout = BINARY_TIMEOUT;\n request.responseType = \"arraybuffer\";\n },\n parse(response: RequestResponse): BinaryAsset {\n return { data: new Uint8Array(response.data as ArrayBuffer) };\n }\n }\n\n static readonly PARSER_MAP: Map<AssetParser, ResponseParser<any>> = new Map<AssetParser, ResponseParser<any>>([\n [AssetParser.MODEL, HostedAssetSource.MODEL],\n [AssetParser.BLOCKSTATE, HostedAssetSource.BLOCKSTATE],\n [AssetParser.META, HostedAssetSource.META],\n [AssetParser.NBT, HostedAssetSource.NBT],\n [AssetParser.IMAGE, HostedAssetSource.IMAGE],\n [AssetParser.LIST, HostedAssetSource.LIST],\n [AssetParser.JSON, HostedAssetSource.JSON],\n [AssetParser.BINARY, HostedAssetSource.BINARY],\n ]);\n\n /** Retries missing assets with the `minecraft` namespace and default root. Other failures reject. */\n public async loadOrRetryWithDefaults<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>> {\n const direct = await this.load<T>(key, parser);\n if (typeof direct !== \"undefined\") {\n return direct;\n }\n if (key.namespace !== DEFAULT_NAMESPACE) {\n log.debug(\"Retrying\", key, \"with default namespace\");\n // Try on the same host but with default minecraft: namespace\n const namespaceKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, key.root);\n const namespaced = await this.load<T>(namespaceKey, parser);\n if (typeof namespaced !== \"undefined\") {\n return namespaced;\n }\n if ((typeof key.root !== \"undefined\" && key.root !== AssetLoader.ROOT) || (typeof this.root !== \"undefined\" && this.root !== AssetLoader.ROOT)) {\n log.debug(\"Retrying\", key, \"with default root+namespace\");\n // Try both defaults\n const namespacedRootedKey = new AssetKey(DEFAULT_NAMESPACE, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);\n const namespacedRooted = await this.load<T>(namespacedRootedKey, parser);\n if (typeof namespacedRooted !== \"undefined\") {\n return namespacedRooted;\n }\n }\n } else if ((typeof key.root !== \"undefined\" && key.root !== AssetLoader.ROOT) || (typeof this.root !== \"undefined\" && this.root !== AssetLoader.ROOT)) {\n log.debug(\"Retrying\", key, \"with default root\");\n // Try on default root\n const rootKey = new AssetKey(key.namespace, key.path, key.assetType, key.type, key.rootType, key.extension, AssetLoader.ROOT);\n const rooted = await this.load<T>(rootKey, parser);\n if (typeof rooted !== \"undefined\") {\n return rooted;\n }\n }\n return undefined;\n }\n\n\n protected async load<T extends MinecraftAsset>(key: AssetKey, parser: ResponseParser<T>): Promise<Maybe<T>> {\n const url = `${ this.assetBasePath(key) }${ key.type !== undefined ? key.type + '/' : '' }${ key.path }${ key.extension }`;\n log.debug(\"Loading\", url);\n const request: RequestConfig = { url };\n try {\n parser.config(request);\n let response: RequestResponse;\n try {\n response = await Requests.mcAssetRequest(request);\n } catch (cause) {\n // HTTP 404 is the only request failure that permits source fallback.\n if (cause instanceof RequestError && cause.response?.status === 404) {\n return undefined;\n }\n throw cause;\n }\n if (response.data === undefined) {\n throw new Error(\"Asset response has no data\");\n }\n return await parser.parse(response);\n } catch (cause) {\n throw new AssetLoadError(this, key, request.url, cause);\n }\n }\n\n public assetBasePath(key: AssetKey) {\n return `${ key.root ?? this.root ?? AssetLoader.ROOT }/${ key.rootType !== undefined ? key.rootType + '/' : '' }${ key.namespace !== undefined ? key.namespace + '/' : '' }${ key.assetType !== undefined ? key.assetType + '/' : '' }`;\n }\n\n private readonly _root: string;\n private readonly _options: HostedAssetSourceOptions;\n\n /**\n * Creates a hosted source for {@link AssetLoader.addSource}.\n * Set `options.retryDefaults` to `false` to restrict lookups to the requested namespace and root.\n */\n public constructor(root: string, options?: Partial<HostedAssetSourceOptions>) {\n super();\n this._root = root;\n this._options = merge({}, DEFAULT_OPTIONS, options ?? {});\n }\n\n public get root(): string {\n return this._root;\n }\n\n public get cacheId(): string {\n return `hosted:${this._root}`;\n }\n\n public get options(): HostedAssetSourceOptions {\n return this._options;\n }\n\n public get<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser): Promise<Maybe<T>> {\n const responseParser = HostedAssetSource.PARSER_MAP.get(parser) as ResponseParser<T>;\n if (this.options.retryDefaults && !(key.rootType === undefined && key.namespace === \"minerender-data\")) {\n return this.loadOrRetryWithDefaults(key, responseParser);\n }\n return this.load(key, responseParser);\n }\n\n}\n\ninterface HostedAssetSourceOptions {\n retryDefaults: boolean;\n}\n\n/** Encoded asset bytes loaded without JSON or image decoding. */\nexport interface BinaryAsset extends MinecraftAsset {\n data: Uint8Array;\n}\n"],"mappings":"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","names":[]}
@@ -7,6 +7,7 @@ var AssetParser = /* @__PURE__ */ ((AssetParser2) => {
7
7
  AssetParser2["IMAGE"] = "image";
8
8
  AssetParser2["LIST"] = "list";
9
9
  AssetParser2["JSON"] = "json";
10
+ AssetParser2["BINARY"] = "binary";
10
11
  return AssetParser2;
11
12
  })(AssetParser || {});
12
13
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../src/assets/source/parser/AssetParsers.ts"],"sourcesContent":["export enum AssetParser {\n\n MODEL = \"model\",\n BLOCKSTATE = \"blockstate\",\n META = \"meta\",\n NBT = \"nbt\",\n IMAGE = \"image\",\n LIST = \"list\",\n JSON = \"json\",\n\n}"],"mappings":";AAAO,IAAK,cAAL,kBAAKA,iBAAL;AAEH,EAAAA,aAAA,WAAQ;AACR,EAAAA,aAAA,gBAAa;AACb,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,SAAM;AACN,EAAAA,aAAA,WAAQ;AACR,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,UAAO;AARC,SAAAA;AAAA,GAAA;","names":["AssetParser"]}
1
+ {"version":3,"sources":["../../../../../../src/assets/source/parser/AssetParsers.ts"],"sourcesContent":["export enum AssetParser {\n\n MODEL = \"model\",\n BLOCKSTATE = \"blockstate\",\n META = \"meta\",\n NBT = \"nbt\",\n IMAGE = \"image\",\n LIST = \"list\",\n JSON = \"json\",\n BINARY = \"binary\",\n\n}\n"],"mappings":";AAAO,IAAK,cAAL,kBAAKA,iBAAL;AAEH,EAAAA,aAAA,WAAQ;AACR,EAAAA,aAAA,gBAAa;AACb,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,SAAM;AACN,EAAAA,aAAA,WAAQ;AACR,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,YAAS;AATD,SAAAA;AAAA,GAAA;","names":["AssetParser"]}
@@ -33,6 +33,7 @@ var _Caching = class _Caching {
33
33
  this.entityAnimationCache,
34
34
  this.blockEntityIndexCache,
35
35
  this.fontCache,
36
+ this.unihexCache,
36
37
  this.bannerPatternCache,
37
38
  this.mineRenderDataCache,
38
39
  this.usernameUuidCache,
@@ -86,6 +87,7 @@ _Caching.entityModelCache = _Caching.createAssetCache();
86
87
  _Caching.entityTextureCache = _Caching.createAssetCache();
87
88
  _Caching.entityAnimationCache = _Caching.createAssetCache();
88
89
  _Caching.blockEntityIndexCache = _Caching.createAssetCache();
90
+ _Caching.unihexCache = _Caching.createAssetCache();
89
91
  _Caching.fontCache = _Caching.createAssetCache();
90
92
  _Caching.bannerPatternCache = _Caching.createAssetCache();
91
93
  _Caching.mineRenderDataCache = _Caching.createAssetCache();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/cache/Caching.ts"],"sourcesContent":["import { AsyncLoadingCache, Caches, Loader, LoadingCache, SimpleCache } from \"@inventivetalent/loading-cache\";\nimport { BoxGeometryKey, CacheKey, serializeBoxGeometryKey, serializeImageKey, TextureKey } from \"./CacheKey\";\nimport { Time } from \"@inventivetalent/time\";\nimport { ImageInfo, ImageLoader } from \"../image/ImageLoader\";\nimport { BoxGeometry, Material, Mesh, PixelFormat, RGBAFormat, Texture } from \"three\";\nimport { Materials } from \"../Materials\";\nimport { CompatImage } from \"../canvas/CanvasCompat\";\nimport { Model, TextureAsset } from \"../model/Model\";\nimport { WrappedImage } from \"../WrappedImage\";\nimport { TextureAtlas } from \"../texture/TextureAtlas\";\nimport { ExtractableImageData } from \"../ExtractableImageData\";\nimport { MinecraftTextureMeta } from \"../MinecraftTextureMeta\";\nimport type { EntityModelFile } from \"../entity/EntityModel\";\nimport type { EntityAnimationFile } from \"../entity/EntityAnimation\";\nimport type { BlockEntityIndex } from \"../assets/BlockEntities\";\nimport type { ListAsset } from \"../ListAsset\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport type { AssetKey } from \"../assets/AssetKey\";\nimport type { BitmapFont } from \"../assets/Fonts\";\nimport type { BannerPattern } from \"../assets/BannerPatterns\";\nimport type { Biome } from \"../assets/Biomes\";\n\n/** Shared in-memory caches for loaded assets and render resources. Persistent stores are managed separately. */\nexport class Caching {\n\n private static _generation = 0;\n\n /** Changes when shared assets are cleared, so derived caches can discard their old values. */\n public static get generation(): number { return this._generation; }\n\n static readonly rawImageCache: AsyncLoadingCache<CacheKey, ImageInfo> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(5))\n .buildAsync<CacheKey, ImageInfo>();\n static readonly imageDataCache: AsyncLoadingCache<CacheKey, ImageData> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, ImageData>();\n static readonly canvasImageDataCache: AsyncLoadingCache<CacheKey, ExtractableImageData> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, ExtractableImageData>();\n static readonly wrappedImageCache: AsyncLoadingCache<CacheKey, WrappedImage> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, WrappedImage>();\n\n static readonly boxGeometryCache: SimpleCache<CacheKey, BoxGeometry> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(20))\n .build<CacheKey, BoxGeometry>();\n\n static readonly textureCache: SimpleCache<CacheKey, Texture> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Texture>();\n\n static readonly materialCache: SimpleCache<CacheKey, Material> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Material>();\n\n static readonly boxMeshCache: SimpleCache<CacheKey, Mesh> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Mesh>();\n\n static readonly textureAssetCache: AsyncLoadingCache<CacheKey, TextureAsset> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, TextureAsset>();\n static readonly textureMetaCache: AsyncLoadingCache<CacheKey, MinecraftTextureMeta> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, MinecraftTextureMeta>();\n\n static readonly rawModelCache: AsyncLoadingCache<CacheKey, Model> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, Model>();\n static readonly mergedModelCache: AsyncLoadingCache<CacheKey, Model> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, Model>();\n static readonly modelTextureAtlasCache: AsyncLoadingCache<CacheKey, TextureAtlas> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, TextureAtlas>();\n\n static readonly blockStateCache: AsyncLoadingCache<CacheKey, BlockState> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, BlockState>();\n\n static readonly listAssetCache: AsyncLoadingCache<CacheKey, ListAsset> = Caching.createAssetCache<ListAsset>();\n\n static readonly blockTintCache: AsyncLoadingCache<CacheKey, number> = Caching.createAssetCache<number>();\n\n static readonly entityModelCache: AsyncLoadingCache<CacheKey, EntityModelFile> = Caching.createAssetCache<EntityModelFile>();\n\n static readonly entityTextureCache: AsyncLoadingCache<CacheKey, AssetKey> = Caching.createAssetCache<AssetKey>();\n\n static readonly entityAnimationCache: AsyncLoadingCache<CacheKey, EntityAnimationFile> = Caching.createAssetCache<EntityAnimationFile>();\n static readonly blockEntityIndexCache: AsyncLoadingCache<CacheKey, BlockEntityIndex> = Caching.createAssetCache<BlockEntityIndex>();\n static readonly fontCache: AsyncLoadingCache<CacheKey, BitmapFont> = Caching.createAssetCache<BitmapFont>();\n static readonly bannerPatternCache: AsyncLoadingCache<CacheKey, BannerPattern> = Caching.createAssetCache<BannerPattern>();\n static readonly mineRenderDataCache: AsyncLoadingCache<CacheKey, unknown> = Caching.createAssetCache<unknown>();\n static readonly usernameUuidCache: AsyncLoadingCache<CacheKey, string> = Caches.builder()\n .expireAfterWrite(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, string>();\n static readonly biomeCache: AsyncLoadingCache<CacheKey, Biome> = Caching.createAssetCache<Biome>();\n\n private static createAssetCache<T>(): AsyncLoadingCache<CacheKey, T> {\n return Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, T>();\n }\n\n\n /** Every cache above, so clear()/end() can never fall out of sync with the field list again. */\n private static get all(): { invalidateAll(): void; end(): void }[] {\n return [\n this.rawImageCache,\n this.imageDataCache,\n this.canvasImageDataCache,\n this.wrappedImageCache,\n this.boxGeometryCache,\n this.textureCache,\n this.materialCache,\n this.boxMeshCache,\n this.textureAssetCache,\n this.textureMetaCache,\n this.rawModelCache,\n this.mergedModelCache,\n this.modelTextureAtlasCache,\n this.blockStateCache,\n this.listAssetCache,\n this.blockTintCache,\n this.entityModelCache,\n this.entityTextureCache,\n this.entityAnimationCache,\n this.blockEntityIndexCache,\n this.fontCache,\n this.bannerPatternCache,\n this.mineRenderDataCache,\n this.usernameUuidCache,\n this.biomeCache\n ];\n }\n\n /** Invalidates in-memory entries so later lookups reload them. Persisted entries are retained. */\n public static clear() {\n this._generation++;\n for (const cache of this.all) {\n cache.invalidateAll();\n }\n }\n\n /**\n * Clears every cache and stops its expiry timer.\n *\n * Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.\n * Use {@link shutdown} to also stop requests and the shared Ticker.\n */\n public static end() {\n this._generation++;\n for (const cache of this.all) {\n cache.invalidateAll();\n cache.end();\n }\n }\n\n public static get cacheSizes() {\n return {\n //TODO\n }\n }\n\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/cache/Caching.ts"],"sourcesContent":["import { AsyncLoadingCache, Caches, Loader, LoadingCache, SimpleCache } from \"@inventivetalent/loading-cache\";\nimport { BoxGeometryKey, CacheKey, serializeBoxGeometryKey, serializeImageKey, TextureKey } from \"./CacheKey\";\nimport { Time } from \"@inventivetalent/time\";\nimport { ImageInfo, ImageLoader } from \"../image/ImageLoader\";\nimport { BoxGeometry, Material, Mesh, PixelFormat, RGBAFormat, Texture } from \"three\";\nimport { Materials } from \"../Materials\";\nimport { CompatImage } from \"../canvas/CanvasCompat\";\nimport { Model, TextureAsset } from \"../model/Model\";\nimport { WrappedImage } from \"../WrappedImage\";\nimport { TextureAtlas } from \"../texture/TextureAtlas\";\nimport { ExtractableImageData } from \"../ExtractableImageData\";\nimport { MinecraftTextureMeta } from \"../MinecraftTextureMeta\";\nimport type { EntityModelFile } from \"../entity/EntityModel\";\nimport type { EntityAnimationFile } from \"../entity/EntityAnimation\";\nimport type { BlockEntityIndex } from \"../assets/BlockEntities\";\nimport type { ListAsset } from \"../ListAsset\";\nimport { BlockState } from \"../model/block/BlockState\";\nimport type { AssetKey } from \"../assets/AssetKey\";\nimport type { UnihexFile } from \"../assets/_fonts/Unihex\";\nimport type { BitmapFont } from \"../assets/Fonts\";\nimport type { BannerPattern } from \"../assets/BannerPatterns\";\nimport type { Biome } from \"../assets/Biomes\";\n\n/** Shared in-memory caches for loaded assets and render resources. Persistent stores are managed separately. */\nexport class Caching {\n\n private static _generation = 0;\n\n /** Changes when shared assets are cleared, so derived caches can discard their old values. */\n public static get generation(): number { return this._generation; }\n\n static readonly rawImageCache: AsyncLoadingCache<CacheKey, ImageInfo> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(5))\n .buildAsync<CacheKey, ImageInfo>();\n static readonly imageDataCache: AsyncLoadingCache<CacheKey, ImageData> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, ImageData>();\n static readonly canvasImageDataCache: AsyncLoadingCache<CacheKey, ExtractableImageData> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, ExtractableImageData>();\n static readonly wrappedImageCache: AsyncLoadingCache<CacheKey, WrappedImage> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(10))\n .buildAsync<CacheKey, WrappedImage>();\n\n static readonly boxGeometryCache: SimpleCache<CacheKey, BoxGeometry> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(20))\n .build<CacheKey, BoxGeometry>();\n\n static readonly textureCache: SimpleCache<CacheKey, Texture> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Texture>();\n\n static readonly materialCache: SimpleCache<CacheKey, Material> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Material>();\n\n static readonly boxMeshCache: SimpleCache<CacheKey, Mesh> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .build<CacheKey, Mesh>();\n\n static readonly textureAssetCache: AsyncLoadingCache<CacheKey, TextureAsset> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, TextureAsset>();\n static readonly textureMetaCache: AsyncLoadingCache<CacheKey, MinecraftTextureMeta> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, MinecraftTextureMeta>();\n\n static readonly rawModelCache: AsyncLoadingCache<CacheKey, Model> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, Model>();\n static readonly mergedModelCache: AsyncLoadingCache<CacheKey, Model> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, Model>();\n static readonly modelTextureAtlasCache: AsyncLoadingCache<CacheKey, TextureAtlas> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, TextureAtlas>();\n\n static readonly blockStateCache: AsyncLoadingCache<CacheKey, BlockState> = Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, BlockState>();\n\n static readonly listAssetCache: AsyncLoadingCache<CacheKey, ListAsset> = Caching.createAssetCache<ListAsset>();\n\n static readonly blockTintCache: AsyncLoadingCache<CacheKey, number> = Caching.createAssetCache<number>();\n\n static readonly entityModelCache: AsyncLoadingCache<CacheKey, EntityModelFile> = Caching.createAssetCache<EntityModelFile>();\n\n static readonly entityTextureCache: AsyncLoadingCache<CacheKey, AssetKey> = Caching.createAssetCache<AssetKey>();\n\n static readonly entityAnimationCache: AsyncLoadingCache<CacheKey, EntityAnimationFile> = Caching.createAssetCache<EntityAnimationFile>();\n static readonly blockEntityIndexCache: AsyncLoadingCache<CacheKey, BlockEntityIndex> = Caching.createAssetCache<BlockEntityIndex>();\n static readonly unihexCache: AsyncLoadingCache<CacheKey, UnihexFile> = Caching.createAssetCache<UnihexFile>();\n static readonly fontCache: AsyncLoadingCache<CacheKey, BitmapFont> = Caching.createAssetCache<BitmapFont>();\n static readonly bannerPatternCache: AsyncLoadingCache<CacheKey, BannerPattern> = Caching.createAssetCache<BannerPattern>();\n static readonly mineRenderDataCache: AsyncLoadingCache<CacheKey, unknown> = Caching.createAssetCache<unknown>();\n static readonly usernameUuidCache: AsyncLoadingCache<CacheKey, string> = Caches.builder()\n .expireAfterWrite(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, string>();\n static readonly biomeCache: AsyncLoadingCache<CacheKey, Biome> = Caching.createAssetCache<Biome>();\n\n private static createAssetCache<T>(): AsyncLoadingCache<CacheKey, T> {\n return Caches.builder()\n .expireAfterWrite(Time.minutes(10))\n .expireAfterAccess(Time.minutes(5))\n .expirationInterval(Time.seconds(30))\n .buildAsync<CacheKey, T>();\n }\n\n\n /** Every cache above, so clear()/end() can never fall out of sync with the field list again. */\n private static get all(): { invalidateAll(): void; end(): void }[] {\n return [\n this.rawImageCache,\n this.imageDataCache,\n this.canvasImageDataCache,\n this.wrappedImageCache,\n this.boxGeometryCache,\n this.textureCache,\n this.materialCache,\n this.boxMeshCache,\n this.textureAssetCache,\n this.textureMetaCache,\n this.rawModelCache,\n this.mergedModelCache,\n this.modelTextureAtlasCache,\n this.blockStateCache,\n this.listAssetCache,\n this.blockTintCache,\n this.entityModelCache,\n this.entityTextureCache,\n this.entityAnimationCache,\n this.blockEntityIndexCache,\n this.fontCache,\n this.unihexCache,\n this.bannerPatternCache,\n this.mineRenderDataCache,\n this.usernameUuidCache,\n this.biomeCache\n ];\n }\n\n /** Invalidates in-memory entries so later lookups reload them. Persisted entries are retained. */\n public static clear() {\n this._generation++;\n for (const cache of this.all) {\n cache.invalidateAll();\n }\n }\n\n /**\n * Clears every cache and stops its expiry timer.\n *\n * Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.\n * Use {@link shutdown} to also stop requests and the shared Ticker.\n */\n public static end() {\n this._generation++;\n for (const cache of this.all) {\n cache.invalidateAll();\n cache.end();\n }\n }\n\n public static get cacheSizes() {\n return {\n //TODO\n }\n }\n\n}\n"],"mappings":"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","names":[]}
@@ -1,16 +1,24 @@
1
1
  // src/entity/scene/EntityAnimationPlayer.ts
2
2
  import { Euler, Vector3 } from "three";
3
- import { sampleEntityAnimation } from "../EntityAnimation.mjs";
3
+ import { ENTITY_ANIMATION_CHANNELS, sampleEntityAnimation } from "../EntityAnimation.mjs";
4
4
  var ZERO = [0, 0, 0];
5
5
  var EntityAnimationPlayer = class {
6
6
  constructor() {
7
7
  this.parts = [];
8
+ this._animations = [];
9
+ this._weights = [];
10
+ this.loops = [];
8
11
  this._time = 0;
9
- this.loop = false;
10
12
  this.speed = 1;
11
13
  }
12
14
  get animation() {
13
- return this._animation;
15
+ return this._animations[0];
16
+ }
17
+ get animations() {
18
+ return this._animations.slice();
19
+ }
20
+ get weights() {
21
+ return this._weights.slice();
14
22
  }
15
23
  get time() {
16
24
  return this._time;
@@ -20,10 +28,20 @@ var EntityAnimationPlayer = class {
20
28
  * without them, the current pose is used. Stopping restores the pose from before playback.
21
29
  */
22
30
  play(layers, animation, options = {}, poses) {
31
+ this.playAnimations(layers, [animation], options, poses);
32
+ }
33
+ /**
34
+ * Starts clips on matching parts with a shared clock. Weighted offsets add to the supplied baked poses
35
+ * or, without poses, to each animated part's pose when playback starts.
36
+ */
37
+ playAnimations(layers, animations, options = {}, poses) {
38
+ const weights = validateAnimationWeights(options.weights ?? animations.map(() => 1), animations.length);
23
39
  this.stop();
24
- this._animation = animation;
40
+ this._animations = animations.slice();
41
+ this._weights = weights;
42
+ if (!animations.length) return;
25
43
  this._time = options.time ?? 0;
26
- this.loop = options.loop ?? animation.loop;
44
+ this.loops = animations.map((animation) => options.loop ?? animation.loop);
27
45
  this.speed = options.speed ?? 1;
28
46
  for (const layer of layers) {
29
47
  const objects = [];
@@ -32,7 +50,8 @@ var EntityAnimationPlayer = class {
32
50
  if (poses.has(object)) objects.push(object);
33
51
  });
34
52
  } else {
35
- for (const bone of Object.keys(animation.bones)) {
53
+ const bones = new Set(animations.flatMap((animation) => Object.keys(animation.bones)));
54
+ for (const bone of bones) {
36
55
  const object = layer.getObjectByName(`group:${bone}`);
37
56
  if (object) objects.push(object);
38
57
  }
@@ -56,7 +75,7 @@ var EntityAnimationPlayer = class {
56
75
  }
57
76
  /** Restores the poses from before playback. Returns whether an animation was active. */
58
77
  stop() {
59
- if (!this._animation) return false;
78
+ if (!this._animations.length) return false;
60
79
  for (const part of this.parts) {
61
80
  part.object.position.copy(part.position);
62
81
  part.object.rotation.copy(part.rotation);
@@ -68,12 +87,14 @@ var EntityAnimationPlayer = class {
68
87
  /** Forgets the animation without touching the parts, for parts that no longer exist. */
69
88
  clear() {
70
89
  this.parts = [];
71
- this._animation = void 0;
90
+ this._animations = [];
91
+ this._weights = [];
92
+ this.loops = [];
72
93
  this._time = 0;
73
94
  }
74
95
  /** Applies the pose at an absolute playback time. Returns `false` when no clip is active. */
75
96
  setTime(seconds) {
76
- if (!this._animation) return false;
97
+ if (!this._animations.length) return false;
77
98
  this._time = seconds;
78
99
  this.apply();
79
100
  return true;
@@ -82,8 +103,30 @@ var EntityAnimationPlayer = class {
82
103
  advance(deltaSeconds) {
83
104
  return this.setTime(this._time + deltaSeconds * this.speed);
84
105
  }
106
+ /** Changes weights in clip order and reapplies the current time without restarting playback. */
107
+ setWeights(weights) {
108
+ if (!this._animations.length) return false;
109
+ const validated = validateAnimationWeights(weights, this._animations.length);
110
+ this._weights = validated;
111
+ this.apply();
112
+ return true;
113
+ }
85
114
  apply() {
86
- const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
115
+ const pose = /* @__PURE__ */ Object.create(null);
116
+ for (let i = 0; i < this._animations.length; i++) {
117
+ const weight = this._weights[i];
118
+ if (weight === 0) continue;
119
+ const sampled = sampleEntityAnimation(this._animations[i], this._time, this.loops[i]);
120
+ for (const [bone, channels] of Object.entries(sampled)) {
121
+ const blended = pose[bone] ?? (pose[bone] = {});
122
+ for (const channel of ENTITY_ANIMATION_CHANNELS) {
123
+ const value = channels[channel];
124
+ if (!value) continue;
125
+ const target = blended[channel] ?? (blended[channel] = [0, 0, 0]);
126
+ for (let axis = 0; axis < 3; axis++) target[axis] += value[axis] * weight;
127
+ }
128
+ }
129
+ }
87
130
  for (const part of this.parts) {
88
131
  const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone] ?? {};
89
132
  part.object.position.set(part.basePosition.x + position[0], part.basePosition.y + position[1], part.basePosition.z + position[2]);
@@ -92,7 +135,15 @@ var EntityAnimationPlayer = class {
92
135
  }
93
136
  }
94
137
  };
138
+ function validateAnimationWeights(weights, count) {
139
+ const values = Array.from(weights);
140
+ if (values.length !== count || values.some((weight) => !Number.isFinite(weight) || weight < 0)) {
141
+ throw new Error("Animation weights must match the clip count and contain only finite nonnegative numbers");
142
+ }
143
+ return values;
144
+ }
95
145
  export {
96
- EntityAnimationPlayer
146
+ EntityAnimationPlayer,
147
+ validateAnimationWeights
97
148
  };
98
149
  //# sourceMappingURL=EntityAnimationPlayer.mjs.map