@nodecraft/rendermite 1.6.1 → 1.6.2
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/{block-entities-xv3bQpEX.js → block-entities-XAynAVUE.js} +1 -1
- package/dist/blocks/block-entities.js +1 -1
- package/dist/blocks/cli.js +1 -1
- package/dist/blocks/entities.js +1 -1
- package/dist/blocks/entity-models.js +1 -1
- package/dist/blocks/export.js +1 -1
- package/dist/{cli-D2KJc_yl.js → cli-Br0mY0LV.js} +2 -2
- package/dist/cli.js +2 -2
- package/dist/entities/inherit.js +1 -1
- package/dist/entities/jar-classes.js +1 -1
- package/dist/entities/merge.d.ts +16 -1
- package/dist/entities/merge.js +2 -2
- package/dist/entities/model-bytecode.js +1 -1
- package/dist/{entities-DvmA9fEV.js → entities-DubtdM11.js} +6 -2
- package/dist/{entity-fallback-Bth0fa7m.js → entity-fallback-BcJWh91-.js} +1 -1
- package/dist/{entity-models-_EZ3PVtN.js → entity-models-D_QGok9j.js} +1 -1
- package/dist/{entity-textures-DFRIVdF1.js → entity-textures-4XXT8jVI.js} +25 -2
- package/dist/{export-BfEIwSxY.js → export-CTKEwro6.js} +3 -3
- package/dist/index.js +2 -2
- package/dist/{inherit-ByHjOJX3.js → inherit-C5Ifg3SM.js} +3 -3
- package/dist/{jar-classes-DCtELr1i.js → jar-classes-3GVCJZT7.js} +13 -3
- package/dist/merge-DeHruviG.js +109 -0
- package/dist/{model-bytecode-gWy5_uCj.js → model-bytecode-BQKCLPze.js} +139 -37
- package/dist/{pipeline-BUIMzMzg.js → pipeline-7rvL6vx1.js} +1 -1
- package/dist/render/entity-fallback.js +1 -1
- package/dist/render/pipeline.js +1 -1
- package/dist/resources/entity-textures.d.ts +13 -1
- package/dist/resources/entity-textures.js +2 -2
- package/dist/{run-BQJkqc5f.js → run-BXAqZ5qY.js} +1 -1
- package/dist/run.js +1 -1
- package/dist/workers/render-worker.js +1 -1
- package/package.json +1 -1
- package/dist/merge-NDYxpmL8.js +0 -48
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as ResourceLocator } from "./locator-COMEtEn9.js";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as findBedTexture, c as findFluidSibling, i as coversSheet, l as findFluidStill, n as HEAD_LAYOUTS, o as findChestTexture, s as findEntityTexture, t as DYE_COLORS, u as findMobTexture } from "./entity-textures-4XXT8jVI.js";
|
|
3
3
|
//#region src/blocks/block-entities.ts
|
|
4
4
|
/**
|
|
5
5
|
* Geometry for blocks the game draws from Java rather than from a model.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as blockEntityGeometry, r as synthesizeVariants, t as INVISIBLE_BLOCKS } from "../block-entities-
|
|
1
|
+
import { n as blockEntityGeometry, r as synthesizeVariants, t as INVISIBLE_BLOCKS } from "../block-entities-XAynAVUE.js";
|
|
2
2
|
export { INVISIBLE_BLOCKS, blockEntityGeometry, synthesizeVariants };
|
package/dist/blocks/cli.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as runBlocksCli } from "../cli-
|
|
1
|
+
import { t as runBlocksCli } from "../cli-Br0mY0LV.js";
|
|
2
2
|
export { runBlocksCli };
|
package/dist/blocks/entities.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as entityTypesOf, t as collectEntities } from "../entities-
|
|
1
|
+
import { n as entityTypesOf, t as collectEntities } from "../entities-DubtdM11.js";
|
|
2
2
|
export { collectEntities, entityTypesOf };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as collectEntityGeometry } from "../entity-models-
|
|
1
|
+
import { t as collectEntityGeometry } from "../entity-models-D_QGok9j.js";
|
|
2
2
|
export { collectEntityGeometry };
|
package/dist/blocks/export.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as exportBlockPack } from "../export-
|
|
1
|
+
import { t as exportBlockPack } from "../export-CTKEwro6.js";
|
|
2
2
|
export { exportBlockPack };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as builtinPackPath } from "./builtin-WkWjATeh.js";
|
|
2
2
|
import { n as LayeredResourceManager, t as FolderResourceManager } from "./manager-BNibYkmI.js";
|
|
3
|
-
import { t as exportBlockPack } from "./export-
|
|
4
|
-
import { n as layeredClasses, t as JarClassReader } from "./jar-classes-
|
|
3
|
+
import { t as exportBlockPack } from "./export-CTKEwro6.js";
|
|
4
|
+
import { n as layeredClasses, t as JarClassReader } from "./jar-classes-3GVCJZT7.js";
|
|
5
5
|
import { n as prepareModResources } from "./prepare-Myd_ec4v.js";
|
|
6
6
|
import { t as downloadClientJar } from "./download-1wAfrGKx.js";
|
|
7
7
|
import { a as prepareVersionResources, r as compareVersions } from "./prepare-D49Gu4Lv.js";
|
package/dist/cli.js
CHANGED
|
@@ -6,8 +6,8 @@ import { t as curatedModelOverrides } from "./models-CZjCOjs4.js";
|
|
|
6
6
|
import { n as harvestTintOverrides, t as curatedTintOverrides } from "./tints-BspVCz2G.js";
|
|
7
7
|
import { t as downloadClientJar } from "./download-1wAfrGKx.js";
|
|
8
8
|
import { a as prepareVersionResources, i as eraForVersion, n as GEOMETRY_DONOR_VERSIONS } from "./prepare-D49Gu4Lv.js";
|
|
9
|
-
import { t as runBlocksCli } from "./cli-
|
|
10
|
-
import { t as run } from "./run-
|
|
9
|
+
import { t as runBlocksCli } from "./cli-Br0mY0LV.js";
|
|
10
|
+
import { t as run } from "./run-BXAqZ5qY.js";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import os from "node:os";
|
|
13
13
|
import { parseArgs } from "node:util";
|
package/dist/entities/inherit.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as extractInheritedModel, t as ancestryOf } from "../inherit-
|
|
1
|
+
import { n as extractInheritedModel, t as ancestryOf } from "../inherit-C5Ifg3SM.js";
|
|
2
2
|
export { ancestryOf, extractInheritedModel };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as layeredClasses, t as JarClassReader } from "../jar-classes-
|
|
1
|
+
import { n as layeredClasses, t as JarClassReader } from "../jar-classes-3GVCJZT7.js";
|
|
2
2
|
export { JarClassReader, layeredClasses };
|
package/dist/entities/merge.d.ts
CHANGED
|
@@ -12,7 +12,22 @@ declare function slotsOf(parts: Part[]): {
|
|
|
12
12
|
declare function buildsOwnMesh(model: ExtractedModel): boolean;
|
|
13
13
|
/** `base` plus the parts of `extra` that `base` does not name. */
|
|
14
14
|
declare function mergeModels(base: ExtractedModel, extra: ExtractedModel): ExtractedModel;
|
|
15
|
+
/**
|
|
16
|
+
* Drops boxes that land exactly where one already is.
|
|
17
|
+
*
|
|
18
|
+
* A model builder's branches are all taken, because they turn on a constructor argument this cannot
|
|
19
|
+
* know — a `CubeDeformation`, a baby-variant flag — so a model that builds one shape *or* another
|
|
20
|
+
* emits both. Where the two arms differ, that is the honest answer and the model says so in a note.
|
|
21
|
+
* Where they agree, it is four legs drawn twice in the same place: `HorseModel` builds
|
|
22
|
+
* `left_hind_leg` and `left_hind_baby_leg` at identical coordinates, and two coplanar boxes are
|
|
23
|
+
* exactly what z-fighting is.
|
|
24
|
+
*
|
|
25
|
+
* Keyed on the accumulated pivot and rotation rather than on evaluated corners, since duplicates come
|
|
26
|
+
* from one builder running twice and land on identical frames. The first is kept: a builder states the
|
|
27
|
+
* ordinary shape before the variant.
|
|
28
|
+
*/
|
|
29
|
+
declare function dedupeCubes(model: ExtractedModel): ExtractedModel;
|
|
15
30
|
declare function countCubes(part: Part): number;
|
|
16
31
|
declare function cubesOf(model: ExtractedModel): number;
|
|
17
32
|
//#endregion
|
|
18
|
-
export { buildsOwnMesh, countCubes, cubesOf, mergeModels, slotsOf };
|
|
33
|
+
export { buildsOwnMesh, countCubes, cubesOf, dedupeCubes, mergeModels, slotsOf };
|
package/dist/entities/merge.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { buildsOwnMesh, countCubes, cubesOf, mergeModels, slotsOf };
|
|
1
|
+
import { a as mergeModels, i as dedupeCubes, n as countCubes, o as slotsOf, r as cubesOf, t as buildsOwnMesh } from "../merge-DeHruviG.js";
|
|
2
|
+
export { buildsOwnMesh, countCubes, cubesOf, dedupeCubes, mergeModels, slotsOf };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as extractModel } from "../model-bytecode-
|
|
1
|
+
import { t as extractModel } from "../model-bytecode-BQKCLPze.js";
|
|
2
2
|
export { extractModel };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as ResourceLocator } from "./locator-COMEtEn9.js";
|
|
2
|
-
import {
|
|
2
|
+
import { d as isOverlayPath, f as tokens, u as findMobTexture } from "./entity-textures-4XXT8jVI.js";
|
|
3
3
|
//#region src/blocks/entities.ts
|
|
4
4
|
/**
|
|
5
5
|
* The entity registry, and one colour per entity.
|
|
@@ -125,13 +125,17 @@ async function findVariantTexture(resources, namespace, name) {
|
|
|
125
125
|
if (!locator.path.startsWith("entity/")) continue;
|
|
126
126
|
const leaf = locator.path.split("/").at(-1) ?? "";
|
|
127
127
|
if (tokens(leaf).some((token) => NOT_THE_MOB.has(token))) continue;
|
|
128
|
+
if (isOverlayPath(locator.path)) continue;
|
|
128
129
|
const candidate = tokens(locator.path);
|
|
129
130
|
let score = 0;
|
|
130
131
|
for (const token of wanted) if (candidate.includes(token)) score += 2;
|
|
131
132
|
if (squashed !== name && candidate.includes(squashed)) score += wanted.length * 2;
|
|
132
133
|
if (score === 0) continue;
|
|
134
|
+
const folder = locator.path.split("/").slice(1, -1);
|
|
135
|
+
const inFamily = folder.length > 0 && folder.flatMap((segment) => tokens(segment)).every((token) => wanted.includes(token));
|
|
136
|
+
const named = tokens(leaf).some((token) => wanted.includes(token));
|
|
133
137
|
const depth = locator.path.split("/").length;
|
|
134
|
-
score = score * 10 - depth - candidate.length;
|
|
138
|
+
score = (inFamily ? 1e3 : 0) + score * 10 + (named ? 5 : 0) - depth - candidate.length;
|
|
135
139
|
if (score > bestScore) {
|
|
136
140
|
best = locator;
|
|
137
141
|
bestScore = score;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as ResourceLocator } from "./locator-COMEtEn9.js";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as findBedTexture, f as tokens, i as coversSheet, n as HEAD_LAYOUTS, o as findChestTexture, s as findEntityTexture, t as DYE_COLORS, u as findMobTexture } from "./entity-textures-4XXT8jVI.js";
|
|
3
3
|
import { c as renderModel } from "./obj-CJHEHpki.js";
|
|
4
4
|
//#region src/render/entity-fallback.ts
|
|
5
5
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as findGeoForEntity } from "./entity-geo-B2CkuMWx.js";
|
|
2
|
-
import { n as extractInheritedModel } from "./inherit-
|
|
2
|
+
import { n as extractInheritedModel } from "./inherit-C5Ifg3SM.js";
|
|
3
3
|
import { a as linkEntityModel, i as classReader, r as buildModelNameIndex } from "./link-5GmBLTzk.js";
|
|
4
4
|
import { s as resolveMappings, t as MappingsUnavailableError } from "./mappings-BEPVaiwE.js";
|
|
5
5
|
import { n as loadModelCode } from "./model-code-1Vuk-zj_.js";
|
|
@@ -68,6 +68,29 @@ const HEAD_LAYOUTS = {
|
|
|
68
68
|
* live at entity/<mob>.png or entity/<mob>/<mob>.png depending on the mod, and a
|
|
69
69
|
* head only ever wants the base skin — never a blink or armour overlay.
|
|
70
70
|
*/
|
|
71
|
+
/**
|
|
72
|
+
* Directories that hold an *overlay* rather than a mob.
|
|
73
|
+
*
|
|
74
|
+
* Matched as whole path segments rather than as tokens, because a token would take `chest_boat` out
|
|
75
|
+
* along with `chest`. A trader llama is the case that needed it: its sheet is filed as
|
|
76
|
+
* `entity/llama/decor/trader_llama`, whose leaf is exactly the mob's name — so a search by name found
|
|
77
|
+
* the carpet it wears, which is a few opaque pixels on a transparent sheet, and the llama underneath
|
|
78
|
+
* came out invisible on most of its faces.
|
|
79
|
+
*/
|
|
80
|
+
const OVERLAY_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
81
|
+
"decor",
|
|
82
|
+
"armor",
|
|
83
|
+
"markings",
|
|
84
|
+
"glow",
|
|
85
|
+
"eyes",
|
|
86
|
+
"overlay",
|
|
87
|
+
"saddle",
|
|
88
|
+
"harness"
|
|
89
|
+
]);
|
|
90
|
+
/** Whether a texture is filed inside one of those, whatever the file itself is called. */
|
|
91
|
+
function isOverlayPath(path) {
|
|
92
|
+
return path.split("/").slice(0, -1).some((segment) => OVERLAY_DIRECTORIES.has(segment));
|
|
93
|
+
}
|
|
71
94
|
async function findMobTexture(resources, namespace, mob) {
|
|
72
95
|
for (const source of [namespace, "minecraft"]) {
|
|
73
96
|
for (const candidate of [`entity/${mob}`, `entity/${mob}/${mob}`]) {
|
|
@@ -77,7 +100,7 @@ async function findMobTexture(resources, namespace, mob) {
|
|
|
77
100
|
let best = null;
|
|
78
101
|
for (const locator of await resources.listResources("texture", source)) {
|
|
79
102
|
const leaf = locator.path.split("/").pop();
|
|
80
|
-
if (!locator.path.startsWith("entity/") || leaf !== mob) continue;
|
|
103
|
+
if (!locator.path.startsWith("entity/") || leaf !== mob || isOverlayPath(locator.path)) continue;
|
|
81
104
|
if (best === null || locator.path.length < best.path.length) best = locator;
|
|
82
105
|
}
|
|
83
106
|
if (best) return best;
|
|
@@ -206,4 +229,4 @@ async function findFluidSibling(resources, still, suffixes) {
|
|
|
206
229
|
return null;
|
|
207
230
|
}
|
|
208
231
|
//#endregion
|
|
209
|
-
export {
|
|
232
|
+
export { findBedTexture as a, findFluidSibling as c, isOverlayPath as d, tokens as f, coversSheet as i, findFluidStill as l, HEAD_LAYOUTS as n, findChestTexture as o, OVERLAY_DIRECTORIES as r, findEntityTexture as s, DYE_COLORS as t, findMobTexture as u };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { r as buildBiomeClimates } from "./biomes-5ZwYxMYe.js";
|
|
2
2
|
import { n as ResourceLocator } from "./locator-COMEtEn9.js";
|
|
3
|
-
import { n as blockEntityGeometry, r as synthesizeVariants, t as INVISIBLE_BLOCKS } from "./block-entities-
|
|
3
|
+
import { n as blockEntityGeometry, r as synthesizeVariants, t as INVISIBLE_BLOCKS } from "./block-entities-XAynAVUE.js";
|
|
4
4
|
import { a as parseBlockState, n as collectModels } from "./blockstate-eval-BRQ3NWY2.js";
|
|
5
|
-
import { t as collectEntities } from "./entities-
|
|
6
|
-
import { t as collectEntityGeometry } from "./entity-models-
|
|
5
|
+
import { t as collectEntities } from "./entities-DubtdM11.js";
|
|
6
|
+
import { t as collectEntityGeometry } from "./entity-models-D_QGok9j.js";
|
|
7
7
|
import { n as discoverItems } from "./discovery-CD0QqxSF.js";
|
|
8
8
|
import { a as salvageJson, i as resolveTexture, t as ModelLoader } from "./loader-C-NuJaEi.js";
|
|
9
9
|
import { t as collectItemSprites } from "./item-sprites-G-yikdfV.js";
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import { n as buildBlockTints, t as UNREGISTERED_TINTS } from "./tints-Cl0r-Ol3.
|
|
|
14
14
|
import { o as createAtlasResolver, s as parseAtlasSources, t as AtlasSourceError } from "./sources-BlUriDCs.js";
|
|
15
15
|
import { n as LayeredResourceManager, r as ResourceKind, t as FolderResourceManager } from "./manager-BNibYkmI.js";
|
|
16
16
|
import { n as TextureLoader, r as TextureResolutionError, t as AnimatedTexture } from "./loader-C18GpurU.js";
|
|
17
|
-
import { t as exportBlockPack } from "./export-
|
|
17
|
+
import { t as exportBlockPack } from "./export-CTKEwro6.js";
|
|
18
18
|
import { n as UnsafeJarError, r as isUnsafeEntryPath, t as JarResourceManager } from "./jar-W2cV2ZVO.js";
|
|
19
19
|
import { n as prepareModResources } from "./prepare-Myd_ec4v.js";
|
|
20
20
|
import { a as prepareVersionResources, i as eraForVersion, r as compareVersions } from "./prepare-D49Gu4Lv.js";
|
|
@@ -22,5 +22,5 @@ import { n as encodeIcon, t as encodeAnimatedIcon } from "./encode-LR9wxigC.js";
|
|
|
22
22
|
import { a as builtinDynamicResources } from "./generators-BCZVlWig.js";
|
|
23
23
|
import { t as minifyStylesheet } from "./minify-bjMRmr5J.js";
|
|
24
24
|
import { n as itemClass, t as generateStylesheet } from "./stylesheet-CovT3B2S.js";
|
|
25
|
-
import { t as run } from "./run-
|
|
25
|
+
import { t as run } from "./run-BXAqZ5qY.js";
|
|
26
26
|
export { AnimatedTexture, AtlasSourceError, BlockStateError, DEFAULT_WATER_COLOR, DYE_COLORS, FolderResourceManager, InvalidItemDefinitionError, InvalidResourceLocatorError, InvalidTinterDefinitionError, ItemRenderError, ItemResolutionError, JarResourceManager, LayeredResourceManager, LightingProfile, ModelLoader, ModelResolutionError, ObjMeshError, ResourceKind, ResourceLocator, TextureLoader, TextureResolutionError, UNKNOWN_MODEL, UNREGISTERED_TINTS, UnsafeJarError, VANILLA_BIOME_CLIMATES, boxDownscale, buildBiomeClimates, buildBlockTints, buildObjMesh, builtinDynamicResources, collectModels, compareVersions, createAtlasResolver, defaultProperties, discoverItems, encodeAnimatedIcon, encodeIcon, eraForVersion, evaluateBlockState, evaluateItemModel, exportBlockPack, generateStylesheet, isUnsafeEntryPath, itemClass, lightsForProfile, matchesCondition, minifyStylesheet, packAtlas, parseAtlasSources, parseBiomeClimate, parseBlockState, parseTintValue, pointResize, prepareModResources, prepareVersionResources, renderModel, renderModelFrames, resolveItem, resolveTexture, resolveTint, resolveTints, run, salvageJson, toByteTexture, toFloatTexture, weightedVariantIndex };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as parseClassFile } from "./classfile-Bo7FUrrD.js";
|
|
2
|
-
import {
|
|
3
|
-
import { t as extractModel } from "./model-bytecode-
|
|
2
|
+
import { a as mergeModels, i as dedupeCubes } from "./merge-DeHruviG.js";
|
|
3
|
+
import { t as extractModel } from "./model-bytecode-BQKCLPze.js";
|
|
4
4
|
//#region src/entities/inherit.ts
|
|
5
5
|
/**
|
|
6
6
|
* A model class read together with its ancestors.
|
|
@@ -71,7 +71,7 @@ async function extractInheritedModel(internalName, read, code) {
|
|
|
71
71
|
});
|
|
72
72
|
model = mergeModels(model, inheritedModel);
|
|
73
73
|
}
|
|
74
|
-
return model;
|
|
74
|
+
return dedupeCubes(model);
|
|
75
75
|
}
|
|
76
76
|
//#endregion
|
|
77
77
|
export { extractInheritedModel as n, ancestryOf as t };
|
|
@@ -25,18 +25,28 @@ function layeredClasses(sources) {
|
|
|
25
25
|
return {
|
|
26
26
|
list: async () => {
|
|
27
27
|
const names = /* @__PURE__ */ new Set();
|
|
28
|
-
for (const source of sources)
|
|
28
|
+
for (const source of sources) try {
|
|
29
|
+
for (const name of await source.list()) names.add(name);
|
|
30
|
+
} catch {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
29
33
|
return [...names];
|
|
30
34
|
},
|
|
31
35
|
read: async (internalName) => {
|
|
32
|
-
for (const source of sources) {
|
|
36
|
+
for (const source of sources) try {
|
|
33
37
|
const bytes = await source.read(internalName);
|
|
34
38
|
if (bytes) return bytes;
|
|
39
|
+
} catch {
|
|
40
|
+
continue;
|
|
35
41
|
}
|
|
36
42
|
return null;
|
|
37
43
|
},
|
|
38
44
|
close: async () => {
|
|
39
|
-
for (const source of sources)
|
|
45
|
+
for (const source of sources) try {
|
|
46
|
+
await source.close();
|
|
47
|
+
} catch {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
40
50
|
}
|
|
41
51
|
};
|
|
42
52
|
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
//#region src/entities/merge.ts
|
|
2
|
+
/** A root the interpreter had to invent, because a `MeshDefinition`'s root part is anonymous. */
|
|
3
|
+
const SYNTHETIC_ROOT = /^part\d+$/;
|
|
4
|
+
/**
|
|
5
|
+
* Where a piece's parts sit: at the top, or inside the one anonymous root a `MeshDefinition` makes.
|
|
6
|
+
* Both merge into the same list of named slots and only one of them is nested.
|
|
7
|
+
*/
|
|
8
|
+
function slotsOf(parts) {
|
|
9
|
+
const [only] = parts;
|
|
10
|
+
if (parts.length === 1 && only.cubes.length === 0 && SYNTHETIC_ROOT.test(only.name)) return {
|
|
11
|
+
container: only,
|
|
12
|
+
slots: only.children
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
container: null,
|
|
16
|
+
slots: parts
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** True when this piece built its own mesh rather than adding to one it was handed. */
|
|
20
|
+
function buildsOwnMesh(model) {
|
|
21
|
+
return slotsOf(model.parts).container !== null;
|
|
22
|
+
}
|
|
23
|
+
/** `base` plus the parts of `extra` that `base` does not name. */
|
|
24
|
+
function mergeModels(base, extra) {
|
|
25
|
+
const target = slotsOf(base.parts);
|
|
26
|
+
const source = slotsOf(extra.parts);
|
|
27
|
+
const named = new Set(target.slots.map((part) => part.name));
|
|
28
|
+
const missing = source.slots.filter((part) => !named.has(part.name));
|
|
29
|
+
if (missing.length === 0) return base;
|
|
30
|
+
const parts = target.container ? [{
|
|
31
|
+
...target.container,
|
|
32
|
+
children: [...target.container.children, ...missing]
|
|
33
|
+
}] : [...target.slots, ...missing];
|
|
34
|
+
const notes = [.../* @__PURE__ */ new Set([...base.notes, ...extra.notes])].filter((note) => parts.length > 1 || !note.includes("disconnected roots"));
|
|
35
|
+
return {
|
|
36
|
+
textureSize: base.textureSize[0] === 64 && base.textureSize[1] === 32 ? extra.textureSize : base.textureSize,
|
|
37
|
+
parts,
|
|
38
|
+
notes
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Drops boxes that land exactly where one already is.
|
|
43
|
+
*
|
|
44
|
+
* A model builder's branches are all taken, because they turn on a constructor argument this cannot
|
|
45
|
+
* know — a `CubeDeformation`, a baby-variant flag — so a model that builds one shape *or* another
|
|
46
|
+
* emits both. Where the two arms differ, that is the honest answer and the model says so in a note.
|
|
47
|
+
* Where they agree, it is four legs drawn twice in the same place: `HorseModel` builds
|
|
48
|
+
* `left_hind_leg` and `left_hind_baby_leg` at identical coordinates, and two coplanar boxes are
|
|
49
|
+
* exactly what z-fighting is.
|
|
50
|
+
*
|
|
51
|
+
* Keyed on the accumulated pivot and rotation rather than on evaluated corners, since duplicates come
|
|
52
|
+
* from one builder running twice and land on identical frames. The first is kept: a builder states the
|
|
53
|
+
* ordinary shape before the variant.
|
|
54
|
+
*/
|
|
55
|
+
function dedupeCubes(model) {
|
|
56
|
+
const seen = /* @__PURE__ */ new Set();
|
|
57
|
+
const round = (value) => value.toFixed(4);
|
|
58
|
+
const walk = (part, pivot, rotation) => {
|
|
59
|
+
const at = [
|
|
60
|
+
pivot[0] + part.pivot[0],
|
|
61
|
+
pivot[1] + part.pivot[1],
|
|
62
|
+
pivot[2] + part.pivot[2]
|
|
63
|
+
];
|
|
64
|
+
const spun = [
|
|
65
|
+
rotation[0] + part.rotation[0],
|
|
66
|
+
rotation[1] + part.rotation[1],
|
|
67
|
+
rotation[2] + part.rotation[2]
|
|
68
|
+
];
|
|
69
|
+
const cubes = part.cubes.filter((cube) => {
|
|
70
|
+
const key = [
|
|
71
|
+
...at.map(round),
|
|
72
|
+
...spun.map(round),
|
|
73
|
+
...cube.origin.map(round),
|
|
74
|
+
...cube.size.map(round),
|
|
75
|
+
...cube.uv.map(round),
|
|
76
|
+
round(cube.inflate)
|
|
77
|
+
].join("|");
|
|
78
|
+
if (seen.has(key)) return false;
|
|
79
|
+
seen.add(key);
|
|
80
|
+
return true;
|
|
81
|
+
});
|
|
82
|
+
const children = part.children.map((child) => walk(child, at, spun)).filter((child) => child.cubes.length > 0 || child.children.length > 0);
|
|
83
|
+
return {
|
|
84
|
+
...part,
|
|
85
|
+
cubes,
|
|
86
|
+
children
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
...model,
|
|
91
|
+
parts: model.parts.map((part) => walk(part, [
|
|
92
|
+
0,
|
|
93
|
+
0,
|
|
94
|
+
0
|
|
95
|
+
], [
|
|
96
|
+
0,
|
|
97
|
+
0,
|
|
98
|
+
0
|
|
99
|
+
])).filter((part) => part.cubes.length > 0 || part.children.length > 0)
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function countCubes(part) {
|
|
103
|
+
return part.cubes.length + part.children.reduce((total, child) => total + countCubes(child), 0);
|
|
104
|
+
}
|
|
105
|
+
function cubesOf(model) {
|
|
106
|
+
return model.parts.reduce((total, part) => total + countCubes(part), 0);
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
export { mergeModels as a, dedupeCubes as i, countCubes as n, slotsOf as o, cubesOf as r, buildsOwnMesh as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as parseClassFile } from "./classfile-Bo7FUrrD.js";
|
|
2
|
-
import {
|
|
2
|
+
import { a as mergeModels, r as cubesOf, t as buildsOwnMesh } from "./merge-DeHruviG.js";
|
|
3
3
|
//#region src/entities/model-bytecode.ts
|
|
4
4
|
/**
|
|
5
5
|
* Abstract interpretation of a boxy-model builder, enough to recover the geometry.
|
|
@@ -43,6 +43,28 @@ const NUMERIC = /* @__PURE__ */ new Set([
|
|
|
43
43
|
"B",
|
|
44
44
|
"C"
|
|
45
45
|
]);
|
|
46
|
+
/**
|
|
47
|
+
* Whether a conditional jump is taken, for the opcodes that compare numbers.
|
|
48
|
+
*
|
|
49
|
+
* The single-operand forms (`ifeq` … `ifle`) test against zero and the two-operand forms (`if_icmpeq`
|
|
50
|
+
* …) against each other, so both reduce to the sign of `left - right`.
|
|
51
|
+
*/
|
|
52
|
+
function compare(op, left, right) {
|
|
53
|
+
const difference = left - right;
|
|
54
|
+
switch (op) {
|
|
55
|
+
case 153:
|
|
56
|
+
case 159: return difference === 0;
|
|
57
|
+
case 154:
|
|
58
|
+
case 160: return difference !== 0;
|
|
59
|
+
case 155:
|
|
60
|
+
case 161: return difference < 0;
|
|
61
|
+
case 156:
|
|
62
|
+
case 162: return difference >= 0;
|
|
63
|
+
case 157:
|
|
64
|
+
case 163: return difference > 0;
|
|
65
|
+
default: return difference <= 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
46
68
|
/** Every entity sheet is a power of two, at least 16 in each direction. A texture offset rarely is. */
|
|
47
69
|
function isSheetSize(width, height) {
|
|
48
70
|
const power = (value) => value >= 16 && (value & value - 1) === 0;
|
|
@@ -109,6 +131,18 @@ const TEXTURE_HEIGHT_FIELDS = /* @__PURE__ */ new Set(["texHeight", "textureHeig
|
|
|
109
131
|
const MAX_INLINE_DEPTH = 5;
|
|
110
132
|
/** Frames per method. A model spends a handful; the cap is there so a strange jar cannot spend all day. */
|
|
111
133
|
const INLINE_BUDGET = 96;
|
|
134
|
+
/**
|
|
135
|
+
* Instructions per extraction, shared across every frame.
|
|
136
|
+
*
|
|
137
|
+
* A model builder is a few hundred instructions and the longest vanilla loop runs a few thousand, so
|
|
138
|
+
* this is two orders of magnitude of headroom — and it is what makes following a backward goto safe: a
|
|
139
|
+
* loop whose bound cannot be worked out stops here instead of spinning.
|
|
140
|
+
*/
|
|
141
|
+
const STEP_BUDGET = 2e5;
|
|
142
|
+
/** Elements tracked per array. A table of segment sizes is a handful; nothing here needs thousands. */
|
|
143
|
+
const MAX_ARRAY = 1024;
|
|
144
|
+
/** Times round a loop. Vanilla's longest builds sixteen segments, so this is generous by four times. */
|
|
145
|
+
const MAX_ITERATIONS = 64;
|
|
112
146
|
/** How far up a hierarchy to look for an inherited method, which is as deep as a model hierarchy goes. */
|
|
113
147
|
const MAX_METHOD_HOPS = 6;
|
|
114
148
|
function newShared(resolve) {
|
|
@@ -120,7 +154,10 @@ function newShared(resolve) {
|
|
|
120
154
|
branched: false,
|
|
121
155
|
nextHandle: 1,
|
|
122
156
|
resolve,
|
|
123
|
-
budget: INLINE_BUDGET
|
|
157
|
+
budget: INLINE_BUDGET,
|
|
158
|
+
statics: /* @__PURE__ */ new Map(),
|
|
159
|
+
initialised: /* @__PURE__ */ new Set(),
|
|
160
|
+
steps: STEP_BUDGET
|
|
124
161
|
};
|
|
125
162
|
}
|
|
126
163
|
/** The method a call names, looked up where the JVM would look: the owner, then up its ancestors. */
|
|
@@ -143,6 +180,8 @@ var Interpreter = class Interpreter {
|
|
|
143
180
|
locals = /* @__PURE__ */ new Map();
|
|
144
181
|
shared;
|
|
145
182
|
depth;
|
|
183
|
+
/** How many times each backward jump has been taken, so an undecidable loop cannot spin. */
|
|
184
|
+
loops = /* @__PURE__ */ new Map();
|
|
146
185
|
/** What this frame returned, for the caller that inlined it. */
|
|
147
186
|
returned = null;
|
|
148
187
|
constructor(shared, depth = 0) {
|
|
@@ -171,6 +210,19 @@ var Interpreter = class Interpreter {
|
|
|
171
210
|
}
|
|
172
211
|
}
|
|
173
212
|
/**
|
|
213
|
+
* Runs a class's `<clinit>` once, so its static tables can be read.
|
|
214
|
+
*
|
|
215
|
+
* Only for model code, and only once per class per extraction: the point is a table of numbers, and
|
|
216
|
+
* anything else a static initialiser does is of no interest here.
|
|
217
|
+
*/
|
|
218
|
+
initialise(owner) {
|
|
219
|
+
if (this.shared.initialised.has(owner) || this.depth >= MAX_INLINE_DEPTH) return;
|
|
220
|
+
this.shared.initialised.add(owner);
|
|
221
|
+
const target = findMethod(this.shared.resolve, owner, "<clinit>", "()V");
|
|
222
|
+
if (!target) return;
|
|
223
|
+
new Interpreter(this.shared, this.depth + 1).run(target.code, target.classFile);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
174
226
|
* Interprets a call into the model's own code, with the arguments it was actually given.
|
|
175
227
|
*
|
|
176
228
|
* This is what makes an inherited part come out right. `CowModel` calls `super(12, 0)` and the legs
|
|
@@ -189,6 +241,10 @@ var Interpreter = class Interpreter {
|
|
|
189
241
|
frame.seed(receiver, descriptor, args);
|
|
190
242
|
return frame.run(target.code, target.classFile) ? frame.returned : null;
|
|
191
243
|
}
|
|
244
|
+
/** Records a note once, since every candidate method would otherwise repeat it. */
|
|
245
|
+
note(message) {
|
|
246
|
+
if (!this.shared.notes.includes(message)) this.shared.notes.push(message);
|
|
247
|
+
}
|
|
192
248
|
pop() {
|
|
193
249
|
return this.stack.pop() ?? { kind: "unknown" };
|
|
194
250
|
}
|
|
@@ -218,6 +274,11 @@ var Interpreter = class Interpreter {
|
|
|
218
274
|
const first = named ? 1 : 0;
|
|
219
275
|
if (target && (named || floats >= 6 && args.length >= 6 && NUMERIC.has(args[0]) && NUMERIC.has(args[5]))) {
|
|
220
276
|
const extra = args.slice(first + 6);
|
|
277
|
+
const floatAt = extra.findIndex((arg) => arg === "F" || arg === "D");
|
|
278
|
+
const deformed = taken.find((value) => value.kind === "object" && value.handle.deformation !== void 0);
|
|
279
|
+
let inflate = target.pendingInflate;
|
|
280
|
+
if (floatAt !== -1) inflate = this.number(taken[first + 6 + floatAt]);
|
|
281
|
+
else if (deformed?.kind === "object") inflate = deformed.handle.deformation ?? 0;
|
|
221
282
|
target.cubes.push({
|
|
222
283
|
origin: [
|
|
223
284
|
numbers[first],
|
|
@@ -230,7 +291,7 @@ var Interpreter = class Interpreter {
|
|
|
230
291
|
numbers[first + 5]
|
|
231
292
|
],
|
|
232
293
|
uv: [...target.pendingUv],
|
|
233
|
-
inflate
|
|
294
|
+
inflate,
|
|
234
295
|
mirror: target.pendingMirror || extra.includes("Z") && this.number(taken[args.length - 1]) === 1
|
|
235
296
|
});
|
|
236
297
|
this.push(returns === "V" ? null : receiver);
|
|
@@ -348,6 +409,11 @@ var Interpreter = class Interpreter {
|
|
|
348
409
|
this.push(returns === "V" ? null : receiver);
|
|
349
410
|
return;
|
|
350
411
|
}
|
|
412
|
+
if (args.length === 0 && target && returns === `L${owner};`) {
|
|
413
|
+
target.pendingMirror = true;
|
|
414
|
+
this.push(receiver);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
351
417
|
if (args.length === 0 && returns.startsWith("L")) {
|
|
352
418
|
if (target) {
|
|
353
419
|
target.isRoot = true;
|
|
@@ -371,6 +437,10 @@ var Interpreter = class Interpreter {
|
|
|
371
437
|
run(code, constants) {
|
|
372
438
|
let at = 0;
|
|
373
439
|
while (at < code.length) {
|
|
440
|
+
if (this.shared.steps-- <= 0) {
|
|
441
|
+
this.note("ran past the step budget, so the shape is only as far as it got");
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
374
444
|
const op = code[at++];
|
|
375
445
|
switch (true) {
|
|
376
446
|
case op === 1:
|
|
@@ -443,9 +513,10 @@ var Interpreter = class Interpreter {
|
|
|
443
513
|
this.locals.set((op - 59) % 4, this.pop());
|
|
444
514
|
break;
|
|
445
515
|
case ARRAY_LOADS.has(op): {
|
|
446
|
-
this.pop();
|
|
516
|
+
const index = this.pop();
|
|
447
517
|
const array = this.pop();
|
|
448
|
-
|
|
518
|
+
const at = index.kind === "number" ? index.value : 0;
|
|
519
|
+
this.push(array.kind === "array" ? array.items[at] ?? { kind: "unknown" } : { kind: "unknown" });
|
|
449
520
|
break;
|
|
450
521
|
}
|
|
451
522
|
case op >= 120 && op <= 131:
|
|
@@ -465,18 +536,19 @@ var Interpreter = class Interpreter {
|
|
|
465
536
|
});
|
|
466
537
|
break;
|
|
467
538
|
case op === 191: return true;
|
|
468
|
-
case op === 190:
|
|
469
|
-
this.pop();
|
|
470
|
-
this.push({
|
|
539
|
+
case op === 190: {
|
|
540
|
+
const array = this.pop();
|
|
541
|
+
this.push(array.kind === "array" ? {
|
|
471
542
|
kind: "number",
|
|
472
|
-
value:
|
|
473
|
-
});
|
|
543
|
+
value: array.items.length
|
|
544
|
+
} : { kind: "unknown" });
|
|
474
545
|
break;
|
|
546
|
+
}
|
|
475
547
|
case ARRAY_STORES.has(op): {
|
|
476
548
|
const value = this.pop();
|
|
477
|
-
this.pop();
|
|
549
|
+
const index = this.pop();
|
|
478
550
|
const array = this.pop();
|
|
479
|
-
if (array.kind === "array") array.items.
|
|
551
|
+
if (array.kind === "array") array.items[index.kind === "number" ? index.value : array.items.length] = value;
|
|
480
552
|
break;
|
|
481
553
|
}
|
|
482
554
|
case op === 87:
|
|
@@ -531,20 +603,36 @@ var Interpreter = class Interpreter {
|
|
|
531
603
|
});
|
|
532
604
|
break;
|
|
533
605
|
case op >= 133 && op <= 147: break;
|
|
534
|
-
case op === 132:
|
|
606
|
+
case op === 132: {
|
|
607
|
+
const slot = code[at];
|
|
608
|
+
const step = code[at + 1] << 24 >> 24;
|
|
535
609
|
at += 2;
|
|
610
|
+
this.locals.set(slot, {
|
|
611
|
+
kind: "number",
|
|
612
|
+
value: this.number(this.locals.get(slot) ?? { kind: "unknown" }) + step
|
|
613
|
+
});
|
|
536
614
|
break;
|
|
615
|
+
}
|
|
537
616
|
case RETURNS.has(op):
|
|
538
617
|
if (op !== 177) this.returned = this.pop();
|
|
539
618
|
return true;
|
|
540
|
-
case op === 178:
|
|
619
|
+
case op === 178: {
|
|
620
|
+
const index = code[at] << 8 | code[at + 1];
|
|
541
621
|
at += 2;
|
|
542
|
-
|
|
622
|
+
const reference = constants.reference(index);
|
|
623
|
+
const key = reference ? `${reference.owner}.${reference.name}` : "";
|
|
624
|
+
if (reference && !this.shared.statics.has(key)) this.initialise(reference.owner);
|
|
625
|
+
this.push(this.shared.statics.get(key) ?? { kind: "unknown" });
|
|
543
626
|
break;
|
|
544
|
-
|
|
627
|
+
}
|
|
628
|
+
case op === 179: {
|
|
629
|
+
const index = code[at] << 8 | code[at + 1];
|
|
545
630
|
at += 2;
|
|
546
|
-
this.pop();
|
|
631
|
+
const value = this.pop();
|
|
632
|
+
const reference = constants.reference(index);
|
|
633
|
+
if (reference) this.shared.statics.set(`${reference.owner}.${reference.name}`, value);
|
|
547
634
|
break;
|
|
635
|
+
}
|
|
548
636
|
case op === 180: {
|
|
549
637
|
const index = code[at] << 8 | code[at + 1];
|
|
550
638
|
at += 2;
|
|
@@ -580,6 +668,7 @@ var Interpreter = class Interpreter {
|
|
|
580
668
|
const taken = [];
|
|
581
669
|
for (let count = 0; count < args.length; count++) taken.unshift(this.pop());
|
|
582
670
|
const objectRef = this.pop();
|
|
671
|
+
if (objectRef.kind === "object" && args.length > 0 && args.length <= 3 && args.every((arg) => arg === "F")) objectRef.handle.deformation = Math.max(...taken.map((value) => this.number(value)));
|
|
583
672
|
if (objectRef.kind === "object" && args.length >= 2 && args.at(-1) === "I" && args.at(-2) === "I") {
|
|
584
673
|
objectRef.handle.pendingUv = [this.number(taken[args.length - 2]), this.number(taken[args.length - 1])];
|
|
585
674
|
objectRef.handle.uvFromConstructor = true;
|
|
@@ -597,22 +686,18 @@ var Interpreter = class Interpreter {
|
|
|
597
686
|
handle: this.handle()
|
|
598
687
|
});
|
|
599
688
|
break;
|
|
600
|
-
case op === 188:
|
|
601
|
-
at += 1;
|
|
602
|
-
this.pop();
|
|
603
|
-
|
|
604
|
-
kind: "array",
|
|
605
|
-
items: []
|
|
606
|
-
});
|
|
607
|
-
break;
|
|
608
|
-
case op === 189:
|
|
609
|
-
at += 2;
|
|
610
|
-
this.pop();
|
|
689
|
+
case op === 188 || op === 189: {
|
|
690
|
+
at += op === 188 ? 1 : 2;
|
|
691
|
+
const length = this.pop();
|
|
692
|
+
const size = length.kind === "number" ? Math.min(Math.max(length.value, 0), MAX_ARRAY) : 0;
|
|
611
693
|
this.push({
|
|
612
694
|
kind: "array",
|
|
613
|
-
items:
|
|
695
|
+
items: Array.from({ length: size }, () => {
|
|
696
|
+
return { kind: "unknown" };
|
|
697
|
+
})
|
|
614
698
|
});
|
|
615
699
|
break;
|
|
700
|
+
}
|
|
616
701
|
case op === 192:
|
|
617
702
|
at += 2;
|
|
618
703
|
break;
|
|
@@ -633,10 +718,20 @@ var Interpreter = class Interpreter {
|
|
|
633
718
|
break;
|
|
634
719
|
}
|
|
635
720
|
case op >= 153 && op <= 166: {
|
|
636
|
-
const
|
|
637
|
-
|
|
721
|
+
const twoOperands = op >= 159;
|
|
722
|
+
const right = this.pop();
|
|
723
|
+
const left = twoOperands ? this.pop() : {
|
|
724
|
+
kind: "number",
|
|
725
|
+
value: 0
|
|
726
|
+
};
|
|
727
|
+
const offset = (code[at] << 8 | code[at + 1]) << 16 >> 16;
|
|
638
728
|
at += 2;
|
|
639
|
-
|
|
729
|
+
const decided = left.kind === "number" && right.kind === "number" && op <= 164 ? compare(op, twoOperands ? left.value : right.value, twoOperands ? right.value : 0) : null;
|
|
730
|
+
if (decided === null) {
|
|
731
|
+
this.shared.branched = true;
|
|
732
|
+
break;
|
|
733
|
+
}
|
|
734
|
+
if (decided) at += offset - 3;
|
|
640
735
|
break;
|
|
641
736
|
}
|
|
642
737
|
case op === 198 || op === 199:
|
|
@@ -646,12 +741,19 @@ var Interpreter = class Interpreter {
|
|
|
646
741
|
break;
|
|
647
742
|
case op === 167: {
|
|
648
743
|
const offset = (code[at] << 8 | code[at + 1]) << 16 >> 16;
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
744
|
+
at += 2;
|
|
745
|
+
if (offset > 0) {
|
|
746
|
+
at += offset - 3;
|
|
747
|
+
break;
|
|
652
748
|
}
|
|
653
|
-
|
|
654
|
-
this.
|
|
749
|
+
const site = at - 3;
|
|
750
|
+
const round = (this.loops.get(site) ?? 0) + 1;
|
|
751
|
+
this.loops.set(site, round);
|
|
752
|
+
if (round > MAX_ITERATIONS) {
|
|
753
|
+
this.note(`a loop at ${site} went round more than ${MAX_ITERATIONS} times, so the shape is only as far as it got`);
|
|
754
|
+
break;
|
|
755
|
+
}
|
|
756
|
+
at += offset - 3;
|
|
655
757
|
break;
|
|
656
758
|
}
|
|
657
759
|
case op >= 148 && op <= 152:
|
|
@@ -11,7 +11,7 @@ import { n as LayeredResourceManager, t as FolderResourceManager } from "./manag
|
|
|
11
11
|
import { n as TextureLoader } from "./loader-C18GpurU.js";
|
|
12
12
|
import { t as encodeAnimatedIcon } from "./encode-LR9wxigC.js";
|
|
13
13
|
import { a as builtinDynamicResources } from "./generators-BCZVlWig.js";
|
|
14
|
-
import { a as spawnEggTints, i as renderEntityFallback, n as dyedVariantTint, r as renderDyedVariantFallback, t as dyeVariantName } from "./entity-fallback-
|
|
14
|
+
import { a as spawnEggTints, i as renderEntityFallback, n as dyedVariantTint, r as renderDyedVariantFallback, t as dyeVariantName } from "./entity-fallback-BcJWh91-.js";
|
|
15
15
|
import { t as legacyTintsForChain } from "./legacy-tints-l-541wgI.js";
|
|
16
16
|
import { n as defaultBlockStateModel, t as blockStateTransform } from "./blockstate-DVb8Mhxc.js";
|
|
17
17
|
import path from "node:path";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as spawnEggTints, i as renderEntityFallback, n as dyedVariantTint, r as renderDyedVariantFallback, t as dyeVariantName } from "../entity-fallback-
|
|
1
|
+
import { a as spawnEggTints, i as renderEntityFallback, n as dyedVariantTint, r as renderDyedVariantFallback, t as dyeVariantName } from "../entity-fallback-BcJWh91-.js";
|
|
2
2
|
export { dyeVariantName, dyedVariantTint, renderDyedVariantFallback, renderEntityFallback, spawnEggTints };
|
package/dist/render/pipeline.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as ItemPipeline } from "../pipeline-
|
|
1
|
+
import { t as ItemPipeline } from "../pipeline-7rvL6vx1.js";
|
|
2
2
|
export { ItemPipeline };
|
|
@@ -12,6 +12,18 @@ declare const HEAD_LAYOUTS: Record<string, string>;
|
|
|
12
12
|
* live at entity/<mob>.png or entity/<mob>/<mob>.png depending on the mod, and a
|
|
13
13
|
* head only ever wants the base skin — never a blink or armour overlay.
|
|
14
14
|
*/
|
|
15
|
+
/**
|
|
16
|
+
* Directories that hold an *overlay* rather than a mob.
|
|
17
|
+
*
|
|
18
|
+
* Matched as whole path segments rather than as tokens, because a token would take `chest_boat` out
|
|
19
|
+
* along with `chest`. A trader llama is the case that needed it: its sheet is filed as
|
|
20
|
+
* `entity/llama/decor/trader_llama`, whose leaf is exactly the mob's name — so a search by name found
|
|
21
|
+
* the carpet it wears, which is a few opaque pixels on a transparent sheet, and the llama underneath
|
|
22
|
+
* came out invisible on most of its faces.
|
|
23
|
+
*/
|
|
24
|
+
declare const OVERLAY_DIRECTORIES: Set<string>;
|
|
25
|
+
/** Whether a texture is filed inside one of those, whatever the file itself is called. */
|
|
26
|
+
declare function isOverlayPath(path: string): boolean;
|
|
15
27
|
declare function findMobTexture(resources: ResourceManager, namespace: string, mob: string): Promise<ResourceLocator | null>;
|
|
16
28
|
/**
|
|
17
29
|
* Find the mod's own chest sheet for a chest-like item by token overlap over
|
|
@@ -48,4 +60,4 @@ declare function findFluidStill(resources: ResourceManager, namespace: string, b
|
|
|
48
60
|
*/
|
|
49
61
|
declare function findFluidSibling(resources: ResourceManager, still: ResourceLocator, suffixes: string[]): Promise<ResourceLocator | null>;
|
|
50
62
|
//#endregion
|
|
51
|
-
export { DYE_COLORS, HEAD_LAYOUTS, coversSheet, findBedTexture, findChestTexture, findEntityTexture, findFluidSibling, findFluidStill, findMobTexture, tokens };
|
|
63
|
+
export { DYE_COLORS, HEAD_LAYOUTS, OVERLAY_DIRECTORIES, coversSheet, findBedTexture, findChestTexture, findEntityTexture, findFluidSibling, findFluidStill, findMobTexture, isOverlayPath, tokens };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { DYE_COLORS, HEAD_LAYOUTS, coversSheet, findBedTexture, findChestTexture, findEntityTexture, findFluidSibling, findFluidStill, findMobTexture, tokens };
|
|
1
|
+
import { a as findBedTexture, c as findFluidSibling, d as isOverlayPath, f as tokens, i as coversSheet, l as findFluidStill, n as HEAD_LAYOUTS, o as findChestTexture, r as OVERLAY_DIRECTORIES, s as findEntityTexture, t as DYE_COLORS, u as findMobTexture } from "../entity-textures-4XXT8jVI.js";
|
|
2
|
+
export { DYE_COLORS, HEAD_LAYOUTS, OVERLAY_DIRECTORIES, coversSheet, findBedTexture, findChestTexture, findEntityTexture, findFluidSibling, findFluidStill, findMobTexture, isOverlayPath, tokens };
|
|
@@ -6,7 +6,7 @@ import { r as encodeRasterAsset } from "./encode-LR9wxigC.js";
|
|
|
6
6
|
import { t as classifyItemStyle } from "./item-styles-DjYRdyHi.js";
|
|
7
7
|
import { t as minifyStylesheet } from "./minify-bjMRmr5J.js";
|
|
8
8
|
import { t as generateStylesheet } from "./stylesheet-CovT3B2S.js";
|
|
9
|
-
import { t as ItemPipeline } from "./pipeline-
|
|
9
|
+
import { t as ItemPipeline } from "./pipeline-7rvL6vx1.js";
|
|
10
10
|
import { t as describeResources } from "./descriptor-JyXhfd-c.js";
|
|
11
11
|
import { t as WorkerRenderPool } from "./pool-CKGp1qup.js";
|
|
12
12
|
import path from "node:path";
|
package/dist/run.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ItemPipeline } from "../pipeline-
|
|
1
|
+
import { t as ItemPipeline } from "../pipeline-7rvL6vx1.js";
|
|
2
2
|
import { n as restoreResources } from "../descriptor-JyXhfd-c.js";
|
|
3
3
|
import sharp from "sharp";
|
|
4
4
|
import { parentPort, workerData } from "node:worker_threads";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodecraft/rendermite",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "Minecraft item icon renderer: renders inventory-identical item icons from vanilla and modded assets across game versions, outputting optimized PNG/WebP/AVIF plus CSS and a JSON item library.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/dist/merge-NDYxpmL8.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
//#region src/entities/merge.ts
|
|
2
|
-
/** A root the interpreter had to invent, because a `MeshDefinition`'s root part is anonymous. */
|
|
3
|
-
const SYNTHETIC_ROOT = /^part\d+$/;
|
|
4
|
-
/**
|
|
5
|
-
* Where a piece's parts sit: at the top, or inside the one anonymous root a `MeshDefinition` makes.
|
|
6
|
-
* Both merge into the same list of named slots and only one of them is nested.
|
|
7
|
-
*/
|
|
8
|
-
function slotsOf(parts) {
|
|
9
|
-
const [only] = parts;
|
|
10
|
-
if (parts.length === 1 && only.cubes.length === 0 && SYNTHETIC_ROOT.test(only.name)) return {
|
|
11
|
-
container: only,
|
|
12
|
-
slots: only.children
|
|
13
|
-
};
|
|
14
|
-
return {
|
|
15
|
-
container: null,
|
|
16
|
-
slots: parts
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
/** True when this piece built its own mesh rather than adding to one it was handed. */
|
|
20
|
-
function buildsOwnMesh(model) {
|
|
21
|
-
return slotsOf(model.parts).container !== null;
|
|
22
|
-
}
|
|
23
|
-
/** `base` plus the parts of `extra` that `base` does not name. */
|
|
24
|
-
function mergeModels(base, extra) {
|
|
25
|
-
const target = slotsOf(base.parts);
|
|
26
|
-
const source = slotsOf(extra.parts);
|
|
27
|
-
const named = new Set(target.slots.map((part) => part.name));
|
|
28
|
-
const missing = source.slots.filter((part) => !named.has(part.name));
|
|
29
|
-
if (missing.length === 0) return base;
|
|
30
|
-
const parts = target.container ? [{
|
|
31
|
-
...target.container,
|
|
32
|
-
children: [...target.container.children, ...missing]
|
|
33
|
-
}] : [...target.slots, ...missing];
|
|
34
|
-
const notes = [.../* @__PURE__ */ new Set([...base.notes, ...extra.notes])].filter((note) => parts.length > 1 || !note.includes("disconnected roots"));
|
|
35
|
-
return {
|
|
36
|
-
textureSize: base.textureSize[0] === 64 && base.textureSize[1] === 32 ? extra.textureSize : base.textureSize,
|
|
37
|
-
parts,
|
|
38
|
-
notes
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
function countCubes(part) {
|
|
42
|
-
return part.cubes.length + part.children.reduce((total, child) => total + countCubes(child), 0);
|
|
43
|
-
}
|
|
44
|
-
function cubesOf(model) {
|
|
45
|
-
return model.parts.reduce((total, part) => total + countCubes(part), 0);
|
|
46
|
-
}
|
|
47
|
-
//#endregion
|
|
48
|
-
export { slotsOf as a, mergeModels as i, countCubes as n, cubesOf as r, buildsOwnMesh as t };
|