@energy8platform/golem 0.2.1 → 0.5.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.
Files changed (38) hide show
  1. package/README.md +28 -2
  2. package/dist/editor.css +50 -0
  3. package/dist/editor.js +1772 -1037
  4. package/dist/lib/cli.js +1575 -366
  5. package/dist/lib/cli.js.map +4 -4
  6. package/dist/lib/editor/controls-panel.d.ts +2 -0
  7. package/dist/lib/editor/stage.d.ts +1 -0
  8. package/dist/lib/editor/store.d.ts +212 -33
  9. package/dist/lib/editor-entry.js +1575 -366
  10. package/dist/lib/editor-entry.js.map +4 -4
  11. package/dist/lib/harness.js +328 -31
  12. package/dist/lib/interactive-bones.d.ts +37 -0
  13. package/dist/lib/interactive-editor.d.ts +80 -0
  14. package/dist/lib/interactive-editor.js +744 -0
  15. package/dist/lib/interactive-editor.js.map +7 -0
  16. package/dist/lib/preview/export-video.d.ts +12 -0
  17. package/dist/lib/preview/harness.d.ts +2 -0
  18. package/dist/lib/preview/render-preview.d.ts +6 -0
  19. package/dist/lib/rig-anim.d.ts +6 -3
  20. package/dist/lib/rig-check.d.ts +2 -1
  21. package/dist/lib/rig-constraints.d.ts +63 -0
  22. package/dist/lib/rig-control-qa.d.ts +319 -0
  23. package/dist/lib/rig-controls.d.ts +13 -0
  24. package/dist/lib/rig-format.d.ts +1469 -331
  25. package/dist/lib/rig-gates.d.ts +209 -0
  26. package/dist/lib/rig-mesh.d.ts +1 -0
  27. package/dist/lib/rig-motion.d.ts +22 -0
  28. package/dist/lib/rig-qa.d.ts +35 -0
  29. package/dist/lib/rig-quality.d.ts +12 -0
  30. package/dist/lib/rig-runtime.d.ts +43 -3
  31. package/dist/lib/rig-state.d.ts +3 -0
  32. package/dist/lib/rig-tools.d.ts +5 -1
  33. package/dist/lib/runtime.d.ts +3 -1
  34. package/dist/lib/runtime.js +306 -28
  35. package/dist/lib/runtime.js.map +4 -4
  36. package/dist/lib/tools.js +1557 -348
  37. package/dist/lib/tools.js.map +4 -4
  38. package/package.json +8 -2
