@energy8platform/golem 0.5.0 → 0.7.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/README.md +18 -0
- package/dist/editor.css +3 -4
- package/dist/editor.js +177 -75
- package/dist/lib/cli.js +302 -126
- package/dist/lib/cli.js.map +4 -4
- package/dist/lib/e8/agent.d.ts +35 -0
- package/dist/lib/e8/host.d.ts +22 -0
- package/dist/lib/e8/node.d.ts +66 -0
- package/dist/lib/e8/runtime.d.ts +10 -0
- package/dist/lib/e8/schema.d.ts +3 -0
- package/dist/lib/e8/types.d.ts +80 -0
- package/dist/lib/e8-agent.js +6781 -0
- package/dist/lib/e8-agent.js.map +7 -0
- package/dist/lib/e8-client.js +116 -0
- package/dist/lib/e8-host.js +6929 -0
- package/dist/lib/e8-host.js.map +7 -0
- package/dist/lib/e8-runtime.js +2024 -0
- package/dist/lib/e8-runtime.js.map +7 -0
- package/dist/lib/e8-schema.js +7 -0
- package/dist/lib/e8-schema.js.map +7 -0
- package/dist/lib/editor/api.d.ts +1 -0
- package/dist/lib/editor/embed.d.ts +9 -0
- package/dist/lib/editor/server.d.ts +23 -1
- package/dist/lib/editor/store.d.ts +107 -0
- package/dist/lib/editor/timeline.d.ts +15 -0
- package/dist/lib/editor-entry.d.ts +1 -1
- package/dist/lib/editor-entry.js +303 -126
- package/dist/lib/editor-entry.js.map +4 -4
- package/dist/lib/harness.js +69 -14
- package/dist/lib/interactive-editor.js.map +1 -1
- package/dist/lib/rig-anim.d.ts +2 -0
- package/dist/lib/rig-control-qa.d.ts +27 -0
- package/dist/lib/rig-format.d.ts +989 -0
- package/dist/lib/rig-import-layers.d.ts +2 -0
- package/dist/lib/rig-version.d.ts +12 -0
- package/dist/lib/runtime.js +69 -14
- package/dist/lib/runtime.js.map +3 -3
- package/dist/lib/spine-import.d.ts +4 -0
- package/dist/lib/tool-schema.d.ts +3 -0
- package/dist/lib/tools.d.ts +2 -0
- package/dist/lib/tools.js +257 -73
- package/dist/lib/tools.js.map +4 -4
- package/editor.html +2 -2
- package/package.json +38 -3
- package/skills/e8-golem/SKILL.md +71 -0
- package/skills/golem-symbol-animation/SKILL.md +87 -0
- package/skills/golem-symbol-animation/agents/openai.yaml +4 -0
- package/skills/golem-symbol-animation/references/facial-controls.md +48 -0
- package/skills/golem-symbol-animation/references/game-engine-integration.md +133 -0
- package/skills/golem-symbol-animation/references/golem-authoring.md +138 -0
- package/skills/golem-symbol-animation/references/interactive-editor.md +17 -0
- package/skills/golem-symbol-animation/references/motion-craft.md +113 -0
- package/skills/golem-symbol-animation/references/packed-delivery.md +88 -0
- package/skills/golem-symbol-animation/references/quantitative-qa.md +106 -0
- package/skills/golem-symbol-animation/references/spine-rive-study.md +87 -0
- package/skills/golem-symbol-animation/scripts/atlas_parts.py +87 -0
- package/skills/golem-symbol-animation/scripts/check_package.py +71 -0
- package/skills/golem-symbol-animation/scripts/image_gates.py +143 -0
- package/skills/golem-symbol-cutting/SKILL.md +70 -0
- package/skills/golem-symbol-cutting/agents/openai.yaml +4 -0
- package/skills/golem-symbol-cutting/assets/h1/h1.atlas.png +0 -0
- package/skills/golem-symbol-cutting/assets/h1/h1.png +0 -0
- package/skills/golem-symbol-cutting/references/cutting-workflow.md +92 -0
- package/skills/golem-symbol-cutting/references/facial-layers.md +44 -0
- package/skills/golem-symbol-cutting/references/generation-workflow.md +109 -0
- package/skills/golem-symbol-cutting/references/golem-handoff.md +62 -0
- package/skills/golem-symbol-cutting/references/h1-example.md +46 -0
- package/skills/golem-symbol-cutting/references/hybrid-workflow.md +119 -0
- package/skills/golem-symbol-cutting/references/registration-and-motion.md +89 -0
- package/skills/golem-symbol-cutting/references/spine-rive-construction.md +73 -0
- package/skills/golem-symbol-cutting/scripts/atlas_parts.py +87 -0
- package/skills/golem-symbol-cutting/scripts/hybrid_parts.py +279 -0
|
@@ -28,5 +28,7 @@ export interface LayerSpec {
|
|
|
28
28
|
blend?: "normal" | "add" | "multiply" | "screen";
|
|
29
29
|
}
|
|
30
30
|
export declare function pngSize(buf: Buffer): [number, number];
|
|
31
|
+
/** `file`, named by a sidecar inside `dir` (layers.json, a Spine atlas), leaves `dir`: absolute or climbing out. */
|
|
32
|
+
export declare function outsideDir(dir: string, file: string): boolean;
|
|
31
33
|
export declare function importLayers(doc: Doc, dir: string, relPrefix?: string): Promise<Doc>;
|
|
32
34
|
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ToolResult } from "./rig-api";
|
|
2
|
+
/** `mtimeMs:size` of the file, or "missing" */
|
|
3
|
+
export declare function rigVersion(abs: string): Promise<string>;
|
|
4
|
+
/**
|
|
5
|
+
* callTool with the rig's version just before and just after, both read inside the rig's queue, so no other writer in
|
|
6
|
+
* this process lands between them. `args.path` must be absolute; a call without one reads "missing" twice.
|
|
7
|
+
*/
|
|
8
|
+
export declare function callToolVersioned(name: string, args: Record<string, unknown>): Promise<{
|
|
9
|
+
result: ToolResult;
|
|
10
|
+
before: string;
|
|
11
|
+
after: string;
|
|
12
|
+
}>;
|
package/dist/lib/runtime.js
CHANGED
|
@@ -159,7 +159,9 @@ var PathAttachment = z.object({
|
|
|
159
159
|
/** curve lengths for constant-speed positioning */
|
|
160
160
|
lengths: z.array(z.number()).default([]),
|
|
161
161
|
closed: z.boolean().default(false),
|
|
162
|
-
constantSpeed: z.boolean().default(true)
|
|
162
|
+
constantSpeed: z.boolean().default(true),
|
|
163
|
+
/** Spine-style active clipping span in the posed draw order; end slot is inclusive. */
|
|
164
|
+
clipping: z.object({ end: Id.optional() }).optional()
|
|
163
165
|
});
|
|
164
166
|
var Attachment = z.discriminatedUnion("type", [RegionAttachment, MeshAttachment, PathAttachment]);
|
|
165
167
|
var IkConstraint = z.object({
|
|
@@ -223,7 +225,9 @@ var Key = z.object({
|
|
|
223
225
|
t: z.number().nonnegative(),
|
|
224
226
|
v: KeyValue,
|
|
225
227
|
/** easing INTO the next key */
|
|
226
|
-
ease: Ease.default("ease_in_out")
|
|
228
|
+
ease: Ease.default("ease_in_out"),
|
|
229
|
+
/** Optional independent easing for numeric-array components (for example Spine RGBA curves). */
|
|
230
|
+
componentEase: z.array(Ease).min(1).optional()
|
|
227
231
|
});
|
|
228
232
|
var Interpolation = { interpolation: z.enum(["segment", "pchip"]).optional() };
|
|
229
233
|
var Track = z.discriminatedUnion("target", [
|
|
@@ -410,6 +414,10 @@ function validate(doc) {
|
|
|
410
414
|
else if (a.slot !== s.id) errs.push(`slot "${s.id}": attachment "${s.attachment}" belongs to slot "${a.slot}"`);
|
|
411
415
|
}
|
|
412
416
|
}
|
|
417
|
+
for (const a of doc.attachments) if (a.type === "path" && a.clipping) {
|
|
418
|
+
if (!a.closed) errs.push(`attachment "${a.id}": clipping path must be closed`);
|
|
419
|
+
if (a.clipping.end && !slots.has(a.clipping.end)) errs.push(`attachment "${a.id}": unknown clipping end slot "${a.clipping.end}"`);
|
|
420
|
+
}
|
|
413
421
|
const vertexCount = (a) => {
|
|
414
422
|
if (a.type === "region") return 4;
|
|
415
423
|
if (a.type === "mesh") return a.uvs.length / 2;
|
|
@@ -493,6 +501,7 @@ function validate(doc) {
|
|
|
493
501
|
const att = t.target === "deform" ? attachments.get(t.id) : void 0;
|
|
494
502
|
let prev = -1;
|
|
495
503
|
for (const k of t.keys) {
|
|
504
|
+
if (k.componentEase && (!Array.isArray(k.v) || !k.v.every((v) => typeof v === "number") || k.componentEase.length !== k.v.length)) errs.push(`animation "${a.id}" ${tid}: componentEase must match the numeric-array value length`);
|
|
496
505
|
if (k.t <= prev && prev >= 0) errs.push(`animation "${a.id}" ${tid}: keys not strictly increasing`);
|
|
497
506
|
if (k.t > a.duration) errs.push(`animation "${a.id}" ${tid}: key at ${k.t}s exceeds duration`);
|
|
498
507
|
if (t.target === "control") {
|
|
@@ -657,8 +666,8 @@ function sample(track, t, loop = false) {
|
|
|
657
666
|
}
|
|
658
667
|
if (Array.isArray(a.v) && Array.isArray(b.v) && typeof a.v[0] === "number") {
|
|
659
668
|
if (track.interpolation === "pchip") return a.v.map((_, j) => smoothValue(track, i, t, j, loop));
|
|
660
|
-
const
|
|
661
|
-
return av.map((v, k) => v + ((bv[k] ?? v) - v) *
|
|
669
|
+
const phase = (t - a.t) / (b.t - a.t), av = a.v, bv = b.v;
|
|
670
|
+
return av.map((v, k) => v + ((bv[k] ?? v) - v) * ease(a.componentEase?.[k] ?? a.ease)(phase));
|
|
662
671
|
}
|
|
663
672
|
return a.v;
|
|
664
673
|
}
|
|
@@ -746,6 +755,13 @@ function boneWorldOf(bone, s, parent) {
|
|
|
746
755
|
if (!parent) return local;
|
|
747
756
|
if (bone.inherit === "normal") return mul(parent, local);
|
|
748
757
|
const [tx, ty] = apply(parent, s.x, s.y);
|
|
758
|
+
if (bone.inherit === "noScale" || bone.inherit === "noScaleOrReflection") {
|
|
759
|
+
const r = s.rotation * DEG2, x = parent.a * Math.cos(r) + parent.c * Math.sin(r), y = parent.b * Math.cos(r) + parent.d * Math.sin(r);
|
|
760
|
+
const length = Math.hypot(x, y), a = length > 1e-5 ? x / length : x, b = length > 1e-5 ? y / length : y;
|
|
761
|
+
const sign = bone.inherit === "noScale" && parent.a * parent.d - parent.b * parent.c < 0 ? -1 : 1;
|
|
762
|
+
const basis2 = { a, b, c: -b * sign, d: a * sign, tx: 0, ty: 0 };
|
|
763
|
+
return { ...mul(basis2, affineOf(0, 0, 0, s.scaleX, s.scaleY, s.shearX, s.shearY)), tx, ty };
|
|
764
|
+
}
|
|
749
765
|
return { ...mul(inheritedParentLinear(bone, parent), { ...local, tx: 0, ty: 0 }), tx, ty };
|
|
750
766
|
}
|
|
751
767
|
var orderCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -778,11 +794,11 @@ var localOf = (doc, pose, b) => {
|
|
|
778
794
|
shearY: num(pose, pk("bone", id, "shearY"), r.shearY)
|
|
779
795
|
};
|
|
780
796
|
};
|
|
781
|
-
function updateSubtree(skel, root) {
|
|
797
|
+
function updateSubtree(skel, root, includeRoot = true) {
|
|
782
798
|
const doc = skel.doc;
|
|
783
799
|
const kids = /* @__PURE__ */ new Map();
|
|
784
800
|
for (const b of doc.bones) if (b.parent) (kids.get(b.parent) ?? kids.set(b.parent, []).get(b.parent)).push(b);
|
|
785
|
-
const stack = [root];
|
|
801
|
+
const stack = includeRoot ? [root] : (kids.get(root) ?? []).map((b) => b.id);
|
|
786
802
|
while (stack.length) {
|
|
787
803
|
const id = stack.pop(), b = boneOf(doc, id), st = skel.bones.get(id);
|
|
788
804
|
st.world = boneWorldOf(b, st, b.parent ? skel.bones.get(b.parent).world : void 0);
|
|
@@ -816,6 +832,23 @@ function evaluate(doc, pose, modifiers) {
|
|
|
816
832
|
}
|
|
817
833
|
return skel;
|
|
818
834
|
}
|
|
835
|
+
function slotClips(skel) {
|
|
836
|
+
const keyed = skel.pose.get(pk("drawOrder", "order", "order"));
|
|
837
|
+
const order = Array.isArray(keyed) ? keyed : [...skel.doc.slots].sort((a, b) => a.z - b.z).map((s) => s.id);
|
|
838
|
+
const masks = /* @__PURE__ */ new Map();
|
|
839
|
+
let active;
|
|
840
|
+
for (const id of order) {
|
|
841
|
+
const att = skel.attachment.get(id);
|
|
842
|
+
if (!active && att?.type === "path" && att.clipping) {
|
|
843
|
+
active = att;
|
|
844
|
+
continue;
|
|
845
|
+
}
|
|
846
|
+
if (active) masks.set(id, active.id);
|
|
847
|
+
if (active?.clipping?.end === id) active = void 0;
|
|
848
|
+
}
|
|
849
|
+
for (const s of skel.doc.slots) if (s.clip) masks.set(s.id, s.clip);
|
|
850
|
+
return masks;
|
|
851
|
+
}
|
|
819
852
|
var cnum = (skel, kind, id, prop, rest) => num(skel.pose, pk(kind, id, prop), typeof rest === "boolean" ? rest ? 1 : 0 : rest);
|
|
820
853
|
var IDENTITY = { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 };
|
|
821
854
|
var wrapRad = (r) => r > Math.PI ? r - 2 * Math.PI : r < -Math.PI ? r + 2 * Math.PI : r;
|
|
@@ -1025,7 +1058,8 @@ function applyTransformConstraint(skel, c) {
|
|
|
1025
1058
|
if (!mixRotate && !mixX && !mixY && !mixScaleX && !mixScaleY && !mixShearY) return;
|
|
1026
1059
|
c = { ...c, ...Object.fromEntries(["x", "y", "rotation", "scaleX", "scaleY", "shearY"].map((p) => [p, cnum(skel, "transform", c.id, p, c[p])])) };
|
|
1027
1060
|
const target = skel.bones.get(c.target), tw = target.world;
|
|
1028
|
-
const
|
|
1061
|
+
const handedness = tw.a * tw.d - tw.b * tw.c < 0 ? -1 : 1;
|
|
1062
|
+
const offsetRotation = c.rotation * DEG2 * (c.local ? 1 : handedness), offsetShearY = c.shearY * DEG2 * (c.local ? 1 : handedness);
|
|
1029
1063
|
for (const id of c.bones) {
|
|
1030
1064
|
const b = boneOf(skel.doc, id), st = skel.bones.get(id);
|
|
1031
1065
|
if (c.local) {
|
|
@@ -1187,6 +1221,7 @@ function applyPathConstraint(skel, c) {
|
|
|
1187
1221
|
const position = cnum(skel, "path", c.id, "position", c.position), spacing = cnum(skel, "path", c.id, "spacing", c.spacing);
|
|
1188
1222
|
const tangents = c.rotateMode === "tangent", scale = c.rotateMode === "chainScale";
|
|
1189
1223
|
const bones = c.bones.map((id) => ({ b: boneOf(skel.doc, id), st: skel.bones.get(id) }));
|
|
1224
|
+
const inputWorlds = bones.map(({ st }) => ({ ...st.world }));
|
|
1190
1225
|
const spacesCount = tangents ? bones.length : bones.length + 1;
|
|
1191
1226
|
const spaces = new Array(spacesCount).fill(0), worldLengths = [];
|
|
1192
1227
|
let sum = 0;
|
|
@@ -1221,9 +1256,10 @@ function applyPathConstraint(skel, c) {
|
|
|
1221
1256
|
if (tw.a * tw.d - tw.b * tw.c < 0) offsetRotation = -offsetRotation;
|
|
1222
1257
|
}
|
|
1223
1258
|
let boneX = samples[0].x, boneY = samples[0].y;
|
|
1259
|
+
const solvedWorlds = /* @__PURE__ */ new Map();
|
|
1224
1260
|
for (let i = 0; i < bones.length; i++) {
|
|
1225
1261
|
const { b, st } = bones[i];
|
|
1226
|
-
let w = { ...
|
|
1262
|
+
let w = { ...inputWorlds[i] };
|
|
1227
1263
|
w.tx += (boneX - w.tx) * mixX;
|
|
1228
1264
|
w.ty += (boneY - w.ty) * mixY;
|
|
1229
1265
|
const next = samples[i + 1] ?? { x: 0, y: 0, angle: 0 };
|
|
@@ -1253,7 +1289,11 @@ function applyPathConstraint(skel, c) {
|
|
|
1253
1289
|
const cos = Math.cos(r), sin = Math.sin(r);
|
|
1254
1290
|
w = { a: cos * a - sin * bb, b: sin * a + cos * bb, c: cos * cc - sin * d, d: sin * cc + cos * d, tx: w.tx, ty: w.ty };
|
|
1255
1291
|
}
|
|
1256
|
-
|
|
1292
|
+
solvedWorlds.set(b.id, w);
|
|
1293
|
+
}
|
|
1294
|
+
for (const b of boneOrder(skel.doc)) {
|
|
1295
|
+
const world = solvedWorlds.get(b.id);
|
|
1296
|
+
if (world) setEffectiveWorld(skel, b, skel.bones.get(b.id), world);
|
|
1257
1297
|
}
|
|
1258
1298
|
}
|
|
1259
1299
|
function measuredPathLength(points, closed, lengths, constantSpeed) {
|
|
@@ -1282,9 +1322,14 @@ function inheritedParentLinear(bone, parent) {
|
|
|
1282
1322
|
case "onlyTranslation":
|
|
1283
1323
|
return { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 };
|
|
1284
1324
|
case "noRotationOrReflection": {
|
|
1285
|
-
const lenX = Math.hypot(parent.a, parent.b)
|
|
1325
|
+
const lenX = Math.hypot(parent.a, parent.b);
|
|
1286
1326
|
const det = parent.a * parent.d - parent.b * parent.c;
|
|
1287
|
-
|
|
1327
|
+
if (lenX * lenX <= 1e-4) {
|
|
1328
|
+
const lenY = Math.hypot(parent.c, parent.d), ux2 = lenY ? parent.c / lenY : 0, uy2 = lenY ? parent.d / lenY : 0;
|
|
1329
|
+
return { a: lenY * ux2 * ux2, b: lenY * ux2 * uy2, c: lenY * ux2 * uy2, d: lenY * uy2 * uy2, tx: 0, ty: 0 };
|
|
1330
|
+
}
|
|
1331
|
+
const ux = parent.a / lenX, uy = parent.b / lenX, sy = Math.abs(det) / lenX;
|
|
1332
|
+
return { a: lenX * ux * ux + sy * uy * uy, b: (lenX - sy) * ux * uy, c: (lenX - sy) * ux * uy, d: lenX * uy * uy + sy * ux * ux, tx: 0, ty: 0 };
|
|
1288
1333
|
}
|
|
1289
1334
|
case "noScale":
|
|
1290
1335
|
case "noScaleOrReflection": {
|
|
@@ -1310,7 +1355,16 @@ function setEffectiveWorld(skel, bone, st, world) {
|
|
|
1310
1355
|
st.scaleY = Math.hypot(lin.c, lin.d);
|
|
1311
1356
|
st.shearX = 0;
|
|
1312
1357
|
st.shearY = shortest(Math.atan2(lin.d, lin.c) / DEG2 - st.rotation - 90);
|
|
1313
|
-
|
|
1358
|
+
if (parent && (bone.inherit === "noScale" || bone.inherit === "noScaleOrReflection")) {
|
|
1359
|
+
const direction = mul(invert({ ...parent, tx: 0, ty: 0 }), { ...world, tx: 0, ty: 0 });
|
|
1360
|
+
st.rotation = Math.atan2(direction.b, direction.a) / DEG2;
|
|
1361
|
+
st.scaleX = Math.hypot(world.a, world.b);
|
|
1362
|
+
st.scaleY = Math.hypot(world.c, world.d);
|
|
1363
|
+
const sign = bone.inherit === "noScale" && parent.a * parent.d - parent.b * parent.c < 0 ? -1 : 1;
|
|
1364
|
+
st.shearY = shortest((Math.atan2(world.d, world.c) - Math.atan2(world.b, world.a)) / DEG2 * sign - 90);
|
|
1365
|
+
}
|
|
1366
|
+
st.world = world;
|
|
1367
|
+
updateSubtree(skel, bone.id, false);
|
|
1314
1368
|
}
|
|
1315
1369
|
function attachmentWorldVertices(skel, slotId, att) {
|
|
1316
1370
|
const deform = skel.pose.get(pk("deform", att.id, "vertices"));
|
|
@@ -1709,7 +1763,7 @@ var RigPlayer = class {
|
|
|
1709
1763
|
this.clipPoints.clear();
|
|
1710
1764
|
const skel = this.skel = evaluate(this.doc, pose, this.beforePose);
|
|
1711
1765
|
pose = skel.pose;
|
|
1712
|
-
const clips = new Set(
|
|
1766
|
+
const masks = slotClips(skel), clips = new Set(masks.values());
|
|
1713
1767
|
for (const [id, g] of this.clipGraphics) if (!clips.has(id)) {
|
|
1714
1768
|
g.destroy();
|
|
1715
1769
|
this.clipGraphics.delete(id);
|
|
@@ -1736,7 +1790,8 @@ var RigPlayer = class {
|
|
|
1736
1790
|
if (Array.isArray(orderV)) orderV.forEach((id, i) => order.set(id, i));
|
|
1737
1791
|
for (const it of this.items) {
|
|
1738
1792
|
const s = it.slot, shown = skel.attachment.get(s.id);
|
|
1739
|
-
|
|
1793
|
+
const mask = masks.get(s.id);
|
|
1794
|
+
it.node.mask = mask ? this.clipGraphics.get(mask) ?? null : null;
|
|
1740
1795
|
if (shown !== it.att || this.hidden.has(s.id)) {
|
|
1741
1796
|
it.node.visible = false;
|
|
1742
1797
|
continue;
|