@ikijs/editor 0.3.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.
- package/README.md +30 -1
- package/dist/index.d.mts +115 -2
- package/dist/index.d.ts +115 -2
- package/dist/index.js +966 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +964 -72
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ leaves the document untouched.
|
|
|
49
49
|
| Grid keyforms | `computeGridOffsets`, `interpolateGridOffsets`, `upsertGridKeyform` |
|
|
50
50
|
| Factories | `createDefaultPart`, `createDefaultMatrixDeformer`, `createDefaultWarpDeformer`, `createGridMesh` |
|
|
51
51
|
| Pixels | `detectAlphaBbox`, `ALPHA_BBOX_THRESHOLD`, `AlphaBbox` |
|
|
52
|
-
| Auto-rig | `generateIkiFromLayerSet`, `parseLayerRoles`
|
|
52
|
+
| Auto-rig | `generateIkiFromLayerSet`, `parseLayerRoles`, `TurnTargets`, `DEFAULT_TURN_TARGETS`, `TurnSolveReport` |
|
|
53
53
|
| Bindings | `captureBindingEndpoint` |
|
|
54
54
|
|
|
55
55
|
## Auto-rig
|
|
@@ -60,6 +60,35 @@ leaves the document untouched.
|
|
|
60
60
|
torso that follows and breathes, and emotes with its brows — including a
|
|
61
61
|
hair-sway physics rig when a `hair_front` layer is present.
|
|
62
62
|
|
|
63
|
+
On the turn the head's outline holds still — the bangs that draw it pin their
|
|
64
|
+
own silhouette — while everything inside it slides: the face plate, its
|
|
65
|
+
features, and the bangs' own inner strands. That slide is the plate's own ask, a
|
|
66
|
+
quarter of its half-width, capped to what the held outline has room for when
|
|
67
|
+
`turnTargets.headHalfWidth` was measured and uncut when it was not. That turn is
|
|
68
|
+
**fitted, not tuned**: on a layer set with a `nose`, the cylinder's radius and
|
|
69
|
+
each feature's own depth on top of that slide are solved from
|
|
70
|
+
`options.turnTargets` — the cues a 30° reference measures (how far the eye pair
|
|
71
|
+
slides, how much the far eye foreshortens, whether the silhouette holds),
|
|
72
|
+
defaulting to `DEFAULT_TURN_TARGETS`. The features' slide is bounded by the art:
|
|
73
|
+
every feature has to stay on the face plate, because past its contour the far
|
|
74
|
+
eye is drawn over the side hair, which still bends with the plate inside that
|
|
75
|
+
held outline and swallows it. A target you passed that this layer set cannot
|
|
76
|
+
reach **throws**, naming the field and the range it could have had; a target
|
|
77
|
+
that came from the defaults is a style prior, not a measurement of this
|
|
78
|
+
character, so it is **clamped** to what the layer set can do and the rig is
|
|
79
|
+
built. Pass `options.onTurnSolved` to see what the turn settled on and which
|
|
80
|
+
targets were clamped.
|
|
81
|
+
|
|
82
|
+
`turnTargets.headHalfWidth` is what the shift targets are fractions of, when a
|
|
83
|
+
caller has measured the actual head (the face plate stands in otherwise).
|
|
84
|
+
Alongside it, `options.headEdges` names, per side, every layer with an opaque
|
|
85
|
+
pixel at the eye row and its own rest x there — a companion to a measured
|
|
86
|
+
`headHalfWidth`, absent otherwise — so the solver can land each candidate
|
|
87
|
+
through its OWN part's deformation (the bangs move with their hold, the back
|
|
88
|
+
hair holds still, a face-plate or body edge slide) rather than assume the head
|
|
89
|
+
is centred on the face plate or that whichever part drew furthest out at rest
|
|
90
|
+
is still the furthest out after it turns.
|
|
91
|
+
|
|
63
92
|
It takes **already-decoded** layer geometry (`LayerInput`), never pixels, which
|
|
64
93
|
is what keeps this package free of any image dependency: the editor app
|
|
65
94
|
decodes with canvas, `@ikijs/mcp` decodes with `sharp`, and both feed the same
|
package/dist/index.d.mts
CHANGED
|
@@ -891,6 +891,92 @@ declare function parseLayerRoles(fileNames: string[]): {
|
|
|
891
891
|
role: string;
|
|
892
892
|
fileName: string;
|
|
893
893
|
}[];
|
|
894
|
+
/**
|
|
895
|
+
* What a head does at full turn, as the cues `measure_turn_reference` reads off
|
|
896
|
+
* a front/turned reference pair. The turn is fitted to these — the cylinder's
|
|
897
|
+
* radius and the features' depths are solved from them, not tuned.
|
|
898
|
+
*
|
|
899
|
+
* Every field is optional: `DEFAULT_TURN_TARGETS` supplies the three a
|
|
900
|
+
* reference measures, and the nose and the mouth derive from the eyes when they
|
|
901
|
+
* are not given.
|
|
902
|
+
*
|
|
903
|
+
* What happens when the layer set cannot reach a target depends on where the
|
|
904
|
+
* target came from. A number the CALLER passed is a measurement, so an
|
|
905
|
+
* unreachable one throws, naming the field and what was on offer. A number this
|
|
906
|
+
* module filled in — a default, or a nose/mouth derived from the eyes — is a
|
|
907
|
+
* style prior, not a promise about this character: it is CLAMPED to what the
|
|
908
|
+
* layer set can do and the rig is built. The alternative is a generator that
|
|
909
|
+
* refuses its own defaults, which would leave a perfectly good layer set with
|
|
910
|
+
* no model at all. `solveTurnModel` reports which fields it clamped.
|
|
911
|
+
*/
|
|
912
|
+
interface TurnTargets {
|
|
913
|
+
/** How far the eye pair's centre slides toward the far side at full turn, as
|
|
914
|
+
* a fraction of the head's half-width. The sign is ignored: which way is
|
|
915
|
+
* the turn's own business. */
|
|
916
|
+
eyeShift?: number;
|
|
917
|
+
/** The far eye's width over the near eye's at full turn, divided by the same
|
|
918
|
+
* ratio at rest. 1 is no foreshortening; 0 is an edge-on far eye. */
|
|
919
|
+
farEyeRatio?: number;
|
|
920
|
+
/** The head's half-width at full turn over its half-width at rest, as a
|
|
921
|
+
* RENDER measures it — the outermost opaque edge on each side, whichever
|
|
922
|
+
* part owns it. 1 holds the silhouette; below 1 narrows it. The hold that
|
|
923
|
+
* produces it is fitted to it, so a measured one is met or refused, never
|
|
924
|
+
* quietly rendered as something else. */
|
|
925
|
+
silhouetteRatio?: number;
|
|
926
|
+
/** `eyeShift` for the nose. Derived from `eyeShift` when absent. */
|
|
927
|
+
noseShift?: number;
|
|
928
|
+
/** `eyeShift` for the mouth. Derived from `eyeShift` when absent. */
|
|
929
|
+
mouthShift?: number;
|
|
930
|
+
/** The head's own half-width at the eye row, in canvas px: what the shift
|
|
931
|
+
* fractions are fractions OF, and the rest distance the silhouette hold
|
|
932
|
+
* pivots on. Without it both fall back to the face plate's half-width, which
|
|
933
|
+
* is narrower than the head the hair draws, so the shifts land short — an
|
|
934
|
+
* approximation for callers that have no pixels, not a default to prefer. */
|
|
935
|
+
headHalfWidth?: number;
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* A `turnTargets` field this generator will not build a rig from: not a number,
|
|
939
|
+
* outside its range, unreachable on this layer set, or a measured head narrower
|
|
940
|
+
* than the face plate it is drawn around. Every one of them carries a number
|
|
941
|
+
* the CALLER passed, so a host can tell them apart from the invariant breaks the
|
|
942
|
+
* rest of the generator throws and report them as bad input instead of failing.
|
|
943
|
+
*/
|
|
944
|
+
declare class TurnTargetError extends Error {
|
|
945
|
+
constructor(message: string);
|
|
946
|
+
}
|
|
947
|
+
/**
|
|
948
|
+
* The reference the turn is fitted to when the caller measured none of its own:
|
|
949
|
+
* a 3/4 portrait, which `measure_turn_reference` reads as 0.671 / −0.224 /
|
|
950
|
+
* 1.012 (its raw turned far/near iris ratio is 0.71 — 0.67 is that ratio
|
|
951
|
+
* normalised by the same ratio at rest, which is what the field means).
|
|
952
|
+
* The silhouette is held exactly: a 1 % change is inside that tool's own noise.
|
|
953
|
+
*/
|
|
954
|
+
declare const DEFAULT_TURN_TARGETS: Readonly<Required<Pick<TurnTargets, "eyeShift" | "farEyeRatio" | "silhouetteRatio">>>;
|
|
955
|
+
/** The turn depth of each feature family: the share of the pinned bulk slide
|
|
956
|
+
* (`headTurnParallaxUnit`) it gets back at full turn. Solved, never tuned. */
|
|
957
|
+
interface TurnDepths {
|
|
958
|
+
eye: number;
|
|
959
|
+
nose: number;
|
|
960
|
+
mouth: number;
|
|
961
|
+
}
|
|
962
|
+
/** What the turn solve settled on, for a caller that wants to see it — the
|
|
963
|
+
* cues it reached and the targets it had to cut down to reach them. */
|
|
964
|
+
interface TurnSolveReport {
|
|
965
|
+
/** Cylinder radius the face-warp bake and the parallax unit were built on. */
|
|
966
|
+
radius: number;
|
|
967
|
+
/** Rest distance from the face centre the silhouette hold pivots on. */
|
|
968
|
+
holdBase: number;
|
|
969
|
+
depths: TurnDepths;
|
|
970
|
+
/** What the rig actually reaches, in the targets' own units. */
|
|
971
|
+
achieved: {
|
|
972
|
+
eyeShift: number;
|
|
973
|
+
farEyeRatio: number;
|
|
974
|
+
silhouetteRatio: number;
|
|
975
|
+
};
|
|
976
|
+
/** Defaulted fields the layer set could not reach, cut down to what it can.
|
|
977
|
+
* Empty when every target was met. */
|
|
978
|
+
clamped: (keyof TurnTargets)[];
|
|
979
|
+
}
|
|
894
980
|
/**
|
|
895
981
|
* Auto-rig: given decoded layer inputs and the shared canvas size, produce a
|
|
896
982
|
* valid IkiModel ready for parseIkiModel.
|
|
@@ -900,7 +986,8 @@ declare function parseLayerRoles(fileNames: string[]): {
|
|
|
900
986
|
* - Emit the standard parameters (same ids/ranges as sample-model.ts), plus a
|
|
901
987
|
* conditional HairSwayX descriptor + hair-sway physics rig when a hair_front
|
|
902
988
|
* layer is present.
|
|
903
|
-
* - Build headDeformer (matrix, neck pivot,
|
|
989
|
+
* - Build headDeformer (matrix, neck pivot, nod/tilt/breath bindings — the
|
|
990
|
+
* turn translates nothing rigidly; its travel is in the face warp),
|
|
904
991
|
* bodyDeformer when a body layer is present (matrix, torso-base pivot,
|
|
905
992
|
* AngleX follow + Breath follow), and faceWarp (warp, FACE_GRID_CELLS²,
|
|
906
993
|
* baked cylinder warp center-relative on faceCenterX).
|
|
@@ -910,10 +997,36 @@ declare function parseLayerRoles(fileNames: string[]): {
|
|
|
910
997
|
* - Part ids equal the role string (deterministic, no crypto.randomUUID).
|
|
911
998
|
* - Return parseIkiModel(structuredClone(model)) — every caller gets a
|
|
912
999
|
* validated model; bad assembly fails loudly.
|
|
1000
|
+
*
|
|
1001
|
+
* `options.turnTargets` is what the head turn is fitted to: the cues a 30°
|
|
1002
|
+
* reference measures, defaulting to DEFAULT_TURN_TARGETS. A target the CALLER
|
|
1003
|
+
* passed that this layer set cannot reach throws; one that came from the
|
|
1004
|
+
* defaults is clamped to what it can do — see TurnTargets for why the two
|
|
1005
|
+
* differ, and pass `options.onTurnSolved` to see which ones were clamped and
|
|
1006
|
+
* what the turn ended up reaching.
|
|
913
1007
|
*/
|
|
914
1008
|
declare function generateIkiFromLayerSet(layers: LayerInput[], canvas: {
|
|
915
1009
|
width: number;
|
|
916
1010
|
height: number;
|
|
1011
|
+
}, options?: {
|
|
1012
|
+
turnTargets?: TurnTargets;
|
|
1013
|
+
/** Called once, after a turn is solved, with what it settled on. Not called
|
|
1014
|
+
* for a layer set without a nose, which solves no turn at all. */
|
|
1015
|
+
onTurnSolved?: (report: TurnSolveReport) => void;
|
|
1016
|
+
/** Every role with an opaque pixel in the eye-row band, per side, when
|
|
1017
|
+
* `turnTargets.headHalfWidth` was measured off that same union — a
|
|
1018
|
+
* companion to it, not a turn target itself (the caller-facing contract
|
|
1019
|
+
* stays the three cues). See `TurnSolveContext.headEdges`. */
|
|
1020
|
+
headEdges?: {
|
|
1021
|
+
left: {
|
|
1022
|
+
role: string;
|
|
1023
|
+
x: number;
|
|
1024
|
+
}[];
|
|
1025
|
+
right: {
|
|
1026
|
+
role: string;
|
|
1027
|
+
x: number;
|
|
1028
|
+
}[];
|
|
1029
|
+
};
|
|
917
1030
|
}): IkiModel;
|
|
918
1031
|
|
|
919
|
-
export { ALPHA_BBOX_THRESHOLD, ATLAS_PADDING, AddDeformer, AddPart, AddPhysicsRig, type AlphaBbox, type ApplyAtlasInput, type AtlasAssignment, type AtlasLayout, type AtlasPlacement, type AtlasSource, CaptureGridKeyform, type DeformerTransformChannel, DeleteDeformer, DeletePart, DeletePhysicsRig, type EditCommand, type EditTransformChannel, EditorDocument, type LayerInput, SetDeformerBindings, SetDeformerParent, SetDeformerPivot, SetDeformerPivotX, SetDeformerPivotY, SetDeformerTransform, SetPartBindings, SetPartColor, SetPartDeformer, SetPartHeight, SetPartMesh, SetPartOrder, SetPartTransform, SetPartWidth, SetPhysicsRig, UV_INSET_PX, captureBindingEndpoint, computeGridOffsets, createDefaultMatrixDeformer, createDefaultPart, createDefaultWarpDeformer, createGridMesh, detectAlphaBbox, generateIkiFromLayerSet, interpolateGridOffsets, packAtlas, parseLayerRoles, upsertGridKeyform, uvRectFor, validateDeformerDelete, validateDeformerReparent, validatePartAttach };
|
|
1032
|
+
export { ALPHA_BBOX_THRESHOLD, ATLAS_PADDING, AddDeformer, AddPart, AddPhysicsRig, type AlphaBbox, type ApplyAtlasInput, type AtlasAssignment, type AtlasLayout, type AtlasPlacement, type AtlasSource, CaptureGridKeyform, DEFAULT_TURN_TARGETS, type DeformerTransformChannel, DeleteDeformer, DeletePart, DeletePhysicsRig, type EditCommand, type EditTransformChannel, EditorDocument, type LayerInput, SetDeformerBindings, SetDeformerParent, SetDeformerPivot, SetDeformerPivotX, SetDeformerPivotY, SetDeformerTransform, SetPartBindings, SetPartColor, SetPartDeformer, SetPartHeight, SetPartMesh, SetPartOrder, SetPartTransform, SetPartWidth, SetPhysicsRig, type TurnDepths, type TurnSolveReport, TurnTargetError, type TurnTargets, UV_INSET_PX, captureBindingEndpoint, computeGridOffsets, createDefaultMatrixDeformer, createDefaultPart, createDefaultWarpDeformer, createGridMesh, detectAlphaBbox, generateIkiFromLayerSet, interpolateGridOffsets, packAtlas, parseLayerRoles, upsertGridKeyform, uvRectFor, validateDeformerDelete, validateDeformerReparent, validatePartAttach };
|
package/dist/index.d.ts
CHANGED
|
@@ -891,6 +891,92 @@ declare function parseLayerRoles(fileNames: string[]): {
|
|
|
891
891
|
role: string;
|
|
892
892
|
fileName: string;
|
|
893
893
|
}[];
|
|
894
|
+
/**
|
|
895
|
+
* What a head does at full turn, as the cues `measure_turn_reference` reads off
|
|
896
|
+
* a front/turned reference pair. The turn is fitted to these — the cylinder's
|
|
897
|
+
* radius and the features' depths are solved from them, not tuned.
|
|
898
|
+
*
|
|
899
|
+
* Every field is optional: `DEFAULT_TURN_TARGETS` supplies the three a
|
|
900
|
+
* reference measures, and the nose and the mouth derive from the eyes when they
|
|
901
|
+
* are not given.
|
|
902
|
+
*
|
|
903
|
+
* What happens when the layer set cannot reach a target depends on where the
|
|
904
|
+
* target came from. A number the CALLER passed is a measurement, so an
|
|
905
|
+
* unreachable one throws, naming the field and what was on offer. A number this
|
|
906
|
+
* module filled in — a default, or a nose/mouth derived from the eyes — is a
|
|
907
|
+
* style prior, not a promise about this character: it is CLAMPED to what the
|
|
908
|
+
* layer set can do and the rig is built. The alternative is a generator that
|
|
909
|
+
* refuses its own defaults, which would leave a perfectly good layer set with
|
|
910
|
+
* no model at all. `solveTurnModel` reports which fields it clamped.
|
|
911
|
+
*/
|
|
912
|
+
interface TurnTargets {
|
|
913
|
+
/** How far the eye pair's centre slides toward the far side at full turn, as
|
|
914
|
+
* a fraction of the head's half-width. The sign is ignored: which way is
|
|
915
|
+
* the turn's own business. */
|
|
916
|
+
eyeShift?: number;
|
|
917
|
+
/** The far eye's width over the near eye's at full turn, divided by the same
|
|
918
|
+
* ratio at rest. 1 is no foreshortening; 0 is an edge-on far eye. */
|
|
919
|
+
farEyeRatio?: number;
|
|
920
|
+
/** The head's half-width at full turn over its half-width at rest, as a
|
|
921
|
+
* RENDER measures it — the outermost opaque edge on each side, whichever
|
|
922
|
+
* part owns it. 1 holds the silhouette; below 1 narrows it. The hold that
|
|
923
|
+
* produces it is fitted to it, so a measured one is met or refused, never
|
|
924
|
+
* quietly rendered as something else. */
|
|
925
|
+
silhouetteRatio?: number;
|
|
926
|
+
/** `eyeShift` for the nose. Derived from `eyeShift` when absent. */
|
|
927
|
+
noseShift?: number;
|
|
928
|
+
/** `eyeShift` for the mouth. Derived from `eyeShift` when absent. */
|
|
929
|
+
mouthShift?: number;
|
|
930
|
+
/** The head's own half-width at the eye row, in canvas px: what the shift
|
|
931
|
+
* fractions are fractions OF, and the rest distance the silhouette hold
|
|
932
|
+
* pivots on. Without it both fall back to the face plate's half-width, which
|
|
933
|
+
* is narrower than the head the hair draws, so the shifts land short — an
|
|
934
|
+
* approximation for callers that have no pixels, not a default to prefer. */
|
|
935
|
+
headHalfWidth?: number;
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* A `turnTargets` field this generator will not build a rig from: not a number,
|
|
939
|
+
* outside its range, unreachable on this layer set, or a measured head narrower
|
|
940
|
+
* than the face plate it is drawn around. Every one of them carries a number
|
|
941
|
+
* the CALLER passed, so a host can tell them apart from the invariant breaks the
|
|
942
|
+
* rest of the generator throws and report them as bad input instead of failing.
|
|
943
|
+
*/
|
|
944
|
+
declare class TurnTargetError extends Error {
|
|
945
|
+
constructor(message: string);
|
|
946
|
+
}
|
|
947
|
+
/**
|
|
948
|
+
* The reference the turn is fitted to when the caller measured none of its own:
|
|
949
|
+
* a 3/4 portrait, which `measure_turn_reference` reads as 0.671 / −0.224 /
|
|
950
|
+
* 1.012 (its raw turned far/near iris ratio is 0.71 — 0.67 is that ratio
|
|
951
|
+
* normalised by the same ratio at rest, which is what the field means).
|
|
952
|
+
* The silhouette is held exactly: a 1 % change is inside that tool's own noise.
|
|
953
|
+
*/
|
|
954
|
+
declare const DEFAULT_TURN_TARGETS: Readonly<Required<Pick<TurnTargets, "eyeShift" | "farEyeRatio" | "silhouetteRatio">>>;
|
|
955
|
+
/** The turn depth of each feature family: the share of the pinned bulk slide
|
|
956
|
+
* (`headTurnParallaxUnit`) it gets back at full turn. Solved, never tuned. */
|
|
957
|
+
interface TurnDepths {
|
|
958
|
+
eye: number;
|
|
959
|
+
nose: number;
|
|
960
|
+
mouth: number;
|
|
961
|
+
}
|
|
962
|
+
/** What the turn solve settled on, for a caller that wants to see it — the
|
|
963
|
+
* cues it reached and the targets it had to cut down to reach them. */
|
|
964
|
+
interface TurnSolveReport {
|
|
965
|
+
/** Cylinder radius the face-warp bake and the parallax unit were built on. */
|
|
966
|
+
radius: number;
|
|
967
|
+
/** Rest distance from the face centre the silhouette hold pivots on. */
|
|
968
|
+
holdBase: number;
|
|
969
|
+
depths: TurnDepths;
|
|
970
|
+
/** What the rig actually reaches, in the targets' own units. */
|
|
971
|
+
achieved: {
|
|
972
|
+
eyeShift: number;
|
|
973
|
+
farEyeRatio: number;
|
|
974
|
+
silhouetteRatio: number;
|
|
975
|
+
};
|
|
976
|
+
/** Defaulted fields the layer set could not reach, cut down to what it can.
|
|
977
|
+
* Empty when every target was met. */
|
|
978
|
+
clamped: (keyof TurnTargets)[];
|
|
979
|
+
}
|
|
894
980
|
/**
|
|
895
981
|
* Auto-rig: given decoded layer inputs and the shared canvas size, produce a
|
|
896
982
|
* valid IkiModel ready for parseIkiModel.
|
|
@@ -900,7 +986,8 @@ declare function parseLayerRoles(fileNames: string[]): {
|
|
|
900
986
|
* - Emit the standard parameters (same ids/ranges as sample-model.ts), plus a
|
|
901
987
|
* conditional HairSwayX descriptor + hair-sway physics rig when a hair_front
|
|
902
988
|
* layer is present.
|
|
903
|
-
* - Build headDeformer (matrix, neck pivot,
|
|
989
|
+
* - Build headDeformer (matrix, neck pivot, nod/tilt/breath bindings — the
|
|
990
|
+
* turn translates nothing rigidly; its travel is in the face warp),
|
|
904
991
|
* bodyDeformer when a body layer is present (matrix, torso-base pivot,
|
|
905
992
|
* AngleX follow + Breath follow), and faceWarp (warp, FACE_GRID_CELLS²,
|
|
906
993
|
* baked cylinder warp center-relative on faceCenterX).
|
|
@@ -910,10 +997,36 @@ declare function parseLayerRoles(fileNames: string[]): {
|
|
|
910
997
|
* - Part ids equal the role string (deterministic, no crypto.randomUUID).
|
|
911
998
|
* - Return parseIkiModel(structuredClone(model)) — every caller gets a
|
|
912
999
|
* validated model; bad assembly fails loudly.
|
|
1000
|
+
*
|
|
1001
|
+
* `options.turnTargets` is what the head turn is fitted to: the cues a 30°
|
|
1002
|
+
* reference measures, defaulting to DEFAULT_TURN_TARGETS. A target the CALLER
|
|
1003
|
+
* passed that this layer set cannot reach throws; one that came from the
|
|
1004
|
+
* defaults is clamped to what it can do — see TurnTargets for why the two
|
|
1005
|
+
* differ, and pass `options.onTurnSolved` to see which ones were clamped and
|
|
1006
|
+
* what the turn ended up reaching.
|
|
913
1007
|
*/
|
|
914
1008
|
declare function generateIkiFromLayerSet(layers: LayerInput[], canvas: {
|
|
915
1009
|
width: number;
|
|
916
1010
|
height: number;
|
|
1011
|
+
}, options?: {
|
|
1012
|
+
turnTargets?: TurnTargets;
|
|
1013
|
+
/** Called once, after a turn is solved, with what it settled on. Not called
|
|
1014
|
+
* for a layer set without a nose, which solves no turn at all. */
|
|
1015
|
+
onTurnSolved?: (report: TurnSolveReport) => void;
|
|
1016
|
+
/** Every role with an opaque pixel in the eye-row band, per side, when
|
|
1017
|
+
* `turnTargets.headHalfWidth` was measured off that same union — a
|
|
1018
|
+
* companion to it, not a turn target itself (the caller-facing contract
|
|
1019
|
+
* stays the three cues). See `TurnSolveContext.headEdges`. */
|
|
1020
|
+
headEdges?: {
|
|
1021
|
+
left: {
|
|
1022
|
+
role: string;
|
|
1023
|
+
x: number;
|
|
1024
|
+
}[];
|
|
1025
|
+
right: {
|
|
1026
|
+
role: string;
|
|
1027
|
+
x: number;
|
|
1028
|
+
}[];
|
|
1029
|
+
};
|
|
917
1030
|
}): IkiModel;
|
|
918
1031
|
|
|
919
|
-
export { ALPHA_BBOX_THRESHOLD, ATLAS_PADDING, AddDeformer, AddPart, AddPhysicsRig, type AlphaBbox, type ApplyAtlasInput, type AtlasAssignment, type AtlasLayout, type AtlasPlacement, type AtlasSource, CaptureGridKeyform, type DeformerTransformChannel, DeleteDeformer, DeletePart, DeletePhysicsRig, type EditCommand, type EditTransformChannel, EditorDocument, type LayerInput, SetDeformerBindings, SetDeformerParent, SetDeformerPivot, SetDeformerPivotX, SetDeformerPivotY, SetDeformerTransform, SetPartBindings, SetPartColor, SetPartDeformer, SetPartHeight, SetPartMesh, SetPartOrder, SetPartTransform, SetPartWidth, SetPhysicsRig, UV_INSET_PX, captureBindingEndpoint, computeGridOffsets, createDefaultMatrixDeformer, createDefaultPart, createDefaultWarpDeformer, createGridMesh, detectAlphaBbox, generateIkiFromLayerSet, interpolateGridOffsets, packAtlas, parseLayerRoles, upsertGridKeyform, uvRectFor, validateDeformerDelete, validateDeformerReparent, validatePartAttach };
|
|
1032
|
+
export { ALPHA_BBOX_THRESHOLD, ATLAS_PADDING, AddDeformer, AddPart, AddPhysicsRig, type AlphaBbox, type ApplyAtlasInput, type AtlasAssignment, type AtlasLayout, type AtlasPlacement, type AtlasSource, CaptureGridKeyform, DEFAULT_TURN_TARGETS, type DeformerTransformChannel, DeleteDeformer, DeletePart, DeletePhysicsRig, type EditCommand, type EditTransformChannel, EditorDocument, type LayerInput, SetDeformerBindings, SetDeformerParent, SetDeformerPivot, SetDeformerPivotX, SetDeformerPivotY, SetDeformerTransform, SetPartBindings, SetPartColor, SetPartDeformer, SetPartHeight, SetPartMesh, SetPartOrder, SetPartTransform, SetPartWidth, SetPhysicsRig, type TurnDepths, type TurnSolveReport, TurnTargetError, type TurnTargets, UV_INSET_PX, captureBindingEndpoint, computeGridOffsets, createDefaultMatrixDeformer, createDefaultPart, createDefaultWarpDeformer, createGridMesh, detectAlphaBbox, generateIkiFromLayerSet, interpolateGridOffsets, packAtlas, parseLayerRoles, upsertGridKeyform, uvRectFor, validateDeformerDelete, validateDeformerReparent, validatePartAttach };
|