@@ -0,0 +1,209 @@
1
+ /** Brief-specific pass/fail measurements over the real evaluator and AnimationState. */
2
+ import { z } from 'zod';
3
+ import type { RigDocument } from './rig-format';
4
+ export declare const GateConfig: z.ZodObject<{
5
+ animation: z.ZodString;
6
+ fps: z.ZodDefault<z.ZodNumber>;
7
+ requiredAnimations: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
8
+ motion: z.ZodDefault<z.ZodArray<z.ZodObject<{
9
+ bone: z.ZodString;
10
+ channel: z.ZodDefault<z.ZodEnum<["position", "rotation"]>>;
11
+ space: z.ZodDefault<z.ZodEnum<["world", "local"]>>;
12
+ minAmplitude: z.ZodOptional<z.ZodNumber>;
13
+ maxSpeed: z.ZodOptional<z.ZodNumber>;
14
+ maxAcceleration: z.ZodOptional<z.ZodNumber>;
15
+ maxJerk: z.ZodOptional<z.ZodNumber>;
16
+ maxStep: z.ZodOptional<z.ZodNumber>;
17
+ maxSetupDrift: z.ZodOptional<z.ZodNumber>;
18
+ during: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
19
+ }, "strip", z.ZodTypeAny, {
20
+ bone: string;
21
+ channel: "rotation" | "position";
22
+ space: "local" | "world";
23
+ minAmplitude?: number | undefined;
24
+ maxSpeed?: number | undefined;
25
+ maxAcceleration?: number | undefined;
26
+ maxJerk?: number | undefined;
27
+ maxStep?: number | undefined;
28
+ maxSetupDrift?: number | undefined;
29
+ during?: [number, number] | undefined;
30
+ }, {
31
+ bone: string;
32
+ channel?: "rotation" | "position" | undefined;
33
+ space?: "local" | "world" | undefined;
34
+ minAmplitude?: number | undefined;
35
+ maxSpeed?: number | undefined;
36
+ maxAcceleration?: number | undefined;
37
+ maxJerk?: number | undefined;
38
+ maxStep?: number | undefined;
39
+ maxSetupDrift?: number | undefined;
40
+ during?: [number, number] | undefined;
41
+ }>, "many">>;
42
+ distances: z.ZodDefault<z.ZodArray<z.ZodObject<{
43
+ a: z.ZodString;
44
+ b: z.ZodString;
45
+ min: z.ZodOptional<z.ZodNumber>;
46
+ max: z.ZodOptional<z.ZodNumber>;
47
+ minRatio: z.ZodOptional<z.ZodNumber>;
48
+ maxRatio: z.ZodOptional<z.ZodNumber>;
49
+ during: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
50
+ }, "strip", z.ZodTypeAny, {
51
+ b: string;
52
+ a: string;
53
+ min?: number | undefined;
54
+ max?: number | undefined;
55
+ during?: [number, number] | undefined;
56
+ minRatio?: number | undefined;
57
+ maxRatio?: number | undefined;
58
+ }, {
59
+ b: string;
60
+ a: string;
61
+ min?: number | undefined;
62
+ max?: number | undefined;
63
+ during?: [number, number] | undefined;
64
+ minRatio?: number | undefined;
65
+ maxRatio?: number | undefined;
66
+ }>, "many">>;
67
+ conditions: z.ZodDefault<z.ZodArray<z.ZodObject<{
68
+ whenSlotVisible: z.ZodString;
69
+ bone: z.ZodString;
70
+ prop: z.ZodEnum<["x", "y", "rotation"]>;
71
+ space: z.ZodDefault<z.ZodEnum<["world", "local"]>>;
72
+ min: z.ZodOptional<z.ZodNumber>;
73
+ max: z.ZodOptional<z.ZodNumber>;
74
+ required: z.ZodDefault<z.ZodBoolean>;
75
+ }, "strip", z.ZodTypeAny, {
76
+ bone: string;
77
+ prop: "x" | "y" | "rotation";
78
+ space: "local" | "world";
79
+ whenSlotVisible: string;
80
+ required: boolean;
81
+ min?: number | undefined;
82
+ max?: number | undefined;
83
+ }, {
84
+ bone: string;
85
+ prop: "x" | "y" | "rotation";
86
+ whenSlotVisible: string;
87
+ min?: number | undefined;
88
+ max?: number | undefined;
89
+ space?: "local" | "world" | undefined;
90
+ required?: boolean | undefined;
91
+ }>, "many">>;
92
+ transitions: z.ZodDefault<z.ZodArray<z.ZodObject<{
93
+ from: z.ZodString;
94
+ to: z.ZodString;
95
+ fromTime: z.ZodDefault<z.ZodNumber>;
96
+ mix: z.ZodDefault<z.ZodNumber>;
97
+ maxStep: z.ZodNumber;
98
+ duration: z.ZodDefault<z.ZodNumber>;
99
+ }, "strip", z.ZodTypeAny, {
100
+ mix: number;
101
+ duration: number;
102
+ maxStep: number;
103
+ from: string;
104
+ to: string;
105
+ fromTime: number;
106
+ }, {
107
+ maxStep: number;
108
+ from: string;
109
+ to: string;
110
+ mix?: number | undefined;
111
+ duration?: number | undefined;
112
+ fromTime?: number | undefined;
113
+ }>, "many">>;
114
+ }, "strict", z.ZodTypeAny, {
115
+ animation: string;
116
+ fps: number;
117
+ requiredAnimations: string[];
118
+ motion: {
119
+ bone: string;
120
+ channel: "rotation" | "position";
121
+ space: "local" | "world";
122
+ minAmplitude?: number | undefined;
123
+ maxSpeed?: number | undefined;
124
+ maxAcceleration?: number | undefined;
125
+ maxJerk?: number | undefined;
126
+ maxStep?: number | undefined;
127
+ maxSetupDrift?: number | undefined;
128
+ during?: [number, number] | undefined;
129
+ }[];
130
+ distances: {
131
+ b: string;
132
+ a: string;
133
+ min?: number | undefined;
134
+ max?: number | undefined;
135
+ during?: [number, number] | undefined;
136
+ minRatio?: number | undefined;
137
+ maxRatio?: number | undefined;
138
+ }[];
139
+ conditions: {
140
+ bone: string;
141
+ prop: "x" | "y" | "rotation";
142
+ space: "local" | "world";
143
+ whenSlotVisible: string;
144
+ required: boolean;
145
+ min?: number | undefined;
146
+ max?: number | undefined;
147
+ }[];
148
+ transitions: {
149
+ mix: number;
150
+ duration: number;
151
+ maxStep: number;
152
+ from: string;
153
+ to: string;
154
+ fromTime: number;
155
+ }[];
156
+ }, {
157
+ animation: string;
158
+ fps?: number | undefined;
159
+ requiredAnimations?: string[] | undefined;
160
+ motion?: {
161
+ bone: string;
162
+ channel?: "rotation" | "position" | undefined;
163
+ space?: "local" | "world" | undefined;
164
+ minAmplitude?: number | undefined;
165
+ maxSpeed?: number | undefined;
166
+ maxAcceleration?: number | undefined;
167
+ maxJerk?: number | undefined;
168
+ maxStep?: number | undefined;
169
+ maxSetupDrift?: number | undefined;
170
+ during?: [number, number] | undefined;
171
+ }[] | undefined;
172
+ distances?: {
173
+ b: string;
174
+ a: string;
175
+ min?: number | undefined;
176
+ max?: number | undefined;
177
+ during?: [number, number] | undefined;
178
+ minRatio?: number | undefined;
179
+ maxRatio?: number | undefined;
180
+ }[] | undefined;
181
+ conditions?: {
182
+ bone: string;
183
+ prop: "x" | "y" | "rotation";
184
+ whenSlotVisible: string;
185
+ min?: number | undefined;
186
+ max?: number | undefined;
187
+ space?: "local" | "world" | undefined;
188
+ required?: boolean | undefined;
189
+ }[] | undefined;
190
+ transitions?: {
191
+ maxStep: number;
192
+ from: string;
193
+ to: string;
194
+ mix?: number | undefined;
195
+ duration?: number | undefined;
196
+ fromTime?: number | undefined;
197
+ }[] | undefined;
198
+ }>;
199
+ export type GateConfig = z.infer<typeof GateConfig>;
200
+ export declare function runGates(doc: RigDocument, config: z.input<typeof GateConfig>): {
201
+ pass: boolean;
202
+ animation: string;
203
+ fps: number;
204
+ interval: number;
205
+ expected: number;
206
+ inspected: number;
207
+ metrics: Record<string, unknown>;
208
+ failures: string[];
209
+ };
@@ -10,6 +10,7 @@ export interface TraceOptions {
10
10
  threshold?: number;
11
11
  tolerance?: number;
12
12
  margin?: number;
13
+ minIslandRatio?: number;
13
14
  }
