@ikijs/editor 0.13.0 → 0.15.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 CHANGED
@@ -57,10 +57,15 @@ leaves the document untouched.
57
57
  ## Auto-rig
58
58
 
59
59
  `generateIkiFromLayerSet` turns role-named layers (`face`, `eye_L`, `eye_R`,
60
- `mouth`, plus optional `iris_*`, `brow_*`, `lash_*`, `hair_front`, `hair_back`,
60
+ `mouth`, plus optional `iris_*`, `brow_*`, `lash_*`, `lash_lower_*`, `hair_front`, `hair_back`,
61
61
  …) into a rigged model that blinks, gazes, opens its mouth, turns its head over
62
62
  a torso that breathes, and emotes with its brows — including a
63
- hair-sway physics rig when a `hair_front` layer is present.
63
+ hair-sway physics rig when a `hair_front` layer is present. With a `blush_*`
64
+ layer it declares `ParamCheek`, which fades the blush from faint at rest to
65
+ as drawn. Every rigged model also declares the head motions Nod, Shake and
66
+ Tilt and up to six default expressions (smile, laugh, angry, sad, surprised,
67
+ shy; shy needs a blush, angry and sad need brows), each with a description a
68
+ host picks by (`AUTO-RIG.md`).
64
69
 
65
70
  The rig turns the head by parallax, not a reshaped face, with values of our
66
71
  own picked by eye (`auto-rig/profile.ts`, `AUTO-RIG.md`). The face plate
