pixelkiln 0.87.0 → 0.89.0

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.
@@ -1439,7 +1439,7 @@
1439
1439
  }
1440
1440
  return out;
1441
1441
  }
1442
- var fieldReaches = (field2, style) => field2 === "enforcePalette" ? false : field2 !== "noBackground" || style.generator === "pixflux" || style.provider !== "pixellab";
1442
+ var fieldReaches = (field2, style) => style.generator === "vfx" || field2 === "enforcePalette" ? false : field2 !== "noBackground" || style.generator === "pixflux" || style.provider !== "pixellab";
1443
1443
  function blastRadius(style, fields) {
1444
1444
  const byId = new Map(S.snap.styles.filter((x) => x.project === style.project).map((x) => [x.id, x]));
1445
1445
  const styleIds = /* @__PURE__ */ new Set();
@@ -1680,11 +1680,15 @@
1680
1680
  return [["image-to-image", "edit with a text instruction"], ...single ? [["inpaint", "repaint a painted area"]] : []];
1681
1681
  }
1682
1682
  if (item.provider !== "pixellab") return [["image-to-image", "edit with a text instruction"]];
1683
+ const style = S.snap.styles.find((s) => s.id === item.styleId && s.project === item.project);
1684
+ const normals = !(style && (style.enforcePalette || style.quality)) && sized(8, 512);
1683
1685
  if (!single) {
1686
+ const loop = item.outputs.length <= 32 && item.outputs.every((output) => output.role && output.role.startsWith("frame-"));
1684
1687
  return [
1685
1688
  ["edit-animation", "one text edit across every frame"],
1686
1689
  ["reduce-colors", "fewer colours, across every frame"],
1687
- ["correct-pixelart", "clean up the pixel grid, across every frame"]
1690
+ ["correct-pixelart", "clean up the pixel grid, across every frame"],
1691
+ ...loop && normals ? [["normal-map", "lighting normals, one steady map per frame"]] : []
1688
1692
  ];
1689
1693
  }
1690
1694
  return [
@@ -1695,7 +1699,8 @@
1695
1699
  ...sized(16, 128) && endingKeyframes(item).length ? [["interpolate", "in-betweens toward another sprite"]] : [],
1696
1700
  ["reduce-colors", "fewer colours, optional dithering"],
1697
1701
  ["correct-pixelart", "clean up the pixel grid"],
1698
- ["remove-background", "cut the background out to transparency"]
1702
+ ["remove-background", "cut the background out to transparency"],
1703
+ ...normals ? [["normal-map", "a normal map, so an engine can light it"]] : []
1699
1704
  ];
1700
1705
  }