14
15
  /**
15
16
  * Every separate opaque island's outline, simplified and offset, largest first. A layer is not always one blob —
@@ -0,0 +1,22 @@
1
+ /** Reusable authoring operations. All output is ordinary editable tracks and constraints. */
2
+ import type { RigDocument } from './rig-format';
3
+ /** Blend between neighbouring chain joints by projected distance along the polyline. */
4
+ export declare function gradientWeights(doc: RigDocument, id: string, bones: string[]): RigDocument;
5
+ /** Smooth through triangle adjacency; locked vertices are fixed boundary conditions. */
6
+ export declare function smoothWeights(doc: RigDocument, id: string, iterations?: number, strength?: number, locked?: number[]): RigDocument;
7
+ /** Rigid or mixed binding for a vertex selection or document-space rectangle. */
8
+ export declare function pinWeights(doc: RigDocument, id: string, bone: string, vertices?: number[], region?: [number, number, number, number]): RigDocument;
9
+ /** Switch following controls while preserving the evaluated world pose at the contact time. */
10
+ export declare function attachToBone(doc: RigDocument, animation: string, bone: string, target: string, t: number): RigDocument;
11
+ export interface SpringOptions {
12
+ driver: string;
13
+ driverProp?: "rotation" | "x" | "y";
14
+ bones: string[];
15
+ frequency?: number;
16
+ damping?: number;
17
+ gain?: number;
18
+ fps?: number;
19
+ maxAngle?: number;
20
+ }
21
+ /** Velocity-driven damped oscillator, baked at uniform times. No runtime simulation is needed. */
22
+ export declare function bakeSecondary(doc: RigDocument, animation: string, opts: SpringOptions): RigDocument;
@@ -0,0 +1,35 @@
1
+ export declare const sha256: (data: string | Buffer) => string;
2
+ export interface CaptureIdentity {
3
+ document: string;
4
+ assets: Record<string, string>;
5
+ renderer: string;
6
+ masks: Record<string, string>;
7
+ }
8
+ export interface RenderManifest {
9
+ version: 1;
10
+ rigFile: string;
11
+ capturedAt: string;
12
+ identity: CaptureIdentity;
13
+ animation: string | null;
14
+ transparent: boolean;
15
+ scale: number;
16
+ times: number[];
17
+ render: {
18
+ background?: string;
19
+ overlayBones: boolean;
20
+ onionSkin: boolean;
21
+ weightBone?: string;
22
+ debugFillMasks: Record<string, string>;
23
+ region?: [number, number, number, number];
24
+ };
25
+ frames: {
26
+ file: string;
27
+ sha256: string;
28
+ }[];
29
+ }
30
+ export declare function verifyRenderManifest(rigPath: string, framesDir: string, expected: {
31
+ animation?: string;
32
+ times: number[];
33
+ renderer: string;
34
+ transparent?: boolean;
35
+ }): Promise<RenderManifest>;
@@ -0,0 +1,12 @@
1
+ /** Motion diagnostics describe measured evidence; semantic rules are supplied by the brief. */
2
+ import type { Animation, RigDocument } from './rig-format';
3
+ import type { Finding } from './rig-check';
4
+ export interface QualityOptions {
5
+ secondaryBones?: string[];
6
+ /** [foreground, background] slot pairs from the art brief, e.g. face above scarf. */
7
+ frontOf?: [string, string][];
8
+ /** Attachment → named normalized image coordinates (0..1). */
9
+ landmarks?: Record<string, Record<string, [number, number]>>;
10
+ landmarkTolerance?: number;
11
+ }
12
+ export declare function motionQuality(doc: RigDocument, anim: Animation, opts?: QualityOptions): Finding[];
@@ -8,8 +8,8 @@
8
8
  * - play/tick/stop are a thin wrapper over an AnimationState (see rig-state.ts) kept for simple consumers
