@ikijs/editor 0.12.2 → 0.13.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/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({ eyeShift: 0.22, farEyeRatio: 0.78, silhouetteRatio: 1 });
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 = [
@@ -2358,117 +2499,6 @@ function land(l, offsets, x, y) {
2358
2499
  return [topX + (botX - topX) * t, topY + (botY - topY) * t];
2359
2500
  }
2360
2501
 
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
2502
  // src/auto-rig/head.ts
2473
2503
  function outerEdge(runs, axisX, side) {
2474
2504
  if (runs.length === 0) return void 0;
@@ -2681,7 +2711,7 @@ function buildHeadFrame(layers, opts) {
2681
2711
  return face.y1;
2682
2712
  };
2683
2713
  const chin = chinY;
2684
- const shade = JAW_SHADE * HH_PER_EYE_TO_CHIN * Math.max(1, eyeY - chin);
2714
+ const shade = JAW_SHADE * Math.max(1, eyeY - chin);
2685
2715
  const reach = opts.chinSlide === void 0 ? nk.waist : clamp(
2686
2716
  nk.waist - opts.chinSlide - CUT_MARGIN - (CUT_LOW + 1),
2687
2717
  0,
@@ -2730,7 +2760,7 @@ function buildHeadFrame(layers, opts) {
2730
2760
  }
2731
2761
  }
2732
2762
  }
2733
- const hh = HH_PER_EYE_TO_CHIN * Math.max(1, eyeY - chinY);
2763
+ const hh = Math.max(1, eyeY - chinY);
2734
2764
  const headHalf = opts.headHalfWidth;
2735
2765
  const hairShell = headHalf !== void 0;
2736
2766
  let shellLeft = axisX - plateHalf;