@ikijs/editor 0.32.0 → 0.33.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 +2 -2
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +45 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +45 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1972,7 +1972,8 @@ var PROFILE_VALUES = {
|
|
|
1972
1972
|
hairFollow: 1,
|
|
1973
1973
|
fore: 0.2,
|
|
1974
1974
|
backShare: 0.1,
|
|
1975
|
-
earFar: 0
|
|
1975
|
+
earFar: 0,
|
|
1976
|
+
earFore: 0.1,
|
|
1976
1977
|
nodDown: 0.18,
|
|
1977
1978
|
nodUp: 0.1,
|
|
1978
1979
|
nodLead: 0.06,
|
|
@@ -2039,7 +2040,7 @@ function deriveProfile(v) {
|
|
|
2039
2040
|
earNear: 1,
|
|
2040
2041
|
/** The far ear's width at full turn, about its outer edge, where the head
|
|
2041
2042
|
* leaves it room; less where it does not. */
|
|
2042
|
-
earFarScale: 1 - v.
|
|
2043
|
+
earFarScale: 1 - v.earFore
|
|
2043
2044
|
};
|
|
2044
2045
|
const mid = v.nodDown * (1 + v.chinShare) / 2;
|
|
2045
2046
|
const feature = (depth) => ({
|
|
@@ -2936,6 +2937,7 @@ function mouthAnchor(byRole) {
|
|
|
2936
2937
|
}
|
|
2937
2938
|
|
|
2938
2939
|
// src/auto-rig/head.ts
|
|
2940
|
+
var EAR_EDGE = 3;
|
|
2939
2941
|
function outerEdge(runs, axisX, side) {
|
|
2940
2942
|
if (runs.length === 0) return void 0;
|
|
2941
2943
|
const x = side > 0 ? runs[runs.length - 1] : runs[0];
|
|
@@ -2969,7 +2971,11 @@ function findEars(raw, wMax, firstRow, lastRow, minRows, maxRows) {
|
|
|
2969
2971
|
if (raw[t] - raw[t - EAR_ROWS] < step) continue;
|
|
2970
2972
|
for (let b = t + minRows; b <= Math.min(lastRow, t + maxRows); b++) {
|
|
2971
2973
|
if (raw[b - EAR_ROWS] - raw[b] >= step) {
|
|
2972
|
-
|
|
2974
|
+
let end = b;
|
|
2975
|
+
for (let k = b + 1; k <= Math.min(lastRow, b + minRows); k++) {
|
|
2976
|
+
if (raw[k - EAR_ROWS] - raw[k] >= step) end = k;
|
|
2977
|
+
}
|
|
2978
|
+
return { top: t - EAR_ROWS, bottom: end };
|
|
2973
2979
|
}
|
|
2974
2980
|
}
|
|
2975
2981
|
return void 0;
|
|
@@ -3047,6 +3053,7 @@ function buildHeadFrame(layers, opts) {
|
|
|
3047
3053
|
return rows[i] + (rows[j] - rows[i]) * clamp(r - i, 0, 1);
|
|
3048
3054
|
};
|
|
3049
3055
|
const rawRows = raw;
|
|
3056
|
+
let earRows;
|
|
3050
3057
|
const earless = (chin) => {
|
|
3051
3058
|
const rowOf = (y) => Math.round(canvasH / 2 - y - faceLayer.bbox.y - 0.5);
|
|
3052
3059
|
const span3 = Math.max(1, eyeY - chin);
|
|
@@ -3069,8 +3076,10 @@ function buildHeadFrame(layers, opts) {
|
|
|
3069
3076
|
top: rowY(top) + 0.5,
|
|
3070
3077
|
bottom: rowY(bottom) - 0.5,
|
|
3071
3078
|
attachAt: (y) => attach(clamp(canvasH / 2 - y - faceLayer.bbox.y - 0.5, top, bottom)),
|
|
3072
|
-
outer
|
|
3079
|
+
outer,
|
|
3080
|
+
edgeAt: (y) => attach(clamp(canvasH / 2 - y - faceLayer.bbox.y - 0.5, top, bottom)) + EAR_EDGE
|
|
3073
3081
|
};
|
|
3082
|
+
earRows = { top, bottom };
|
|
3074
3083
|
return smoothProfile(
|
|
3075
3084
|
rawRows.map((v, r) => r > top && r < bottom ? attach(r) : v)
|
|
3076
3085
|
);
|
|
@@ -3192,9 +3201,13 @@ function buildHeadFrame(layers, opts) {
|
|
|
3192
3201
|
headHalfAt = readRows(head);
|
|
3193
3202
|
headMax = Math.max(...head);
|
|
3194
3203
|
if (ears !== void 0) {
|
|
3204
|
+
const band = earRows;
|
|
3205
|
+
const edge = head.map(
|
|
3206
|
+
(w, r) => r >= band.top && r <= band.bottom ? w + EAR_EDGE : w
|
|
3207
|
+
);
|
|
3195
3208
|
const bottomOf = (d) => {
|
|
3196
|
-
for (let r =
|
|
3197
|
-
if (
|
|
3209
|
+
for (let r = edge.length - 1; r >= 0; r--) {
|
|
3210
|
+
if (edge[r] >= d) return rowY(r) - 0.5;
|
|
3198
3211
|
}
|
|
3199
3212
|
return face.y1;
|
|
3200
3213
|
};
|
|
@@ -3394,7 +3407,7 @@ function earField(m) {
|
|
|
3394
3407
|
const attach = ears.attachAt(y);
|
|
3395
3408
|
const span3 = Math.max(1, ears.outer - attach);
|
|
3396
3409
|
if (sideOf(m, x, s) === "far") {
|
|
3397
|
-
const rim2 =
|
|
3410
|
+
const rim2 = m.earFar * m.face;
|
|
3398
3411
|
const root2 = earRoot(m, face, y, s);
|
|
3399
3412
|
const lead = Math.max(
|
|
3400
3413
|
0,
|
|
@@ -3419,7 +3432,7 @@ function farEarCovered(m) {
|
|
|
3419
3432
|
const ears = m.frame.ears;
|
|
3420
3433
|
if (ears === void 0) return true;
|
|
3421
3434
|
const face = faceField(m);
|
|
3422
|
-
const rim =
|
|
3435
|
+
const rim = m.earFar * m.face;
|
|
3423
3436
|
const y0 = ears.bottom - 2;
|
|
3424
3437
|
const y1 = ears.top + 2;
|
|
3425
3438
|
const n = Math.max(1, Math.ceil(y1 - y0));
|
|
@@ -4260,6 +4273,7 @@ function fitTurn(ctx, targets, plan, build) {
|
|
|
4260
4273
|
lead: plan.turn.featureLead,
|
|
4261
4274
|
follow: plan.hair.follow,
|
|
4262
4275
|
outline: plan.hair.outlineFollow,
|
|
4276
|
+
earFar: plan.turn.farEar,
|
|
4263
4277
|
fore: targets.farEyeRatio === void 0 ? plan.turn.eyeForeshorten : 1,
|
|
4264
4278
|
shell: 1,
|
|
4265
4279
|
noseLead: targets.noseShift !== void 0 || plan.turn.noseLead === 1 ? void 0 : plan.turn.noseLead
|
|
@@ -4496,6 +4510,7 @@ function buildTurn(frame, landmarks, q, turn) {
|
|
|
4496
4510
|
hairOuter: q.outline * face,
|
|
4497
4511
|
hairBack: A * hh * turn.hairBack,
|
|
4498
4512
|
shellScale: q.shell,
|
|
4513
|
+
earFar: q.earFar,
|
|
4499
4514
|
earFarScale: 1 + A * (turn.earFarScale - 1),
|
|
4500
4515
|
...landmarks
|
|
4501
4516
|
};
|
|
@@ -4583,6 +4598,23 @@ var RIG_PLAN_FIELDS = [
|
|
|
4583
4598
|
migratedFrom: null,
|
|
4584
4599
|
what: "how far the nose leads the face plate on the turn \u2014 turn only, the nod keeps the profile's nose depth"
|
|
4585
4600
|
},
|
|
4601
|
+
{
|
|
4602
|
+
path: "turn.farEar",
|
|
4603
|
+
group: "turn",
|
|
4604
|
+
key: "farEar",
|
|
4605
|
+
kind: "absolute",
|
|
4606
|
+
unit: "share of the face plate's slide",
|
|
4607
|
+
default: PROFILE.TURN.earFar,
|
|
4608
|
+
range: [0, 1],
|
|
4609
|
+
recommended: [0, 0.5],
|
|
4610
|
+
step: 0.1,
|
|
4611
|
+
poses: TURN_POSES,
|
|
4612
|
+
cue: null,
|
|
4613
|
+
fitBy: null,
|
|
4614
|
+
provisional: false,
|
|
4615
|
+
migratedFrom: null,
|
|
4616
|
+
what: "how far the far ear's outer edge follows the face on the turn (0: it holds and the head slides over it, about half of a default-sized ear going under the face; 1: it rides with the face and stays whole)"
|
|
4617
|
+
},
|
|
4586
4618
|
{
|
|
4587
4619
|
path: "hair.follow",
|
|
4588
4620
|
group: "hair",
|
|
@@ -6681,6 +6713,11 @@ function buildFaceMesh(frame, b, head, neckCells) {
|
|
|
6681
6713
|
frame.axisX - frame.headMax + 0.5,
|
|
6682
6714
|
frame.axisX + frame.headMax - 0.5
|
|
6683
6715
|
];
|
|
6716
|
+
const ears2 = frame.ears;
|
|
6717
|
+
if (ears2 !== void 0 && neck2 === void 0) {
|
|
6718
|
+
const d = ears2.edgeAt(ears2.bottom);
|
|
6719
|
+
at.push(frame.axisX - d, frame.axisX + d);
|
|
6720
|
+
}
|
|
6684
6721
|
if (neck2 !== void 0) {
|
|
6685
6722
|
at.push(
|
|
6686
6723
|
frame.axisX,
|