9
9
  * (harness, viewer). Games should drive `state` directly for queues, priorities and overlays.
10
10
  */
11
- import { Container, Texture } from "pixi.js";
12
- import { type RigDocument, type Asset } from "./rig-format";
11
+ import { Container, Sprite, Mesh, MeshPlane, Texture } from "pixi.js";
12
+ import { type RigDocument, type Slot, type Attachment, type Asset } from "./rig-format";
13
13
  import { type Pose, type Affine } from "./rig-anim";
14
14
  import { AnimationState, type PlayResult } from "./rig-state";
15
15
  /** vertices per axis of a lattice-deformed region's render mesh (8 segments) */
@@ -23,6 +23,22 @@ export interface PlayOptions {
23
23
  onComplete?: () => void;
24
24
  onEvent?: (name: string, payload?: Record<string, unknown>) => void;
25
25
  }
26
+ export interface RigRenderItem {
27
+ att: Attachment;
28
+ slot: Slot;
29
+ node: Sprite | MeshPlane | Mesh;
30
+ /** lattice-deformed region */
31
+ lattice?: {
32
+ plane: MeshPlane;
33
+ offsets: Float64Array;
34
+ applied: Float64Array;
35
+ };
36
+ /** skinned mesh */
37
+ skinned?: {
38
+ mesh: Mesh;
39
+ positions: Float32Array;
40
+ };
41
+ }
26
42
  /** Build the asset-id → Texture map, loading each `src` once and cutting atlas frames (with rotation and trim). */
27
43
  export declare function createTextures(doc: RigDocument, loadSource: (src: string) => Promise<Texture>): Promise<Map<string, Texture>>;
28
44
  /**
@@ -32,9 +48,17 @@ export declare function createTextures(doc: RigDocument, loadSource: (src: strin
32
48
  export declare function atlasUV(asset: Asset, u: number, v: number, sourceW: number, sourceH: number): [number, number];
33
49
  export declare class RigPlayer {
34
50
  doc: RigDocument;
51
+ private inputPose;
52
+ private controlOverrides;
53
+ /** Manual inputs override animated controls until resetControls; values are clamped to declared ranges. */
54
+ setControls(values: Record<string, number>): void;
55
+ resetControls(): void;
35
56
  readonly view: Container<import("pixi.js").ContainerChild>;
36
57
  readonly state: AnimationState;
37
58
  private items;
59
+ private beforePose;
60
+ private afterPose;
61
+ private clipPoints;
38
62
  private skel;
39
63
  private textures;
40
64
  private pages;
