pixelkiln 0.71.0 → 0.72.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.
- package/PROVIDERS.md +1 -1
- package/dist/cli.js +27 -14
- package/dist/cli.js.map +1 -1
- package/dist/client/gallery.js +17 -5
- package/dist/index.cjs +27 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +86 -55
- package/dist/index.d.ts +86 -55
- package/dist/index.js +27 -14
- package/dist/index.js.map +1 -1
- package/docs/CHARACTERS.md +13 -0
- package/docs/GENERATORS.md +1 -1
- package/package.json +1 -1
- package/schema/manifest.schema.json +1 -0
- package/skills/pixelkiln/references/pixellab-roadmap.md +6 -0
- package/skills/pixelkiln/references/pixellab.md +8 -1
package/dist/client/gallery.js
CHANGED
|
@@ -363,13 +363,22 @@
|
|
|
363
363
|
prompt.placeholder = 'What the loop does, e.g. "a slow idle sway".';
|
|
364
364
|
prompt.required = true;
|
|
365
365
|
const mode = el("select");
|
|
366
|
-
if (isCharacter)
|
|
366
|
+
if (isCharacter) {
|
|
367
|
+
mode.append(
|
|
368
|
+
new Option("skeleton-v3 (a template, posed by the skeleton model; steadiest)", "skeleton-v3"),
|
|
369
|
+
new Option("template (a template, redrawn; 1 generation)", "template")
|
|
370
|
+
);
|
|
371
|
+
}
|
|
367
372
|
mode.append(new Option("v3 (text-described)", "v3"), new Option("pro (sequential, high quality)", "pro"));
|
|
368
|
-
mode.value = "v3";
|
|
373
|
+
mode.value = isCharacter ? "skeleton-v3" : "v3";
|
|
369
374
|
const template = el("input");
|
|
370
375
|
template.type = "text";
|
|
371
376
|
template.placeholder = "e.g. walk, breathing-idle";
|
|
372
|
-
const
|
|
377
|
+
const templateHint = {
|
|
378
|
+
"skeleton-v3": "A PixelLab template posed onto the character by the skeleton model, which moves it instead of redrawing it: steadier identity and colours. 2 to 4 generations and 3 to 5 minutes per direction; beta, Tier 1 plans and up.",
|
|
379
|
+
template: "A PixelLab template, redrawn frame by frame; 1 generation regardless of frame count."
|
|
380
|
+
};
|
|
381
|
+
const templateField = field("template id", template, templateHint.template);
|
|
373
382
|
const frames = el("input");
|
|
374
383
|
frames.type = "number";
|
|
375
384
|
frames.min = "4";
|
|
@@ -403,9 +412,11 @@
|
|
|
403
412
|
form.append(row2);
|
|
404
413
|
if (subject) form.append(field("subject override", subject));
|
|
405
414
|
const syncMode = () => {
|
|
406
|
-
const isTemplate = isCharacter && mode.value === "template";
|
|
415
|
+
const isTemplate = isCharacter && (mode.value === "template" || mode.value === "skeleton-v3");
|
|
407
416
|
templateField.style.display = isTemplate ? "" : "none";
|
|
417
|
+
if (isTemplate) templateField.querySelector("small").textContent = templateHint[mode.value];
|
|
408
418
|
template.required = isTemplate;
|
|
419
|
+
prompt.required = !isTemplate;
|
|
409
420
|
row2.style.display = isTemplate ? "none" : "";
|
|
410
421
|
};
|
|
411
422
|
if (isCharacter) {
|
|
@@ -433,8 +444,9 @@
|
|
|
433
444
|
msg.textContent = "saving…";
|
|
434
445
|
const animation = { of: item.assetId };
|
|
435
446
|
if (directionField) animation.direction = directionField.select.value;
|
|
436
|
-
if (isCharacter && mode.value === "template" && template.value.trim()) {
|
|
447
|
+
if (isCharacter && (mode.value === "template" || mode.value === "skeleton-v3") && template.value.trim()) {
|
|
437
448
|
animation.template = template.value.trim();
|
|
449
|
+
if (mode.value === "skeleton-v3") animation.mode = "skeleton-v3";
|
|
438
450
|
} else {
|
|
439
451
|
animation.mode = mode.value;
|
|
440
452
|
if (frames.value.trim() !== "") animation.frames = Number(frames.value);
|
package/dist/index.cjs
CHANGED
|
@@ -449,7 +449,7 @@ var CharacterProportionsSchema = import_zod.z.union([
|
|
|
449
449
|
hipWidth: import_zod.z.number().min(0.5).max(2).optional()
|
|
450
450
|
}).strict()
|
|
451
451
|
]);
|
|
452
|
-
var CharacterAnimationModeSchema = import_zod.z.enum(["template", "v3", "pro"]);
|
|
452
|
+
var CharacterAnimationModeSchema = import_zod.z.enum(["template", "skeleton-v3", "v3", "pro"]);
|
|
453
453
|
var UiPieceSchema = import_zod.z.discriminatedUnion("kind", [
|
|
454
454
|
import_zod.z.object({
|
|
455
455
|
id: import_zod.z.string().min(1),
|
|
@@ -563,7 +563,11 @@ var CharacterAnimationSchema = import_zod.z.object({
|
|
|
563
563
|
fps: import_zod.z.number().int().min(1).max(60).default(8),
|
|
564
564
|
/** v3 only: keep the resting pose as frame 0, so `frames` generated frames land as `frames + 1` files. */
|
|
565
565
|
keepFirstFrame: import_zod.z.boolean().default(true),
|
|
566
|
-
/**
|
|
566
|
+
/**
|
|
567
|
+
* `template` when a template is named, otherwise `v3`; `skeleton-v3`
|
|
568
|
+
* poses a template with PixelLab's skeleton model instead; `pro` for the
|
|
569
|
+
* sequential high-quality engine.
|
|
570
|
+
*/
|
|
567
571
|
mode: CharacterAnimationModeSchema.optional(),
|
|
568
572
|
/**
|
|
569
573
|
* v3 only: a manifest-relative image of the pose to start from, instead
|
|
@@ -600,7 +604,7 @@ var CharacterAnimationSchema = import_zod.z.object({
|
|
|
600
604
|
if (animation[key] !== void 0 && mode2 !== "v3") {
|
|
601
605
|
context.addIssue({
|
|
602
606
|
code: import_zod.z.ZodIssueCode.custom,
|
|
603
|
-
message: `${key} is for v3 loops; a ${mode2} loop ${mode2 === "template" ? "starts from the character's rotation and follows its template" : "takes neither"}`,
|
|
607
|
+
message: `${key} is for v3 loops; a ${mode2} loop ${mode2 === "template" || mode2 === "skeleton-v3" ? "starts from the character's rotation and follows its template" : "takes neither"}`,
|
|
604
608
|
path: [key]
|
|
605
609
|
});
|
|
606
610
|
}
|
|
@@ -610,10 +614,10 @@ var CharacterAnimationSchema = import_zod.z.object({
|
|
|
610
614
|
context.addIssue({ code: import_zod.z.ZodIssueCode.custom, message: `${key} overrides apply to template loops only`, path: [key] });
|
|
611
615
|
}
|
|
612
616
|
}
|
|
613
|
-
if (animation.template && animation.mode && animation.mode !== "template") {
|
|
617
|
+
if (animation.template && animation.mode && animation.mode !== "template" && animation.mode !== "skeleton-v3") {
|
|
614
618
|
context.addIssue({
|
|
615
619
|
code: import_zod.z.ZodIssueCode.custom,
|
|
616
|
-
message: `a template animation cannot use mode "${animation.mode}"`,
|
|
620
|
+
message: `a template animation cannot use mode "${animation.mode}"; use "template" or "skeleton-v3"`,
|
|
617
621
|
path: ["mode"]
|
|
618
622
|
});
|
|
619
623
|
}
|
|
@@ -624,8 +628,8 @@ var CharacterAnimationSchema = import_zod.z.object({
|
|
|
624
628
|
path: ["frames"]
|
|
625
629
|
});
|
|
626
630
|
}
|
|
627
|
-
if (!animation.template && animation.mode === "template") {
|
|
628
|
-
context.addIssue({ code: import_zod.z.ZodIssueCode.custom, message:
|
|
631
|
+
if (!animation.template && (animation.mode === "template" || animation.mode === "skeleton-v3")) {
|
|
632
|
+
context.addIssue({ code: import_zod.z.ZodIssueCode.custom, message: `${animation.mode} mode needs a template`, path: ["template"] });
|
|
629
633
|
}
|
|
630
634
|
});
|
|
631
635
|
var RevisionDitheringSchema = import_zod.z.enum(["none", "2x2", "4x4", "8x8"]);
|
|
@@ -2559,12 +2563,20 @@ var PixelLabClient = class {
|
|
|
2559
2563
|
}
|
|
2560
2564
|
/**
|
|
2561
2565
|
* One animation of one character. Template mode costs a generation per
|
|
2562
|
-
* direction and fixes the frame count; v3
|
|
2563
|
-
* the
|
|
2566
|
+
* direction and fixes the frame count; skeleton-v3 poses the same template
|
|
2567
|
+
* with the skeleton video model (2-4 generations per direction); v3 draws
|
|
2568
|
+
* `frameCount` frames from the action text; pro is the sequential engine.
|
|
2569
|
+
* One job per direction.
|
|
2570
|
+
*
|
|
2571
|
+
* Every mode but skeleton-v3 goes to `/animate-character`, the path whose
|
|
2572
|
+
* shapes were measured live. skeleton-v3 is documented only on
|
|
2573
|
+
* `/characters/animations`, which takes the same request and answers with
|
|
2574
|
+
* the same job list (plus an `animation_group_id`).
|
|
2564
2575
|
*/
|
|
2565
2576
|
async animateCharacter(args) {
|
|
2566
2577
|
const encode = (image) => ({ type: "base64", base64: image.base64, format: image.format });
|
|
2567
|
-
const
|
|
2578
|
+
const endpoint = args.mode === "skeleton-v3" ? "/characters/animations" : "/animate-character";
|
|
2579
|
+
const raw = await this.request(endpoint, {
|
|
2568
2580
|
method: "POST",
|
|
2569
2581
|
body: JSON.stringify({
|
|
2570
2582
|
character_id: args.characterId,
|
|
@@ -2588,7 +2600,7 @@ var PixelLabClient = class {
|
|
|
2588
2600
|
...args.seed != null ? { seed: args.seed } : {}
|
|
2589
2601
|
})
|
|
2590
2602
|
});
|
|
2591
|
-
return validateResponse(AnimateSubmitSchema, raw,
|
|
2603
|
+
return validateResponse(AnimateSubmitSchema, raw, endpoint.slice(1));
|
|
2592
2604
|
}
|
|
2593
2605
|
/**
|
|
2594
2606
|
* A full-body sprite in, a bust portrait out (or the reverse, unused
|
|
@@ -3881,6 +3893,7 @@ function characterCost(spec) {
|
|
|
3881
3893
|
if (character.kind === "animation") {
|
|
3882
3894
|
const animation = character.animation;
|
|
3883
3895
|
if (animation.mode === "template") return 1;
|
|
3896
|
+
if (animation.mode === "skeleton-v3") return 4;
|
|
3884
3897
|
if (animation.mode === "v3") return Math.max(1, Math.ceil(px * animation.frames / 65536));
|
|
3885
3898
|
return generationCost(spec.width, spec.height, "1dir");
|
|
3886
3899
|
}
|
|
@@ -4473,7 +4486,7 @@ var PixelLabProvider = class _PixelLabProvider {
|
|
|
4473
4486
|
`${spec.styleId}/${spec.assetId} animates "${character.animation.direction}", but its character has ${character.directions} directions: ${allowed.join(", ")}`
|
|
4474
4487
|
);
|
|
4475
4488
|
}
|
|
4476
|
-
if (character.animation.mode !== "template" && !spec.prompt.trim()) {
|
|
4489
|
+
if (character.animation.mode !== "template" && character.animation.mode !== "skeleton-v3" && !spec.prompt.trim()) {
|
|
4477
4490
|
throw new Error(`${spec.styleId}/${spec.assetId} needs a prompt describing the motion, or a template`);
|
|
4478
4491
|
}
|
|
4479
4492
|
}
|
|
@@ -9401,8 +9414,8 @@ async function resolveObjectProShape(assetId, asset, style, kind, files) {
|
|
|
9401
9414
|
);
|
|
9402
9415
|
}
|
|
9403
9416
|
}
|
|
9404
|
-
if (asset.animation.mode === "template") {
|
|
9405
|
-
throw new Error(`assets.${assetId}: objectPro animations have no "
|
|
9417
|
+
if (asset.animation.mode === "template" || asset.animation.mode === "skeleton-v3") {
|
|
9418
|
+
throw new Error(`assets.${assetId}: objectPro animations have no "${asset.animation.mode}" mode; use "v3" or "pro"`);
|
|
9406
9419
|
}
|
|
9407
9420
|
const pose = async (rel, what) => {
|
|
9408
9421
|
const image = await files.load(rel, what);
|