@ikijs/editor 0.12.2 → 0.14.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 +7 -8
- package/dist/index.d.mts +16 -20
- package/dist/index.d.ts +16 -20
- package/dist/index.js +152 -116
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +152 -116
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1890,14 +1890,155 @@ function createDefaultWarpDeformer(model) {
|
|
|
1890
1890
|
};
|
|
1891
1891
|
}
|
|
1892
1892
|
|
|
1893
|
+
// src/auto-rig/profile.ts
|
|
1894
|
+
var PROFILE_VALUES = {
|
|
1895
|
+
slide: 0.12,
|
|
1896
|
+
lead: 0.1,
|
|
1897
|
+
noseDepth: 2,
|
|
1898
|
+
hairFollow: 1,
|
|
1899
|
+
fore: 0.2,
|
|
1900
|
+
backShare: 0.1,
|
|
1901
|
+
earFar: 0.5,
|
|
1902
|
+
nodDown: 0.18,
|
|
1903
|
+
nodUp: 0.1,
|
|
1904
|
+
nodLead: 0.06,
|
|
1905
|
+
chinShare: 0.75,
|
|
1906
|
+
rollDeg: 14,
|
|
1907
|
+
gaze: 0.2,
|
|
1908
|
+
blink: 0.6,
|
|
1909
|
+
mouthOpen: 0.8,
|
|
1910
|
+
mouthWiden: 1.2,
|
|
1911
|
+
brow: 0.15,
|
|
1912
|
+
breath: 0.03,
|
|
1913
|
+
sway: 0.08
|
|
1914
|
+
};
|
|
1915
|
+
function deriveProfile(v) {
|
|
1916
|
+
const farLead = v.lead * (1 - v.fore / 2);
|
|
1917
|
+
const nearLead = v.lead * (1 + v.fore / 2);
|
|
1918
|
+
const turn = {
|
|
1919
|
+
/** The face plate's translation. */
|
|
1920
|
+
face: v.slide,
|
|
1921
|
+
/** The chin tip's lead over the plate. */
|
|
1922
|
+
chinLead: v.lead,
|
|
1923
|
+
/** The plate's width at full turn: eye and cheek rows, then the jaw. The
|
|
1924
|
+
* plate translates; it does not narrow. */
|
|
1925
|
+
widthUpper: 1,
|
|
1926
|
+
widthJaw: 1,
|
|
1927
|
+
eyeFar: v.slide + farLead,
|
|
1928
|
+
eyeNear: v.slide + nearLead,
|
|
1929
|
+
/** Each eye's width at full turn, about its own centre. */
|
|
1930
|
+
eyeFarScale: 1 - v.fore,
|
|
1931
|
+
eyeNearScale: 1 + v.fore / 2,
|
|
1932
|
+
browFar: v.slide + farLead,
|
|
1933
|
+
browNear: v.slide + nearLead,
|
|
1934
|
+
nose: v.slide + v.noseDepth * v.lead,
|
|
1935
|
+
mouth: v.slide + v.lead,
|
|
1936
|
+
mouthWidth: 1,
|
|
1937
|
+
/** The mouth's far corner rises (its near end drops) by this much: it
|
|
1938
|
+
* stays level. */
|
|
1939
|
+
mouthTiltDeg: 0,
|
|
1940
|
+
/** The front hair (bangs and side locks) rides the face at this share of
|
|
1941
|
+
* its translation. */
|
|
1942
|
+
hairFollow: v.hairFollow,
|
|
1943
|
+
/** The head's outline at the eye row holds: where the front hair draws
|
|
1944
|
+
* it, its outer edge follows the face this much on a row where no back
|
|
1945
|
+
* hair paints behind that edge. Where back hair does, the edge rides
|
|
1946
|
+
* further, as far as that back hair stays behind it through the turn and
|
|
1947
|
+
* the nod, up to the face's follow there (`hairFollow`; over the far
|
|
1948
|
+
* eye's rows, as far as that eye's outer corner goes). On the cap (the
|
|
1949
|
+
* rows above the eyes) it follows less where the turn would otherwise
|
|
1950
|
+
* carry it further outside its back hair than the nod alone does. */
|
|
1951
|
+
outlineFollow: 0,
|
|
1952
|
+
/** The back hair's slight counter-motion. */
|
|
1953
|
+
hairBack: -v.backShare * v.slide,
|
|
1954
|
+
/** The ears lag the plate: the far one's outer edge moves this share of
|
|
1955
|
+
* its slide; the near one rides the head. */
|
|
1956
|
+
earFar: v.earFar,
|
|
1957
|
+
earNear: 1,
|
|
1958
|
+
/** The far ear's width at full turn, about its outer edge, where the head
|
|
1959
|
+
* leaves it room; less where it does not. */
|
|
1960
|
+
earFarScale: 1 - v.fore
|
|
1961
|
+
};
|
|
1962
|
+
const mid = v.nodDown * (1 + v.chinShare) / 2;
|
|
1963
|
+
const feature = (depth) => ({
|
|
1964
|
+
up: -(v.nodUp + depth * v.nodLead),
|
|
1965
|
+
down: mid + depth * v.nodLead
|
|
1966
|
+
});
|
|
1967
|
+
const nod = {
|
|
1968
|
+
faceTop: { up: -v.nodUp, down: v.nodDown },
|
|
1969
|
+
chin: { up: -v.nodUp, down: v.chinShare * v.nodDown },
|
|
1970
|
+
eye: feature(1),
|
|
1971
|
+
/** Eye height at the extreme, about the eye's centre: it holds. */
|
|
1972
|
+
eyeHeight: { up: 1, down: 1 },
|
|
1973
|
+
brow: feature(1),
|
|
1974
|
+
nose: feature(v.noseDepth),
|
|
1975
|
+
mouth: feature(1),
|
|
1976
|
+
hairFront: { up: -v.hairFollow * v.nodUp, down: v.hairFollow * v.nodDown },
|
|
1977
|
+
/** The front hair's cap top: half the plate's rise looking up; looking
|
|
1978
|
+
* down the plate's top, which the rig slides only as far as the back
|
|
1979
|
+
* hair covers the crown behind it. */
|
|
1980
|
+
hairFrontTop: { up: -v.nodUp / 2, down: v.nodDown },
|
|
1981
|
+
hairBack: { up: -v.backShare * v.nodUp, down: v.backShare * v.nodDown }
|
|
1982
|
+
};
|
|
1983
|
+
const amplitude = {
|
|
1984
|
+
/** Iris travel, in iris widths. */
|
|
1985
|
+
gazeX: v.gaze,
|
|
1986
|
+
gazeY: v.gaze / 2,
|
|
1987
|
+
/** How far the upper lid comes down, over the eye's height. */
|
|
1988
|
+
blink: v.blink,
|
|
1989
|
+
/** A single mouth drawing opens to this height over its rest width. */
|
|
1990
|
+
mouthOpenHeight: v.mouthOpen,
|
|
1991
|
+
/** The mouth widens this much open. */
|
|
1992
|
+
mouthOpenWidth: v.mouthWiden,
|
|
1993
|
+
/** Brow raise / lower, hh. */
|
|
1994
|
+
brow: v.brow,
|
|
1995
|
+
/** Breath lifts the shoulders and the head, hh. */
|
|
1996
|
+
breathBody: v.breath,
|
|
1997
|
+
breathHead: v.breath * 2 / 3,
|
|
1998
|
+
/** Hair tip travel at full sway (±20), hh. */
|
|
1999
|
+
sway: v.sway,
|
|
2000
|
+
/** The neck under the face reaches this far above the jaw, hh — what the
|
|
2001
|
+
* chin uncovers as it slides off it: half again the chin's full-turn
|
|
2002
|
+
* slide, to the next 0.05. */
|
|
2003
|
+
hiddenNeck: Math.ceil(30 * (v.slide + v.lead) - 1e-9) / 20
|
|
2004
|
+
};
|
|
2005
|
+
return { TURN: turn, NOD: nod, ROLL_DEG: v.rollDeg, AMPLITUDE: amplitude };
|
|
2006
|
+
}
|
|
2007
|
+
var { TURN, NOD, ROLL_DEG, AMPLITUDE } = deriveProfile(PROFILE_VALUES);
|
|
2008
|
+
var STYLE_KNOBS = [
|
|
2009
|
+
"turn",
|
|
2010
|
+
"featureLead",
|
|
2011
|
+
"hairFollow",
|
|
2012
|
+
"outlineFollow",
|
|
2013
|
+
"blink",
|
|
2014
|
+
"sway"
|
|
2015
|
+
];
|
|
2016
|
+
function resolveStyle(style, check) {
|
|
2017
|
+
const s = style ?? {};
|
|
2018
|
+
const get = (key, def, lo, hi) => s[key] === void 0 ? def : check(`style.${key}`, s[key], lo, hi);
|
|
2019
|
+
return {
|
|
2020
|
+
turn: get("turn", 1, 0, 3),
|
|
2021
|
+
featureLead: get("featureLead", 1, 0, 3),
|
|
2022
|
+
hairFollow: get("hairFollow", TURN.hairFollow, 0, 2),
|
|
2023
|
+
outlineFollow: get("outlineFollow", TURN.outlineFollow, 0, 2),
|
|
2024
|
+
blink: get("blink", AMPLITUDE.blink, 0.1, 1),
|
|
2025
|
+
sway: get("sway", 1, 0, 5)
|
|
2026
|
+
};
|
|
2027
|
+
}
|
|
2028
|
+
|
|
1893
2029
|
// src/auto-rig/types.ts
|
|
2030
|
+
var round2 = (v) => Math.round(v * 100) / 100;
|
|
1894
2031
|
var TurnTargetError = class extends Error {
|
|
1895
2032
|
constructor(message) {
|
|
1896
2033
|
super(message);
|
|
1897
2034
|
this.name = "TurnTargetError";
|
|
1898
2035
|
}
|
|
1899
2036
|
};
|
|
1900
|
-
var DEFAULT_TURN_TARGETS = Object.freeze({
|
|
2037
|
+
var DEFAULT_TURN_TARGETS = Object.freeze({
|
|
2038
|
+
eyeShift: round2((TURN.eyeFar + TURN.eyeNear) / 2 - TURN.hairBack),
|
|
2039
|
+
farEyeRatio: round2(TURN.eyeFarScale / TURN.eyeNearScale),
|
|
2040
|
+
silhouetteRatio: 1
|
|
2041
|
+
});
|
|
1901
2042
|
|
|
1902
2043
|
// src/auto-rig/roles.ts
|
|
1903
2044
|
var ROLE_TABLE = [
|
|
@@ -1917,6 +2058,8 @@ var ROLE_TABLE = [
|
|
|
1917
2058
|
{ role: "pupil_R", family: "eye_R" },
|
|
1918
2059
|
{ role: "highlight_L", family: "eye_L" },
|
|
1919
2060
|
{ role: "highlight_R", family: "eye_R" },
|
|
2061
|
+
{ role: "lash_lower_L", family: "eye_L" },
|
|
2062
|
+
{ role: "lash_lower_R", family: "eye_R" },
|
|
1920
2063
|
{ role: "lash_L", family: "eye_L" },
|
|
1921
2064
|
{ role: "lash_R", family: "eye_R" },
|
|
1922
2065
|
{ role: "brow_L", family: "brow_L" },
|
|
@@ -2358,117 +2501,6 @@ function land(l, offsets, x, y) {
|
|
|
2358
2501
|
return [topX + (botX - topX) * t, topY + (botY - topY) * t];
|
|
2359
2502
|
}
|
|
2360
2503
|
|
|
2361
|
-
// src/auto-rig/profile.ts
|
|
2362
|
-
var HH_PER_EYE_TO_CHIN = 1.017;
|
|
2363
|
-
var TURN = {
|
|
2364
|
-
/** The face plate's translation (its cheek edges, 0.118 / 0.126). */
|
|
2365
|
-
face: 0.118,
|
|
2366
|
-
/** The chin tip's lead over the plate (it moves 0.194). */
|
|
2367
|
-
chinLead: 0.076,
|
|
2368
|
-
/** The plate's width at full turn: eye and cheek rows, then the jaw. */
|
|
2369
|
-
widthUpper: 0.985,
|
|
2370
|
-
widthJaw: 0.96,
|
|
2371
|
-
eyeFar: 0.192,
|
|
2372
|
-
eyeNear: 0.23,
|
|
2373
|
-
/** Each eye's width at full turn, about its own centre. */
|
|
2374
|
-
eyeFarScale: 0.85,
|
|
2375
|
-
eyeNearScale: 1.085,
|
|
2376
|
-
browFar: 0.213,
|
|
2377
|
-
browNear: 0.243,
|
|
2378
|
-
nose: 0.301,
|
|
2379
|
-
mouth: 0.213,
|
|
2380
|
-
mouthWidth: 0.975,
|
|
2381
|
-
/** The mouth's far corner rises (its near end drops) by this much. */
|
|
2382
|
-
mouthTiltDeg: 4.4,
|
|
2383
|
-
/** The front hair (bangs and side locks) rides the face at this share of
|
|
2384
|
-
* its translation (bangs 1.18×, side locks at the eye row ≈ 1.0×). */
|
|
2385
|
-
hairFollow: 1.1,
|
|
2386
|
-
/** The head's outline at the eye row holds (−0.014 / −0.004 hh): where the
|
|
2387
|
-
* front hair draws it, its outer edge follows the face this much on a row
|
|
2388
|
-
* where no back hair paints behind that edge. Where back hair does, the
|
|
2389
|
-
* edge rides further, as far as that back hair stays behind it through
|
|
2390
|
-
* the turn and the nod, up to the face's follow there (`hairFollow`;
|
|
2391
|
-
* over the far eye's rows, as far as that eye's outer corner goes). On
|
|
2392
|
-
* the cap (the rows above the eyes) it follows less where the turn would
|
|
2393
|
-
* otherwise carry it further outside its back hair than the nod alone
|
|
2394
|
-
* does. */
|
|
2395
|
-
outlineFollow: 0,
|
|
2396
|
-
/** The back hair's slight counter-motion. */
|
|
2397
|
-
hairBack: -0.027,
|
|
2398
|
-
/** The ears lag the plate: the far one's outer edge moves this share of
|
|
2399
|
-
* its slide, the near one this at its widest reach, its root riding the
|
|
2400
|
-
* head (the samples' parallax ratios, 0.44 and 0.87). */
|
|
2401
|
-
earFar: 0.44,
|
|
2402
|
-
earNear: 0.87,
|
|
2403
|
-
/** The far ear's width at full turn, about its outer edge, where the head
|
|
2404
|
-
* leaves it room (the samples' median: Haru 0.81 / 0.91, Hiyori 0.90 /
|
|
2405
|
-
* 0.85, Mao 0.77 / 0.79; none fades); less where it does not. */
|
|
2406
|
-
earFarScale: 0.83
|
|
2407
|
-
};
|
|
2408
|
-
var NOD = {
|
|
2409
|
-
faceTop: { up: -0.081, down: 0.178 },
|
|
2410
|
-
chin: { up: -0.0875, down: 0.109 },
|
|
2411
|
-
eye: { up: -0.167, down: 0.202 },
|
|
2412
|
-
/** Eye height at the extreme, about the eye's centre. */
|
|
2413
|
-
eyeHeight: { up: 0.994, down: 0.96 },
|
|
2414
|
-
brow: { up: -0.167, down: 0.223 },
|
|
2415
|
-
nose: { up: -0.207, down: 0.193 },
|
|
2416
|
-
mouth: { up: -0.172, down: 0.177 },
|
|
2417
|
-
hairFront: { up: -0.11, down: 0.189 },
|
|
2418
|
-
/** The front hair's cap top. The samples' cap top moves 1.215× their face's
|
|
2419
|
-
* centroid looking down (Mao 1.236, Haru 1.626, Hiyori 1.194, Natori
|
|
2420
|
-
* 0.730) and 0.415× looking up (0.385, 0.430, 0.400, 0.487); each ratio
|
|
2421
|
-
* times the plate's own nod halfway between its top and the chin (0.1435
|
|
2422
|
-
* down, 0.084 up). Looking down, the rig slides it only as far as the
|
|
2423
|
-
* back hair covers the crown behind it. */
|
|
2424
|
-
hairFrontTop: { up: -0.035, down: 0.174 },
|
|
2425
|
-
hairBack: { up: -0.011, down: 0.025 }
|
|
2426
|
-
};
|
|
2427
|
-
var ROLL_DEG = 10;
|
|
2428
|
-
var AMPLITUDE = {
|
|
2429
|
-
/** Iris travel, in iris widths (X 0.045 hh, Y 0.031 hh on the samples). */
|
|
2430
|
-
gazeX: 0.17,
|
|
2431
|
-
gazeY: 0.11,
|
|
2432
|
-
/** How far the upper lid comes down, over the eye's height (Haru 0.30,
|
|
2433
|
-
* Mao 0.58, Hiyori 0.67). */
|
|
2434
|
-
blink: 0.58,
|
|
2435
|
-
/** A single mouth drawing opens to this height over its rest width. */
|
|
2436
|
-
mouthOpenHeight: 0.77,
|
|
2437
|
-
/** The mouth widens this much open. */
|
|
2438
|
-
mouthOpenWidth: 1.15,
|
|
2439
|
-
/** Brow raise / lower, hh. */
|
|
2440
|
-
brow: 0.089,
|
|
2441
|
-
/** Breath lifts the shoulders and the head, hh. */
|
|
2442
|
-
breathBody: 0.025,
|
|
2443
|
-
breathHead: 0.016,
|
|
2444
|
-
/** Hair tip travel at full sway (±20), hh (the keyform ranges at ±1 have a
|
|
2445
|
-
* median of 0.05–0.06 hh). */
|
|
2446
|
-
sway: 0.06,
|
|
2447
|
-
/** The neck under the face reaches this far above the jaw, hh — what the
|
|
2448
|
-
* chin uncovers as it slides off it. */
|
|
2449
|
-
hiddenNeck: 0.3
|
|
2450
|
-
};
|
|
2451
|
-
var STYLE_KNOBS = [
|
|
2452
|
-
"turn",
|
|
2453
|
-
"featureLead",
|
|
2454
|
-
"hairFollow",
|
|
2455
|
-
"outlineFollow",
|
|
2456
|
-
"blink",
|
|
2457
|
-
"sway"
|
|
2458
|
-
];
|
|
2459
|
-
function resolveStyle(style, check) {
|
|
2460
|
-
const s = style ?? {};
|
|
2461
|
-
const get = (key, def, lo, hi) => s[key] === void 0 ? def : check(`style.${key}`, s[key], lo, hi);
|
|
2462
|
-
return {
|
|
2463
|
-
turn: get("turn", 1, 0, 3),
|
|
2464
|
-
featureLead: get("featureLead", 1, 0, 3),
|
|
2465
|
-
hairFollow: get("hairFollow", TURN.hairFollow, 0, 2),
|
|
2466
|
-
outlineFollow: get("outlineFollow", TURN.outlineFollow, 0, 2),
|
|
2467
|
-
blink: get("blink", AMPLITUDE.blink, 0.1, 1),
|
|
2468
|
-
sway: get("sway", 1, 0, 5)
|
|
2469
|
-
};
|
|
2470
|
-
}
|
|
2471
|
-
|
|
2472
2504
|
// src/auto-rig/head.ts
|
|
2473
2505
|
function outerEdge(runs, axisX, side) {
|
|
2474
2506
|
if (runs.length === 0) return void 0;
|
|
@@ -2681,7 +2713,7 @@ function buildHeadFrame(layers, opts) {
|
|
|
2681
2713
|
return face.y1;
|
|
2682
2714
|
};
|
|
2683
2715
|
const chin = chinY;
|
|
2684
|
-
const shade = JAW_SHADE *
|
|
2716
|
+
const shade = JAW_SHADE * Math.max(1, eyeY - chin);
|
|
2685
2717
|
const reach = opts.chinSlide === void 0 ? nk.waist : clamp(
|
|
2686
2718
|
nk.waist - opts.chinSlide - CUT_MARGIN - (CUT_LOW + 1),
|
|
2687
2719
|
0,
|
|
@@ -2730,7 +2762,7 @@ function buildHeadFrame(layers, opts) {
|
|
|
2730
2762
|
}
|
|
2731
2763
|
}
|
|
2732
2764
|
}
|
|
2733
|
-
const hh =
|
|
2765
|
+
const hh = Math.max(1, eyeY - chinY);
|
|
2734
2766
|
const headHalf = opts.headHalfWidth;
|
|
2735
2767
|
const hairShell = headHalf !== void 0;
|
|
2736
2768
|
let shellLeft = axisX - plateHalf;
|
|
@@ -4361,12 +4393,12 @@ function motionReach(warps, mesh, box, extra = [0, 0]) {
|
|
|
4361
4393
|
}
|
|
4362
4394
|
return out;
|
|
4363
4395
|
}
|
|
4364
|
-
function blinkFold(param, mesh,
|
|
4396
|
+
function blinkFold(param, mesh, box, travel, eye = box) {
|
|
4365
4397
|
const yc = eye.y1 - travel * bh(eye);
|
|
4366
4398
|
return localWarp(
|
|
4367
4399
|
param,
|
|
4368
4400
|
mesh,
|
|
4369
|
-
|
|
4401
|
+
box,
|
|
4370
4402
|
[0, 1],
|
|
4371
4403
|
([, y], v) => v === 1 ? [0, 0] : [0, yc - y]
|
|
4372
4404
|
);
|
|
@@ -4715,6 +4747,10 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
|
|
|
4715
4747
|
case "eye_R":
|
|
4716
4748
|
warps.push(blinkFold(eyeOpen, mesh, b, style.blink));
|
|
4717
4749
|
break;
|
|
4750
|
+
case "lash_lower_L":
|
|
4751
|
+
case "lash_lower_R":
|
|
4752
|
+
warps.push(blinkFold(eyeOpen, mesh, b, style.blink, box(`eye_${side}`)));
|
|
4753
|
+
break;
|
|
4718
4754
|
case "lash_L":
|
|
4719
4755
|
case "lash_R":
|
|
4720
4756
|
warps.push(lashFold(eyeOpen, mesh, b, box(`eye_${side}`), style.blink));
|