1701
1706
  function endingKeyframes(item) {
@@ -1753,6 +1758,8 @@
1753
1758
  const subject = el("input");
1754
1759
  subject.type = "text";
1755
1760
  subject.placeholder = "optional: e.g. a knight holding a sword";
1761
+ const convention = el("select");
1762
+ convention.append(new Option("opengl: green up (Godot, Unity, Phaser)", "opengl"), new Option("directx: green down (Unreal)", "directx"));
1756
1763
  const ending = el("select");
1757
1764
  for (const other of endingKeyframes(item)) ending.append(new Option(other.assetId, other.outputs[0].path));
1758
1765
  const endingField = field("ending keyframe", ending, "Another sprite of the same style and size; the parent is the start. Regenerating that sprite makes this stale.");
@@ -1800,11 +1807,12 @@
1800
1807
  const ditherField = field("dithering", dithering);
1801
1808
  const removalField = field("removal", removal, "PixelLab takes at most 400 by 400 pixels.");
1802
1809
  const subjectField = field("foreground", subject, "A hint that helps PixelLab find what to keep.");
1810
+ const conventionField = field("convention", convention, "Which way green points. 0.5 generation per sprite or per loop.");
1803
1811
  const grids = el("div", "row");
1804
1812
  grids.append(framesField, fpsField);
1805
1813
  const cleanup = el("div", "row");
1806
1814
  cleanup.append(colorsField, ditherField);
1807
- form.append(row1, promptField, maskBox, endingField, strengthField, grids, driftField, captionRow, directionField, enhanceField, cleanup, removalField, subjectField);
1815
+ form.append(row1, promptField, maskBox, endingField, strengthField, grids, driftField, captionRow, directionField, enhanceField, cleanup, removalField, subjectField, conventionField);
1808
1816
  const hints = {
1809
1817
  "image-to-image": ["edit instruction", "add snow on the roof", "The style still adds its prefix and suffix."],
1810
1818
  animate: ["motion", "the chest wobbling gently", "Describes the movement; the parent image is the first frame."],
@@ -1814,7 +1822,8 @@
1814
1822
  "edit-animation": ["edit instruction", "add a red cape", "Applied across every frame in one call, so the change stays consistent."],
1815
1823
  "reduce-colors": ["note", "optional", "Cleanup only: the text is kept as a label, not sent."],
1816
1824
  "correct-pixelart": ["note", "optional", "Cleanup only: the text is kept as a label, not sent."],
1817
- "remove-background": ["note", "optional", "Cleanup only: the text is kept as a label, not sent."]
1825
+ "remove-background": ["note", "optional", "Cleanup only: the text is kept as a label, not sent."],
1826
+ "normal-map": ["note", "optional", "Cleanup only: the text is kept as a label, not sent."]
1818
1827
  };
1819
1828
  const sync = () => {
1820
1829
  const m = mode.value;
@@ -1823,7 +1832,7 @@
1823
1832
  promptField.querySelector("small")?.remove();
1824
1833
  promptField.append(el("small", null, hint));
1825
1834
  prompt.placeholder = placeholder;
1826
- prompt.required = !["reduce-colors", "correct-pixelart", "remove-background"].includes(m);
1835
+ prompt.required = !["reduce-colors", "correct-pixelart", "remove-background", "normal-map"].includes(m);
1827
1836
  strengthField.hidden = m !== "image-to-image" && m !== "correct-pixelart";
1828
1837
  grids.hidden = !(m === "animate" || m === "animate-pixminimax" || m === "edit-animation" || m === "interpolate");
1829
1838
  driftField.hidden = !(m === "animate" || m === "animate-pixminimax");
@@ -1836,6 +1845,7 @@
1836
1845
  enhanceField.hidden = !(m === "animate" || m === "animate-pixminimax");
1837
1846
  cleanup.hidden = m !== "reduce-colors";
1838
1847
  removalField.hidden = subjectField.hidden = m !== "remove-background";
1848
+ conventionField.hidden = m !== "normal-map";
1839
1849
  };
1840
1850
  mode.onchange = sync;
1841
1851
  enhance.onchange = sync;
@@ -1878,7 +1888,8 @@
1878
1888
  revision.removalTask = removal.value;
1879
1889
  if (subject.value.trim()) revision.description = subject.value.trim();
1880
1890
  }
1881
- const text = prompt.value.trim() || { "reduce-colors": "reduce colours", "correct-pixelart": "correct pixel art", "remove-background": "remove background" }[m] || "";
1891
+ if (m === "normal-map" && convention.value === "directx") revision.convention = "directx";
1892
+ const text = prompt.value.trim() || { "reduce-colors": "reduce colours", "correct-pixelart": "correct pixel art", "remove-background": "remove background", "normal-map": "normal map" }[m] || "";
1882
1893
  const asset = { prompt: text, styles: [item.styleId], revision };
1883
1894
  try {
1884
1895
  let body;
@@ -4745,7 +4756,7 @@
4745
4756
  }
4746
4757
  const declared = item.asset && item.asset.revision;
4747
4758
  if (declared) {
4748
- for (const [label, key] of [["facing", "direction"], ["looks like", "description"], ["body template", "skeletonTemplate"], ["frames", "frames"], ["fps", "fps"], ["colours", "numColors"], ["dithering", "dithering"], ["removal", "removalTask"]]) {
4759
+ for (const [label, key] of [["facing", "direction"], ["looks like", "description"], ["body template", "skeletonTemplate"], ["frames", "frames"], ["fps", "fps"], ["colours", "numColors"], ["dithering", "dithering"], ["removal", "removalTask"], ["normal convention", "convention"]]) {
4749
4760
  if (declared[key] !== void 0) row(dl, label, declared[key]);
4750
4761
  }
4751
4762
  }