@energy8platform/golem 0.1.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 +376 -0
- package/bin/golem.js +2 -0
- package/dist/editor.css +701 -0
- package/dist/editor.js +59202 -0
- package/dist/lib/cli.d.ts +1 -0
- package/dist/lib/cli.js +5521 -0
- package/dist/lib/cli.js.map +7 -0
- package/dist/lib/editor/api.d.ts +42 -0
- package/dist/lib/editor/app.d.ts +13 -0
- package/dist/lib/editor/atlas-detect.d.ts +28 -0
- package/dist/lib/editor/atlas-panel.d.ts +1 -0
- package/dist/lib/editor/atlas.d.ts +39 -0
- package/dist/lib/editor/gizmo-math.d.ts +36 -0
- package/dist/lib/editor/gizmos.d.ts +185 -0
- package/dist/lib/editor/layers.d.ts +1 -0
- package/dist/lib/editor/library.d.ts +3 -0
- package/dist/lib/editor/panels.d.ts +26 -0
- package/dist/lib/editor/props.d.ts +19 -0
- package/dist/lib/editor/server.d.ts +11 -0
- package/dist/lib/editor/stage.d.ts +222 -0
- package/dist/lib/editor/store.d.ts +1053 -0
- package/dist/lib/editor/timeline-layout.d.ts +64 -0
- package/dist/lib/editor/timeline.d.ts +45 -0
- package/dist/lib/editor-entry.d.ts +2 -0
- package/dist/lib/editor-entry.js +5490 -0
- package/dist/lib/editor-entry.js.map +7 -0
- package/dist/lib/harness.js +51012 -0
- package/dist/lib/ktx2.d.ts +15 -0
- package/dist/lib/mcp-server.d.ts +2 -0
- package/dist/lib/preview/harness.d.ts +16 -0
- package/dist/lib/preview/render-preview.d.ts +27 -0
- package/dist/lib/preview/viewer.d.ts +1 -0
- package/dist/lib/rig-anim.d.ts +109 -0
- package/dist/lib/rig-api.d.ts +26 -0
- package/dist/lib/rig-atlas.d.ts +20 -0
- package/dist/lib/rig-check.d.ts +45 -0
- package/dist/lib/rig-constraints.d.ts +59 -0
- package/dist/lib/rig-deform.d.ts +27 -0
- package/dist/lib/rig-format.d.ts +5036 -0
- package/dist/lib/rig-history.d.ts +21 -0
- package/dist/lib/rig-import-layers.d.ts +32 -0
- package/dist/lib/rig-io.d.ts +9 -0
- package/dist/lib/rig-mesh-image.d.ts +2 -0
- package/dist/lib/rig-mesh.d.ts +143 -0
- package/dist/lib/rig-path.d.ts +101 -0
- package/dist/lib/rig-presets.d.ts +101 -0
- package/dist/lib/rig-queue.d.ts +2 -0
- package/dist/lib/rig-runtime.d.ts +70 -0
- package/dist/lib/rig-state.d.ts +64 -0
- package/dist/lib/rig-symbol.d.ts +60 -0
- package/dist/lib/rig-template-library.d.ts +3 -0
- package/dist/lib/rig-templates.d.ts +46 -0
- package/dist/lib/rig-tools.d.ts +376 -0
- package/dist/lib/runtime.d.ts +9 -0
- package/dist/lib/runtime.js +1584 -0
- package/dist/lib/runtime.js.map +7 -0
- package/dist/lib/spine-import.d.ts +68 -0
- package/dist/lib/tools.d.ts +2 -0
- package/dist/lib/tools.js +5242 -0
- package/dist/lib/tools.js.map +7 -0
- package/editor.html +3 -0
- package/package.json +96 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rig-templates — turn a finished animation into a reusable preset ("rig_save_as_preset").
|
|
3
|
+
*
|
|
4
|
+
* A template stores tracks relative to the source rig's rest pose and keyed by bone `role`, so it can be
|
|
5
|
+
* instantiated on a different rig: bone x/y/rotation as deltas, scale as ratios, slot alpha as a delta,
|
|
6
|
+
* deform params as-is, attachment/z unchanged. Params are scalar multipliers: `amplitude` (every relative
|
|
7
|
+
* value), `speed` (time), plus optional named groups that scale only the listed source tracks.
|
|
8
|
+
* Pure (no node:*) so the editor bundles it and previews param changes locally; the library on disk
|
|
9
|
+
* (a JSON array of templates, `presets.json` next to the rig by default) lives in `rig-template-library.ts`.
|
|
10
|
+
*/
|
|
11
|
+
import type { RigDocument, Animation, Track } from "./rig-format";
|
|
12
|
+
type Key = Track["keys"][number];
|
|
13
|
+
export interface TemplateTrack {
|
|
14
|
+
target: Track["target"];
|
|
15
|
+
/** source id (bone or slot) — used when the target rig has no matching role */
|
|
16
|
+
id: string;
|
|
17
|
+
/** role of the bone (or of the slot's bone) in the source rig */
|
|
18
|
+
role?: string;
|
|
19
|
+
prop: string;
|
|
20
|
+
/** values relative to rest (see module doc) */
|
|
21
|
+
keys: Key[];
|
|
22
|
+
}
|
|
23
|
+
export interface TemplateParam {
|
|
24
|
+
default: number; /** source track ids `target.id.prop`; absent = every track */
|
|
25
|
+
tracks?: string[];
|
|
26
|
+
}
|
|
27
|
+
export interface AnimationTemplate {
|
|
28
|
+
name: string;
|
|
29
|
+
duration: number;
|
|
30
|
+
loop: boolean;
|
|
31
|
+
events: Animation["events"];
|
|
32
|
+
tracks: TemplateTrack[];
|
|
33
|
+
params: Record<string, TemplateParam>;
|
|
34
|
+
/** source track ids left out because their keys are arrays (see `extractTemplate`) — absent when nothing was */
|
|
35
|
+
skipped?: string[];
|
|
36
|
+
source: {
|
|
37
|
+
rig: string;
|
|
38
|
+
animation: string;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export declare function extractTemplate(doc: RigDocument, animId: string, name: string, groups?: Record<string, string[]>): AnimationTemplate;
|
|
42
|
+
export declare function instantiateTemplate(doc: RigDocument, tpl: AnimationTemplate, params?: Record<string, number>, id?: string): Animation;
|
|
43
|
+
/** replace/add the instantiated animation in the document */
|
|
44
|
+
export declare function applyTemplate(doc: RigDocument, tpl: AnimationTemplate, params?: Record<string, number>, id?: string): RigDocument;
|
|
45
|
+
export declare function describeTemplate(t: AnimationTemplate): string;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rig-tools v0 — pure operations over RigDocument. No UI, no MCP; both sit on top of this.
|
|
3
|
+
* Every op returns a NEW document (undo-friendly, MCP-friendly).
|
|
4
|
+
*/
|
|
5
|
+
import { type RigDocument, type Bone, type Slot, type Track, type Attachment, type RegionAttachment, type MeshAttachment, type Influence, type Animation, type Reference, type Asset } from "./rig-format";
|
|
6
|
+
import { type EaseSpec } from "./rig-anim";
|
|
7
|
+
import { type Pt } from "./rig-constraints";
|
|
8
|
+
type Doc = RigDocument;
|
|
9
|
+
type Key = Track["keys"][number];
|
|
10
|
+
type Transform = Bone["transform"];
|
|
11
|
+
/** patches may give any subset of transform fields; `parent: null` detaches the bone (makes it a root) */
|
|
12
|
+
export type BonePatch = Partial<Omit<Bone, "id" | "transform" | "parent">> & {
|
|
13
|
+
parent?: string | null;
|
|
14
|
+
transform?: Partial<Transform>;
|
|
15
|
+
};
|
|
16
|
+
export type SlotPatch = Partial<Omit<Slot, "id">>;
|
|
17
|
+
export type KeyInput = Omit<Key, "ease"> & {
|
|
18
|
+
ease?: Key["ease"];
|
|
19
|
+
};
|
|
20
|
+
/** region placement: image centre in the slot bone's space */
|
|
21
|
+
export type RegionPlacement = {
|
|
22
|
+
x?: number;
|
|
23
|
+
y?: number;
|
|
24
|
+
rotation?: number;
|
|
25
|
+
scaleX?: number;
|
|
26
|
+
scaleY?: number;
|
|
27
|
+
width?: number;
|
|
28
|
+
height?: number;
|
|
29
|
+
};
|
|
30
|
+
export declare function createDoc(name: string, width: number, height: number, notes?: string): Doc;
|
|
31
|
+
/** One image as a rig: canvas = image + margin on every side, root at the image's bottom centre, slot pivot (0.5, 1). */
|
|
32
|
+
export declare function createSymbol(name: string, asset: {
|
|
33
|
+
id?: string;
|
|
34
|
+
src: string;
|
|
35
|
+
width: number;
|
|
36
|
+
height: number;
|
|
37
|
+
}, margin?: number, notes?: string): Doc;
|
|
38
|
+
/** Swap a layer's file (e.g. after regeneration). Pivots are fractions, so slots keep working; provenance is merged. */
|
|
39
|
+
export declare function replaceAsset(doc: Doc, id: string, next: {
|
|
40
|
+
src: string;
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
prompt?: string;
|
|
44
|
+
sourceImage?: string;
|
|
45
|
+
inpainted?: boolean;
|
|
46
|
+
bbox?: [number, number, number, number];
|
|
47
|
+
}): Doc;
|
|
48
|
+
export type AssetPatch = {
|
|
49
|
+
src?: string;
|
|
50
|
+
width?: number;
|
|
51
|
+
height?: number;
|
|
52
|
+
frame?: [number, number, number, number] | null;
|
|
53
|
+
origin?: Asset["origin"];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Create or patch an asset. `image` is the size of the PNG `src` names (the caller reads it — this module cannot
|
|
57
|
+
* read files); a `frame` must fit inside it. Size is only derived from `frame`/`image` when this patch actually
|
|
58
|
+
* REFRAMES (a `frame` or `src` was given) — with a frame the asset's size IS the frame's, without one it's the
|
|
59
|
+
* image's; an unrelated patch (e.g. `origin` only) leaves the current width/height alone, since for a packed
|
|
60
|
+
* atlas asset (rotate/trim) the frame's [w, h] is the packed size, not the true one `width`/`height` store.
|
|
61
|
+
* Re-framing an asset that regions already show keeps the SOURCE pixel that sat under each image centre
|
|
62
|
+
* where it was drawn (spec §3): the old centre lands at (u, v) of the new frame, so each placement moves by
|
|
63
|
+
* −L·(u, v) in its own rotated, scaled frame. A mesh keeps its uvs — they index the old pixels — and is named
|
|
64
|
+
* in `notes` so the caller re-traces it. Only a frame or src change resets `rotate`/`trim` (packer fields).
|
|
65
|
+
*/
|
|
66
|
+
export declare function setAsset(doc: Doc, id: string, patch: AssetPatch, image?: {
|
|
67
|
+
width: number;
|
|
68
|
+
height: number;
|
|
69
|
+
}): {
|
|
70
|
+
doc: Doc;
|
|
71
|
+
notes: string[];
|
|
72
|
+
};
|
|
73
|
+
export declare function removeAsset(doc: Doc, id: string): Doc;
|
|
74
|
+
/**
|
|
75
|
+
* One mutation for "this picture on that bone, here": the slot (`slot ?? asset`, created on `bone` when missing —
|
|
76
|
+
* an existing slot keeps its own bone), a region attachment named like the asset with its centre at the DOCUMENT
|
|
77
|
+
* point (x, y) expressed in the slot bone's rest frame, and the slot showing it.
|
|
78
|
+
*/
|
|
79
|
+
export declare function placeAsset(doc: Doc, p: {
|
|
80
|
+
asset: string;
|
|
81
|
+
bone: string;
|
|
82
|
+
x: number;
|
|
83
|
+
y: number;
|
|
84
|
+
slot?: string;
|
|
85
|
+
z?: number;
|
|
86
|
+
}): Doc;
|
|
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;
|
|
89
|
+
export type MetaPatch = {
|
|
90
|
+
name?: string;
|
|
91
|
+
width?: number;
|
|
92
|
+
height?: number;
|
|
93
|
+
notes?: string;
|
|
94
|
+
reference?: (Partial<Omit<Reference, 'src'>> & {
|
|
95
|
+
src: string;
|
|
96
|
+
}) | null;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Patch the document's meta. Resizing the canvas moves nothing — bones keep their document coordinates, only the
|
|
100
|
+
* bounds change. `reference: null` clears the editor's underlay; a reference `src` has to stay inside the rig's
|
|
101
|
+
* directory, since that is the only place the editor server serves images from.
|
|
102
|
+
*/
|
|
103
|
+
export declare function setMeta(doc: Doc, patch: MetaPatch): Doc;
|
|
104
|
+
export declare function addBone(doc: Doc, bone: BonePatch & {
|
|
105
|
+
id: string;
|
|
106
|
+
}): Doc;
|
|
107
|
+
export declare function updateBone(doc: Doc, id: string, patch: BonePatch): Doc;
|
|
108
|
+
/** `approx` is the largest of its re-bound slots' (see `rebindSlot`), 0 when every re-expression was exact. */
|
|
109
|
+
export declare function removeBone(doc: Doc, id: string): {
|
|
110
|
+
doc: Doc;
|
|
111
|
+
approx: number;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Create or patch a slot. A NEW slot is appended to every `drawOrder` key (it draws on top — the same place
|
|
115
|
+
* `z = max + 1` puts it), so a rig with such keys stays valid. A `bone` change on an existing slot goes through
|
|
116
|
+
* `rebindSlot`, so the images stay where they are on the document.
|
|
117
|
+
*/
|
|
118
|
+
export declare function setSlot(doc: Doc, slot: SlotPatch & {
|
|
119
|
+
id: string;
|
|
120
|
+
}): Doc;
|
|
121
|
+
export declare function removeSlot(doc: Doc, id: string): Doc;
|
|
122
|
+
/**
|
|
123
|
+
* Move `slotId` onto `bone` WITHOUT moving what it shows. Every region's placement and every unweighted mesh or
|
|
124
|
+
* path vertex is re-expressed in the new bone's REST frame; weighted data is left alone — its points live in the
|
|
125
|
+
* influence bones, and the slot bone is not one of them. A region has no shear, so between two bones whose axes
|
|
126
|
+
* are not similar (a shear, a non-uniform scale, a mirror) the decomposition cannot be exact: `approx` is the
|
|
127
|
+
* largest distance (document px) any region corner moved, 0 when the re-expression is exact.
|
|
128
|
+
*/
|
|
129
|
+
export declare function rebindSlot(doc: Doc, slotId: string, bone: string): {
|
|
130
|
+
doc: Doc;
|
|
131
|
+
approx: number;
|
|
132
|
+
};
|
|
133
|
+
/** setup draw order in one call: `order` lists every slot back-to-front (the drawOrder key's order); z = index */
|
|
134
|
+
export declare function setDrawOrder(doc: Doc, order: string[]): Doc;
|
|
135
|
+
/** Create or patch a region attachment (an image placed in a slot). Placement is the image CENTRE in the slot bone's space. */
|
|
136
|
+
export declare function setAttachment(doc: Doc, att: RegionPlacement & {
|
|
137
|
+
id: string;
|
|
138
|
+
slot?: string;
|
|
139
|
+
asset?: string;
|
|
140
|
+
}): Doc;
|
|
141
|
+
/** Create or replace any attachment (mesh / path / region) from a full description. */
|
|
142
|
+
export declare function setAttachmentRaw(doc: Doc, att: Record<string, unknown> & {
|
|
143
|
+
id: string;
|
|
144
|
+
}): Doc;
|
|
145
|
+
/**
|
|
146
|
+
* Replace the geometry arrays of a mesh attachment. `vertices` and `weights` are exclusive: giving one drops
|
|
147
|
+
* the other, and exactly one must remain. Deform `vertices` keys whose length no longer matches the mesh are
|
|
148
|
+
* dropped (returned in `dropped`) — they would otherwise make the document invalid.
|
|
149
|
+
*/
|
|
150
|
+
export declare function setMesh(doc: Doc, id: string, patch: {
|
|
151
|
+
vertices?: number[];
|
|
152
|
+
weights?: MeshAttachment["weights"];
|
|
153
|
+
uvs?: number[];
|
|
154
|
+
triangles?: number[];
|
|
155
|
+
hull?: number;
|
|
156
|
+
}): {
|
|
157
|
+
doc: Doc;
|
|
158
|
+
dropped: string[];
|
|
159
|
+
};
|
|
160
|
+
/** Replace a mesh's skinning (drops its unweighted `vertices`); stale deform vertex keys are pruned. */
|
|
161
|
+
export declare const setWeights: (doc: Doc, id: string, weights: NonNullable<MeshAttachment["weights"]>) => {
|
|
162
|
+
doc: Doc;
|
|
163
|
+
dropped: string[];
|
|
164
|
+
};
|
|
165
|
+
/** Replace a REGION attachment by the given mesh (same id); lattice deform tracks on that id are removed (returned). */
|
|
166
|
+
export declare function convertToMesh(doc: Doc, mesh: MeshAttachment): {
|
|
167
|
+
doc: Doc;
|
|
168
|
+
droppedTracks: string[];
|
|
169
|
+
};
|
|
170
|
+
export declare function removeAttachment(doc: Doc, id: string): Doc;
|
|
171
|
+
/** the region attachment currently at rest in a slot (undefined when hidden or not a region) */
|
|
172
|
+
export declare const restRegion: (doc: Doc, slotId: string) => RegionAttachment | undefined;
|
|
173
|
+
/** region placement equivalent to a v1 pivot (fraction) + bone-local offset for an image of size w×h */
|
|
174
|
+
export declare function placementFromPivot(pivot: {
|
|
175
|
+
x: number;
|
|
176
|
+
y: number;
|
|
177
|
+
}, offset: Partial<Transform>, w: number, h: number): Required<Pick<RegionPlacement, "x" | "y" | "rotation" | "scaleX" | "scaleY">>;
|
|
178
|
+
export type ConstraintKind = "ik" | "transform" | "path";
|
|
179
|
+
/** which list holds `id` — constraint ids are unique across the three kinds */
|
|
180
|
+
export declare const constraintKind: (doc: Doc, id: string) => ConstraintKind | undefined;
|
|
181
|
+
/**
|
|
182
|
+
* Create or patch a constraint. The patch is merged over the current value and re-parsed, so schema defaults
|
|
183
|
+
* fill in on creation and a patch only has to name what changes (an explicit `undefined` changes nothing).
|
|
184
|
+
* A constraint's KIND is fixed on creation: changing it means removing the constraint and creating it again,
|
|
185
|
+
* because the three kinds share an id space and their fields (and tracks) do not translate.
|
|
186
|
+
*/
|
|
187
|
+
export declare function setConstraint(doc: Doc, kind: ConstraintKind, id: string, patch: Record<string, unknown>): Doc;
|
|
188
|
+
/** Remove a constraint of any kind together with its tracks (mix / position / …). */
|
|
189
|
+
export declare function removeConstraint(doc: Doc, id: string): Doc;
|
|
190
|
+
/**
|
|
191
|
+
* Rig a limb in one call: `ikChainFor(bone)` gets a target bone at the chain's current tip and an IK constraint
|
|
192
|
+
* `<bone>_ik` whose bend sign reproduces the authored pose, so adding it moves nothing.
|
|
193
|
+
*
|
|
194
|
+
* The target is parented to the ROOT bone, never inside the chain: a target dragged by the bones it drives is a
|
|
195
|
+
* cycle (the solver would read what it just wrote). When the two-bone chain would reach up to the root — the only
|
|
196
|
+
* parent available for the target — the chain DEGRADES to the single bone (a one-bone IK aims that bone at the
|
|
197
|
+
* target and is cycle-free), and `note` says so; only a `bone` that is itself a root is refused (by `ikChainFor`).
|
|
198
|
+
*/
|
|
199
|
+
export declare function addIkChain(doc: Doc, bone: string, opts?: {
|
|
200
|
+
target?: string;
|
|
201
|
+
mix?: number;
|
|
202
|
+
softness?: number;
|
|
203
|
+
}): {
|
|
204
|
+
doc: Doc;
|
|
205
|
+
chain: string[];
|
|
206
|
+
target: string;
|
|
207
|
+
bendPositive: boolean;
|
|
208
|
+
note?: string;
|
|
209
|
+
};
|
|
210
|
+
/** the vertex data of a path: anchors to smooth into a curve, or the raw control points themselves */
|
|
211
|
+
export interface PathGeometryIn {
|
|
212
|
+
points?: Pt[];
|
|
213
|
+
vertices?: number[];
|
|
214
|
+
weights?: Influence[][];
|
|
215
|
+
closed?: boolean;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Create or replace a PATH attachment. Two forms, exactly one per call:
|
|
219
|
+
* `points` — anchors in DOCUMENT space; the curve is rebuilt with Catmull-Rom tangents (the agent's form).
|
|
220
|
+
* `vertices` / `weights` — raw control points, [cPrev, p, cNext] per anchor, in the slot bone's space
|
|
221
|
+
* (or skinned), which is the ONLY form that preserves authored tangents and weights.
|
|
222
|
+
* `lengths` are re-measured in both cases. Deform tracks whose length no longer fits are dropped.
|
|
223
|
+
* `closed` and `constantSpeed` keep the attachment's current values when it already exists.
|
|
224
|
+
*/
|
|
225
|
+
export declare function setPathAttachment(doc: Doc, id: string, slot: string, geom: PathGeometryIn): {
|
|
226
|
+
doc: Doc;
|
|
227
|
+
dropped: string[];
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* Structural path edit. `insert` splits the curve AFTER anchor `index` at parameter `t`, which leaves the curve's
|
|
231
|
+
* shape untouched (de Casteljau); `remove` drops an anchor's triple, which necessarily changes the shape.
|
|
232
|
+
*
|
|
233
|
+
* A skinned path stays skinned: the five control points a split touches get their influence lists — bones,
|
|
234
|
+
* weights and bone-space positions alike — blended from the four the curve already had, by the split's own
|
|
235
|
+
* affine coefficients (`blendInfluences`). No bone appears or disappears, every list still sums to 1, and the
|
|
236
|
+
* shape is preserved in every POSE, not only in the setup one.
|
|
237
|
+
*
|
|
238
|
+
* `insert` also carries the DEFORM tracks through: the same coefficients blend the offsets of the same four
|
|
239
|
+
* control points (`blendOffsets`), which is the identity again with `q + d` in place of `q`, so the animated
|
|
240
|
+
* curve is unchanged too. That makes an insert lossless — which matters, because a single Ctrl-click on `ross`'s
|
|
241
|
+
* `tail_path` reaches 17 of them. `remove` cannot make that promise (it changes the curve's shape by
|
|
242
|
+
* construction), so its stale keys are still dropped and reported in `dropped`.
|
|
243
|
+
*/
|
|
244
|
+
export declare function pathAnchorOp(doc: Doc, id: string, op: "insert" | "remove", index: number, t?: number): {
|
|
245
|
+
doc: Doc;
|
|
246
|
+
dropped: string[];
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* Replace the keys of one track (creating the animation/track if missing). Manual edit → drops `preset`.
|
|
250
|
+
* `merge: true` keeps existing keys except those at the given times (fix one key without retyping all).
|
|
251
|
+
*/
|
|
252
|
+
export declare function setKeys(doc: Doc, animId: string, track: Omit<Track, "keys">, keys: KeyInput[], duration?: number, opts?: {
|
|
253
|
+
merge?: boolean;
|
|
254
|
+
}): Doc;
|
|
255
|
+
/**
|
|
256
|
+
* Re-tune one existing track without retyping keys: `amplitude` scales deviations from the rest value
|
|
257
|
+
* (scale props as ratios), `offset` adds a constant, `timeScale` stretches key times (duration grows to fit).
|
|
258
|
+
*/
|
|
259
|
+
export declare function adjustTrack(doc: Doc, animId: string, track: Omit<Track, "keys">, adj: {
|
|
260
|
+
amplitude?: number;
|
|
261
|
+
offset?: number;
|
|
262
|
+
timeScale?: number;
|
|
263
|
+
}): Doc;
|
|
264
|
+
export declare function removeAnimation(doc: Doc, id: string): Doc;
|
|
265
|
+
/** Animation properties without touching keys. Creates the animation when missing. `rename` changes the id. */
|
|
266
|
+
export declare function setAnimation(doc: Doc, id: string, patch: {
|
|
267
|
+
duration?: number;
|
|
268
|
+
loop?: boolean;
|
|
269
|
+
events?: Animation["events"];
|
|
270
|
+
rename?: string;
|
|
271
|
+
}): Doc;
|
|
272
|
+
/** Remove the keys of one track at the given times (1e-6 tolerance); an emptied track is dropped. Manual edit → drops `preset`. */
|
|
273
|
+
export declare function removeKeys(doc: Doc, animId: string, track: Omit<Track, "keys">, times: number[]): Doc;
|
|
274
|
+
/**
|
|
275
|
+
* Copy every `target: "bone"` track of each `from[i]` bone onto `to[i]`, pair by pair, replacing whatever
|
|
276
|
+
* `to[i]` already held for that prop. `phase` rotates each key's time by a fraction of the animation's duration,
|
|
277
|
+
* wrapping around (0.5 = half a cycle later, 1 is a full turn — the same identity as 0); `mirrorX` negates the
|
|
278
|
+
* props in `MIRRORED_BONE_PROPS`. A source bone with no bone tracks is collected into `empty` rather than failing the
|
|
279
|
+
* call — an agent may name a whole limb when only half of it is animated.
|
|
280
|
+
*
|
|
281
|
+
* Easing belongs to the key that STARTS a segment, so rotating keys around the end can split the segment that
|
|
282
|
+
* ran from the last key to the first: on a looping animation that is the same segment and nothing is lost, on a
|
|
283
|
+
* one-shot animation it is a different curve — `rig_copy_tracks` says so once when that applies. A track keyed at
|
|
284
|
+
* both 0 and `duration` (the standard closed-loop shape) keys the SAME point of the circle twice; any nonzero
|
|
285
|
+
* shift would send both copies to the same time, so the duplicate at `duration` is dropped before shifting. That
|
|
286
|
+
* is lossless when the two ends agree (the ordinary case: the cycle returns to where it started). Nothing forces
|
|
287
|
+
* them to — a tail can author a different rest angle at the loop's seam — so a drop where they DISAGREE is
|
|
288
|
+
* collected into `lossy` (bone, prop, both values) instead of silently discarding the segment between them: not
|
|
289
|
+
* an error (the source shape is legal), not something to nudge either key to avoid (there is no basis to pick
|
|
290
|
+
* which end wins), just a fact the caller needs to hear.
|
|
291
|
+
*/
|
|
292
|
+
export declare function copyTracks(doc: Doc, animId: string, from: string[], to: string[], opts: {
|
|
293
|
+
phase?: number;
|
|
294
|
+
mirrorX?: boolean;
|
|
295
|
+
}): {
|
|
296
|
+
doc: Doc;
|
|
297
|
+
copied: number;
|
|
298
|
+
empty: string[];
|
|
299
|
+
lossy: string[];
|
|
300
|
+
};
|
|
301
|
+
/** compact key summary for one track: count and value range (or the set of discrete values) */
|
|
302
|
+
export declare function trackSummary(t: Track): string;
|
|
303
|
+
export type RenameKind = "bone" | "slot" | "attachment" | "asset" | "constraint";
|
|
304
|
+
/**
|
|
305
|
+
* Rename one thing and every reference to it (spec §3). A bone is named by bone parents, slots, ik/transform
|
|
306
|
+
* chains and targets, path chains, every mesh/path influence and bone tracks; a slot by its attachments, path
|
|
307
|
+
* constraint targets (those aim at a slot), slot tracks and every drawOrder key; an attachment by the slot that
|
|
308
|
+
* shows it, `attachment` key values and deform tracks; an asset by regions and meshes; a constraint by its own
|
|
309
|
+
* tracks. Roles are not ids and stay. Templates in presets.json are a separate file and are NOT rewritten.
|
|
310
|
+
*/
|
|
311
|
+
export declare function rename(doc: Doc, kind: RenameKind, id: string, to: string): Doc;
|
|
312
|
+
/** Compact text for agents. `verbose`: slot pivot/offset and every track with its key summary (no asset prompts). */
|
|
313
|
+
/**
|
|
314
|
+
* One attachment in one line: what shape it is, and the counts an agent needs before it asks for the arrays.
|
|
315
|
+
* `deform.<id>.vertices` keys are `deformLength` numbers long, which is 2·Σ influences on a skinned shape and
|
|
316
|
+
* 2·vertices otherwise, so it is stated rather than left to be derived from the two counts.
|
|
317
|
+
*/
|
|
318
|
+
export declare function describeAttachment(doc: Doc, att: Attachment): string;
|
|
319
|
+
export declare function describe(doc: Doc, opts?: {
|
|
320
|
+
verbose?: boolean;
|
|
321
|
+
}): string;
|
|
322
|
+
export interface PoseReport {
|
|
323
|
+
animation?: string;
|
|
324
|
+
t: number;
|
|
325
|
+
/** the animation's duration, so a caller can see that a `t` beyond it was clamped rather than sampled */
|
|
326
|
+
duration?: number;
|
|
327
|
+
bones: {
|
|
328
|
+
id: string;
|
|
329
|
+
x: number;
|
|
330
|
+
y: number;
|
|
331
|
+
angle: number;
|
|
332
|
+
scaleX: number;
|
|
333
|
+
scaleY: number;
|
|
334
|
+
local: {
|
|
335
|
+
x: number;
|
|
336
|
+
y: number;
|
|
337
|
+
rotation: number;
|
|
338
|
+
};
|
|
339
|
+
}[];
|
|
340
|
+
slots: {
|
|
341
|
+
id: string;
|
|
342
|
+
attachment: string | null;
|
|
343
|
+
bbox?: [number, number, number, number];
|
|
344
|
+
}[];
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Where every bone and slot actually IS after `evaluate`: posed, not rest — constraints have run, so this is
|
|
348
|
+
* what the runtime draws. Without `animation`, the pose is empty (rest); `bones`/`slots` narrow the report and
|
|
349
|
+
* an id the document does not have is an error, not a silent drop, so a typo shows up at once.
|
|
350
|
+
*/
|
|
351
|
+
export declare function poseReport(doc: Doc, opts: {
|
|
352
|
+
animation?: string;
|
|
353
|
+
t?: number;
|
|
354
|
+
bones?: string[];
|
|
355
|
+
slots?: string[];
|
|
356
|
+
}): PoseReport;
|
|
357
|
+
/**
|
|
358
|
+
* A bone sent to a point in DOCUMENT coordinates — the gesture a human gets by dragging the bone in the editor.
|
|
359
|
+
*
|
|
360
|
+
* The point is converted through the parent's world matrix TAKEN FROM THE POSE AT `t`, never from rest: a goal
|
|
361
|
+
* solved against the setup pose is exact at rest and off by the parent's animated turn in every other frame.
|
|
362
|
+
* Which bone is actually written follows the editor's rule (`Stage.grabDriven`), because a bone a solver owns
|
|
363
|
+
* cannot be posed by writing it — a live ik hands the edit to its target bone, a live transform or path refuses.
|
|
364
|
+
*/
|
|
365
|
+
export declare function setGoal(doc: Doc, bone: string, x: number, y: number, opts: {
|
|
366
|
+
animation?: string;
|
|
367
|
+
t?: number;
|
|
368
|
+
ease?: EaseSpec;
|
|
369
|
+
}): {
|
|
370
|
+
doc: Doc;
|
|
371
|
+
wrote: string;
|
|
372
|
+
redirected?: string;
|
|
373
|
+
origin: Pt;
|
|
374
|
+
tip: Pt;
|
|
375
|
+
};
|
|
376
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@energy8platform/golem/runtime` — the browser half: play a rig document in PixiJS v8.
|
|
3
|
+
* Depends on pixi.js (peer) and zod only; no node, no tools, no editor.
|
|
4
|
+
*/
|
|
5
|
+
export { RigPlayer, createTextures, atlasUV, MESH_GRID, type PlayOptions } from "./rig-runtime";
|
|
6
|
+
export { RigSymbol, type RigSymbolOptions, type SymbolSize, type SymbolViewLike, type TickerLike } from "./rig-symbol";
|
|
7
|
+
export { AnimationState, type PlayResult, type PoseSink } from "./rig-state";
|
|
8
|
+
export { parse, validate, migrateV1, RigDocument as RigDocumentSchema } from "./rig-format";
|
|
9
|
+
export type { RigDocument, Bone, Slot, Asset, Attachment, Animation, Track, Key } from "./rig-format";
|