@nodecraft/rendermite 1.1.1 → 1.1.3

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/cli.js CHANGED
@@ -4,7 +4,7 @@ import { n as LayeredResourceManager, t as FolderResourceManager } from "./manag
4
4
  import { t as curatedModelOverrides } from "./models-BKxGkPS7.js";
5
5
  import { n as harvestTintOverrides, t as curatedTintOverrides } from "./tints-CebmvjmP.js";
6
6
  import { t as JarResourceManager } from "./jar-D9z-X7tA.js";
7
- import { t as run } from "./run-D87zIGfr.js";
7
+ import { t as run } from "./run-BPfpBZyZ.js";
8
8
  import { t as downloadClientJar } from "./download-D9aARBFp.js";
9
9
  import { a as prepareVersionResources, i as eraForVersion, n as GEOMETRY_DONOR_VERSIONS } from "./prepare-Cc8QZ3j0.js";
10
10
  import path from "node:path";
@@ -1,5 +1,5 @@
1
1
  import { n as ResourceLocator } from "./locator-ycZzh_6z.js";
2
- import { i as renderModel } from "./renderer-oi1MSF3Y.js";
2
+ import { i as renderModel } from "./renderer-DB1Oe7xs.js";
3
3
  //#region src/render/entity-fallback.ts
