@ikijs/editor 0.33.1 → 0.34.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 +4 -4
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +35 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +35 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,10 +72,10 @@ The rig turns the head by parallax, not a reshaped face, with values of our
|
|
|
72
72
|
own picked by eye (`auto-rig/profile.ts`, `AUTO-RIG.md`). The face plate
|
|
73
73
|
translates, the chin leading it; the features lead the plate by their depth
|
|
74
74
|
(the nose most, then the eyes, brows and mouth), the eyes foreshortening mildly
|
|
75
|
-
about their own centres; the front hair rides the face where it lies over it and
|
|
76
|
-
outline where it draws it — though on its cap the turn never carries its outer
|
|
75
|
+
about their own centres; the front hair rides the face where it lies over it and turns the head's
|
|
76
|
+
outline, where it draws it, only as the back hair turns — though on its cap the turn never carries its outer
|
|
77
77
|
edge further outside the back hair painted behind it than the nod alone does —
|
|
78
|
-
and the back hair
|
|
78
|
+
and the back hair, the head's shell, follows the head by 0.3 of the face's turn and nod; the neck and the
|
|
79
79
|
ears the face layer paints are cut off into islands of the plate's own mesh,
|
|
80
80
|
drawn behind the head — the neck stays (only the chin's shade slides across
|
|
81
81
|
it), the ears lag the face, the far one held while the head slides partly over it (about half of an ear of the default size). AngleZ rolls the head 14° about the chin.
|
|
@@ -176,7 +176,7 @@ row's alpha ≥ 128 runs as a flat list of canvas columns `[start, end, …]`, e
|
|
|
176
176
|
end exclusive), measured for `face`, `hair_front`, `hair_back`, `hair_side_L`
|
|
177
177
|
and `hair_side_R` so the turn and the nod can tell where back hair is painted
|
|
178
178
|
behind the front hair and the rig can tell where a side lock first shows under
|
|
179
|
-
the bangs; absent, the front hair
|
|
179
|
+
the bangs; absent, the front hair's outline turns only as the back hair does and it keeps its crown's ease
|
|
180
180
|
to the back hair on the turn, and that ease looking down on the nod, while a
|
|
181
181
|
side lock's root band ends a quarter of the way down its box.
|
|
182
182
|
|
package/dist/index.d.mts
CHANGED
|
@@ -717,7 +717,8 @@ interface RigPlan {
|
|
|
717
717
|
/** The front hair's share of the face's turn. */
|
|
718
718
|
follow?: number;
|
|
719
719
|
/** Its outer edge's share, where the front hair draws the head's outline
|
|
720
|
-
* and no back hair paints behind that edge (
|
|
720
|
+
* and no back hair paints behind that edge (never less than the back
|
|
721
|
+
* hair's own turn: at 0 the outline turns only as the back hair does;
|
|
721
722
|
* `follow` rides it whole). Where back hair does, the edge rides
|
|
722
723
|
* further, as far as that back hair stays behind it through the turn and
|
|
723
724
|
* the nod, up to the front hair's follow there (over the far eye's rows,
|
|
@@ -883,7 +884,7 @@ declare class LayerGeometryError extends Error {
|
|
|
883
884
|
* The profile's own turn (`profile.ts`), in the cues' units — what a rig with
|
|
884
885
|
* no `turnTargets` renders on a head whose silhouette at the eye row is back
|
|
885
886
|
* hair about 1 hh (eye row → chin) wide. eyeShift: the eye pair's mean shift
|
|
886
|
-
* at ±30 less the back hair's
|
|
887
|
+
* at ±30 less the back hair's own turn, over a 1 hh head half-width.
|
|
887
888
|
* farEyeRatio: the far eye's width over the near one's. silhouetteRatio: the
|
|
888
889
|
* silhouette holds its width.
|
|
889
890
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -717,7 +717,8 @@ interface RigPlan {
|
|
|
717
717
|
/** The front hair's share of the face's turn. */
|
|
718
718
|
follow?: number;
|
|
719
719
|
/** Its outer edge's share, where the front hair draws the head's outline
|
|
720
|
-
* and no back hair paints behind that edge (
|
|
720
|
+
* and no back hair paints behind that edge (never less than the back
|
|
721
|
+
* hair's own turn: at 0 the outline turns only as the back hair does;
|
|
721
722
|
* `follow` rides it whole). Where back hair does, the edge rides
|
|
722
723
|
* further, as far as that back hair stays behind it through the turn and
|
|
723
724
|
* the nod, up to the front hair's follow there (over the far eye's rows,
|
|
@@ -883,7 +884,7 @@ declare class LayerGeometryError extends Error {
|
|
|
883
884
|
* The profile's own turn (`profile.ts`), in the cues' units — what a rig with
|
|
884
885
|
* no `turnTargets` renders on a head whose silhouette at the eye row is back
|
|
885
886
|
* hair about 1 hh (eye row → chin) wide. eyeShift: the eye pair's mean shift
|
|
886
|
-
* at ±30 less the back hair's
|
|
887
|
+
* at ±30 less the back hair's own turn, over a 1 hh head half-width.
|
|
887
888
|
* farEyeRatio: the far eye's width over the near one's. silhouetteRatio: the
|
|
888
889
|
* silhouette holds its width.
|
|
889
890
|
*
|
package/dist/index.js
CHANGED
|
@@ -2063,7 +2063,7 @@ var PROFILE_VALUES = {
|
|
|
2063
2063
|
noseDepth: 2,
|
|
2064
2064
|
hairFollow: 1,
|
|
2065
2065
|
fore: 0.2,
|
|
2066
|
-
backShare: 0.
|
|
2066
|
+
backShare: 0.3,
|
|
2067
2067
|
earFar: 0,
|
|
2068
2068
|
earFore: 0.1,
|
|
2069
2069
|
nodDown: 0.18,
|
|
@@ -2115,7 +2115,8 @@ function deriveProfile(v) {
|
|
|
2115
2115
|
* takes it only down to its root, `hairSideField`) rides the face at this
|
|
2116
2116
|
* share of its translation. */
|
|
2117
2117
|
hairFollow: v.hairFollow,
|
|
2118
|
-
/** The head's outline at the eye row
|
|
2118
|
+
/** The head's outline at the eye row turns only as the back hair does
|
|
2119
|
+
* (`hairBack`, which this share never undercuts): where the front hair draws
|
|
2119
2120
|
* it, its outer edge follows the face this much on a row where no back
|
|
2120
2121
|
* hair paints behind that edge. Where back hair does, the edge rides
|
|
2121
2122
|
* further, as far as that back hair stays behind it through the turn and
|
|
@@ -2124,8 +2125,8 @@ function deriveProfile(v) {
|
|
|
2124
2125
|
* rows above the eyes) it follows less where the turn would otherwise
|
|
2125
2126
|
* carry it further outside its back hair than the nod alone does. */
|
|
2126
2127
|
outlineFollow: 0,
|
|
2127
|
-
/** The back hair's
|
|
2128
|
-
hairBack:
|
|
2128
|
+
/** The back hair turns with the head, a share of the plate's slide. */
|
|
2129
|
+
hairBack: v.backShare * v.slide,
|
|
2129
2130
|
/** The ears lag the plate: the far one's outer edge moves this share of
|
|
2130
2131
|
* its slide; the near one rides the head. */
|
|
2131
2132
|
earFar: v.earFar,
|
|
@@ -3768,7 +3769,7 @@ function hairFrontField(m) {
|
|
|
3768
3769
|
)
|
|
3769
3770
|
);
|
|
3770
3771
|
const followOf = (x, y, s) => followAt(x, y, s) + (ride === void 0 ? 0 : ride.lift(x, y, s));
|
|
3771
|
-
const drift =
|
|
3772
|
+
const drift = -m.hairBack;
|
|
3772
3773
|
const boundOf = (x, y, s) => {
|
|
3773
3774
|
if (ride === void 0) return followOf(x, y, s);
|
|
3774
3775
|
const b = ride.blend(x, y, s);
|
|
@@ -3935,7 +3936,7 @@ function outerRide(m, inner, coreAt, followAt, capLimit, eyeTop, irisTop) {
|
|
|
3935
3936
|
if (f.hairRuns("hair_front", top) === void 0 || f.hairRuns("hair_back", top) === void 0) {
|
|
3936
3937
|
return void 0;
|
|
3937
3938
|
}
|
|
3938
|
-
const drift =
|
|
3939
|
+
const drift = -m.hairBack;
|
|
3939
3940
|
const sides = [-1, 1];
|
|
3940
3941
|
const n = ys.length;
|
|
3941
3942
|
const count = Math.round(top - ys[n - 1]);
|
|
@@ -4066,6 +4067,7 @@ function outerRide(m, inner, coreAt, followAt, capLimit, eyeTop, irisTop) {
|
|
|
4066
4067
|
const cuts = new Float64Array(n * 2 * nc);
|
|
4067
4068
|
const blend = new Float64Array(n * 2 * nc);
|
|
4068
4069
|
const motion = new Array(n * 2);
|
|
4070
|
+
const held = new Array(n * 2);
|
|
4069
4071
|
const outward = sides.map((side) => {
|
|
4070
4072
|
const cols = xs.map((_, c) => c).filter((c) => side * (xs[c] - f.axisX) >= 0);
|
|
4071
4073
|
return side < 0 ? cols.reverse() : cols;
|
|
@@ -4122,22 +4124,24 @@ function outerRide(m, inner, coreAt, followAt, capLimit, eyeTop, irisTop) {
|
|
|
4122
4124
|
}
|
|
4123
4125
|
}
|
|
4124
4126
|
motion[r * 2 + j] = after.map((v) => v + drift);
|
|
4127
|
+
held[r * 2 + j] = today.map((v) => v + drift);
|
|
4125
4128
|
for (let c = 0; c < nc; c++)
|
|
4126
4129
|
cuts[(r * 2 + j) * nc + c] = after[c] - today[c];
|
|
4127
4130
|
});
|
|
4128
4131
|
}
|
|
4132
|
+
const at = (r, j, c) => (r * 2 + j) * nc + c;
|
|
4133
|
+
let zero = last + 1;
|
|
4134
|
+
while (zero < n && ys[zero] > eyeTop) zero++;
|
|
4135
|
+
while (zero > last + 1 && zero < n && ys[zero] < irisTop - 0.5) zero--;
|
|
4136
|
+
const endY = zero < n ? ys[zero] : Math.min(Math.max(eyeTop, irisTop - 0.5), ys[n - 1] - 1);
|
|
4129
4137
|
for (let r = 0; r < n; r++) {
|
|
4130
4138
|
sides.forEach((s, j) => {
|
|
4131
4139
|
motion[r * 2 + j] ??= xs.map(
|
|
4132
4140
|
(x) => followAt(x, ys[r], s) + liftAt(x, ys[r], s) + drift
|
|
4133
4141
|
);
|
|
4142
|
+
held[r * 2 + j] ??= motion[r * 2 + j];
|
|
4134
4143
|
});
|
|
4135
4144
|
}
|
|
4136
|
-
const at = (r, j, c) => (r * 2 + j) * nc + c;
|
|
4137
|
-
let zero = last + 1;
|
|
4138
|
-
while (zero < n && ys[zero] > eyeTop) zero++;
|
|
4139
|
-
while (zero > last + 1 && zero < n && ys[zero] < irisTop - 0.5) zero--;
|
|
4140
|
-
const endY = zero < n ? ys[zero] : Math.min(Math.max(eyeTop, irisTop - 0.5), ys[n - 1] - 1);
|
|
4141
4145
|
for (let pass = 0; pass < 8; pass++) {
|
|
4142
4146
|
const was = blend.slice();
|
|
4143
4147
|
for (let j = 0; j < 2; j++) {
|
|
@@ -4155,11 +4159,15 @@ function outerRide(m, inner, coreAt, followAt, capLimit, eyeTop, irisTop) {
|
|
|
4155
4159
|
for (let q = 0; q < r && q <= last; q++) {
|
|
4156
4160
|
if (wr[q] < 1) continue;
|
|
4157
4161
|
const k = (ys[r] - endY) / (ys[q] - endY);
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
);
|
|
4162
|
+
const [mq, hq] = [motion[q * 2 + j], held[q * 2 + j]];
|
|
4163
|
+
const [mr, hr] = [motion[r * 2 + j], held[r * 2 + j]];
|
|
4164
|
+
for (let c = 0; c < nc; c++) {
|
|
4165
|
+
const bq = blend[at(q, j, c)];
|
|
4166
|
+
const ease = hq[c] > 0 ? clamp(1 - (1 - bq) * mq[c] / hq[c], 0, 1) : bq;
|
|
4167
|
+
const want = ease * k;
|
|
4168
|
+
const br = mr[c] > 0 && hr[c] > 0 ? 1 - (1 - want) * hr[c] / mr[c] : want;
|
|
4169
|
+
blend[at(r, j, c)] = Math.max(blend[at(r, j, c)], br);
|
|
4170
|
+
}
|
|
4163
4171
|
}
|
|
4164
4172
|
}
|
|
4165
4173
|
}
|
|
@@ -4176,7 +4184,7 @@ function outerRide(m, inner, coreAt, followAt, capLimit, eyeTop, irisTop) {
|
|
|
4176
4184
|
}
|
|
4177
4185
|
if (blend.every((v, i) => v === was[i])) break;
|
|
4178
4186
|
}
|
|
4179
|
-
const cutRow = (r, j, x) => r > last ? 0 : along(cuts.subarray((r
|
|
4187
|
+
const cutRow = (r, j, x) => r > last ? 0 : along(cuts.subarray(at(r, j, 0), at(r, j, nc)), x);
|
|
4180
4188
|
return {
|
|
4181
4189
|
lift: liftAt,
|
|
4182
4190
|
// Between vertex rows, as the render interpolates; a vertex reads its own
|
|
@@ -4660,6 +4668,7 @@ function buildTurn(frame, landmarks, q, turn) {
|
|
|
4660
4668
|
const eyeHalf = eyes.reduce((sum, e) => sum + (e.x1 - e.x0) / 2, 0) / Math.max(1, eyes.length);
|
|
4661
4669
|
const farScale = 1 + q.fore * A * (turn.eyeFarScale - 1);
|
|
4662
4670
|
const farCorner = lead(turn.eyeFar) - (1 - farScale) * eyeHalf;
|
|
4671
|
+
const shell = A * hh * turn.hairBack;
|
|
4663
4672
|
return {
|
|
4664
4673
|
frame,
|
|
4665
4674
|
face,
|
|
@@ -4677,10 +4686,13 @@ function buildTurn(frame, landmarks, q, turn) {
|
|
|
4677
4686
|
mouth: q.mouth ?? lead(turn.mouth),
|
|
4678
4687
|
mouthWidth: 1 + A * (turn.mouthWidth - 1),
|
|
4679
4688
|
tilt: A,
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4689
|
+
// The front hair lies on the head in front of its shell: neither over
|
|
4690
|
+
// the face nor at the outline it draws does it turn less than the back
|
|
4691
|
+
// hair behind it.
|
|
4692
|
+
hairFront: Math.max(q.follow * face, shell),
|
|
4693
|
+
hairFar: Math.max(q.follow * face, shell, farCorner),
|
|
4694
|
+
hairOuter: Math.max(q.outline * face, shell),
|
|
4695
|
+
hairBack: shell,
|
|
4684
4696
|
shellScale: q.shell,
|
|
4685
4697
|
earFar: q.earFar,
|
|
4686
4698
|
earFarScale: 1 + A * (turn.earFarScale - 1),
|
|
@@ -4802,7 +4814,7 @@ var RIG_PLAN_FIELDS = [
|
|
|
4802
4814
|
fitBy: null,
|
|
4803
4815
|
provisional: false,
|
|
4804
4816
|
migratedFrom: "hairFollow",
|
|
4805
|
-
what: "the front hair's share of the face's turn"
|
|
4817
|
+
what: "the front hair's share of the face's turn (never less than the back hair's own turn, 0.3 of the face's: a share under that has no effect)"
|
|
4806
4818
|
},
|
|
4807
4819
|
{
|
|
4808
4820
|
path: "hair.outlineFollow",
|
|
@@ -4819,7 +4831,7 @@ var RIG_PLAN_FIELDS = [
|
|
|
4819
4831
|
fitBy: null,
|
|
4820
4832
|
provisional: false,
|
|
4821
4833
|
migratedFrom: "outlineFollow",
|
|
4822
|
-
what: "the front hair's outer edge's share where it draws the head's outline (
|
|
4834
|
+
what: "the front hair's outer edge's share where it draws the head's outline (never less than the back hair's own turn: at 0 the outline turns only as the back hair does, though where back hair paints behind it, it may ride further, as far as that back hair reaches; at hair.follow the front hair's side strands ride whole)"
|
|
4823
4835
|
},
|
|
4824
4836
|
{
|
|
4825
4837
|
path: "hair.sway",
|