@@ -42,10 +66,26 @@ export declare class RigPlayer {
42
66
  private hidden;
43
67
  /** slots the editor has selected; setPose draws them at GHOST_ALPHA at least */
44
68
  private ghosts;
45
- /** `mix`: default crossfade seconds for state transitions (setBase, completion → base); play() passes its own */
69
+ private clipGraphics;
70
+ /** Default crossfade is 0.18 seconds; explicit mix: 0 requests a hard cut. */
46
71
  constructor(doc: RigDocument, textures: Map<string, Texture>, opts?: {
47
72
  mix?: number;
73
+ missingAnimation?: "warn" | "throw";
74
+ onWarning?: (message: string) => void;
48
75
  });
76
+ /** Read-only render handles for in-page tools. Nodes remain owned by the player. */
77
+ get renderItems(): readonly Readonly<RigRenderItem>[];
78
+ /** Current document-space clipping polygons, keyed by path attachment id. */
79
+ get clipPolygons(): ReadonlyMap<string, readonly number[]>;
80
+ /**
81
+ * Modify resolved control outputs before skeleton evaluation, constraints and skinning.
82
+ * Callbacks run in registration order, each with its own map. Change control inputs via setControls.
83
+ */
84
+ onBeforePose(callback: (pose: Pose) => Pose): () => void;
85
+ /** Subscribe after the base pose has been rebuilt. Return value removes the callback. */
86
+ onAfterPose(callback: (player: RigPlayer) => void): () => void;
87
+ /** Rebuild the current pose without advancing playback; useful for reversible overlays. */
88
+ refreshPose(): void;
49
89
  /** whole atlas page as a plain texture (identity uv mapping) for skinned meshes */
50
90
  private pageTexture;
51
91
  /** Replace whatever is playing (no queueing). Resolves when the animation completes or is replaced. */
@@ -30,6 +30,7 @@ export interface PlayOptions {
30
30
  }
31
31
  export declare class AnimationState {
32
32
  private readonly sink;
33
+ private readonly opts;
33
34
  onEvent?: (name: string, payload?: Record<string, unknown>) => void;
34
35
  private base?;
35
36
  private main?;
@@ -45,6 +46,8 @@ export declare class AnimationState {
45
46
  private readonly defaultMix;
46
47
  constructor(sink: PoseSink, opts?: {
47
48
  mix?: number;
49
+ missingAnimation?: "warn" | "throw";
50
+ onWarning?: (message: string) => void;
48
51
  });
49
52
  /** id of the animation currently shown (main, else base) */
50
53
  get current(): string | undefined;
@@ -85,7 +85,10 @@ export declare function placeAsset(doc: Doc, p: {
85
85
  z?: number;
86
86
  }): Doc;
87
87
  /** Parts-first regeneration prompt for one layer: style anchor + provenance + rig context + chroma-key rules. */
88
- export declare function layerPrompt(doc: Doc, assetId: string): string;
88
+ export declare function layerPrompt(doc: Doc, assetId: string, opts?: {
89
+ method?: "part" | "repair";
90
+ removed?: string[];
91
+ }): string;
89
92
  export type MetaPatch = {
90
93
  name?: string;
91
94
  width?: number;
@@ -200,6 +203,7 @@ export declare function addIkChain(doc: Doc, bone: string, opts?: {
200
203
  target?: string;
201
204
  mix?: number;
202
205
  softness?: number;
206
+ bones?: string[];
203
207
  }): {
204
208
  doc: Doc;
205
209
  chain: string[];
@@ -2,8 +2,10 @@
2
2
  * `@energy8platform/golem/runtime` — the browser half: play a rig document in PixiJS v8.
3
3
  * Depends on pixi.js (peer) and zod only; no node, no tools, no editor.
4
4
  */
5
- export { RigPlayer, createTextures, atlasUV, MESH_GRID, type PlayOptions } from "./rig-runtime";
5
+ export { RigPlayer, createTextures, atlasUV, MESH_GRID, type PlayOptions, type RigRenderItem } from "./rig-runtime";
6
6
  export { RigSymbol, type RigSymbolOptions, type SymbolSize, type SymbolViewLike, type TickerLike } from "./rig-symbol";
7
7
  export { AnimationState, type PlayResult, type PoseSink } from "./rig-state";
8
8
  export { parse, validate, migrateV1, RigDocument as RigDocumentSchema } from "./rig-format";
9
9
  export type { RigDocument, Bone, Slot, Asset, Attachment, Animation, Track, Key } from "./rig-format";
10
+ export type { RigControl, ControlBinding } from "./rig-format";
11
+ export { controlPose, resolveControls, sampleBinding } from "./rig-controls";