4
4
  /**
5
5
  * Heuristic rendering for mod items that parent `builtin/entity` — chests,
package/dist/index.js CHANGED
@@ -9,12 +9,12 @@ import { a as builtinDynamicResources } from "./generators-BlG4KmtP.js";
9
9
  import { t as minifyStylesheet } from "./minify-bjMRmr5J.js";
10
10
  import { n as itemClass, t as generateStylesheet } from "./stylesheet-CovT3B2S.js";
11
11
  import { c as lightsForProfile, r as LightingProfile } from "./lighting--5myudVu.js";
12
- import { a as salvageJson, i as resolveTexture, n as ModelResolutionError, t as ModelLoader } from "./loader-DwkA9LR5.js";
13
- import { a as renderModelFrames, i as renderModel, n as boxDownscale, r as pointResize, t as ItemRenderError } from "./renderer-oi1MSF3Y.js";
12
+ import { a as salvageJson, i as resolveTexture, n as ModelResolutionError, t as ModelLoader } from "./loader-CWsTZgrk.js";
13
+ import { a as renderModelFrames, i as renderModel, n as boxDownscale, r as pointResize, t as ItemRenderError } from "./renderer-DB1Oe7xs.js";
14
14
  import { a as resolveTints, i as resolveTint, n as InvalidTinterDefinitionError, r as parseTintValue, t as DYE_COLORS } from "./tints-3VI_2SNy.js";
15
15
  import { o as createAtlasResolver, s as parseAtlasSources, t as AtlasSourceError } from "./sources-Bxk-WOzH.js";
16
16
  import { n as TextureLoader, r as TextureResolutionError, t as AnimatedTexture } from "./loader-Lb0ZeILz.js";
17
- import { t as run } from "./run-D87zIGfr.js";
17
+ import { t as run } from "./run-BPfpBZyZ.js";
18
18
  import { a as prepareVersionResources, i as eraForVersion, r as compareVersions } from "./prepare-Cc8QZ3j0.js";
19
19
  import { n as prepareModResources } from "./prepare-D56Z-9cg.js";
20
20
  export { AnimatedTexture, AtlasSourceError, DYE_COLORS, FolderResourceManager, InvalidItemDefinitionError, InvalidResourceLocatorError, InvalidTinterDefinitionError, ItemRenderError, ItemResolutionError, JarResourceManager, LayeredResourceManager, LightingProfile, ModelLoader, ModelResolutionError, ResourceKind, ResourceLocator, TextureLoader, TextureResolutionError, UNKNOWN_MODEL, UnsafeJarError, boxDownscale, builtinDynamicResources, compareVersions, createAtlasResolver, defaultProperties, discoverItems, encodeAnimatedIcon, encodeIcon, eraForVersion, evaluateItemModel, generateStylesheet, isUnsafeEntryPath, itemClass, lightsForProfile, minifyStylesheet, parseAtlasSources, parseTintValue, pointResize, prepareModResources, prepareVersionResources, renderModel, renderModelFrames, resolveItem, resolveTexture, resolveTint, resolveTints, run, salvageJson, toByteTexture, toFloatTexture };
@@ -506,7 +506,13 @@ var ModelLoader = class {
506
506
  if (seen.has(key)) throw new ModelResolutionError(`Model parent cycle at ${key} (from ${locator})`);
507
507
  if (chain.length >= MAX_PARENT_DEPTH) throw new ModelResolutionError(`Model parent chain exceeds ${MAX_PARENT_DEPTH} at ${locator}`);
508
508
  seen.add(key);
509
- const json = await this.readModelJson(current);
509
+ let json;
510
+ try {
511
+ json = await this.readModelJson(current);
512
+ } catch (err) {
513
+ if (chain.length === 0 || !(err instanceof ModelResolutionError)) throw err;
514
+ break;
515
+ }
510
516
  chain.push({
511
517
  locator: current,
512
518
  json
@@ -1,2 +1,2 @@
1
- import { a as salvageJson, i as resolveTexture, n as ModelResolutionError, r as flattenLoaderModel, t as ModelLoader } from "../loader-DwkA9LR5.js";
1
+ import { a as salvageJson, i as resolveTexture, n as ModelResolutionError, r as flattenLoaderModel, t as ModelLoader } from "../loader-CWsTZgrk.js";
2
2
  export { ModelLoader, ModelResolutionError, flattenLoaderModel, resolveTexture, salvageJson };
@@ -5,9 +5,9 @@ import { r as resolveItem } from "./discovery-B9aqV_Rz.js";
5
5
  import { l as toFloatTexture, t as blendPixel } from "./blend-KXMclcHk.js";
6
6
  import { t as encodeAnimatedIcon } from "./encode-LR9wxigC.js";
7
7
  import { a as builtinDynamicResources } from "./generators-BlG4KmtP.js";
8
- import { t as ModelLoader } from "./loader-DwkA9LR5.js";
9
- import { a as renderModelFrames, i as renderModel, n as boxDownscale, r as pointResize } from "./renderer-oi1MSF3Y.js";
10
- import { a as spawnEggTints, i as renderEntityFallback, n as dyedVariantTint, r as renderDyedVariantFallback, t as dyeVariantName } from "./entity-fallback-BnFMSHS6.js";
8
+ import { t as ModelLoader } from "./loader-CWsTZgrk.js";
9
+ import { a as renderModelFrames, i as renderModel, n as boxDownscale, r as pointResize } from "./renderer-DB1Oe7xs.js";
10
+ import { a as spawnEggTints, i as renderEntityFallback, n as dyedVariantTint, r as renderDyedVariantFallback, t as dyeVariantName } from "./entity-fallback-Cu22uEIK.js";
11
11
  import { i as renderGeo, t as findGeoForItem } from "./geo-w9HHIrb5.js";
12
12
  import { t as legacyTintsForChain } from "./legacy-tints-B09J0Rxh.js";
13
13
  import { a as resolveTints } from "./tints-3VI_2SNy.js";
@@ -1,2 +1,2 @@
1
- import { a as spawnEggTints, i as renderEntityFallback, n as dyedVariantTint, r as renderDyedVariantFallback, t as dyeVariantName } from "../entity-fallback-BnFMSHS6.js";
1
+ import { a as spawnEggTints, i as renderEntityFallback, n as dyedVariantTint, r as renderDyedVariantFallback, t as dyeVariantName } from "../entity-fallback-Cu22uEIK.js";
2
2
  export { dyeVariantName, dyedVariantTint, renderDyedVariantFallback, renderEntityFallback, spawnEggTints };
@@ -1,2 +1,2 @@
1
- import { c as renderObjModel, o as parseMtl, s as parseObj } from "../renderer-oi1MSF3Y.js";
1
+ import { c as renderObjModel, o as parseMtl, s as parseObj } from "../renderer-DB1Oe7xs.js";
2
2
  export { parseMtl, parseObj, renderObjModel };
@@ -1,2 +1,2 @@
1
- import { t as ItemPipeline } from "../pipeline-zu_ZjnNc.js";
1
+ import { t as ItemPipeline } from "../pipeline-CgJaVpoL.js";
2
2
  export { ItemPipeline };
@@ -1,2 +1,2 @@
1
- import { a as renderModelFrames, i as renderModel, n as boxDownscale, r as pointResize, t as ItemRenderError } from "../renderer-oi1MSF3Y.js";
1
+ import { a as renderModelFrames, i as renderModel, n as boxDownscale, r as pointResize, t as ItemRenderError } from "../renderer-DB1Oe7xs.js";
2
2
  export { ItemRenderError, boxDownscale, pointResize, renderModel, renderModelFrames };
@@ -7,7 +7,7 @@ import { n as faceMaxZ, r as renderFace, t as createShadeCache } from "./face-CM
7
7
  import { t as paintBucketFluid } from "./fluid-bucket-BzoLofB_.js";
8
8
  import { r as buildElementFaces } from "./geometry-Bi-Bf5rb.js";
9
9
  import { c as lightsForProfile } from "./lighting--5myudVu.js";
10
- import { i as resolveTexture } from "./loader-DwkA9LR5.js";
10
+ import { i as resolveTexture } from "./loader-CWsTZgrk.js";
11
11
  //#region src/render/obj.ts
12
12
  /**
13
13
  * Forge/NeoForge OBJ model rendering — the class the old pipeline left
@@ -16,6 +16,10 @@ import { i as resolveTexture } from "./loader-DwkA9LR5.js";
16
16
  * same projection/lighting as JSON elements, with a z-tested shared buffer
17
17
  * (per-triangle painter buffers would be quadratic in triangle count).
18
18
  */
