@ikijs/editor 0.19.0 → 0.21.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 -14
- package/dist/index.d.mts +74 -17
- package/dist/index.d.ts +74 -17
- package/dist/index.js +574 -157
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +575 -155
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -40,24 +40,24 @@ leaves the document untouched.
|
|
|
40
40
|
|
|
41
41
|
## API
|
|
42
42
|
|
|
43
|
-
| Area | Exports
|
|
44
|
-
| ------------------ |
|
|
45
|
-
| Document | `EditorDocument`, `EditCommand`
|
|
46
|
-
| Part edits | `AddPart`, `DeletePart`, `SetPartColor`, `SetPartWidth`, `SetPartHeight`, `SetPartOrder`, `SetPartTransform`, `SetPartBindings`, `SetPartMesh`, `SetPartDeformer`
|
|
47
|
-
| Deformer edits | `AddDeformer`, `DeleteDeformer`, `SetDeformerParent`, `SetDeformerTransform`, `SetDeformerBindings`, `SetDeformerPivot` (+ `X`/`Y`), `CaptureGridKeyform`
|
|
48
|
-
| Physics edits | `AddPhysicsRig`, `SetPhysicsRig`, `DeletePhysicsRig`
|
|
49
|
-
| Referential guards | `validateDeformerReparent`, `validateDeformerDelete`, `validatePartAttach`
|
|
50
|
-
| Atlas | `packAtlas`, `uvRectFor`, `ATLAS_PADDING`, `UV_INSET_PX`
|
|
51
|
-
| Grid keyforms | `computeGridOffsets`, `interpolateGridOffsets`, `upsertGridKeyform`
|
|
52
|
-
| Factories | `createDefaultPart`, `createDefaultMatrixDeformer`, `createDefaultWarpDeformer`, `createGridMesh`
|
|
53
|
-
| Pixels | `detectAlphaBbox`, `ALPHA_BBOX_THRESHOLD`, `AlphaBbox`, `ALPHA_OPAQUE`, `HEAD_BAND`, `SPECK_CORE_FRACTION`, `denseCoreOf`, `isSpeckCore`, `foregroundSpan`, `headHalfOf`
|
|
54
|
-
| Auto-rig | `generateIkiFromLayerSet`, `parseLayerRoles`, `partIdsOfRole`, `createLayerSetMeasurer`, `armGeometry`, `ArmGeometry`, `TurnTargets`, `DEFAULT_TURN_TARGETS`, `TurnSolveReport`, `RigStyle`, `LayerGeometryError` |
|
|
55
|
-
| Bindings | `captureBindingEndpoint`
|
|
43
|
+
| Area | Exports |
|
|
44
|
+
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
45
|
+
| Document | `EditorDocument`, `EditCommand` |
|
|
46
|
+
| Part edits | `AddPart`, `DeletePart`, `SetPartColor`, `SetPartWidth`, `SetPartHeight`, `SetPartOrder`, `SetPartTransform`, `SetPartBindings`, `SetPartMesh`, `SetPartDeformer` |
|
|
47
|
+
| Deformer edits | `AddDeformer`, `DeleteDeformer`, `SetDeformerParent`, `SetDeformerTransform`, `SetDeformerBindings`, `SetDeformerPivot` (+ `X`/`Y`), `CaptureGridKeyform` |
|
|
48
|
+
| Physics edits | `AddPhysicsRig`, `SetPhysicsRig`, `DeletePhysicsRig` |
|
|
49
|
+
| Referential guards | `validateDeformerReparent`, `validateDeformerDelete`, `validatePartAttach` |
|
|
50
|
+
| Atlas | `packAtlas`, `uvRectFor`, `ATLAS_PADDING`, `UV_INSET_PX` |
|
|
51
|
+
| Grid keyforms | `computeGridOffsets`, `interpolateGridOffsets`, `upsertGridKeyform` |
|
|
52
|
+
| Factories | `createDefaultPart`, `createDefaultMatrixDeformer`, `createDefaultWarpDeformer`, `createGridMesh` |
|
|
53
|
+
| Pixels | `detectAlphaBbox`, `ALPHA_BBOX_THRESHOLD`, `AlphaBbox`, `ALPHA_OPAQUE`, `HEAD_BAND`, `SPECK_CORE_FRACTION`, `denseCoreOf`, `isSpeckCore`, `foregroundSpan`, `headHalfOf` |
|
|
54
|
+
| Auto-rig | `generateIkiFromLayerSet`, `parseLayerRoles`, `partIdsOfRole`, `createLayerSetMeasurer`, `armGeometry`, `ArmGeometry`, `forearmPoseGeometry`, `ForearmPoseGeometry`, `TurnTargets`, `DEFAULT_TURN_TARGETS`, `TurnSolveReport`, `RigStyle`, `LayerGeometryError` |
|
|
55
|
+
| Bindings | `captureBindingEndpoint` |
|
|
56
56
|
|
|
57
57
|
## Auto-rig
|
|
58
58
|
|
|
59
59
|
`generateIkiFromLayerSet` turns role-named layers (`face`, `eye_L`, `eye_R`,
|
|
60
|
-
`mouth`, plus optional `iris_*`, `brow_*`, `lash_*`, `lash_lower_*`, `hair_front`, `hair_back`,
|
|
60
|
+
and `mouth` — or the lip set `mouth_inner`, `lip_lower`, `lip_upper`, which folds open instead of crossfading — plus optional `iris_*`, `brow_*`, `lash_*`, `lash_lower_*`, `hair_front`, `hair_back`,
|
|
61
61
|
`body`, `arm_*`, …) into a rigged model that blinks, gazes, opens its mouth, turns its head over
|
|
62
62
|
a body warp that breathes, follows the head a little and turns on
|
|
63
63
|
`ParamBodyAngleX/Y/Z`, and emotes with its brows — including a
|
|
@@ -85,6 +85,10 @@ hangs from it. `arm_L` / `arm_R`, each a whole arm drawn hanging with its
|
|
|
85
85
|
shoulder at the top, hang from it too: each becomes an elbow cap, an upper
|
|
86
86
|
arm and a forearm cut from the one crop, turning about the shoulder and the
|
|
87
87
|
elbow on `ParamArmL/R` and `ParamElbowL/R`. An arm needs a `body`.
|
|
88
|
+
`forearm_pose_L` / `forearm_pose_R`, a second forearm drawn raised, swap in for
|
|
89
|
+
the hanging one at the elbow on `ParamArmPoseL/R` and rock on
|
|
90
|
+
`ParamArmPoseAngleL/R`; a model with them also declares a `Wave` motion. A
|
|
91
|
+
pose forearm needs its arm.
|
|
88
92
|
|
|
89
93
|
On a layer set with a `nose`, `options.turnTargets` — the cues a 30° reference
|
|
90
94
|
measures (how far the eye pair slides, how much the far eye foreshortens,
|
package/dist/index.d.mts
CHANGED
|
@@ -713,14 +713,18 @@ interface LayerInput {
|
|
|
713
713
|
cropH: number;
|
|
714
714
|
/** Face only: half the opaque span of each crop row, canvas px (0 = none). */
|
|
715
715
|
rowHalfWidths?: number[];
|
|
716
|
-
/** `face` / `hair_front` / `hair_back` / `body` / `arm_L` / `arm_R`
|
|
716
|
+
/** `face` / `hair_front` / `hair_back` / `body` / `arm_L` / `arm_R` /
|
|
717
|
+
* `forearm_pose_L` / `forearm_pose_R` /
|
|
718
|
+
* `mouth_inner` / `lip_lower` / `lip_upper` only:
|
|
717
719
|
* per crop row, its opaque (alpha ≥ 128) runs as a flat list of canvas
|
|
718
720
|
* columns `[start0, end0, start1, end1, …]`, each end exclusive (`[]` for a
|
|
719
721
|
* row with none). The actual pixels, so a gap in the hair is a gap here:
|
|
720
722
|
* the turn and the nod read off it where back hair is painted behind the
|
|
721
723
|
* front hair, and the crown's turn reads the face's so it never bares skin.
|
|
722
724
|
* The body's place the hips (where it splits into legs), and an arm's place
|
|
723
|
-
* its shoulder and elbow pivots
|
|
725
|
+
* its shoulder and elbow pivots, a pose forearm's its elbow-end pivot, and
|
|
726
|
+
* a lip set's place the mouth's opening: the upper line's bottom, the
|
|
727
|
+
* interior's span, the skin's top. */
|
|
724
728
|
rowRuns?: number[][];
|
|
725
729
|
/** Nose only: the tight box of its alpha ≥ 128 pixels, canvas px. */
|
|
726
730
|
denseCore?: {
|
|
@@ -767,9 +771,11 @@ declare class TurnTargetError extends Error {
|
|
|
767
771
|
constructor(message: string);
|
|
768
772
|
}
|
|
769
773
|
/**
|
|
770
|
-
* Art geometry the rig cannot build on —
|
|
771
|
-
*
|
|
772
|
-
*
|
|
774
|
+
* Art geometry the rig cannot build on — a body whose hips leave no row line
|
|
775
|
+
* under its pivots, or too little room for its motion (`body.ts`), an arm
|
|
776
|
+
* without room for its pivots, a lip set whose interior has no opaque pixel
|
|
777
|
+
* (`mouth.ts`). A fact about the layers, not a bug, so a host reports it as an
|
|
778
|
+
* input error.
|
|
773
779
|
*/
|
|
774
780
|
declare class LayerGeometryError extends Error {
|
|
775
781
|
constructor(message: string);
|
|
@@ -923,9 +929,9 @@ interface ArmGeometry {
|
|
|
923
929
|
* The arm's pivots, read off the widest opaque run of each crop row
|
|
924
930
|
* (`rowRuns`); a row without one, or a layer without runs, reads as the
|
|
925
931
|
* crop:
|
|
926
|
-
* - r_u
|
|
927
|
-
*
|
|
928
|
-
* run centre of the row it lands in;
|
|
932
|
+
* - the shoulder pivot and r_u are `endPivot(layer, "top")`: r_u is half the
|
|
933
|
+
* median width over the `CAP_ROWS` rows, the pivot lies r_u under the first
|
|
934
|
+
* painted row's centre, at the run centre of the row it lands in;
|
|
929
935
|
* - the elbow is the centre of the row `ELBOW_AT` of the way from there to
|
|
930
936
|
* the last painted row, at its run centre;
|
|
931
937
|
* - the cap radius is half the elbow's run + 1 px, kept inside the crop;
|
|
@@ -941,13 +947,60 @@ interface ArmGeometry {
|
|
|
941
947
|
*/
|
|
942
948
|
declare function armGeometry(layer: LayerInput, bodyAxisX: number): ArmGeometry;
|
|
943
949
|
|
|
950
|
+
/**
|
|
951
|
+
* The pose forearm. A second drawn forearm per side (`forearm_pose_L` /
|
|
952
|
+
* `forearm_pose_R`), drawn raised: it hangs from the arm's elbow and is
|
|
953
|
+
* swapped in for the hanging forearm by a switch.
|
|
954
|
+
* - One part, the role's own id, over its crop's box on `armPoseDeformer_X`,
|
|
955
|
+
* a child of `armDeformer_X` pivoting at the arm's elbow. It is not a child
|
|
956
|
+
* of `forearmDeformer_X`, so `ParamElbowX` never moves it, and the shoulder
|
|
957
|
+
* still carries it.
|
|
958
|
+
* - `ParamArmPoseX` (0..1) swaps: the hanging forearm and the elbow cap fade
|
|
959
|
+
* out on it, 1 to 0 (`armParts`), the pose forearm fades in, 0 to 1. The
|
|
960
|
+
* pair is exclusive by construction, and between the ends both show at
|
|
961
|
+
* partial opacity. The part has no mesh: the engine draws a meshless part
|
|
962
|
+
* as its full-box quad with its texture rect, and a rigid part needs no
|
|
963
|
+
* more.
|
|
964
|
+
* - `ParamArmPoseAngleX` rocks it about the elbow, in degrees over
|
|
965
|
+
* `POSE_ANGLE_RANGE`. + tips the raised hand outward, away from the body,
|
|
966
|
+
* mirrored per side. The part points up from its pivot where the hanging
|
|
967
|
+
* forearm points down, so its rotate binding takes −side × the value; the
|
|
968
|
+
* elbow's multiplier is the same −side, which gives the shoulder's reading.
|
|
969
|
+
* The composer puts the drawing's elbow end on the pivot (`measure` warns
|
|
970
|
+
* when it is off), so the rig does not use the crop's own pivot
|
|
971
|
+
* (`forearmPoseGeometry`).
|
|
972
|
+
*
|
|
973
|
+
* It draws after the hair, above the face and the front hair: a raised hand
|
|
974
|
+
* passes them (`ROLE_TABLE`).
|
|
975
|
+
*/
|
|
976
|
+
|
|
977
|
+
interface ForearmPoseGeometry {
|
|
978
|
+
/** The elbow end's pivot, model space: where the drawing's elbow end is
|
|
979
|
+
* centred. */
|
|
980
|
+
pivot: {
|
|
981
|
+
x: number;
|
|
982
|
+
y: number;
|
|
983
|
+
};
|
|
984
|
+
/** r_e: half the elbow end's width, px. */
|
|
985
|
+
radius: number;
|
|
986
|
+
/** The first painted row's model y: the raised hand's top. */
|
|
987
|
+
top: number;
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* The pose forearm's own geometry: the shoulder rule run from the bottom
|
|
991
|
+
* (`endPivot`), since it is drawn standing up from its elbow, plus the top of
|
|
992
|
+
* the paint.
|
|
993
|
+
*/
|
|
994
|
+
declare function forearmPoseGeometry(layer: LayerInput): ForearmPoseGeometry;
|
|
995
|
+
|
|
944
996
|
/** The part ids a `role`'s layer becomes, back to front: every one of them
|
|
945
997
|
* takes its texture from the layer's crop. Throws on an unknown role. */
|
|
946
998
|
declare function partIdsOfRole(role: string): readonly string[];
|
|
947
999
|
/**
|
|
948
1000
|
* Map file names to roles. Throws on an unknown role, a role named twice, a
|
|
949
|
-
* required role (`face`, `eye_L`, `eye_R
|
|
950
|
-
* without a body
|
|
1001
|
+
* required role (`face`, `eye_L`, `eye_R`) missing, no mouth (`mouth`, or the
|
|
1002
|
+
* lip set) or a partial or mixed one, an arm without a body, or a pose forearm
|
|
1003
|
+
* without its arm.
|
|
951
1004
|
*/
|
|
952
1005
|
declare function parseLayerRoles(fileNames: string[]): {
|
|
953
1006
|
role: string;
|
|
@@ -962,15 +1015,18 @@ declare function parseLayerRoles(fileNames: string[]): {
|
|
|
962
1015
|
* turns on BodyAngleX/Y/Z, its legs planted; a head deformer hung from it
|
|
963
1016
|
* that rolls about the chin and breathes; each arm hung from it too, as an
|
|
964
1017
|
* upper arm, a forearm and an elbow cap turning about the shoulder and the
|
|
965
|
-
* elbow (`arms.ts`)
|
|
1018
|
+
* elbow (`arms.ts`), and with a drawn pose forearm a switch that swaps it in
|
|
1019
|
+
* for the hanging one (`forearm-pose.ts`); one small warp grid per feature
|
|
966
1020
|
* (each eye, each brow, the nose, the mouth), translating and foreshortening
|
|
967
1021
|
* it by its own lead over the plate; and the plate, the hair and the blush
|
|
968
1022
|
* moved by per-vertex keyforms of their own — the plate as up to four
|
|
969
1023
|
* islands of one drawing: a head that slides, a neck that stays on the torso
|
|
970
1024
|
* and two ears that lag. Blink, gaze, brows, mouth, breath and
|
|
971
1025
|
* hair sway are part warps and bindings under those. The model also declares
|
|
972
|
-
* the default expressions and the Nod, Shake and Tilt motions
|
|
973
|
-
* (`animations.ts`).
|
|
1026
|
+
* the default expressions and the Nod, Shake and Tilt motions, and
|
|
1027
|
+
* with a pose forearm the Wave (`animations.ts`). The mouth has two paths,
|
|
1028
|
+
* chosen by the layers: `mouth` alone stretches, with `mouth_open` it
|
|
1029
|
+
* crossfades; the lip set folds open like the eyelid (`mouth.ts`).
|
|
974
1030
|
*/
|
|
975
1031
|
|
|
976
1032
|
declare function generateIkiFromLayerSet(layers: LayerInput[], canvas: {
|
|
@@ -1106,11 +1162,12 @@ interface RgbaLayer {
|
|
|
1106
1162
|
interface LayerSetMeasurer {
|
|
1107
1163
|
/**
|
|
1108
1164
|
* Measure one layer while its `rgba` is in memory, keeping no reference to
|
|
1109
|
-
* it: only the set's opaque union,
|
|
1165
|
+
* it: only the set's opaque union (a pose forearm, hidden at rest, stays out
|
|
1166
|
+
* of it and of the per-role edges), this layer's per-row opaque extent and
|
|
1110
1167
|
* the `LayerInput` it returns outlive the call, so the host may drop `rgba`
|
|
1111
1168
|
* as soon as it returns. Returns the layer's `LayerInput` — its crop
|
|
1112
|
-
* box, the face's `rowHalfWidths`, the face's, hair layers', body's
|
|
1113
|
-
*
|
|
1169
|
+
* box, the face's `rowHalfWidths`, the face's, hair layers', body's, arms',
|
|
1170
|
+
* pose forearms' and lip set's `rowRuns`, the nose's
|
|
1114
1171
|
* `denseCore` unless that is a speck of its crop (`isSpeckCore`) — or
|
|
1115
1172
|
* `null` for an empty layer, one with no pixel at or above
|
|
1116
1173
|
* `ALPHA_BBOX_THRESHOLD`, which it records nothing for: the host reports
|
|
@@ -1367,4 +1424,4 @@ declare function createGridMesh(cols: number, rows: number): IkiMesh;
|
|
|
1367
1424
|
*/
|
|
1368
1425
|
declare function createDefaultWarpDeformer(model: IkiModel): IkiWarpDeformer;
|
|
1369
1426
|
|
|
1370
|
-
export { ALPHA_BBOX_THRESHOLD, ALPHA_OPAQUE, ATLAS_PADDING, AddDeformer, AddPart, AddPhysicsRig, type AlphaBbox, type ApplyAtlasInput, type ArmGeometry, type AtlasAssignment, type AtlasLayout, type AtlasPlacement, type AtlasSource, CaptureGridKeyform, DEFAULT_TURN_TARGETS, type DeformerTransformChannel, DeleteDeformer, DeletePart, DeletePhysicsRig, type EditCommand, type EditTransformChannel, EditorDocument, HEAD_BAND, type IrisStrand, LayerGeometryError, type LayerInput, type LayerSetMeasurement, type LayerSetMeasurer, type RgbaLayer, type RigStyle, SPECK_CORE_FRACTION, SetDeformerBindings, SetDeformerParent, SetDeformerPivot, SetDeformerPivotX, SetDeformerPivotY, SetDeformerTransform, SetPartBindings, SetPartColor, SetPartDeformer, SetPartHeight, SetPartMesh, SetPartOrder, SetPartTransform, SetPartWidth, SetPhysicsRig, type StrandOverlap, type TurnDepths, type TurnSolveReport, TurnTargetError, type TurnTargets, UV_INSET_PX, armGeometry, captureBindingEndpoint, computeGridOffsets, createDefaultMatrixDeformer, createDefaultPart, createDefaultWarpDeformer, createGridMesh, createLayerSetMeasurer, denseCoreOf, detectAlphaBbox, foregroundSpan, generateIkiFromLayerSet, headHalfOf, interpolateGridOffsets, isSpeckCore, packAtlas, parseLayerRoles, partIdsOfRole, upsertGridKeyform, uvRectFor, validateDeformerDelete, validateDeformerReparent, validatePartAttach };
|
|
1427
|
+
export { ALPHA_BBOX_THRESHOLD, ALPHA_OPAQUE, ATLAS_PADDING, AddDeformer, AddPart, AddPhysicsRig, type AlphaBbox, type ApplyAtlasInput, type ArmGeometry, type AtlasAssignment, type AtlasLayout, type AtlasPlacement, type AtlasSource, CaptureGridKeyform, DEFAULT_TURN_TARGETS, type DeformerTransformChannel, DeleteDeformer, DeletePart, DeletePhysicsRig, type EditCommand, type EditTransformChannel, EditorDocument, type ForearmPoseGeometry, HEAD_BAND, type IrisStrand, LayerGeometryError, type LayerInput, type LayerSetMeasurement, type LayerSetMeasurer, type RgbaLayer, type RigStyle, SPECK_CORE_FRACTION, SetDeformerBindings, SetDeformerParent, SetDeformerPivot, SetDeformerPivotX, SetDeformerPivotY, SetDeformerTransform, SetPartBindings, SetPartColor, SetPartDeformer, SetPartHeight, SetPartMesh, SetPartOrder, SetPartTransform, SetPartWidth, SetPhysicsRig, type StrandOverlap, type TurnDepths, type TurnSolveReport, TurnTargetError, type TurnTargets, UV_INSET_PX, armGeometry, captureBindingEndpoint, computeGridOffsets, createDefaultMatrixDeformer, createDefaultPart, createDefaultWarpDeformer, createGridMesh, createLayerSetMeasurer, denseCoreOf, detectAlphaBbox, forearmPoseGeometry, foregroundSpan, generateIkiFromLayerSet, headHalfOf, interpolateGridOffsets, isSpeckCore, packAtlas, parseLayerRoles, partIdsOfRole, upsertGridKeyform, uvRectFor, validateDeformerDelete, validateDeformerReparent, validatePartAttach };
|
package/dist/index.d.ts
CHANGED
|
@@ -713,14 +713,18 @@ interface LayerInput {
|
|
|
713
713
|
cropH: number;
|
|
714
714
|
/** Face only: half the opaque span of each crop row, canvas px (0 = none). */
|
|
715
715
|
rowHalfWidths?: number[];
|
|
716
|
-
/** `face` / `hair_front` / `hair_back` / `body` / `arm_L` / `arm_R`
|
|
716
|
+
/** `face` / `hair_front` / `hair_back` / `body` / `arm_L` / `arm_R` /
|
|
717
|
+
* `forearm_pose_L` / `forearm_pose_R` /
|
|
718
|
+
* `mouth_inner` / `lip_lower` / `lip_upper` only:
|
|
717
719
|
* per crop row, its opaque (alpha ≥ 128) runs as a flat list of canvas
|
|
718
720
|
* columns `[start0, end0, start1, end1, …]`, each end exclusive (`[]` for a
|
|
719
721
|
* row with none). The actual pixels, so a gap in the hair is a gap here:
|
|
720
722
|
* the turn and the nod read off it where back hair is painted behind the
|
|
721
723
|
* front hair, and the crown's turn reads the face's so it never bares skin.
|
|
722
724
|
* The body's place the hips (where it splits into legs), and an arm's place
|
|
723
|
-
* its shoulder and elbow pivots
|
|
725
|
+
* its shoulder and elbow pivots, a pose forearm's its elbow-end pivot, and
|
|
726
|
+
* a lip set's place the mouth's opening: the upper line's bottom, the
|
|
727
|
+
* interior's span, the skin's top. */
|
|
724
728
|
rowRuns?: number[][];
|
|
725
729
|
/** Nose only: the tight box of its alpha ≥ 128 pixels, canvas px. */
|
|
726
730
|
denseCore?: {
|
|
@@ -767,9 +771,11 @@ declare class TurnTargetError extends Error {
|
|
|
767
771
|
constructor(message: string);
|
|
768
772
|
}
|
|
769
773
|
/**
|
|
770
|
-
* Art geometry the rig cannot build on —
|
|
771
|
-
*
|
|
772
|
-
*
|
|
774
|
+
* Art geometry the rig cannot build on — a body whose hips leave no row line
|
|
775
|
+
* under its pivots, or too little room for its motion (`body.ts`), an arm
|
|
776
|
+
* without room for its pivots, a lip set whose interior has no opaque pixel
|
|
777
|
+
* (`mouth.ts`). A fact about the layers, not a bug, so a host reports it as an
|
|
778
|
+
* input error.
|
|
773
779
|
*/
|
|
774
780
|
declare class LayerGeometryError extends Error {
|
|
775
781
|
constructor(message: string);
|
|
@@ -923,9 +929,9 @@ interface ArmGeometry {
|
|
|
923
929
|
* The arm's pivots, read off the widest opaque run of each crop row
|
|
924
930
|
* (`rowRuns`); a row without one, or a layer without runs, reads as the
|
|
925
931
|
* crop:
|
|
926
|
-
* - r_u
|
|
927
|
-
*
|
|
928
|
-
* run centre of the row it lands in;
|
|
932
|
+
* - the shoulder pivot and r_u are `endPivot(layer, "top")`: r_u is half the
|
|
933
|
+
* median width over the `CAP_ROWS` rows, the pivot lies r_u under the first
|
|
934
|
+
* painted row's centre, at the run centre of the row it lands in;
|
|
929
935
|
* - the elbow is the centre of the row `ELBOW_AT` of the way from there to
|
|
930
936
|
* the last painted row, at its run centre;
|
|
931
937
|
* - the cap radius is half the elbow's run + 1 px, kept inside the crop;
|
|
@@ -941,13 +947,60 @@ interface ArmGeometry {
|
|
|
941
947
|
*/
|
|
942
948
|
declare function armGeometry(layer: LayerInput, bodyAxisX: number): ArmGeometry;
|
|
943
949
|
|
|
950
|
+
/**
|
|
951
|
+
* The pose forearm. A second drawn forearm per side (`forearm_pose_L` /
|
|
952
|
+
* `forearm_pose_R`), drawn raised: it hangs from the arm's elbow and is
|
|
953
|
+
* swapped in for the hanging forearm by a switch.
|
|
954
|
+
* - One part, the role's own id, over its crop's box on `armPoseDeformer_X`,
|
|
955
|
+
* a child of `armDeformer_X` pivoting at the arm's elbow. It is not a child
|
|
956
|
+
* of `forearmDeformer_X`, so `ParamElbowX` never moves it, and the shoulder
|
|
957
|
+
* still carries it.
|
|
958
|
+
* - `ParamArmPoseX` (0..1) swaps: the hanging forearm and the elbow cap fade
|
|
959
|
+
* out on it, 1 to 0 (`armParts`), the pose forearm fades in, 0 to 1. The
|
|
960
|
+
* pair is exclusive by construction, and between the ends both show at
|
|
961
|
+
* partial opacity. The part has no mesh: the engine draws a meshless part
|
|
962
|
+
* as its full-box quad with its texture rect, and a rigid part needs no
|
|
963
|
+
* more.
|
|
964
|
+
* - `ParamArmPoseAngleX` rocks it about the elbow, in degrees over
|
|
965
|
+
* `POSE_ANGLE_RANGE`. + tips the raised hand outward, away from the body,
|
|
966
|
+
* mirrored per side. The part points up from its pivot where the hanging
|
|
967
|
+
* forearm points down, so its rotate binding takes −side × the value; the
|
|
968
|
+
* elbow's multiplier is the same −side, which gives the shoulder's reading.
|
|
969
|
+
* The composer puts the drawing's elbow end on the pivot (`measure` warns
|
|
970
|
+
* when it is off), so the rig does not use the crop's own pivot
|
|
971
|
+
* (`forearmPoseGeometry`).
|
|
972
|
+
*
|
|
973
|
+
* It draws after the hair, above the face and the front hair: a raised hand
|
|
974
|
+
* passes them (`ROLE_TABLE`).
|
|
975
|
+
*/
|
|
976
|
+
|
|
977
|
+
interface ForearmPoseGeometry {
|
|
978
|
+
/** The elbow end's pivot, model space: where the drawing's elbow end is
|
|
979
|
+
* centred. */
|
|
980
|
+
pivot: {
|
|
981
|
+
x: number;
|
|
982
|
+
y: number;
|
|
983
|
+
};
|
|
984
|
+
/** r_e: half the elbow end's width, px. */
|
|
985
|
+
radius: number;
|
|
986
|
+
/** The first painted row's model y: the raised hand's top. */
|
|
987
|
+
top: number;
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* The pose forearm's own geometry: the shoulder rule run from the bottom
|
|
991
|
+
* (`endPivot`), since it is drawn standing up from its elbow, plus the top of
|
|
992
|
+
* the paint.
|
|
993
|
+
*/
|
|
994
|
+
declare function forearmPoseGeometry(layer: LayerInput): ForearmPoseGeometry;
|
|
995
|
+
|
|
944
996
|
/** The part ids a `role`'s layer becomes, back to front: every one of them
|
|
945
997
|
* takes its texture from the layer's crop. Throws on an unknown role. */
|
|
946
998
|
declare function partIdsOfRole(role: string): readonly string[];
|
|
947
999
|
/**
|
|
948
1000
|
* Map file names to roles. Throws on an unknown role, a role named twice, a
|
|
949
|
-
* required role (`face`, `eye_L`, `eye_R
|
|
950
|
-
* without a body
|
|
1001
|
+
* required role (`face`, `eye_L`, `eye_R`) missing, no mouth (`mouth`, or the
|
|
1002
|
+
* lip set) or a partial or mixed one, an arm without a body, or a pose forearm
|
|
1003
|
+
* without its arm.
|
|
951
1004
|
*/
|
|
952
1005
|
declare function parseLayerRoles(fileNames: string[]): {
|
|
953
1006
|
role: string;
|
|
@@ -962,15 +1015,18 @@ declare function parseLayerRoles(fileNames: string[]): {
|
|
|
962
1015
|
* turns on BodyAngleX/Y/Z, its legs planted; a head deformer hung from it
|
|
963
1016
|
* that rolls about the chin and breathes; each arm hung from it too, as an
|
|
964
1017
|
* upper arm, a forearm and an elbow cap turning about the shoulder and the
|
|
965
|
-
* elbow (`arms.ts`)
|
|
1018
|
+
* elbow (`arms.ts`), and with a drawn pose forearm a switch that swaps it in
|
|
1019
|
+
* for the hanging one (`forearm-pose.ts`); one small warp grid per feature
|
|
966
1020
|
* (each eye, each brow, the nose, the mouth), translating and foreshortening
|
|
967
1021
|
* it by its own lead over the plate; and the plate, the hair and the blush
|
|
968
1022
|
* moved by per-vertex keyforms of their own — the plate as up to four
|
|
969
1023
|
* islands of one drawing: a head that slides, a neck that stays on the torso
|
|
970
1024
|
* and two ears that lag. Blink, gaze, brows, mouth, breath and
|
|
971
1025
|
* hair sway are part warps and bindings under those. The model also declares
|
|
972
|
-
* the default expressions and the Nod, Shake and Tilt motions
|
|
973
|
-
* (`animations.ts`).
|
|
1026
|
+
* the default expressions and the Nod, Shake and Tilt motions, and
|
|
1027
|
+
* with a pose forearm the Wave (`animations.ts`). The mouth has two paths,
|
|
1028
|
+
* chosen by the layers: `mouth` alone stretches, with `mouth_open` it
|
|
1029
|
+
* crossfades; the lip set folds open like the eyelid (`mouth.ts`).
|
|
974
1030
|
*/
|
|
975
1031
|
|
|
976
1032
|
declare function generateIkiFromLayerSet(layers: LayerInput[], canvas: {
|
|
@@ -1106,11 +1162,12 @@ interface RgbaLayer {
|
|
|
1106
1162
|
interface LayerSetMeasurer {
|
|
1107
1163
|
/**
|
|
1108
1164
|
* Measure one layer while its `rgba` is in memory, keeping no reference to
|
|
1109
|
-
* it: only the set's opaque union,
|
|
1165
|
+
* it: only the set's opaque union (a pose forearm, hidden at rest, stays out
|
|
1166
|
+
* of it and of the per-role edges), this layer's per-row opaque extent and
|
|
1110
1167
|
* the `LayerInput` it returns outlive the call, so the host may drop `rgba`
|
|
1111
1168
|
* as soon as it returns. Returns the layer's `LayerInput` — its crop
|
|
1112
|
-
* box, the face's `rowHalfWidths`, the face's, hair layers', body's
|
|
1113
|
-
*
|
|
1169
|
+
* box, the face's `rowHalfWidths`, the face's, hair layers', body's, arms',
|
|
1170
|
+
* pose forearms' and lip set's `rowRuns`, the nose's
|
|
1114
1171
|
* `denseCore` unless that is a speck of its crop (`isSpeckCore`) — or
|
|
1115
1172
|
* `null` for an empty layer, one with no pixel at or above
|
|
1116
1173
|
* `ALPHA_BBOX_THRESHOLD`, which it records nothing for: the host reports
|
|
@@ -1367,4 +1424,4 @@ declare function createGridMesh(cols: number, rows: number): IkiMesh;
|
|
|
1367
1424
|
*/
|
|
1368
1425
|
declare function createDefaultWarpDeformer(model: IkiModel): IkiWarpDeformer;
|
|
1369
1426
|
|
|
1370
|
-
export { ALPHA_BBOX_THRESHOLD, ALPHA_OPAQUE, ATLAS_PADDING, AddDeformer, AddPart, AddPhysicsRig, type AlphaBbox, type ApplyAtlasInput, type ArmGeometry, type AtlasAssignment, type AtlasLayout, type AtlasPlacement, type AtlasSource, CaptureGridKeyform, DEFAULT_TURN_TARGETS, type DeformerTransformChannel, DeleteDeformer, DeletePart, DeletePhysicsRig, type EditCommand, type EditTransformChannel, EditorDocument, HEAD_BAND, type IrisStrand, LayerGeometryError, type LayerInput, type LayerSetMeasurement, type LayerSetMeasurer, type RgbaLayer, type RigStyle, SPECK_CORE_FRACTION, SetDeformerBindings, SetDeformerParent, SetDeformerPivot, SetDeformerPivotX, SetDeformerPivotY, SetDeformerTransform, SetPartBindings, SetPartColor, SetPartDeformer, SetPartHeight, SetPartMesh, SetPartOrder, SetPartTransform, SetPartWidth, SetPhysicsRig, type StrandOverlap, type TurnDepths, type TurnSolveReport, TurnTargetError, type TurnTargets, UV_INSET_PX, armGeometry, captureBindingEndpoint, computeGridOffsets, createDefaultMatrixDeformer, createDefaultPart, createDefaultWarpDeformer, createGridMesh, createLayerSetMeasurer, denseCoreOf, detectAlphaBbox, foregroundSpan, generateIkiFromLayerSet, headHalfOf, interpolateGridOffsets, isSpeckCore, packAtlas, parseLayerRoles, partIdsOfRole, upsertGridKeyform, uvRectFor, validateDeformerDelete, validateDeformerReparent, validatePartAttach };
|
|
1427
|
+
export { ALPHA_BBOX_THRESHOLD, ALPHA_OPAQUE, ATLAS_PADDING, AddDeformer, AddPart, AddPhysicsRig, type AlphaBbox, type ApplyAtlasInput, type ArmGeometry, type AtlasAssignment, type AtlasLayout, type AtlasPlacement, type AtlasSource, CaptureGridKeyform, DEFAULT_TURN_TARGETS, type DeformerTransformChannel, DeleteDeformer, DeletePart, DeletePhysicsRig, type EditCommand, type EditTransformChannel, EditorDocument, type ForearmPoseGeometry, HEAD_BAND, type IrisStrand, LayerGeometryError, type LayerInput, type LayerSetMeasurement, type LayerSetMeasurer, type RgbaLayer, type RigStyle, SPECK_CORE_FRACTION, SetDeformerBindings, SetDeformerParent, SetDeformerPivot, SetDeformerPivotX, SetDeformerPivotY, SetDeformerTransform, SetPartBindings, SetPartColor, SetPartDeformer, SetPartHeight, SetPartMesh, SetPartOrder, SetPartTransform, SetPartWidth, SetPhysicsRig, type StrandOverlap, type TurnDepths, type TurnSolveReport, TurnTargetError, type TurnTargets, UV_INSET_PX, armGeometry, captureBindingEndpoint, computeGridOffsets, createDefaultMatrixDeformer, createDefaultPart, createDefaultWarpDeformer, createGridMesh, createLayerSetMeasurer, denseCoreOf, detectAlphaBbox, forearmPoseGeometry, foregroundSpan, generateIkiFromLayerSet, headHalfOf, interpolateGridOffsets, isSpeckCore, packAtlas, parseLayerRoles, partIdsOfRole, upsertGridKeyform, uvRectFor, validateDeformerDelete, validateDeformerReparent, validatePartAttach };
|