@ikijs/editor 0.14.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 +6 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +221 -54
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +221 -52
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1910,7 +1910,8 @@ var PROFILE_VALUES = {
|
|
|
1910
1910
|
mouthWiden: 1.2,
|
|
1911
1911
|
brow: 0.15,
|
|
1912
1912
|
breath: 0.03,
|
|
1913
|
-
sway: 0.08
|
|
1913
|
+
sway: 0.08,
|
|
1914
|
+
blushRest: 0.4
|
|
1914
1915
|
};
|
|
1915
1916
|
function deriveProfile(v) {
|
|
1916
1917
|
const farLead = v.lead * (1 - v.fore / 2);
|
|
@@ -1997,6 +1998,8 @@ function deriveProfile(v) {
|
|
|
1997
1998
|
breathHead: v.breath * 2 / 3,
|
|
1998
1999
|
/** Hair tip travel at full sway (±20), hh. */
|
|
1999
2000
|
sway: v.sway,
|
|
2001
|
+
/** The blush's opacity at Cheek 0; at Cheek 1 it is as drawn. */
|
|
2002
|
+
blushRest: v.blushRest,
|
|
2000
2003
|
/** The neck under the face reaches this far above the jaw, hh — what the
|
|
2001
2004
|
* chin uncovers as it slides off it: half again the chin's full-turn
|
|
2002
2005
|
* slide, to the next 0.05. */
|
|
@@ -2116,10 +2119,161 @@ function parseLayerRoles(fileNames) {
|
|
|
2116
2119
|
// src/auto-rig/generate.ts
|
|
2117
2120
|
import {
|
|
2118
2121
|
IKI_FORMAT_VERSION as IKI_FORMAT_VERSION2,
|
|
2119
|
-
StandardParameter as
|
|
2122
|
+
StandardParameter as P4,
|
|
2120
2123
|
parseIkiModel as parseIkiModel3
|
|
2121
2124
|
} from "@ikijs/format";
|
|
2122
2125
|
|
|
2126
|
+
// src/auto-rig/animations.ts
|
|
2127
|
+
import {
|
|
2128
|
+
StandardParameter as P
|
|
2129
|
+
} from "@ikijs/format";
|
|
2130
|
+
function browsY(y) {
|
|
2131
|
+
return [
|
|
2132
|
+
{ parameter: P.BrowLeftY, value: y, blend: "add" },
|
|
2133
|
+
{ parameter: P.BrowRightY, value: y, blend: "add" }
|
|
2134
|
+
];
|
|
2135
|
+
}
|
|
2136
|
+
function browsTilt(innerDown) {
|
|
2137
|
+
return [
|
|
2138
|
+
{ parameter: P.BrowLeftAngle, value: innerDown, blend: "add" },
|
|
2139
|
+
{ parameter: P.BrowRightAngle, value: -innerDown, blend: "add" }
|
|
2140
|
+
];
|
|
2141
|
+
}
|
|
2142
|
+
function cheek(value) {
|
|
2143
|
+
return { parameter: P.Cheek, value, blend: "add" };
|
|
2144
|
+
}
|
|
2145
|
+
var BROWS = [P.BrowLeftY, P.BrowRightY, P.BrowLeftAngle, P.BrowRightAngle];
|
|
2146
|
+
var EXPRESSIONS = [
|
|
2147
|
+
{
|
|
2148
|
+
id: "smile",
|
|
2149
|
+
description: "Smiling and pleased: warm, friendly, content. For greetings, thanks, agreement and gentle happiness.",
|
|
2150
|
+
parameters: [
|
|
2151
|
+
{ parameter: P.MouthForm, value: 1, blend: "add" },
|
|
2152
|
+
...browsY(0.25),
|
|
2153
|
+
cheek(0.4)
|
|
2154
|
+
]
|
|
2155
|
+
},
|
|
2156
|
+
{
|
|
2157
|
+
id: "laugh",
|
|
2158
|
+
description: "Laughing, eyes shut and mouth open: delighted, amused. For jokes, playfulness and big joy.",
|
|
2159
|
+
parameters: [
|
|
2160
|
+
{ parameter: P.EyeOpenLeft, value: 0, blend: "multiply" },
|
|
2161
|
+
{ parameter: P.EyeOpenRight, value: 0, blend: "multiply" },
|
|
2162
|
+
{ parameter: P.MouthForm, value: 1, blend: "add" },
|
|
2163
|
+
{ parameter: P.MouthOpen, value: 0.8, blend: "overwrite" },
|
|
2164
|
+
...browsY(0.4),
|
|
2165
|
+
cheek(0.65)
|
|
2166
|
+
]
|
|
2167
|
+
},
|
|
2168
|
+
{
|
|
2169
|
+
id: "angry",
|
|
2170
|
+
description: "Angry or annoyed, frowning. For irritation, frustration, indignation or scolding.",
|
|
2171
|
+
needs: BROWS,
|
|
2172
|
+
parameters: [
|
|
2173
|
+
...browsY(-0.5),
|
|
2174
|
+
...browsTilt(0.8),
|
|
2175
|
+
{ parameter: P.MouthForm, value: -0.9, blend: "add" }
|
|
2176
|
+
]
|
|
2177
|
+
},
|
|
2178
|
+
{
|
|
2179
|
+
id: "sad",
|
|
2180
|
+
description: "Sad or disappointed, downcast. For sorrow, regret, apology or sympathy.",
|
|
2181
|
+
needs: BROWS,
|
|
2182
|
+
parameters: [
|
|
2183
|
+
...browsY(0.35),
|
|
2184
|
+
...browsTilt(-0.8),
|
|
2185
|
+
{ parameter: P.MouthForm, value: -0.8, blend: "add" }
|
|
2186
|
+
]
|
|
2187
|
+
},
|
|
2188
|
+
{
|
|
2189
|
+
id: "surprised",
|
|
2190
|
+
description: "Surprised, mouth dropped open: startled, amazed. For shock, sudden news or disbelief.",
|
|
2191
|
+
parameters: [
|
|
2192
|
+
...browsY(0.8),
|
|
2193
|
+
{ parameter: P.MouthOpen, value: 0.9, blend: "overwrite" }
|
|
2194
|
+
]
|
|
2195
|
+
},
|
|
2196
|
+
{
|
|
2197
|
+
id: "shy",
|
|
2198
|
+
description: "Shy or embarrassed: bashful, flustered. For being praised, teased or caught off guard.",
|
|
2199
|
+
needs: [P.Cheek],
|
|
2200
|
+
parameters: [
|
|
2201
|
+
cheek(1),
|
|
2202
|
+
// Gaze down.
|
|
2203
|
+
{ parameter: P.EyeballY, value: -0.65, blend: "add" },
|
|
2204
|
+
{ parameter: P.MouthForm, value: 0.4, blend: "add" },
|
|
2205
|
+
...browsTilt(-0.25)
|
|
2206
|
+
]
|
|
2207
|
+
}
|
|
2208
|
+
];
|
|
2209
|
+
function defaultExpressions(declared) {
|
|
2210
|
+
return EXPRESSIONS.filter(
|
|
2211
|
+
(e) => e.needs === void 0 || e.needs.some((id) => declared.has(id))
|
|
2212
|
+
).map(({ needs: _needs, ...e }) => ({
|
|
2213
|
+
...e,
|
|
2214
|
+
parameters: e.parameters.filter((t) => declared.has(t.parameter))
|
|
2215
|
+
}));
|
|
2216
|
+
}
|
|
2217
|
+
var DEFAULT_MOTIONS = {
|
|
2218
|
+
Nod: [
|
|
2219
|
+
{
|
|
2220
|
+
description: "Nods yes: agreement, acknowledgement, understanding.",
|
|
2221
|
+
duration: 1,
|
|
2222
|
+
curves: [
|
|
2223
|
+
{
|
|
2224
|
+
parameter: P.AngleY,
|
|
2225
|
+
keys: [
|
|
2226
|
+
[0, 0],
|
|
2227
|
+
[0.3, -18],
|
|
2228
|
+
[0.6, 4],
|
|
2229
|
+
[0.8, -1],
|
|
2230
|
+
[1, 0]
|
|
2231
|
+
]
|
|
2232
|
+
}
|
|
2233
|
+
]
|
|
2234
|
+
}
|
|
2235
|
+
],
|
|
2236
|
+
Shake: [
|
|
2237
|
+
{
|
|
2238
|
+
description: "Shakes the head no: disagreement, refusal, disbelief.",
|
|
2239
|
+
duration: 1.2,
|
|
2240
|
+
// The first swing peaks at 0.2 s, which the default fade would still
|
|
2241
|
+
// be damping.
|
|
2242
|
+
fadeIn: 0.15,
|
|
2243
|
+
curves: [
|
|
2244
|
+
{
|
|
2245
|
+
parameter: P.AngleX,
|
|
2246
|
+
keys: [
|
|
2247
|
+
[0, 0],
|
|
2248
|
+
[0.2, -18],
|
|
2249
|
+
[0.45, 18],
|
|
2250
|
+
[0.7, -16],
|
|
2251
|
+
[0.95, 10],
|
|
2252
|
+
[1.2, 0]
|
|
2253
|
+
]
|
|
2254
|
+
}
|
|
2255
|
+
]
|
|
2256
|
+
}
|
|
2257
|
+
],
|
|
2258
|
+
Tilt: [
|
|
2259
|
+
{
|
|
2260
|
+
description: "Tilts the head to one side and back: curiosity, puzzlement, a question.",
|
|
2261
|
+
duration: 1.4,
|
|
2262
|
+
curves: [
|
|
2263
|
+
{
|
|
2264
|
+
parameter: P.AngleZ,
|
|
2265
|
+
keys: [
|
|
2266
|
+
[0, 0],
|
|
2267
|
+
[0.35, 20],
|
|
2268
|
+
[1, 20],
|
|
2269
|
+
[1.4, 0]
|
|
2270
|
+
]
|
|
2271
|
+
}
|
|
2272
|
+
]
|
|
2273
|
+
}
|
|
2274
|
+
]
|
|
2275
|
+
};
|
|
2276
|
+
|
|
2123
2277
|
// src/auto-rig/layout.ts
|
|
2124
2278
|
function boxOfLayer(layer) {
|
|
2125
2279
|
return boxOfPixels(layer.bbox, layer.canvasW, layer.canvasH);
|
|
@@ -2413,7 +2567,7 @@ function checkStrandEdges(strand, irises, hair) {
|
|
|
2413
2567
|
}
|
|
2414
2568
|
|
|
2415
2569
|
// src/auto-rig/context.ts
|
|
2416
|
-
import { StandardParameter as
|
|
2570
|
+
import { StandardParameter as P2 } from "@ikijs/format";
|
|
2417
2571
|
|
|
2418
2572
|
// src/auto-rig/grid.ts
|
|
2419
2573
|
var X_STOPS = [-30, 0, 30];
|
|
@@ -3629,7 +3783,7 @@ function renderedLander(turn, parts, grids, from = /* @__PURE__ */ new Map()) {
|
|
|
3629
3783
|
const family = roleSpec(role).family;
|
|
3630
3784
|
const part = parts.find((p) => p.id === role);
|
|
3631
3785
|
const g = grids.get(family);
|
|
3632
|
-
const warp = part?.warps?.find((w) => w.parameter ===
|
|
3786
|
+
const warp = part?.warps?.find((w) => w.parameter === P2.AngleX);
|
|
3633
3787
|
if (part === void 0 || part.mesh === void 0 || !g && !warp) {
|
|
3634
3788
|
return x + field(role)(x, y, ax, 0)[0];
|
|
3635
3789
|
}
|
|
@@ -4340,7 +4494,7 @@ function buildTurn(frame, landmarks, q) {
|
|
|
4340
4494
|
|
|
4341
4495
|
// src/auto-rig/drivers.ts
|
|
4342
4496
|
import {
|
|
4343
|
-
StandardParameter as
|
|
4497
|
+
StandardParameter as P3
|
|
4344
4498
|
} from "@ikijs/format";
|
|
4345
4499
|
var SWAY_RANGE = 20;
|
|
4346
4500
|
var SWAY_CURVE = 1.4;
|
|
@@ -4419,13 +4573,13 @@ function gazeBindings(irisW, share = 1) {
|
|
|
4419
4573
|
const gy = AMPLITUDE.gazeY * irisW * share;
|
|
4420
4574
|
return [
|
|
4421
4575
|
{
|
|
4422
|
-
parameter:
|
|
4576
|
+
parameter: P3.EyeballX,
|
|
4423
4577
|
channel: "translateX",
|
|
4424
4578
|
from: -round1(gx),
|
|
4425
4579
|
to: round1(gx)
|
|
4426
4580
|
},
|
|
4427
4581
|
{
|
|
4428
|
-
parameter:
|
|
4582
|
+
parameter: P3.EyeballY,
|
|
4429
4583
|
channel: "translateY",
|
|
4430
4584
|
from: -round1(gy),
|
|
4431
4585
|
to: round1(gy)
|
|
@@ -4439,8 +4593,8 @@ function browReach(hh) {
|
|
|
4439
4593
|
return AMPLITUDE.brow * hh;
|
|
4440
4594
|
}
|
|
4441
4595
|
function browBindings(side, reach) {
|
|
4442
|
-
const y = side === "L" ?
|
|
4443
|
-
const a = side === "L" ?
|
|
4596
|
+
const y = side === "L" ? P3.BrowLeftY : P3.BrowRightY;
|
|
4597
|
+
const a = side === "L" ? P3.BrowLeftAngle : P3.BrowRightAngle;
|
|
4444
4598
|
return [
|
|
4445
4599
|
{
|
|
4446
4600
|
parameter: y,
|
|
@@ -4456,7 +4610,7 @@ function mouthForm(mesh, box) {
|
|
|
4456
4610
|
const a = 0.3 * bh(box);
|
|
4457
4611
|
const c = cx(box);
|
|
4458
4612
|
const half = bw(box) / 2;
|
|
4459
|
-
return localWarp(
|
|
4613
|
+
return localWarp(P3.MouthForm, mesh, box, [-1, 0, 1], ([x], v) => {
|
|
4460
4614
|
if (v === 0) return [0, 0];
|
|
4461
4615
|
const u = (x - c) / half;
|
|
4462
4616
|
const widen = v > 0 ? 0.05 : 0.03;
|
|
@@ -4466,7 +4620,7 @@ function mouthForm(mesh, box) {
|
|
|
4466
4620
|
function mouthOpenGrow(mesh, box) {
|
|
4467
4621
|
const c = cx(box);
|
|
4468
4622
|
return localWarp(
|
|
4469
|
-
|
|
4623
|
+
P3.MouthOpen,
|
|
4470
4624
|
mesh,
|
|
4471
4625
|
box,
|
|
4472
4626
|
[0, 1],
|
|
@@ -4475,7 +4629,7 @@ function mouthOpenGrow(mesh, box) {
|
|
|
4475
4629
|
}
|
|
4476
4630
|
function mouthWiden(mesh, box) {
|
|
4477
4631
|
const c = cx(box);
|
|
4478
|
-
return localWarp(
|
|
4632
|
+
return localWarp(P3.MouthOpen, mesh, box, [0, 1], ([x], v) => [
|
|
4479
4633
|
v * (AMPLITUDE.mouthOpenWidth - 1) * (x - c),
|
|
4480
4634
|
0
|
|
4481
4635
|
]);
|
|
@@ -4493,7 +4647,7 @@ function hairSway(param, mesh, box, amp) {
|
|
|
4493
4647
|
);
|
|
4494
4648
|
}
|
|
4495
4649
|
function tiltHang(mesh, box, pivot, weight) {
|
|
4496
|
-
return localWarp(
|
|
4650
|
+
return localWarp(P3.AngleZ, mesh, box, Z_STOPS, ([x, y], v, i) => {
|
|
4497
4651
|
const g = weight(y, i);
|
|
4498
4652
|
if (g === 0 || v === 0) return [0, 0];
|
|
4499
4653
|
const a = -g * rollOf(v);
|
|
@@ -4646,14 +4800,17 @@ function generateIkiFromLayerSet(layers, canvas, options = {}) {
|
|
|
4646
4800
|
...part.warps ?? []
|
|
4647
4801
|
];
|
|
4648
4802
|
}
|
|
4803
|
+
const parameters = declareParameters(new Set(byRole.keys()));
|
|
4649
4804
|
const model = {
|
|
4650
4805
|
version: IKI_FORMAT_VERSION2,
|
|
4651
4806
|
name: "auto-rigged",
|
|
4652
4807
|
canvas: { width: canvas.width, height: canvas.height },
|
|
4653
|
-
parameters
|
|
4808
|
+
parameters,
|
|
4654
4809
|
parts,
|
|
4655
4810
|
deformers: deformers(frame, grids, has("body") ? box("body") : void 0),
|
|
4656
|
-
...has("hair_front") ? { physics: hairPhysics() } : {}
|
|
4811
|
+
...has("hair_front") ? { physics: hairPhysics() } : {},
|
|
4812
|
+
expressions: defaultExpressions(new Set(parameters.map((p) => p.id))),
|
|
4813
|
+
motions: DEFAULT_MOTIONS
|
|
4657
4814
|
};
|
|
4658
4815
|
const valid = parseIkiModel3(model);
|
|
4659
4816
|
if (hasNose && options.onTurnSolved) {
|
|
@@ -4670,14 +4827,14 @@ function generateIkiFromLayerSet(layers, canvas, options = {}) {
|
|
|
4670
4827
|
function turnWarps(mesh, b, fieldOf) {
|
|
4671
4828
|
return [
|
|
4672
4829
|
localWarp(
|
|
4673
|
-
|
|
4830
|
+
P4.AngleX,
|
|
4674
4831
|
mesh,
|
|
4675
4832
|
b,
|
|
4676
4833
|
X_STOPS,
|
|
4677
4834
|
([x, y], v, i) => v === 0 ? [0, 0] : [fieldOf(i)(x, y, v, 0)[0], 0]
|
|
4678
4835
|
),
|
|
4679
4836
|
localWarp(
|
|
4680
|
-
|
|
4837
|
+
P4.AngleY,
|
|
4681
4838
|
mesh,
|
|
4682
4839
|
b,
|
|
4683
4840
|
Y_STOPS,
|
|
@@ -4725,7 +4882,7 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
|
|
|
4725
4882
|
}
|
|
4726
4883
|
if (mesh !== void 0) part.mesh = mesh;
|
|
4727
4884
|
const side = spec.role.endsWith("_L") ? "L" : "R";
|
|
4728
|
-
const eyeOpen = side === "L" ?
|
|
4885
|
+
const eyeOpen = side === "L" ? P4.EyeOpenLeft : P4.EyeOpenRight;
|
|
4729
4886
|
const hh = frame.hh;
|
|
4730
4887
|
switch (spec.role) {
|
|
4731
4888
|
case "face":
|
|
@@ -4734,7 +4891,7 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
|
|
|
4734
4891
|
warps.push(
|
|
4735
4892
|
tiltHang(mesh, b, pivot, (_y, i) => isNeck[i] ? 1 : 0),
|
|
4736
4893
|
localWarp(
|
|
4737
|
-
|
|
4894
|
+
P4.Breath,
|
|
4738
4895
|
mesh,
|
|
4739
4896
|
b,
|
|
4740
4897
|
[0, 1],
|
|
@@ -4781,8 +4938,8 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
|
|
|
4781
4938
|
if (byRole.has("mouth_open")) {
|
|
4782
4939
|
warps.push(mouthWiden(mesh, b));
|
|
4783
4940
|
bindings.push(
|
|
4784
|
-
{ parameter:
|
|
4785
|
-
{ parameter:
|
|
4941
|
+
{ parameter: P4.MouthOpen, channel: "opacity", from: 1, to: 0 },
|
|
4942
|
+
{ parameter: P4.MouthOpen, channel: "opacity", from: 1, to: 0 }
|
|
4786
4943
|
);
|
|
4787
4944
|
extra = [(AMPLITUDE.mouthOpenWidth - 1) * (bw(b) / 2), 0];
|
|
4788
4945
|
} else {
|
|
@@ -4792,19 +4949,19 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
|
|
|
4792
4949
|
);
|
|
4793
4950
|
bindings.push(
|
|
4794
4951
|
{
|
|
4795
|
-
parameter:
|
|
4952
|
+
parameter: P4.MouthOpen,
|
|
4796
4953
|
channel: "scaleY",
|
|
4797
4954
|
from: 0,
|
|
4798
4955
|
to: roundTo(grow, 0.01)
|
|
4799
4956
|
},
|
|
4800
4957
|
{
|
|
4801
|
-
parameter:
|
|
4958
|
+
parameter: P4.MouthOpen,
|
|
4802
4959
|
channel: "scaleX",
|
|
4803
4960
|
from: 0,
|
|
4804
4961
|
to: roundTo(AMPLITUDE.mouthOpenWidth - 1, 0.01)
|
|
4805
4962
|
},
|
|
4806
4963
|
{
|
|
4807
|
-
parameter:
|
|
4964
|
+
parameter: P4.MouthOpen,
|
|
4808
4965
|
channel: "translateY",
|
|
4809
4966
|
from: 0,
|
|
4810
4967
|
to: -roundTo(grow * bh(b) / 2, 0.01)
|
|
@@ -4816,20 +4973,29 @@ function buildPart(spec, b, order, frame, byRole, style, frontGrid) {
|
|
|
4816
4973
|
case "mouth_open":
|
|
4817
4974
|
warps.push(mouthForm(mesh, b), mouthOpenGrow(mesh, b));
|
|
4818
4975
|
bindings.push({
|
|
4819
|
-
parameter:
|
|
4976
|
+
parameter: P4.MouthOpen,
|
|
4820
4977
|
channel: "opacity",
|
|
4821
4978
|
from: 0,
|
|
4822
4979
|
to: 1
|
|
4823
4980
|
});
|
|
4824
4981
|
extra = [(AMPLITUDE.mouthOpenWidth - 1) * (bw(b) / 2), 0];
|
|
4825
4982
|
break;
|
|
4983
|
+
case "blush_L":
|
|
4984
|
+
case "blush_R":
|
|
4985
|
+
bindings.push({
|
|
4986
|
+
parameter: P4.Cheek,
|
|
4987
|
+
channel: "opacity",
|
|
4988
|
+
from: AMPLITUDE.blushRest,
|
|
4989
|
+
to: 1
|
|
4990
|
+
});
|
|
4991
|
+
break;
|
|
4826
4992
|
case "hair_front":
|
|
4827
4993
|
case "hair_back":
|
|
4828
4994
|
if (byRole.has("hair_front")) {
|
|
4829
4995
|
const amp = style.sway * AMPLITUDE.sway * hh;
|
|
4830
4996
|
warps.push(
|
|
4831
|
-
hairSway(
|
|
4832
|
-
hairSway(
|
|
4997
|
+
hairSway(P4.HairSwayX, mesh, b, amp),
|
|
4998
|
+
hairSway(P4.HairSwayZ, mesh, b, amp)
|
|
4833
4999
|
);
|
|
4834
5000
|
}
|
|
4835
5001
|
warps.push(tiltHang(mesh, b, pivot, hairHangWeight(frame.chinY, b.y0)));
|
|
@@ -4910,7 +5076,7 @@ function deformers(frame, grids, body) {
|
|
|
4910
5076
|
pivot: { x: roundTo(cx(body), 0.01), y: roundTo(body.y1, 0.01) },
|
|
4911
5077
|
bindings: [
|
|
4912
5078
|
{
|
|
4913
|
-
parameter:
|
|
5079
|
+
parameter: P4.Breath,
|
|
4914
5080
|
channel: "translateY",
|
|
4915
5081
|
from: 0,
|
|
4916
5082
|
to: roundTo(AMPLITUDE.breathBody * frame.hh, 0.01)
|
|
@@ -4923,9 +5089,9 @@ function deformers(frame, grids, body) {
|
|
|
4923
5089
|
pivot: { x: roundTo(frame.axisX, 0.01), y: roundTo(frame.chinY, 0.01) },
|
|
4924
5090
|
bindings: [
|
|
4925
5091
|
// AngleZ is clockwise-positive (Live2D's); a rotation is CCW-positive.
|
|
4926
|
-
{ parameter:
|
|
5092
|
+
{ parameter: P4.AngleZ, channel: "rotate", from: ROLL_DEG, to: -ROLL_DEG },
|
|
4927
5093
|
{
|
|
4928
|
-
parameter:
|
|
5094
|
+
parameter: P4.Breath,
|
|
4929
5095
|
channel: "translateY",
|
|
4930
5096
|
from: 0,
|
|
4931
5097
|
to: roundTo(AMPLITUDE.breathHead * frame.hh, 0.01)
|
|
@@ -4943,8 +5109,8 @@ function deformers(frame, grids, body) {
|
|
|
4943
5109
|
points: g.lattice.points
|
|
4944
5110
|
},
|
|
4945
5111
|
warp2d: {
|
|
4946
|
-
parameter:
|
|
4947
|
-
parameterY:
|
|
5112
|
+
parameter: P4.AngleX,
|
|
5113
|
+
parameterY: P4.AngleY,
|
|
4948
5114
|
valuesX: X_STOPS,
|
|
4949
5115
|
valuesY: Y_STOPS,
|
|
4950
5116
|
keyforms2d: g.keyforms.map((offsets) => ({ offsets }))
|
|
@@ -4957,16 +5123,16 @@ function hairPhysics() {
|
|
|
4957
5123
|
return [
|
|
4958
5124
|
{
|
|
4959
5125
|
id: "hairSway",
|
|
4960
|
-
input: { parameter:
|
|
4961
|
-
output: { parameter:
|
|
5126
|
+
input: { parameter: P4.AngleX, weight: 1 },
|
|
5127
|
+
output: { parameter: P4.HairSwayX, scale: 5 },
|
|
4962
5128
|
mass: 1,
|
|
4963
5129
|
stiffness: 30,
|
|
4964
5130
|
damping: 3
|
|
4965
5131
|
},
|
|
4966
5132
|
{
|
|
4967
5133
|
id: "hairTilt",
|
|
4968
|
-
input: { parameter:
|
|
4969
|
-
output: { parameter:
|
|
5134
|
+
input: { parameter: P4.AngleZ, weight: 1 },
|
|
5135
|
+
output: { parameter: P4.HairSwayZ, scale: 8 },
|
|
4970
5136
|
mass: 1,
|
|
4971
5137
|
stiffness: 25,
|
|
4972
5138
|
damping: 2.5
|
|
@@ -4976,29 +5142,32 @@ function hairPhysics() {
|
|
|
4976
5142
|
function declareParameters(roles) {
|
|
4977
5143
|
const out = [];
|
|
4978
5144
|
const add = (id, name, min, max, def) => out.push({ id, name, min, max, default: def });
|
|
4979
|
-
add(
|
|
4980
|
-
add(
|
|
4981
|
-
add(
|
|
4982
|
-
add(
|
|
4983
|
-
add(
|
|
5145
|
+
add(P4.AngleX, "Head Angle", -30, 30, 0);
|
|
5146
|
+
add(P4.AngleY, "Head Angle Y", -30, 30, 0);
|
|
5147
|
+
add(P4.AngleZ, "Head Angle Z", -30, 30, 0);
|
|
5148
|
+
add(P4.EyeOpenLeft, "Eye L", 0, 1, 1);
|
|
5149
|
+
add(P4.EyeOpenRight, "Eye R", 0, 1, 1);
|
|
4984
5150
|
if ([...roles].some((r) => /^(iris|pupil|highlight)_/.test(r))) {
|
|
4985
|
-
add(
|
|
4986
|
-
add(
|
|
5151
|
+
add(P4.EyeballX, "Gaze X", -1, 1, 0);
|
|
5152
|
+
add(P4.EyeballY, "Gaze Y", -1, 1, 0);
|
|
4987
5153
|
}
|
|
4988
|
-
add(
|
|
4989
|
-
add(
|
|
5154
|
+
add(P4.MouthOpen, "Mouth Open", 0, 1, 0);
|
|
5155
|
+
add(P4.MouthForm, "Mouth Form", -1, 1, 0);
|
|
4990
5156
|
if (roles.has("brow_L")) {
|
|
4991
|
-
add(
|
|
4992
|
-
add(
|
|
5157
|
+
add(P4.BrowLeftY, "Brow L Y", -1, 1, 0);
|
|
5158
|
+
add(P4.BrowLeftAngle, "Brow L Angle", -1, 1, 0);
|
|
4993
5159
|
}
|
|
4994
5160
|
if (roles.has("brow_R")) {
|
|
4995
|
-
add(
|
|
4996
|
-
add(
|
|
5161
|
+
add(P4.BrowRightY, "Brow R Y", -1, 1, 0);
|
|
5162
|
+
add(P4.BrowRightAngle, "Brow R Angle", -1, 1, 0);
|
|
5163
|
+
}
|
|
5164
|
+
if (roles.has("blush_L") || roles.has("blush_R")) {
|
|
5165
|
+
add(P4.Cheek, "Cheek", 0, 1, 0);
|
|
4997
5166
|
}
|
|
4998
|
-
add(
|
|
5167
|
+
add(P4.Breath, "Breath", 0, 1, 0);
|
|
4999
5168
|
if (roles.has("hair_front")) {
|
|
5000
|
-
add(
|
|
5001
|
-
add(
|
|
5169
|
+
add(P4.HairSwayX, "Hair Sway X", -SWAY_RANGE, SWAY_RANGE, 0);
|
|
5170
|
+
add(P4.HairSwayZ, "Hair Sway Z", -SWAY_RANGE, SWAY_RANGE, 0);
|
|
5002
5171
|
}
|
|
5003
5172
|
return out;
|
|
5004
5173
|
}
|