19
+ /** RGBA float channels, 8 bytes each. */
20
+ const FLOAT_BYTES_PER_TEXEL = 32;
21
+ /** Clone budget for one OBJ render; past it samples are shaded individually. */
22
+ const MAX_OBJ_SHADE_BYTES = 67108864;
19
23
  /** Parse OBJ text into triangles (polygon faces are fan-triangulated). */
20
24
  function parseObj(text, flipV) {
21
25
  const positions = [];
@@ -153,6 +157,7 @@ async function renderObjModel(model, resources, textures, options) {
153
157
  const out = createFaceBuffer(renderSize, renderSize);
154
158
  const scratch = createFaceBuffer(renderSize, renderSize);
155
159
  const shaded = /* @__PURE__ */ new Map();
160
+ let shadedBytes = 0;
156
161
  for (const triangle of parsed.triangles) {
157
162
  const transformed = triangle.positions.map((position) => transformVector(transformation, position));
158
163
  const rawNormal = cross(sub(transformed[1], transformed[0]), sub(transformed[2], transformed[0]));
@@ -165,16 +170,34 @@ async function renderObjModel(model, resources, textures, options) {
165
170
  ], normal) >= -.01) continue;
166
171
  const level = light.lightLevelForNormal(normal);
167
172
  const bucket = Math.round(level * 64);
173
+ const darkness = 1 - bucket / 64;
168
174
  const locator = materialTexture(model, materials, triangle.material);
169
175
  if (!locator) throw new ItemRenderError(`Unresolvable OBJ material ${triangle.material} in ${model.locator}`);
170
176
  const key = `${locator} ${bucket}`;
171
177
  let texture = shaded.get(key);
178
+ let shading = null;
172
179
  if (!texture) {
173
180
  const base = await textures.load(locator) ?? await textures.load(new ResourceLocator(locator.namespace, `item/${locator.path}`));
174
181
  if (!base) throw new ItemRenderError(`Missing texture ${locator} referenced by ${model.obj.model}`);
175
- texture = cloneFloatTexture(toFloatTexture(base));
176
- darkenTexture(texture, 1 - bucket / 64, 0, 0, texture.width, texture.height);
177
- shaded.set(key, texture);
182
+ const float = toFloatTexture(base);
183
+ const bytes = float.width * float.height * FLOAT_BYTES_PER_TEXEL;
184
+ if (shadedBytes + bytes <= MAX_OBJ_SHADE_BYTES) {
185
+ texture = cloneFloatTexture(float);
186
+ darkenTexture(texture, darkness, 0, 0, texture.width, texture.height);
187
+ shaded.set(key, texture);
188
+ shadedBytes += bytes;
189
+ } else {
190
+ texture = float;
191
+ shading = {
192
+ tint: null,
193
+ darkness,
194
+ alpha: 1,
195
+ windowX1: 0,
196
+ windowY1: 0,
197
+ windowX2: float.width - 1,
198
+ windowY2: float.height - 1
199
+ };
200
+ }
178
201
  }
179
202
  clearFaceBuffer(scratch);
180
203
  const cursor = new RowCursor();
@@ -187,7 +210,7 @@ async function renderObjModel(model, resources, textures, options) {
187
210
  depth: (transformed[index][2] + 1) / 3
188
211
  };
189
212
  };