package/dist/index.d.mts CHANGED
@@ -861,7 +861,9 @@ declare function parseLayerRoles(fileNames: string[]): {
861
861
  * plate, the hair and the blush moved by per-vertex keyforms of their own —
862
862
  * the plate as up to four islands of one drawing: a head that slides, a neck
863
863
  * that stays and two ears that lag. Blink, gaze, brows, mouth, breath and
864
- * hair sway are part warps and bindings under those.
864
+ * hair sway are part warps and bindings under those. The model also declares
865
+ * the default expressions and the Nod, Shake and Tilt motions
866
+ * (`animations.ts`).
865
867
  */
866
868
 
867
869
  declare function generateIkiFromLayerSet(layers: LayerInput[], canvas: {
package/dist/index.d.ts CHANGED
@@ -861,7 +861,9 @@ declare function parseLayerRoles(fileNames: string[]): {
861
861
  * plate, the hair and the blush moved by per-vertex keyforms of their own —
862
862
  * the plate as up to four islands of one drawing: a head that slides, a neck
863
863
  * that stays and two ears that lag. Blink, gaze, brows, mouth, breath and
864
- * hair sway are part warps and bindings under those.
864
+ * hair sway are part warps and bindings under those. The model also declares
865
+ * the default expressions and the Nod, Shake and Tilt motions
866
+ * (`animations.ts`).
865
867
  */
866
868
 
867
869
  declare function generateIkiFromLayerSet(layers: LayerInput[], canvas: {
package/dist/index.js CHANGED
@@ -1983,7 +1983,8 @@ var PROFILE_VALUES = {
1983
1983
  mouthWiden: 1.2,
1984
1984
  brow: 0.15,
1985
1985
  breath: 0.03,
1986
- sway: 0.08
1986
+ sway: 0.08,
1987
+ blushRest: 0.4
1987
1988
  };
1988
1989
  function deriveProfile(v) {
1989
1990
  const farLead = v.lead * (1 - v.fore / 2);
@@ -2070,6 +2071,8 @@ function deriveProfile(v) {
2070
2071
  breathHead: v.breath * 2 / 3,
2071
2072
  /** Hair tip travel at full sway (±20), hh. */
2072
2073
  sway: v.sway,
2074
+ /** The blush's opacity at Cheek 0; at Cheek 1 it is as drawn. */
2075
+ blushRest: v.blushRest,
2073
2076
  /** The neck under the face reaches this far above the jaw, hh — what the
2074
2077
  * chin uncovers as it slides off it: half again the chin's full-turn
2075
2078
  * slide, to the next 0.05. */
@@ -2131,6 +2134,8 @@ var ROLE_TABLE = [
2131
2134
  { role: "pupil_R", family: "eye_R" },
2132
2135
  { role: "highlight_L", family: "eye_L" },
2133
2136
  { role: "highlight_R", family: "eye_R" },
2137
+ { role: "lash_lower_L", family: "eye_L" },
2138
+ { role: "lash_lower_R", family: "eye_R" },
2134
2139
  { role: "lash_L", family: "eye_L" },
2135
2140
  { role: "lash_R", family: "eye_R" },
2136
2141
  { role: "brow_L", family: "brow_L" },
@@ -2185,7 +2190,156 @@ function parseLayerRoles(fileNames) {
2185
2190
  }
2186
2191
 
2187
2192
  // src/auto-rig/generate.ts
2188
- var import_format5 = require("@ikijs/format");
2193
+ var import_format6 = require("@ikijs/format");
2194
+
2195
+ // src/auto-rig/animations.ts
2196
+ var import_format3 = require("@ikijs/format");
2197
+ function browsY(y) {
2198
+ return [
2199
+ { parameter: import_format3.StandardParameter.BrowLeftY, value: y, blend: "add" },
2200
+ { parameter: import_format3.StandardParameter.BrowRightY, value: y, blend: "add" }
2201
+ ];
2202
+ }
2203
+ function browsTilt(innerDown) {
2204
+ return [
2205
+ { parameter: import_format3.StandardParameter.BrowLeftAngle, value: innerDown, blend: "add" },
2206
+ { parameter: import_format3.StandardParameter.BrowRightAngle, value: -innerDown, blend: "add" }
2207
+ ];
2208
+ }
2209
+ function cheek(value) {
2210
+ return { parameter: import_format3.StandardParameter.Cheek, value, blend: "add" };
2211
+ }
2212
+ var BROWS = [import_format3.StandardParameter.BrowLeftY, import_format3.StandardParameter.BrowRightY, import_format3.StandardParameter.BrowLeftAngle, import_format3.StandardParameter.BrowRightAngle];
2213
+ var EXPRESSIONS = [
2214
+ {
2215
+ id: "smile",
2216
+ description: "Smiling and pleased: warm, friendly, content. For greetings, thanks, agreement and gentle happiness.",
2217
+ parameters: [
2218
+ { parameter: import_format3.StandardParameter.MouthForm, value: 1, blend: "add" },
2219
+ ...browsY(0.25),
2220
+ cheek(0.4)
2221
+ ]
2222
+ },
2223
+ {
2224
+ id: "laugh",
2225
+ description: "Laughing, eyes shut and mouth open: delighted, amused. For jokes, playfulness and big joy.",
2226
+ parameters: [
2227
+ { parameter: import_format3.StandardParameter.EyeOpenLeft, value: 0, blend: "multiply" },
2228
+ { parameter: import_format3.StandardParameter.EyeOpenRight, value: 0, blend: "multiply" },
2229
+ { parameter: import_format3.StandardParameter.MouthForm, value: 1, blend: "add" },
2230
+ { parameter: import_format3.StandardParameter.MouthOpen, value: 0.8, blend: "overwrite" },
2231
+ ...browsY(0.4),
2232
+ cheek(0.65)
2233
+ ]
2234
+ },
2235
+ {
2236
+ id: "angry",
2237
+ description: "Angry or annoyed, frowning. For irritation, frustration, indignation or scolding.",
2238
+ needs: BROWS,
2239
+ parameters: [
2240
+ ...browsY(-0.5),
2241
+ ...browsTilt(0.8),
2242
+ { parameter: import_format3.StandardParameter.MouthForm, value: -0.9, blend: "add" }
2243
+ ]
2244
+ },
2245
+ {
2246
+ id: "sad",
2247
+ description: "Sad or disappointed, downcast. For sorrow, regret, apology or sympathy.",
2248
+ needs: BROWS,
2249
+ parameters: [
2250
+ ...browsY(0.35),
2251
+ ...browsTilt(-0.8),
2252
+ { parameter: import_format3.StandardParameter.MouthForm, value: -0.8, blend: "add" }
2253
+ ]
2254
+ },
2255
+ {
2256
+ id: "surprised",
2257
+ description: "Surprised, mouth dropped open: startled, amazed. For shock, sudden news or disbelief.",
2258
+ parameters: [
2259
+ ...browsY(0.8),
2260
+ { parameter: import_format3.StandardParameter.MouthOpen, value: 0.9, blend: "overwrite" }
2261
+ ]
2262
+ },
2263
+ {
2264
+ id: "shy",
2265
+ description: "Shy or embarrassed: bashful, flustered. For being praised, teased or caught off guard.",
2266
+ needs: [import_format3.StandardParameter.Cheek],
2267
+ parameters: [
2268
+ cheek(1),
2269
+ // Gaze down.
2270
+ { parameter: import_format3.StandardParameter.EyeballY, value: -0.65, blend: "add" },
2271
+ { parameter: import_format3.StandardParameter.MouthForm, value: 0.4, blend: "add" },
2272
+ ...browsTilt(-0.25)
2273
+ ]
2274
+ }
2275
+ ];
2276
+ function defaultExpressions(declared) {
2277
+ return EXPRESSIONS.filter(
2278
+ (e) => e.needs === void 0 || e.needs.some((id) => declared.has(id))
2279
+ ).map(({ needs: _needs, ...e }) => ({
2280
+ ...e,
2281
+ parameters: e.parameters.filter((t) => declared.has(t.parameter))
2282
+ }));
2283
+ }
2284
+ var DEFAULT_MOTIONS = {
2285
+ Nod: [
2286
+ {
2287
+ description: "Nods yes: agreement, acknowledgement, understanding.",
2288
+ duration: 1,
2289
+ curves: [
2290
+ {
2291
+ parameter: import_format3.StandardParameter.AngleY,
2292
+ keys: [
2293
+ [0, 0],
2294
+ [0.3, -18],
2295
+ [0.6, 4],
2296
+ [0.8, -1],
2297
+ [1, 0]
2298
+ ]
2299
+ }
2300
+ ]
2301
+ }
2302
+ ],
2303
+ Shake: [
2304
+ {
2305
+ description: "Shakes the head no: disagreement, refusal, disbelief.",
2306
+ duration: 1.2,
2307
+ // The first swing peaks at 0.2 s, which the default fade would still
2308
+ // be damping.
2309
+ fadeIn: 0.15,
2310
+ curves: [
2311
+ {
2312
+ parameter: import_format3.StandardParameter.AngleX,
2313
+ keys: [
2314
+ [0, 0],
2315
+ [0.2, -18],
2316
+ [0.45, 18],
2317
+ [0.7, -16],
2318
+ [0.95, 10],
2319
+ [1.2, 0]
2320
+ ]
2321
+ }
2322
+ ]
2323
+ }
2324
+ ],
2325
+ Tilt: [
2326
+ {
2327
+ description: "Tilts the head to one side and back: curiosity, puzzlement, a question.",
2328
+ duration: 1.4,
2329
+ curves: [
2330
+ {
2331
+ parameter: import_format3.StandardParameter.AngleZ,
2332
+ keys: [
2333
+ [0, 0],
2334
+ [0.35, 20],
2335
+ [1, 20],
2336
+ [1.4, 0]
2337
+ ]
2338
+ }
2339
+ ]
2340
+ }
2341
+ ]
2342
+ };
2189
2343
 
2190
2344
  // src/auto-rig/layout.ts
2191
2345
  function boxOfLayer(layer) {
@@ -2480,7 +2634,7 @@ function checkStrandEdges(strand, irises, hair) {
2480
2634
  }
2481
2635
 
2482
2636
  // src/auto-rig/context.ts
2483
- var import_format3 = require("@ikijs/format");
2637
+ var import_format4 = require("@ikijs/format");
2484
2638
 
2485
2639
  // src/auto-rig/grid.ts
2486
2640
  var X_STOPS = [-30, 0, 30];
@@ -3696,7 +3850,7 @@ function renderedLander(turn, parts, grids, from = /* @__PURE__ */ new Map()) {
3696
3850
  const family = roleSpec(role).family;
3697
3851
  const part = parts.find((p) => p.id === role);
3698
3852
  const g = grids.get(family);
3699
- const warp = part?.warps?.find((w) => w.parameter === import_format3.StandardParameter.AngleX);
3853
+ const warp = part?.warps?.find((w) => w.parameter === import_format4.StandardParameter.AngleX);
3700
3854
  if (part === void 0 || part.mesh === void 0 || !g && !warp) {
3701
3855
  return x + field(role)(x, y, ax, 0)[0];
3702
3856
  }
@@ -4406,7 +4560,7 @@ function buildTurn(frame, landmarks, q) {
4406
4560
  }
4407
4561
 
4408
4562
  // src/auto-rig/drivers.ts
4409
- var import_format4 = require("@ikijs/format");
4563
+ var import_format5 = require("@ikijs/format");
4410
4564
  var SWAY_RANGE = 20;
4411
4565
  var SWAY_CURVE = 1.4;
4412
4566
  var HAIR_HANG = 0.35;
@@ -4458,12 +4612,12 @@ function motionReach(warps, mesh, box, extra = [0, 0]) {
4458
4612
  }
4459
4613
  return out;
4460
4614
  }
4461
- function blinkFold(param, mesh, eye, travel) {
4615
+ function blinkFold(param, mesh, box, travel, eye = box) {
4462
4616
  const yc = eye.y1 - travel * bh(eye);
4463
4617
  return localWarp(
4464
4618
  param,
4465
4619
  mesh,
4466
- eye,
4620
+ box,
4467
4621
  [0, 1],
4468
4622
  ([, y], v) => v === 1 ? [0, 0] : [0, yc - y]
4469
4623
  );
@@ -4484,13 +4638,13 @@ function gazeBindings(irisW, share = 1) {
4484
4638
  const gy = AMPLITUDE.gazeY * irisW * share;
4485
4639
  return [
4486
4640
  {
4487
- parameter: import_format4.StandardParameter.EyeballX,
4641
+ parameter: import_format5.StandardParameter.EyeballX,
4488
4642
  channel: "translateX",
4489
4643
  from: -round1(gx),
4490
4644
  to: round1(gx)
4491
4645
  },
4492
4646
  {
4493
- parameter: import_format4.StandardParameter.EyeballY,
4647
+ parameter: import_format5.StandardParameter.EyeballY,
4494
4648
  channel: "translateY",
4495
4649
  from: -round1(gy),
4496
4650
  to: round1(gy)
@@ -4504,8 +4658,8 @@ function browReach(hh) {
4504
4658
  return AMPLITUDE.brow * hh;
4505
4659
  }
4506
4660
  function browBindings(side, reach) {
4507
- const y = side === "L" ? import_format4.StandardParameter.BrowLeftY : import_format4.StandardParameter.BrowRightY;
4508
- const a = side === "L" ? import_format4.StandardParameter.BrowLeftAngle : import_format4.StandardParameter.BrowRightAngle;
4661
+ const y = side === "L" ? import_format5.StandardParameter.BrowLeftY : import_format5.StandardParameter.BrowRightY;
4662
+ const a = side === "L" ? import_format5.StandardParameter.BrowLeftAngle : import_format5.StandardParameter.BrowRightAngle;
4509
4663
  return [
4510
4664
  {
4511
4665
  parameter: y,
@@ -4521,7 +4675,7 @@ function mouthForm(mesh, box) {
4521
4675
  const a = 0.3 * bh(box);
4522
4676
  const c = cx(box);
4523
4677
  const half = bw(box) / 2;
4524
- return localWarp(import_format4.StandardParameter.MouthForm, mesh, box, [-1, 0, 1], ([x], v) => {
4678
+ return localWarp(import_format5.StandardParameter.MouthForm, mesh, box, [-1, 0, 1], ([x], v) => {
4525
4679
  if (v === 0) return [0, 0];
4526
4680
  const u = (x - c) / half;
4527
4681
  const widen = v > 0 ? 0.05 : 0.03;
@@ -4531,7 +4685,7 @@ function mouthForm(mesh, box) {
4531
4685
  function mouthOpenGrow(mesh, box) {
4532
4686
  const c = cx(box);
4533
4687
  return localWarp(
4534
- import_format4.StandardParameter.MouthOpen,
4688
+ import_format5.StandardParameter.MouthOpen,
4535
4689
  mesh,
4536
4690
  box,
4537
4691
  [0, 1],
@@ -4540,7 +4694,7 @@ function mouthOpenGrow(mesh, box) {
4540
4694
  }
4541
4695
  function mouthWiden(mesh, box) {
4542
4696
  const c = cx(box);
4543
- return localWarp(import_format4.StandardParameter.MouthOpen, mesh, box, [0, 1], ([x], v) => [
4697
+ return localWarp(import_format5.StandardParameter.MouthOpen, mesh, box, [0, 1], ([x], v) => [
4544
4698
  v * (AMPLITUDE.mouthOpenWidth - 1) * (x - c),
4545
4699
  0
4546
4700
  ]);
@@ -4558,7 +4712,7 @@ function hairSway(param, mesh, box, amp) {
4558
4712
  );
4559
4713
  }
4560
4714
  function tiltHang(mesh, box, pivot, weight) {
4561
- return localWarp(import_format4.StandardParameter.AngleZ, mesh, box, Z_STOPS, ([x, y], v, i) => {
4715
+ return localWarp(import_format5.StandardParameter.AngleZ, mesh, box, Z_STOPS, ([x, y], v, i) => {
4562
4716
  const g = weight(y, i);
4563
4717
  if (g === 0 || v === 0) return [0, 0];
4564
4718
  const a = -g * rollOf(v);
@@ -4711,16 +4865,19 @@ function generateIkiFromLayerSet(layers, canvas, options = {}) {
4711
4865
  ...part.warps ?? []
4712
4866
  ];
4713
4867
  }
4868
+ const parameters = declareParameters(new Set(byRole.keys()));
4714
4869
  const model = {
4715
- version: import_format5.IKI_FORMAT_VERSION,
4870
+ version: import_format6.IKI_FORMAT_VERSION,
4716
4871
  name: "auto-rigged",
4717
4872
  canvas: { width: canvas.width, height: canvas.height },
4718
- parameters: declareParameters(new Set(byRole.keys())),
4873
+ parameters,
4719
4874
  parts,
4720
4875
  deformers: deformers(frame, grids, has("body") ? box("body") : void 0),
4721
- ...has("hair_front") ? { physics: hairPhysics() } : {}
4876
+ ...has("hair_front") ? { physics: hairPhysics() } : {},
4877
+ expressions: defaultExpressions(new Set(parameters.map((p) => p.id))),
4878
+ motions: DEFAULT_MOTIONS
4722
4879
  };
4723
- const valid = (0, import_format5.parseIkiModel)(model);
4880
+ const valid = (0, import_format6.parseIkiModel)(model);
4724
4881
  if (hasNose && options.onTurnSolved) {
4725
4882
  options.onTurnSolved(
4726
4883
  turnReport(
@@ -4735,14 +4892,14 @@ function generateIkiFromLayerSet(layers, canvas, options = {}) {
4735
4892
  function turnWarps(mesh, b, fieldOf) {
4736
4893
  return [
4737
4894
  localWarp(
4738
- import_format5.StandardParameter.AngleX,
4895
+ import_format6.StandardParameter.AngleX,
4739
4896
  mesh,
4740
4897
  b,
4741
4898
  X_STOPS,
4742
4899
  ([x, y], v, i) => v === 0 ? [0, 0] : [fieldOf(i)(x, y, v, 0)[0], 0]
4743
4900
  ),
4744
4901
  localWarp(
4745
- import_format5.StandardParameter.AngleY,
4902
+ import_format6.StandardParameter.AngleY,
4746
4903
  mesh,
4747
4904
  b,
4748
4905
  Y_STOPS,
@@ -4790,7 +4947,7 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
4790
4947
  }
4791
4948
  if (mesh !== void 0) part.mesh = mesh;
4792
4949
  const side = spec.role.endsWith("_L") ? "L" : "R";
4793
- const eyeOpen = side === "L" ? import_format5.StandardParameter.EyeOpenLeft : import_format5.StandardParameter.EyeOpenRight;
4950
+ const eyeOpen = side === "L" ? import_format6.StandardParameter.EyeOpenLeft : import_format6.StandardParameter.EyeOpenRight;
4794
4951
  const hh = frame.hh;
4795
4952
  switch (spec.role) {
4796
4953
  case "face":
@@ -4799,7 +4956,7 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
4799
4956
  warps.push(
4800
4957
  tiltHang(mesh, b, pivot, (_y, i) => isNeck[i] ? 1 : 0),
4801
4958
  localWarp(
4802
- import_format5.StandardParameter.Breath,
4959
+ import_format6.StandardParameter.Breath,
4803
4960
  mesh,
4804
4961
  b,
4805
4962
  [0, 1],
@@ -4812,6 +4969,10 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
4812
4969
  case "eye_R":
4813
4970
  warps.push(blinkFold(eyeOpen, mesh, b, style.blink));
4814
4971
  break;
4972
+ case "lash_lower_L":
4973
+ case "lash_lower_R":
4974
+ warps.push(blinkFold(eyeOpen, mesh, b, style.blink, box(`eye_${side}`)));
4975
+ break;
4815
4976
  case "lash_L":
4816
4977
  case "lash_R":
4817
4978
  warps.push(lashFold(eyeOpen, mesh, b, box(`eye_${side}`), style.blink));
@@ -4842,8 +5003,8 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
4842
5003
  if (byRole.has("mouth_open")) {
4843
5004
  warps.push(mouthWiden(mesh, b));
4844
5005
  bindings.push(
4845
- { parameter: import_format5.StandardParameter.MouthOpen, channel: "opacity", from: 1, to: 0 },
4846
- { parameter: import_format5.StandardParameter.MouthOpen, channel: "opacity", from: 1, to: 0 }
5006
+ { parameter: import_format6.StandardParameter.MouthOpen, channel: "opacity", from: 1, to: 0 },
5007
+ { parameter: import_format6.StandardParameter.MouthOpen, channel: "opacity", from: 1, to: 0 }
4847
5008
  );
4848
5009
  extra = [(AMPLITUDE.mouthOpenWidth - 1) * (bw(b) / 2), 0];
4849
5010
  } else {
@@ -4853,19 +5014,19 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
4853
5014
  );
4854
5015
  bindings.push(
4855
5016
  {
4856
- parameter: import_format5.StandardParameter.MouthOpen,
5017
+ parameter: import_format6.StandardParameter.MouthOpen,
4857
5018
  channel: "scaleY",
4858
5019
  from: 0,
4859
5020
  to: roundTo(grow, 0.01)
4860
5021
  },
4861
5022
  {
4862
- parameter: import_format5.StandardParameter.MouthOpen,
5023
+ parameter: import_format6.StandardParameter.MouthOpen,
4863
5024
  channel: "scaleX",
4864
5025
  from: 0,
4865
5026
  to: roundTo(AMPLITUDE.mouthOpenWidth - 1, 0.01)
4866
5027
  },
4867
5028
  {
4868
- parameter: import_format5.StandardParameter.MouthOpen,
5029
+ parameter: import_format6.StandardParameter.MouthOpen,
4869
5030
  channel: "translateY",
4870
5031
  from: 0,
4871
5032
  to: -roundTo(grow * bh(b) / 2, 0.01)
@@ -4877,20 +5038,29 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
4877
5038
  case "mouth_open":
4878
5039
  warps.push(mouthForm(mesh, b), mouthOpenGrow(mesh, b));
4879
5040
  bindings.push({
4880
- parameter: import_format5.StandardParameter.MouthOpen,
5041
+ parameter: import_format6.StandardParameter.MouthOpen,
4881
5042
  channel: "opacity",
4882
5043
  from: 0,
4883
5044
  to: 1
4884
5045
  });
4885
5046
  extra = [(AMPLITUDE.mouthOpenWidth - 1) * (bw(b) / 2), 0];
4886
5047
  break;
5048
+ case "blush_L":
5049
+ case "blush_R":
5050
+ bindings.push({
5051
+ parameter: import_format6.StandardParameter.Cheek,
5052
+ channel: "opacity",
5053
+ from: AMPLITUDE.blushRest,
5054
+ to: 1
5055
+ });
5056
+ break;
4887
5057
  case "hair_front":
4888
5058
  case "hair_back":
4889
5059
  if (byRole.has("hair_front")) {
4890
5060
  const amp = style.sway * AMPLITUDE.sway * hh;
4891
5061
  warps.push(
4892
- hairSway(import_format5.StandardParameter.HairSwayX, mesh, b, amp),
4893
- hairSway(import_format5.StandardParameter.HairSwayZ, mesh, b, amp)
5062
+ hairSway(import_format6.StandardParameter.HairSwayX, mesh, b, amp),
5063
+ hairSway(import_format6.StandardParameter.HairSwayZ, mesh, b, amp)
4894
5064
  );
4895
5065
  }
4896
5066
  warps.push(tiltHang(mesh, b, pivot, hairHangWeight(frame.chinY, b.y0)));
@@ -4971,7 +5141,7 @@ function deformers(frame, grids, body) {
4971
5141
  pivot: { x: roundTo(cx(body), 0.01), y: roundTo(body.y1, 0.01) },
4972
5142
  bindings: [
4973
5143
  {
4974
- parameter: import_format5.StandardParameter.Breath,
5144
+ parameter: import_format6.StandardParameter.Breath,
4975
5145
  channel: "translateY",
4976
5146
  from: 0,
4977
5147
  to: roundTo(AMPLITUDE.breathBody * frame.hh, 0.01)
@@ -4984,9 +5154,9 @@ function deformers(frame, grids, body) {
4984
5154
  pivot: { x: roundTo(frame.axisX, 0.01), y: roundTo(frame.chinY, 0.01) },
4985
5155
  bindings: [
4986
5156
  // AngleZ is clockwise-positive (Live2D's); a rotation is CCW-positive.
4987
- { parameter: import_format5.StandardParameter.AngleZ, channel: "rotate", from: ROLL_DEG, to: -ROLL_DEG },
5157
+ { parameter: import_format6.StandardParameter.AngleZ, channel: "rotate", from: ROLL_DEG, to: -ROLL_DEG },
4988
5158
  {
4989
- parameter: import_format5.StandardParameter.Breath,
5159
+ parameter: import_format6.StandardParameter.Breath,
4990
5160
  channel: "translateY",
4991
5161
  from: 0,
4992
5162
  to: roundTo(AMPLITUDE.breathHead * frame.hh, 0.01)
@@ -5004,8 +5174,8 @@ function deformers(frame, grids, body) {
5004
5174
  points: g.lattice.points
5005
5175
  },
5006
5176
  warp2d: {
5007
- parameter: import_format5.StandardParameter.AngleX,
5008
- parameterY: import_format5.StandardParameter.AngleY,
5177
+ parameter: import_format6.StandardParameter.AngleX,
5178
+ parameterY: import_format6.StandardParameter.AngleY,
5009
5179
  valuesX: X_STOPS,
5010
5180
  valuesY: Y_STOPS,
5011
5181
  keyforms2d: g.keyforms.map((offsets) => ({ offsets }))
@@ -5018,16 +5188,16 @@ function hairPhysics() {
5018
5188
  return [
5019
5189
  {
5020
5190
  id: "hairSway",
5021
- input: { parameter: import_format5.StandardParameter.AngleX, weight: 1 },
5022
- output: { parameter: import_format5.StandardParameter.HairSwayX, scale: 5 },
5191
+ input: { parameter: import_format6.StandardParameter.AngleX, weight: 1 },
5192
+ output: { parameter: import_format6.StandardParameter.HairSwayX, scale: 5 },
5023
5193
  mass: 1,
5024
5194
  stiffness: 30,
5025
5195
  damping: 3
5026
5196
  },
5027
5197
  {
5028
5198
  id: "hairTilt",
5029
- input: { parameter: import_format5.StandardParameter.AngleZ, weight: 1 },
5030
- output: { parameter: import_format5.StandardParameter.HairSwayZ, scale: 8 },
5199
+ input: { parameter: import_format6.StandardParameter.AngleZ, weight: 1 },
5200
+ output: { parameter: import_format6.StandardParameter.HairSwayZ, scale: 8 },
5031
5201
  mass: 1,
5032
5202
  stiffness: 25,
5033
5203
  damping: 2.5
@@ -5037,29 +5207,32 @@ function hairPhysics() {
5037
5207
  function declareParameters(roles) {
5038
5208
  const out = [];
5039
5209
  const add = (id, name, min, max, def) => out.push({ id, name, min, max, default: def });
5040
- add(import_format5.StandardParameter.AngleX, "Head Angle", -30, 30, 0);
5041
- add(import_format5.StandardParameter.AngleY, "Head Angle Y", -30, 30, 0);
5042
- add(import_format5.StandardParameter.AngleZ, "Head Angle Z", -30, 30, 0);
5043
- add(import_format5.StandardParameter.EyeOpenLeft, "Eye L", 0, 1, 1);
5044
- add(import_format5.StandardParameter.EyeOpenRight, "Eye R", 0, 1, 1);
5210
+ add(import_format6.StandardParameter.AngleX, "Head Angle", -30, 30, 0);
5211
+ add(import_format6.StandardParameter.AngleY, "Head Angle Y", -30, 30, 0);
5212
+ add(import_format6.StandardParameter.AngleZ, "Head Angle Z", -30, 30, 0);
5213
+ add(import_format6.StandardParameter.EyeOpenLeft, "Eye L", 0, 1, 1);
5214
+ add(import_format6.StandardParameter.EyeOpenRight, "Eye R", 0, 1, 1);
5045
5215
  if ([...roles].some((r) => /^(iris|pupil|highlight)_/.test(r))) {
5046
- add(import_format5.StandardParameter.EyeballX, "Gaze X", -1, 1, 0);
5047
- add(import_format5.StandardParameter.EyeballY, "Gaze Y", -1, 1, 0);
5216
+ add(import_format6.StandardParameter.EyeballX, "Gaze X", -1, 1, 0);
5217
+ add(import_format6.StandardParameter.EyeballY, "Gaze Y", -1, 1, 0);
5048
5218
  }
5049
- add(import_format5.StandardParameter.MouthOpen, "Mouth Open", 0, 1, 0);
5050
- add(import_format5.StandardParameter.MouthForm, "Mouth Form", -1, 1, 0);
5219
+ add(import_format6.StandardParameter.MouthOpen, "Mouth Open", 0, 1, 0);
5220
+ add(import_format6.StandardParameter.MouthForm, "Mouth Form", -1, 1, 0);
5051
5221
  if (roles.has("brow_L")) {
5052
- add(import_format5.StandardParameter.BrowLeftY, "Brow L Y", -1, 1, 0);
5053
- add(import_format5.StandardParameter.BrowLeftAngle, "Brow L Angle", -1, 1, 0);
5222
+ add(import_format6.StandardParameter.BrowLeftY, "Brow L Y", -1, 1, 0);
5223
+ add(import_format6.StandardParameter.BrowLeftAngle, "Brow L Angle", -1, 1, 0);
5054
5224
  }
5055
5225
  if (roles.has("brow_R")) {
5056
- add(import_format5.StandardParameter.BrowRightY, "Brow R Y", -1, 1, 0);
5057
- add(import_format5.StandardParameter.BrowRightAngle, "Brow R Angle", -1, 1, 0);
5226
+ add(import_format6.StandardParameter.BrowRightY, "Brow R Y", -1, 1, 0);
5227
+ add(import_format6.StandardParameter.BrowRightAngle, "Brow R Angle", -1, 1, 0);
5228
+ }
5229
+ if (roles.has("blush_L") || roles.has("blush_R")) {
5230
+ add(import_format6.StandardParameter.Cheek, "Cheek", 0, 1, 0);
5058
5231
  }
5059
- add(import_format5.StandardParameter.Breath, "Breath", 0, 1, 0);
5232
+ add(import_format6.StandardParameter.Breath, "Breath", 0, 1, 0);
5060
5233
  if (roles.has("hair_front")) {
5061
- add(import_format5.StandardParameter.HairSwayX, "Hair Sway X", -SWAY_RANGE, SWAY_RANGE, 0);
5062
- add(import_format5.StandardParameter.HairSwayZ, "Hair Sway Z", -SWAY_RANGE, SWAY_RANGE, 0);
5234
+ add(import_format6.StandardParameter.HairSwayX, "Hair Sway X", -SWAY_RANGE, SWAY_RANGE, 0);
5235
+ add(import_format6.StandardParameter.HairSwayZ, "Hair Sway Z", -SWAY_RANGE, SWAY_RANGE, 0);
5063
5236
  }
5064
5237
  return out;
5065
5238
  }