@ikijs/editor 0.33.0 → 0.33.1

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.js CHANGED
@@ -3463,6 +3463,19 @@ function spin(x, y, ox, oy, a) {
3463
3463
  ];
3464
3464
  }
3465
3465
  function faceField(m) {
3466
+ const plate = plateField(m);
3467
+ const floor = foreheadFloor(m);
3468
+ let hold;
3469
+ return (x, y, ax, ay) => {
3470
+ const d = plate(x, y, ax, ay);
3471
+ if (ax === 0 || y <= floor) return d;
3472
+ if (hold === void 0) hold = foreheadHold(m, floor) ?? null;
3473
+ if (hold === null) return d;
3474
+ const s = Math.sign(ax);
3475
+ return [d[0] - s * Math.abs(ax) * hold(x, y, s) / 30, d[1]];
3476
+ };
3477
+ }
3478
+ function plateField(m) {
3466
3479
  const f = m.frame;
3467
3480
  return (x, y, ax, ay) => {
3468
3481
  const s = Math.sign(ax);
@@ -3482,6 +3495,77 @@ function faceField(m) {
3482
3495
  return [dx, nodDy(v, ay, f.hh)];
3483
3496
  };
3484
3497
  }
3498
+ function faceCellPx(frame) {
3499
+ return Math.min(FACE_CELL_PX, 2 * frame.wMax / 14);
3500
+ }
3501
+ var FACE_CELL_PX = 28;
3502
+ var FOREHEAD_FADE = 0.04;
3503
+ function foreheadFloor(m) {
3504
+ const f = m.frame;
3505
+ const eyes = [m.boxes.eye_L, m.boxes.eye_R].filter(
3506
+ (e) => e !== void 0
3507
+ );
3508
+ const eyeTop = eyes.length > 0 ? Math.max(...eyes.map((e) => e.y1)) : f.eyeY;
3509
+ return Math.max(eyeTop, f.ears === void 0 ? -Infinity : f.ears.top + 2);
3510
+ }
3511
+ function foreheadHold(m, floor) {
3512
+ const f = m.frame;
3513
+ const top = f.face.y1;
3514
+ const count = Math.floor(top - floor);
3515
+ if (count <= 0 || f.faceRuns(top - 0.5) === void 0 || f.hairRuns("hair_front", top - 0.5) === void 0) {
3516
+ return void 0;
3517
+ }
3518
+ const plate = plateField(m);
3519
+ const front = hairFrontField(m);
3520
+ const { inner } = hairFrontBends(f, m.boxes);
3521
+ const cell = faceCellPx(f);
3522
+ const fade = FOREHEAD_FADE * f.hh;
3523
+ const sides = [-1, 1];
3524
+ const hold = sides.map(() => new Float64Array(count));
3525
+ const whole = sides.map(() => new Float64Array(count));
3526
+ const span3 = sides.map(() => new Float64Array(count));
3527
+ let any = false;
3528
+ for (let i = 0; i < count; i++) {
3529
+ const y = top - i - 0.5;
3530
+ const faceRuns = f.faceRuns(y);
3531
+ const hairRuns = f.hairRuns("hair_front", y);
3532
+ sides.forEach((side, k) => {
3533
+ const edge = outerEdge(faceRuns, f.axisX, side);
3534
+ const hair = outerEdge(hairRuns, f.axisX, side);
3535
+ if (edge === void 0 || hair === void 0) return;
3536
+ const end = side * (edge - f.axisX) - cell;
3537
+ if (end <= 0) return;
3538
+ const cover = side * (hair - edge);
3539
+ const room = Math.max(0, cover);
3540
+ const goes = side * plate(edge - side * 0.5, y, 30 * side, 0)[0];
3541
+ const held = side * front(hair - side * 0.5, y, 30 * side, 0)[0];
3542
+ const need = clamp(1 + cover / fade, 0, 1) * Math.max(0, goes - held - room + Math.min(1, room));
3543
+ if (need <= 0) return;
3544
+ const over = Math.min(end, Math.max(2 * cell, end - inner, 2 * need));
3545
+ hold[k][i] = Math.min(need, over / 2);
3546
+ whole[k][i] = end;
3547
+ span3[k][i] = over;
3548
+ any = true;
3549
+ });
3550
+ }
3551
+ if (!any) return void 0;
3552
+ const reach = Math.ceil(cell);
3553
+ return (x, y, s) => {
3554
+ const u = s * (x - f.axisX);
3555
+ if (s === 0 || u <= 0 || y <= floor) return 0;
3556
+ const k = s < 0 ? 0 : 1;
3557
+ const i = clamp(Math.floor(top - y), 0, count - 1);
3558
+ let h = 0;
3559
+ const j1 = Math.min(count - 1, i + 3 * reach);
3560
+ for (let j = Math.max(0, i - 3 * reach); j <= j1; j++) {
3561
+ if (hold[k][j] === 0) continue;
3562
+ const near = clamp((3 * reach - Math.abs(i - j)) / (2 * reach), 0, 1);
3563
+ const across = clamp((u - (whole[k][j] - span3[k][j])) / span3[k][j], 0, 1);
3564
+ h = Math.max(h, hold[k][j] * near * across);
3565
+ }
3566
+ return h * clamp((y - floor) / (2 * cell), 0, 1);
3567
+ };
3568
+ }
3485
3569
  function earField(m) {
3486
3570
  const f = m.frame;
3487
3571
  const ears = f.ears;
@@ -7412,7 +7496,7 @@ function writeOcclusion(customParts, built, parts) {
7412
7496
 
7413
7497
  // src/auto-rig/generate.ts
7414
7498
  var MESH_CELLS = {
7415
- face: { px: 28, min: 4, max: 24 },
7499
+ face: { px: FACE_CELL_PX, min: 4, max: 24 },
7416
7500
  // The front hair eases from riding the face to holding the outline.
7417
7501
  hair_front: { px: 32, min: 3, max: 24 },
7418
7502
  // A side lock's rows come from `sideLockGrid`: even ones, plus the root
@@ -7720,7 +7804,7 @@ function buildPart(spec, b, order, frame, byRole, plan, frontGrid, lips) {
7720
7804
  let region;
7721
7805
  let headStart = 0;
7722
7806
  if (spec.role === "face") {
7723
- const px = Math.min(MESH_CELLS.face.px, 2 * frame.wMax / 14);
7807
+ const px = faceCellPx(frame);
7724
7808
  const fm = buildFaceMesh(frame, b, { ...MESH_CELLS.face, px }, NECK_CELLS);
7725
7809
  mesh = fm.mesh;
7726
7810
  region = fm.region;