190
- drawTexturedTriangle(point(0), point(1), point(2), scratch, texture, cursor);
213
+ drawTexturedTriangle(point(0), point(1), point(2), scratch, texture, cursor, shading);
191
214
  for (let y = Math.max(scratch.dirty.minY, 0); y <= Math.min(scratch.dirty.maxY, renderSize - 1); y++) for (let x = Math.max(scratch.dirty.minX, 0); x <= Math.min(scratch.dirty.maxX, renderSize - 1); x++) {
192
215
  const pixel = y * renderSize + x;
193
216
  const offset = pixel * 4;
@@ -220,6 +243,8 @@ async function renderObjModel(model, resources, textures, options) {
220
243
  var ItemRenderError = class extends Error {};
221
244
  const TICK_MS = 50;
222
245
  const MAX_ANIMATION_FRAMES = 128;
246
+ /** Per-frame delay is a uint16 of milliseconds in both WebP and GIF. */
247
+ const MAX_FRAME_DELAY_MS = 65535;
223
248
  function gcd(left, right) {
224
249
  return right === 0 ? left : gcd(right, left % right);
225
250
  }
@@ -282,8 +307,8 @@ async function renderModelFrames(model, textures, options) {
282
307
  return {
283
308
  frames,
284
309
  delaysMs: emitTicks.map((tick, index) => {
285
- const next = index + 1 < emitTicks.length ? emitTicks[index + 1] : ticks;
286
- return Math.max(TICK_MS, (next - tick) * TICK_MS);
310
+ const raw = ((index + 1 < emitTicks.length ? emitTicks[index + 1] : ticks) - tick) * TICK_MS;
311
+ return Math.min(MAX_FRAME_DELAY_MS, Math.max(TICK_MS, Math.round(raw)));
287
312
  }),
288
313
  animation: {
289
314
  ticks,
@@ -4,7 +4,7 @@ import { r as encodeRasterAsset } from "./encode-LR9wxigC.js";
4
4
  import { t as classifyItemStyle } from "./item-styles-upgEO1yP.js";
5
5
  import { t as minifyStylesheet } from "./minify-bjMRmr5J.js";
6
6
  import { t as generateStylesheet } from "./stylesheet-CovT3B2S.js";
7
- import { t as ItemPipeline } from "./pipeline-zu_ZjnNc.js";
7
+ import { t as ItemPipeline } from "./pipeline-CgJaVpoL.js";
8
8
  import { t as describeResources } from "./descriptor-DWebtkI1.js";
9
9
  import { t as WorkerRenderPool } from "./pool-CKGp1qup.js";
10
10
  import path from "node:path";
package/dist/run.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { o as evaluateItemModel } from "./definition-ColsvWrH.js";
2
- import { t as run } from "./run-D87zIGfr.js";
2
+ import { t as run } from "./run-BPfpBZyZ.js";
3
3
  export { evaluateItemModel, run };
@@ -1,4 +1,4 @@
1
- import { t as ItemPipeline } from "../pipeline-zu_ZjnNc.js";
1
+ import { t as ItemPipeline } from "../pipeline-CgJaVpoL.js";
2
2
  import { n as restoreResources } from "../descriptor-DWebtkI1.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.1.1",
3
+ "version": "1.1.3",
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",