@ikijs/editor 0.17.0 → 0.18.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 +13 -13
- package/dist/index.d.mts +64 -1
- package/dist/index.d.ts +64 -1
- package/dist/index.js +268 -266
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +273 -272
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -52,6 +52,7 @@ __export(index_exports, {
|
|
|
52
52
|
SetPhysicsRig: () => SetPhysicsRig,
|
|
53
53
|
TurnTargetError: () => TurnTargetError,
|
|
54
54
|
UV_INSET_PX: () => UV_INSET_PX,
|
|
55
|
+
armGeometry: () => armGeometry,
|
|
55
56
|
captureBindingEndpoint: () => captureBindingEndpoint,
|
|
56
57
|
computeGridOffsets: () => computeGridOffsets,
|
|
57
58
|
createDefaultMatrixDeformer: () => createDefaultMatrixDeformer,
|
|
@@ -2180,258 +2181,11 @@ var DEFAULT_TURN_TARGETS = Object.freeze({
|
|
|
2180
2181
|
silhouetteRatio: 1
|
|
2181
2182
|
});
|
|
2182
2183
|
|
|
2183
|
-
// src/auto-rig/roles.ts
|
|
2184
|
-
var ROLE_TABLE = [
|
|
2185
|
-
{ role: "hair_back", family: "hair_back" },
|
|
2186
|
-
{ role: "body", family: "body" },
|
|
2187
|
-
{ role: "arm_L", family: "arm", parts: ["arm_L", "forearm_L"] },
|
|
2188
|
-
{ role: "arm_R", family: "arm", parts: ["arm_R", "forearm_R"] },
|
|
2189
|
-
{ role: "face", family: "face", required: true },
|
|
2190
|
-
{ role: "blush_L", family: "face" },
|
|
2191
|
-
{ role: "blush_R", family: "face" },
|
|
2192
|
-
{ role: "nose", family: "nose" },
|
|
2193
|
-
{ role: "mouth", family: "mouth", required: true },
|
|
2194
|
-
{ role: "mouth_open", family: "mouth" },
|
|
2195
|
-
{ role: "eye_L", family: "eye_L", required: true },
|
|
2196
|
-
{ role: "eye_R", family: "eye_R", required: true },
|
|
2197
|
-
{ role: "iris_L", family: "eye_L" },
|
|
2198
|
-
{ role: "iris_R", family: "eye_R" },
|
|
2199
|
-
{ role: "pupil_L", family: "eye_L" },
|
|
2200
|
-
{ role: "pupil_R", family: "eye_R" },
|
|
2201
|
-
{ role: "highlight_L", family: "eye_L" },
|
|
2202
|
-
{ role: "highlight_R", family: "eye_R" },
|
|
2203
|
-
{ role: "lash_lower_L", family: "eye_L" },
|
|
2204
|
-
{ role: "lash_lower_R", family: "eye_R" },
|
|
2205
|
-
{ role: "lash_L", family: "eye_L" },
|
|
2206
|
-
{ role: "lash_R", family: "eye_R" },
|
|
2207
|
-
{ role: "brow_L", family: "brow_L" },
|
|
2208
|
-
{ role: "brow_R", family: "brow_R" },
|
|
2209
|
-
{ role: "hair_front", family: "hair_front" }
|
|
2210
|
-
];
|
|
2211
|
-
var REQUIRED_ROLES = ROLE_TABLE.filter(
|
|
2212
|
-
(r) => r.required
|
|
2213
|
-
).map((r) => r.role);
|
|
2214
|
-
var SPEC_BY_ROLE = new Map(ROLE_TABLE.map((r, i) => [r.role, { ...r, i }]));
|
|
2215
|
-
function roleSpec(role) {
|
|
2216
|
-
const spec = SPEC_BY_ROLE.get(role);
|
|
2217
|
-
if (spec === void 0) throw new Error(`auto-rig: unknown role "${role}"`);
|
|
2218
|
-
return spec;
|
|
2219
|
-
}
|
|
2220
|
-
function partIdsOfRole(role) {
|
|
2221
|
-
return roleSpec(role).parts ?? [role];
|
|
2222
|
-
}
|
|
2223
|
-
var ROLE_BY_PART = new Map(
|
|
2224
|
-
ROLE_TABLE.flatMap((r) => (r.parts ?? []).map((p) => [p, r.role]))
|
|
2225
|
-
);
|
|
2226
|
-
function roleOfPart(partId) {
|
|
2227
|
-
return ROLE_BY_PART.get(partId) ?? partId;
|
|
2228
|
-
}
|
|
2229
|
-
var ALIASES = {
|
|
2230
|
-
eyebrow_L: "brow_L",
|
|
2231
|
-
eyebrow_R: "brow_R",
|
|
2232
|
-
eye_white_L: "eye_L",
|
|
2233
|
-
eye_white_R: "eye_R"
|
|
2234
|
-
};
|
|
2235
|
-
function roleOf(fileName) {
|
|
2236
|
-
const role = fileName.replace(/\.[^.]+$/, "").toLowerCase().replace(/[-\s]+/g, "_").replace(/_([lr])$/, (_, s) => `_${s.toUpperCase()}`);
|
|
2237
|
-
return ALIASES[role] ?? role;
|
|
2238
|
-
}
|
|
2239
|
-
function checkArmsHaveBody(roles) {
|
|
2240
|
-
const has = new Set(roles);
|
|
2241
|
-
if (has.has("body")) return;
|
|
2242
|
-
const arm = ROLE_TABLE.find((r) => r.family === "arm" && has.has(r.role));
|
|
2243
|
-
if (arm !== void 0) {
|
|
2244
|
-
throw new Error(
|
|
2245
|
-
`auto-rig: ${arm.role} needs a body layer (an arm hangs from the body's shoulder)`
|
|
2246
|
-
);
|
|
2247
|
-
}
|
|
2248
|
-
}
|
|
2249
|
-
function parseLayerRoles(fileNames) {
|
|
2250
|
-
const seen = /* @__PURE__ */ new Map();
|
|
2251
|
-
const out = [];
|
|
2252
|
-
for (const fileName of fileNames) {
|
|
2253
|
-
const role = roleOf(fileName);
|
|
2254
|
-
if (!SPEC_BY_ROLE.has(role)) {
|
|
2255
|
-
throw new Error(
|
|
2256
|
-
`auto-rig: "${fileName}" names no known role (expected one of ${ROLE_TABLE.map((r) => r.role).join(", ")})`
|
|
2257
|
-
);
|
|
2258
|
-
}
|
|
2259
|
-
const prior = seen.get(role);
|
|
2260
|
-
if (prior !== void 0) {
|
|
2261
|
-
throw new Error(
|
|
2262
|
-
`auto-rig: role "${role}" is named twice ("${prior}" and "${fileName}")`
|
|
2263
|
-
);
|
|
2264
|
-
}
|
|
2265
|
-
seen.set(role, fileName);
|
|
2266
|
-
out.push({ role, fileName });
|
|
2267
|
-
}
|
|
2268
|
-
const missing = REQUIRED_ROLES.filter((r) => !seen.has(r));
|
|
2269
|
-
if (missing.length > 0) {
|
|
2270
|
-
throw new Error(
|
|
2271
|
-
`auto-rig: missing required role${missing.length > 1 ? "s" : ""} ${missing.join(", ")}`
|
|
2272
|
-
);
|
|
2273
|
-
}
|
|
2274
|
-
checkArmsHaveBody(seen.keys());
|
|
2275
|
-
return out;
|
|
2276
|
-
}
|
|
2277
|
-
|
|
2278
|
-
// src/auto-rig/generate.ts
|
|
2279
|
-
var import_format8 = require("@ikijs/format");
|
|
2280
|
-
|
|
2281
|
-
// src/auto-rig/animations.ts
|
|
2282
|
-
var import_format3 = require("@ikijs/format");
|
|
2283
|
-
function browsY(y) {
|
|
2284
|
-
return [
|
|
2285
|
-
{ parameter: import_format3.StandardParameter.BrowLeftY, value: y, blend: "add" },
|
|
2286
|
-
{ parameter: import_format3.StandardParameter.BrowRightY, value: y, blend: "add" }
|
|
2287
|
-
];
|
|
2288
|
-
}
|
|
2289
|
-
function browsTilt(innerDown) {
|
|
2290
|
-
return [
|
|
2291
|
-
{ parameter: import_format3.StandardParameter.BrowLeftAngle, value: innerDown, blend: "add" },
|
|
2292
|
-
{ parameter: import_format3.StandardParameter.BrowRightAngle, value: -innerDown, blend: "add" }
|
|
2293
|
-
];
|
|
2294
|
-
}
|
|
2295
|
-
function cheek(value) {
|
|
2296
|
-
return { parameter: import_format3.StandardParameter.Cheek, value, blend: "add" };
|
|
2297
|
-
}
|
|
2298
|
-
var BROWS = [import_format3.StandardParameter.BrowLeftY, import_format3.StandardParameter.BrowRightY, import_format3.StandardParameter.BrowLeftAngle, import_format3.StandardParameter.BrowRightAngle];
|
|
2299
|
-
var EXPRESSIONS = [
|
|
2300
|
-
{
|
|
2301
|
-
id: "smile",
|
|
2302
|
-
description: "Smiling and pleased: warm, friendly, content. For greetings, thanks, agreement and gentle happiness.",
|
|
2303
|
-
parameters: [
|
|
2304
|
-
{ parameter: import_format3.StandardParameter.MouthForm, value: 1, blend: "add" },
|
|
2305
|
-
...browsY(0.25),
|
|
2306
|
-
cheek(0.4)
|
|
2307
|
-
]
|
|
2308
|
-
},
|
|
2309
|
-
{
|
|
2310
|
-
id: "laugh",
|
|
2311
|
-
description: "Laughing, eyes shut and mouth open: delighted, amused. For jokes, playfulness and big joy.",
|
|
2312
|
-
parameters: [
|
|
2313
|
-
{ parameter: import_format3.StandardParameter.EyeOpenLeft, value: 0, blend: "multiply" },
|
|
2314
|
-
{ parameter: import_format3.StandardParameter.EyeOpenRight, value: 0, blend: "multiply" },
|
|
2315
|
-
{ parameter: import_format3.StandardParameter.MouthForm, value: 1, blend: "add" },
|
|
2316
|
-
{ parameter: import_format3.StandardParameter.MouthOpen, value: 0.8, blend: "overwrite" },
|
|
2317
|
-
...browsY(0.4),
|
|
2318
|
-
cheek(0.65)
|
|
2319
|
-
]
|
|
2320
|
-
},
|
|
2321
|
-
{
|
|
2322
|
-
id: "angry",
|
|
2323
|
-
description: "Angry or annoyed, frowning. For irritation, frustration, indignation or scolding.",
|
|
2324
|
-
needs: BROWS,
|
|
2325
|
-
parameters: [
|
|
2326
|
-
...browsY(-0.5),
|
|
2327
|
-
...browsTilt(0.8),
|
|
2328
|
-
{ parameter: import_format3.StandardParameter.MouthForm, value: -0.9, blend: "add" }
|
|
2329
|
-
]
|
|
2330
|
-
},
|
|
2331
|
-
{
|
|
2332
|
-
id: "sad",
|
|
2333
|
-
description: "Sad or disappointed, downcast. For sorrow, regret, apology or sympathy.",
|
|
2334
|
-
needs: BROWS,
|
|
2335
|
-
parameters: [
|
|
2336
|
-
...browsY(0.35),
|
|
2337
|
-
...browsTilt(-0.8),
|
|
2338
|
-
{ parameter: import_format3.StandardParameter.MouthForm, value: -0.8, blend: "add" }
|
|
2339
|
-
]
|
|
2340
|
-
},
|
|
2341
|
-
{
|
|
2342
|
-
id: "surprised",
|
|
2343
|
-
description: "Surprised, mouth dropped open: startled, amazed. For shock, sudden news or disbelief.",
|
|
2344
|
-
parameters: [
|
|
2345
|
-
...browsY(0.8),
|
|
2346
|
-
{ parameter: import_format3.StandardParameter.MouthOpen, value: 0.9, blend: "overwrite" }
|
|
2347
|
-
]
|
|
2348
|
-
},
|
|
2349
|
-
{
|
|
2350
|
-
id: "shy",
|
|
2351
|
-
description: "Shy or embarrassed: bashful, flustered. For being praised, teased or caught off guard.",
|
|
2352
|
-
needs: [import_format3.StandardParameter.Cheek],
|
|
2353
|
-
parameters: [
|
|
2354
|
-
cheek(1),
|
|
2355
|
-
// Gaze down.
|
|
2356
|
-
{ parameter: import_format3.StandardParameter.EyeballY, value: -0.65, blend: "add" },
|
|
2357
|
-
{ parameter: import_format3.StandardParameter.MouthForm, value: 0.4, blend: "add" },
|
|
2358
|
-
...browsTilt(-0.25)
|
|
2359
|
-
]
|
|
2360
|
-
}
|
|
2361
|
-
];
|
|
2362
|
-
function defaultExpressions(declared) {
|
|
2363
|
-
return EXPRESSIONS.filter(
|
|
2364
|
-
(e) => e.needs === void 0 || e.needs.some((id) => declared.has(id))
|
|
2365
|
-
).map(({ needs: _needs, ...e }) => ({
|
|
2366
|
-
...e,
|
|
2367
|
-
parameters: e.parameters.filter((t) => declared.has(t.parameter))
|
|
2368
|
-
}));
|
|
2369
|
-
}
|
|
2370
|
-
var DEFAULT_MOTIONS = {
|
|
2371
|
-
Nod: [
|
|
2372
|
-
{
|
|
2373
|
-
description: "Nods yes: agreement, acknowledgement, understanding.",
|
|
2374
|
-
duration: 1,
|
|
2375
|
-
curves: [
|
|
2376
|
-
{
|
|
2377
|
-
parameter: import_format3.StandardParameter.AngleY,
|
|
2378
|
-
keys: [
|
|
2379
|
-
[0, 0],
|
|
2380
|
-
[0.3, -18],
|
|
2381
|
-
[0.6, 4],
|
|
2382
|
-
[0.8, -1],
|
|
2383
|
-
[1, 0]
|
|
2384
|
-
]
|
|
2385
|
-
}
|
|
2386
|
-
]
|
|
2387
|
-
}
|
|
2388
|
-
],
|
|
2389
|
-
Shake: [
|
|
2390
|
-
{
|
|
2391
|
-
description: "Shakes the head no: disagreement, refusal, disbelief.",
|
|
2392
|
-
duration: 1.2,
|
|
2393
|
-
// The first swing peaks at 0.2 s, which the default fade would still
|
|
2394
|
-
// be damping.
|
|
2395
|
-
fadeIn: 0.15,
|
|
2396
|
-
curves: [
|
|
2397
|
-
{
|
|
2398
|
-
parameter: import_format3.StandardParameter.AngleX,
|
|
2399
|
-
keys: [
|
|
2400
|
-
[0, 0],
|
|
2401
|
-
[0.2, -18],
|
|
2402
|
-
[0.45, 18],
|
|
2403
|
-
[0.7, -16],
|
|
2404
|
-
[0.95, 10],
|
|
2405
|
-
[1.2, 0]
|
|
2406
|
-
]
|
|
2407
|
-
}
|
|
2408
|
-
]
|
|
2409
|
-
}
|
|
2410
|
-
],
|
|
2411
|
-
Tilt: [
|
|
2412
|
-
{
|
|
2413
|
-
description: "Tilts the head to one side and back: curiosity, puzzlement, a question.",
|
|
2414
|
-
duration: 1.4,
|
|
2415
|
-
curves: [
|
|
2416
|
-
{
|
|
2417
|
-
parameter: import_format3.StandardParameter.AngleZ,
|
|
2418
|
-
keys: [
|
|
2419
|
-
[0, 0],
|
|
2420
|
-
[0.35, 20],
|
|
2421
|
-
[1, 20],
|
|
2422
|
-
[1.4, 0]
|
|
2423
|
-
]
|
|
2424
|
-
}
|
|
2425
|
-
]
|
|
2426
|
-
}
|
|
2427
|
-
]
|
|
2428
|
-
};
|
|
2429
|
-
|
|
2430
2184
|
// src/auto-rig/arms.ts
|
|
2431
|
-
var
|
|
2185
|
+
var import_format5 = require("@ikijs/format");
|
|
2432
2186
|
|
|
2433
2187
|
// src/auto-rig/body.ts
|
|
2434
|
-
var
|
|
2188
|
+
var import_format4 = require("@ikijs/format");
|
|
2435
2189
|
|
|
2436
2190
|
// src/auto-rig/layout.ts
|
|
2437
2191
|
function boxOfLayer(layer) {
|
|
@@ -2507,7 +2261,7 @@ function meshPoints(mesh, box) {
|
|
|
2507
2261
|
}
|
|
2508
2262
|
|
|
2509
2263
|
// src/auto-rig/drivers.ts
|
|
2510
|
-
var
|
|
2264
|
+
var import_format3 = require("@ikijs/format");
|
|
2511
2265
|
var SWAY_RANGE = 20;
|
|
2512
2266
|
var SWAY_CURVE = 1.4;
|
|
2513
2267
|
var HAIR_HANG = 0.35;
|
|
@@ -2585,13 +2339,13 @@ function gazeBindings(irisW, share = 1) {
|
|
|
2585
2339
|
const gy = AMPLITUDE.gazeY * irisW * share;
|
|
2586
2340
|
return [
|
|
2587
2341
|
{
|
|
2588
|
-
parameter:
|
|
2342
|
+
parameter: import_format3.StandardParameter.EyeballX,
|
|
2589
2343
|
channel: "translateX",
|
|
2590
2344
|
from: -round1(gx),
|
|
2591
2345
|
to: round1(gx)
|
|
2592
2346
|
},
|
|
2593
2347
|
{
|
|
2594
|
-
parameter:
|
|
2348
|
+
parameter: import_format3.StandardParameter.EyeballY,
|
|
2595
2349
|
channel: "translateY",
|
|
2596
2350
|
from: -round1(gy),
|
|
2597
2351
|
to: round1(gy)
|
|
@@ -2605,8 +2359,8 @@ function browReach(hh) {
|
|
|
2605
2359
|
return AMPLITUDE.brow * hh;
|
|
2606
2360
|
}
|
|
2607
2361
|
function browBindings(side, reach) {
|
|
2608
|
-
const y = side === "L" ?
|
|
2609
|
-
const a = side === "L" ?
|
|
2362
|
+
const y = side === "L" ? import_format3.StandardParameter.BrowLeftY : import_format3.StandardParameter.BrowRightY;
|
|
2363
|
+
const a = side === "L" ? import_format3.StandardParameter.BrowLeftAngle : import_format3.StandardParameter.BrowRightAngle;
|
|
2610
2364
|
return [
|
|
2611
2365
|
{
|
|
2612
2366
|
parameter: y,
|
|
@@ -2622,7 +2376,7 @@ function mouthForm(mesh, box) {
|
|
|
2622
2376
|
const a = 0.3 * bh(box);
|
|
2623
2377
|
const c = cx(box);
|
|
2624
2378
|
const half = bw(box) / 2;
|
|
2625
|
-
return localWarp(
|
|
2379
|
+
return localWarp(import_format3.StandardParameter.MouthForm, mesh, box, [-1, 0, 1], ([x], v) => {
|
|
2626
2380
|
if (v === 0) return [0, 0];
|
|
2627
2381
|
const u = (x - c) / half;
|
|
2628
2382
|
const widen = v > 0 ? 0.05 : 0.03;
|
|
@@ -2632,7 +2386,7 @@ function mouthForm(mesh, box) {
|
|
|
2632
2386
|
function mouthOpenGrow(mesh, box) {
|
|
2633
2387
|
const c = cx(box);
|
|
2634
2388
|
return localWarp(
|
|
2635
|
-
|
|
2389
|
+
import_format3.StandardParameter.MouthOpen,
|
|
2636
2390
|
mesh,
|
|
2637
2391
|
box,
|
|
2638
2392
|
[0, 1],
|
|
@@ -2641,7 +2395,7 @@ function mouthOpenGrow(mesh, box) {
|
|
|
2641
2395
|
}
|
|
2642
2396
|
function mouthWiden(mesh, box) {
|
|
2643
2397
|
const c = cx(box);
|
|
2644
|
-
return localWarp(
|
|
2398
|
+
return localWarp(import_format3.StandardParameter.MouthOpen, mesh, box, [0, 1], ([x], v) => [
|
|
2645
2399
|
v * (AMPLITUDE.mouthOpenWidth - 1) * (x - c),
|
|
2646
2400
|
0
|
|
2647
2401
|
]);
|
|
@@ -2659,7 +2413,7 @@ function hairSway(param, mesh, box, amp) {
|
|
|
2659
2413
|
);
|
|
2660
2414
|
}
|
|
2661
2415
|
function tiltHang(mesh, box, pivot, weight, deg = ROLL_DEG) {
|
|
2662
|
-
return localWarp(
|
|
2416
|
+
return localWarp(import_format3.StandardParameter.AngleZ, mesh, box, Z_STOPS, ([x, y], v, i) => {
|
|
2663
2417
|
const g = weight(y, i);
|
|
2664
2418
|
if (g === 0 || v === 0) return [0, 0];
|
|
2665
2419
|
const a = -g * rollOf(v, deg);
|
|
@@ -2908,16 +2662,16 @@ function buildBodyWarp({
|
|
|
2908
2662
|
points: ys.flatMap((y) => xs.flatMap((x) => [x, y]))
|
|
2909
2663
|
},
|
|
2910
2664
|
warps: [
|
|
2911
|
-
warp(
|
|
2912
|
-
warp(
|
|
2665
|
+
warp(import_format4.StandardParameter.BodyAngleX, BODY_STOPS, (x, _y, t) => [turn(x, t), 0]),
|
|
2666
|
+
warp(import_format4.StandardParameter.BodyAngleY, BODY_STOPS, (_x, _y, t) => [0, t * BODY.bow * hh]),
|
|
2913
2667
|
warp(
|
|
2914
|
-
|
|
2668
|
+
import_format4.StandardParameter.BodyAngleZ,
|
|
2915
2669
|
BODY_STOPS,
|
|
2916
2670
|
(x, y, t) => roll(x, y, -t * BODY.rollDeg)
|
|
2917
2671
|
),
|
|
2918
|
-
warp(
|
|
2919
|
-
warp(
|
|
2920
|
-
warp(
|
|
2672
|
+
warp(import_format4.StandardParameter.AngleX, X_STOPS, (x, _y, t) => [BODY.followX * turn(x, t), 0]),
|
|
2673
|
+
warp(import_format4.StandardParameter.AngleZ, Z_STOPS, (x, y, t) => roll(x, y, -t * BODY.followRoll)),
|
|
2674
|
+
warp(import_format4.StandardParameter.Breath, [0, 1], (_x, _y, t) => [0, t * AMPLITUDE.breathBody * hh])
|
|
2921
2675
|
]
|
|
2922
2676
|
};
|
|
2923
2677
|
refuseFold(body, deformer, anchor, [chin, ...pivots]);
|
|
@@ -3002,8 +2756,8 @@ var CAP_ROWS = [0.1, 0.3];
|
|
|
3002
2756
|
var CAP_SEGMENTS = 12;
|
|
3003
2757
|
var ARM_RANGE = [-30, 150];
|
|
3004
2758
|
var ARM_PARAMS = {
|
|
3005
|
-
arm_L: { arm:
|
|
3006
|
-
arm_R: { arm:
|
|
2759
|
+
arm_L: { arm: import_format5.StandardParameter.ArmLeft, elbow: import_format5.StandardParameter.ElbowLeft },
|
|
2760
|
+
arm_R: { arm: import_format5.StandardParameter.ArmRight, elbow: import_format5.StandardParameter.ElbowRight }
|
|
3007
2761
|
};
|
|
3008
2762
|
var ARM_IDS = {
|
|
3009
2763
|
arm_L: {
|
|
@@ -3151,6 +2905,253 @@ function armDeformers(role, g) {
|
|
|
3151
2905
|
];
|
|
3152
2906
|
}
|
|
3153
2907
|
|
|
2908
|
+
// src/auto-rig/roles.ts
|
|
2909
|
+
var ROLE_TABLE = [
|
|
2910
|
+
{ role: "hair_back", family: "hair_back" },
|
|
2911
|
+
{ role: "body", family: "body" },
|
|
2912
|
+
{ role: "arm_L", family: "arm", parts: ["arm_L", "forearm_L"] },
|
|
2913
|
+
{ role: "arm_R", family: "arm", parts: ["arm_R", "forearm_R"] },
|
|
2914
|
+
{ role: "face", family: "face", required: true },
|
|
2915
|
+
{ role: "blush_L", family: "face" },
|
|
2916
|
+
{ role: "blush_R", family: "face" },
|
|
2917
|
+
{ role: "nose", family: "nose" },
|
|
2918
|
+
{ role: "mouth", family: "mouth", required: true },
|
|
2919
|
+
{ role: "mouth_open", family: "mouth" },
|
|
2920
|
+
{ role: "eye_L", family: "eye_L", required: true },
|
|
2921
|
+
{ role: "eye_R", family: "eye_R", required: true },
|
|
2922
|
+
{ role: "iris_L", family: "eye_L" },
|
|
2923
|
+
{ role: "iris_R", family: "eye_R" },
|
|
2924
|
+
{ role: "pupil_L", family: "eye_L" },
|
|
2925
|
+
{ role: "pupil_R", family: "eye_R" },
|
|
2926
|
+
{ role: "highlight_L", family: "eye_L" },
|
|
2927
|
+
{ role: "highlight_R", family: "eye_R" },
|
|
2928
|
+
{ role: "lash_lower_L", family: "eye_L" },
|
|
2929
|
+
{ role: "lash_lower_R", family: "eye_R" },
|
|
2930
|
+
{ role: "lash_L", family: "eye_L" },
|
|
2931
|
+
{ role: "lash_R", family: "eye_R" },
|
|
2932
|
+
{ role: "brow_L", family: "brow_L" },
|
|
2933
|
+
{ role: "brow_R", family: "brow_R" },
|
|
2934
|
+
{ role: "hair_front", family: "hair_front" }
|
|
2935
|
+
];
|
|
2936
|
+
var REQUIRED_ROLES = ROLE_TABLE.filter(
|
|
2937
|
+
(r) => r.required
|
|
2938
|
+
).map((r) => r.role);
|
|
2939
|
+
var SPEC_BY_ROLE = new Map(ROLE_TABLE.map((r, i) => [r.role, { ...r, i }]));
|
|
2940
|
+
function roleSpec(role) {
|
|
2941
|
+
const spec = SPEC_BY_ROLE.get(role);
|
|
2942
|
+
if (spec === void 0) throw new Error(`auto-rig: unknown role "${role}"`);
|
|
2943
|
+
return spec;
|
|
2944
|
+
}
|
|
2945
|
+
function partIdsOfRole(role) {
|
|
2946
|
+
return roleSpec(role).parts ?? [role];
|
|
2947
|
+
}
|
|
2948
|
+
var ROLE_BY_PART = new Map(
|
|
2949
|
+
ROLE_TABLE.flatMap((r) => (r.parts ?? []).map((p) => [p, r.role]))
|
|
2950
|
+
);
|
|
2951
|
+
function roleOfPart(partId) {
|
|
2952
|
+
return ROLE_BY_PART.get(partId) ?? partId;
|
|
2953
|
+
}
|
|
2954
|
+
var ALIASES = {
|
|
2955
|
+
eyebrow_L: "brow_L",
|
|
2956
|
+
eyebrow_R: "brow_R",
|
|
2957
|
+
eye_white_L: "eye_L",
|
|
2958
|
+
eye_white_R: "eye_R"
|
|
2959
|
+
};
|
|
2960
|
+
function roleOf(fileName) {
|
|
2961
|
+
const role = fileName.replace(/\.[^.]+$/, "").toLowerCase().replace(/[-\s]+/g, "_").replace(/_([lr])$/, (_, s) => `_${s.toUpperCase()}`);
|
|
2962
|
+
return ALIASES[role] ?? role;
|
|
2963
|
+
}
|
|
2964
|
+
function checkArmsHaveBody(roles) {
|
|
2965
|
+
const has = new Set(roles);
|
|
2966
|
+
if (has.has("body")) return;
|
|
2967
|
+
const arm = ROLE_TABLE.find((r) => r.family === "arm" && has.has(r.role));
|
|
2968
|
+
if (arm !== void 0) {
|
|
2969
|
+
throw new Error(
|
|
2970
|
+
`auto-rig: ${arm.role} needs a body layer (an arm hangs from the body's shoulder)`
|
|
2971
|
+
);
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
function parseLayerRoles(fileNames) {
|
|
2975
|
+
const seen = /* @__PURE__ */ new Map();
|
|
2976
|
+
const out = [];
|
|
2977
|
+
for (const fileName of fileNames) {
|
|
2978
|
+
const role = roleOf(fileName);
|
|
2979
|
+
if (!SPEC_BY_ROLE.has(role)) {
|
|
2980
|
+
throw new Error(
|
|
2981
|
+
`auto-rig: "${fileName}" names no known role (expected one of ${ROLE_TABLE.map((r) => r.role).join(", ")})`
|
|
2982
|
+
);
|
|
2983
|
+
}
|
|
2984
|
+
const prior = seen.get(role);
|
|
2985
|
+
if (prior !== void 0) {
|
|
2986
|
+
throw new Error(
|
|
2987
|
+
`auto-rig: role "${role}" is named twice ("${prior}" and "${fileName}")`
|
|
2988
|
+
);
|
|
2989
|
+
}
|
|
2990
|
+
seen.set(role, fileName);
|
|
2991
|
+
out.push({ role, fileName });
|
|
2992
|
+
}
|
|
2993
|
+
const missing = REQUIRED_ROLES.filter((r) => !seen.has(r));
|
|
2994
|
+
if (missing.length > 0) {
|
|
2995
|
+
throw new Error(
|
|
2996
|
+
`auto-rig: missing required role${missing.length > 1 ? "s" : ""} ${missing.join(", ")}`
|
|
2997
|
+
);
|
|
2998
|
+
}
|
|
2999
|
+
checkArmsHaveBody(seen.keys());
|
|
3000
|
+
return out;
|
|
3001
|
+
}
|
|
3002
|
+
|
|
3003
|
+
// src/auto-rig/generate.ts
|
|
3004
|
+
var import_format8 = require("@ikijs/format");
|
|
3005
|
+
|
|
3006
|
+
// src/auto-rig/animations.ts
|
|
3007
|
+
var import_format6 = require("@ikijs/format");
|
|
3008
|
+
function browsY(y) {
|
|
3009
|
+
return [
|
|
3010
|
+
{ parameter: import_format6.StandardParameter.BrowLeftY, value: y, blend: "add" },
|
|
3011
|
+
{ parameter: import_format6.StandardParameter.BrowRightY, value: y, blend: "add" }
|
|
3012
|
+
];
|
|
3013
|
+
}
|
|
3014
|
+
function browsTilt(innerDown) {
|
|
3015
|
+
return [
|
|
3016
|
+
{ parameter: import_format6.StandardParameter.BrowLeftAngle, value: innerDown, blend: "add" },
|
|
3017
|
+
{ parameter: import_format6.StandardParameter.BrowRightAngle, value: -innerDown, blend: "add" }
|
|
3018
|
+
];
|
|
3019
|
+
}
|
|
3020
|
+
function cheek(value) {
|
|
3021
|
+
return { parameter: import_format6.StandardParameter.Cheek, value, blend: "add" };
|
|
3022
|
+
}
|
|
3023
|
+
var BROWS = [import_format6.StandardParameter.BrowLeftY, import_format6.StandardParameter.BrowRightY, import_format6.StandardParameter.BrowLeftAngle, import_format6.StandardParameter.BrowRightAngle];
|
|
3024
|
+
var EXPRESSIONS = [
|
|
3025
|
+
{
|
|
3026
|
+
id: "smile",
|
|
3027
|
+
description: "Smiling and pleased: warm, friendly, content. For greetings, thanks, agreement and gentle happiness.",
|
|
3028
|
+
parameters: [
|
|
3029
|
+
{ parameter: import_format6.StandardParameter.MouthForm, value: 1, blend: "add" },
|
|
3030
|
+
...browsY(0.25),
|
|
3031
|
+
cheek(0.4)
|
|
3032
|
+
]
|
|
3033
|
+
},
|
|
3034
|
+
{
|
|
3035
|
+
id: "laugh",
|
|
3036
|
+
description: "Laughing, eyes shut and mouth open: delighted, amused. For jokes, playfulness and big joy.",
|
|
3037
|
+
parameters: [
|
|
3038
|
+
{ parameter: import_format6.StandardParameter.EyeOpenLeft, value: 0, blend: "multiply" },
|
|
3039
|
+
{ parameter: import_format6.StandardParameter.EyeOpenRight, value: 0, blend: "multiply" },
|
|
3040
|
+
{ parameter: import_format6.StandardParameter.MouthForm, value: 1, blend: "add" },
|
|
3041
|
+
{ parameter: import_format6.StandardParameter.MouthOpen, value: 0.8, blend: "overwrite" },
|
|
3042
|
+
...browsY(0.4),
|
|
3043
|
+
cheek(0.65)
|
|
3044
|
+
]
|
|
3045
|
+
},
|
|
3046
|
+
{
|
|
3047
|
+
id: "angry",
|
|
3048
|
+
description: "Angry or annoyed, frowning. For irritation, frustration, indignation or scolding.",
|
|
3049
|
+
needs: BROWS,
|
|
3050
|
+
parameters: [
|
|
3051
|
+
...browsY(-0.5),
|
|
3052
|
+
...browsTilt(0.8),
|
|
3053
|
+
{ parameter: import_format6.StandardParameter.MouthForm, value: -0.9, blend: "add" }
|
|
3054
|
+
]
|
|
3055
|
+
},
|
|
3056
|
+
{
|
|
3057
|
+
id: "sad",
|
|
3058
|
+
description: "Sad or disappointed, downcast. For sorrow, regret, apology or sympathy.",
|
|
3059
|
+
needs: BROWS,
|
|
3060
|
+
parameters: [
|
|
3061
|
+
...browsY(0.35),
|
|
3062
|
+
...browsTilt(-0.8),
|
|
3063
|
+
{ parameter: import_format6.StandardParameter.MouthForm, value: -0.8, blend: "add" }
|
|
3064
|
+
]
|
|
3065
|
+
},
|
|
3066
|
+
{
|
|
3067
|
+
id: "surprised",
|
|
3068
|
+
description: "Surprised, mouth dropped open: startled, amazed. For shock, sudden news or disbelief.",
|
|
3069
|
+
parameters: [
|
|
3070
|
+
...browsY(0.8),
|
|
3071
|
+
{ parameter: import_format6.StandardParameter.MouthOpen, value: 0.9, blend: "overwrite" }
|
|
3072
|
+
]
|
|
3073
|
+
},
|
|
3074
|
+
{
|
|
3075
|
+
id: "shy",
|
|
3076
|
+
description: "Shy or embarrassed: bashful, flustered. For being praised, teased or caught off guard.",
|
|
3077
|
+
needs: [import_format6.StandardParameter.Cheek],
|
|
3078
|
+
parameters: [
|
|
3079
|
+
cheek(1),
|
|
3080
|
+
// Gaze down.
|
|
3081
|
+
{ parameter: import_format6.StandardParameter.EyeballY, value: -0.65, blend: "add" },
|
|
3082
|
+
{ parameter: import_format6.StandardParameter.MouthForm, value: 0.4, blend: "add" },
|
|
3083
|
+
...browsTilt(-0.25)
|
|
3084
|
+
]
|
|
3085
|
+
}
|
|
3086
|
+
];
|
|
3087
|
+
function defaultExpressions(declared) {
|
|
3088
|
+
return EXPRESSIONS.filter(
|
|
3089
|
+
(e) => e.needs === void 0 || e.needs.some((id) => declared.has(id))
|
|
3090
|
+
).map(({ needs: _needs, ...e }) => ({
|
|
3091
|
+
...e,
|
|
3092
|
+
parameters: e.parameters.filter((t) => declared.has(t.parameter))
|
|
3093
|
+
}));
|
|
3094
|
+
}
|
|
3095
|
+
var DEFAULT_MOTIONS = {
|
|
3096
|
+
Nod: [
|
|
3097
|
+
{
|
|
3098
|
+
description: "Nods yes: agreement, acknowledgement, understanding.",
|
|
3099
|
+
duration: 1,
|
|
3100
|
+
curves: [
|
|
3101
|
+
{
|
|
3102
|
+
parameter: import_format6.StandardParameter.AngleY,
|
|
3103
|
+
keys: [
|
|
3104
|
+
[0, 0],
|
|
3105
|
+
[0.3, -18],
|
|
3106
|
+
[0.6, 4],
|
|
3107
|
+
[0.8, -1],
|
|
3108
|
+
[1, 0]
|
|
3109
|
+
]
|
|
3110
|
+
}
|
|
3111
|
+
]
|
|
3112
|
+
}
|
|
3113
|
+
],
|
|
3114
|
+
Shake: [
|
|
3115
|
+
{
|
|
3116
|
+
description: "Shakes the head no: disagreement, refusal, disbelief.",
|
|
3117
|
+
duration: 1.2,
|
|
3118
|
+
// The first swing peaks at 0.2 s, which the default fade would still
|
|
3119
|
+
// be damping.
|
|
3120
|
+
fadeIn: 0.15,
|
|
3121
|
+
curves: [
|
|
3122
|
+
{
|
|
3123
|
+
parameter: import_format6.StandardParameter.AngleX,
|
|
3124
|
+
keys: [
|
|
3125
|
+
[0, 0],
|
|
3126
|
+
[0.2, -18],
|
|
3127
|
+
[0.45, 18],
|
|
3128
|
+
[0.7, -16],
|
|
3129
|
+
[0.95, 10],
|
|
3130
|
+
[1.2, 0]
|
|
3131
|
+
]
|
|
3132
|
+
}
|
|
3133
|
+
]
|
|
3134
|
+
}
|
|
3135
|
+
],
|
|
3136
|
+
Tilt: [
|
|
3137
|
+
{
|
|
3138
|
+
description: "Tilts the head to one side and back: curiosity, puzzlement, a question.",
|
|
3139
|
+
duration: 1.4,
|
|
3140
|
+
curves: [
|
|
3141
|
+
{
|
|
3142
|
+
parameter: import_format6.StandardParameter.AngleZ,
|
|
3143
|
+
keys: [
|
|
3144
|
+
[0, 0],
|
|
3145
|
+
[0.35, 20],
|
|
3146
|
+
[1, 20],
|
|
3147
|
+
[1.4, 0]
|
|
3148
|
+
]
|
|
3149
|
+
}
|
|
3150
|
+
]
|
|
3151
|
+
}
|
|
3152
|
+
]
|
|
3153
|
+
};
|
|
3154
|
+
|
|
3154
3155
|
// src/auto-rig/checks.ts
|
|
3155
3156
|
var finite = (v) => typeof v === "number" && Number.isFinite(v);
|
|
3156
3157
|
var isObject = (v) => typeof v === "object" && v !== null;
|
|
@@ -5790,6 +5791,7 @@ function declareParameters(roles) {
|
|
|
5790
5791
|
SetPhysicsRig,
|
|
5791
5792
|
TurnTargetError,
|
|
5792
5793
|
UV_INSET_PX,
|
|
5794
|
+
armGeometry,
|
|
5793
5795
|
captureBindingEndpoint,
|
|
5794
5796
|
computeGridOffsets,
|
|
5795
5797
|
createDefaultMatrixDeformer,
|