var T = Object.defineProperty;
var F = (f, t, i) => t in f ? T(f, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : f[t] = i;
var d = (f, t, i) => (F(f, typeof t != "symbol" ? t + "" : t, i), i);
import { V as r, M as R, O as y, Q as U } from "../../../three.module-g4QKgdLf.js";
import { a as V } from "../../../three-vrm.module--Wx-EJJ8.js";
import { clampVector3ByRadian as E } from "../three-helpers.js";
const e = V, A = [
  e.Chest,
  e.Head,
  e.Hips,
  e.Jaw,
  e.LeftEye,
  e.LeftFoot,
  e.LeftHand,
  e.LeftIndexDistal,
  e.LeftIndexIntermediate,
  e.LeftIndexProximal,
  e.LeftLittleDistal,
  e.LeftLittleIntermediate,
  e.LeftLittleProximal,
  e.LeftLowerArm,
  e.LeftLowerLeg,
  e.LeftMiddleDistal,
  e.LeftMiddleIntermediate,
  e.LeftMiddleProximal,
  e.LeftRingDistal,
  e.LeftRingIntermediate,
  e.LeftRingProximal,
  e.LeftShoulder,
  e.LeftThumbDistal,
  e.LeftThumbMetacarpal,
  e.LeftThumbProximal,
  e.LeftToes,
  e.LeftUpperArm,
  e.LeftUpperLeg,
  e.Neck,
  e.RightEye,
  e.RightFoot,
  e.RightHand,
  e.RightIndexDistal,
  e.RightIndexIntermediate,
  e.RightIndexProximal,
  e.RightLittleDistal,
  e.RightLittleIntermediate,
  e.RightLittleProximal,
  e.RightLowerArm,
  e.RightLowerLeg,
  e.RightMiddleDistal,
  e.RightMiddleIntermediate,
  e.RightMiddleProximal,
  e.RightRingDistal,
  e.RightRingIntermediate,
  e.RightRingProximal,
  e.RightShoulder,
  e.RightThumbDistal,
  e.RightThumbMetacarpal,
  e.RightThumbProximal,
  e.RightToes,
  e.RightUpperArm,
  e.RightUpperLeg,
  e.Spine,
  e.UpperChest
], s = new Map(
  A.map((f, t) => [f, t])
), h = new U(), b = new r(), x = new r(), w = new r(), p = new r(), u = new r(), S = new r(), k = new r(), L = class L {
  constructor(t) {
    d(this, "targets", /* @__PURE__ */ new Map());
    d(this, "iks", /* @__PURE__ */ new Map());
    d(this, "bones");
    d(this, "root");
    var c;
    this.model = t;
    const { humanoid: i } = this.model;
    if (!i)
      throw new Error("VRM does not contains humanoid");
    this.bones = A.map(
      i.getNormalizedBoneNode,
      i
    ), this.root = ((c = this.bones[s.get(e.Hips)]) == null ? void 0 : c.parent) ?? this.model.scene;
    const o = s.get(e.LeftFoot);
    this.iks.set(o, {
      effector: o,
      target: o,
      iteration: 40,
      maxAngle: 0.5,
      links: [
        {
          enabled: !1,
          index: s.get(e.LeftLowerLeg),
          rotationMin: new r(-180, 0, 0).multiplyScalar(
            R.DEG2RAD
          ),
          rotationMax: new r(0, 0, 0)
        },
        {
          enabled: !1,
          index: s.get(e.LeftUpperLeg)
        }
      ]
    });
    const n = s.get(e.RightFoot);
    this.iks.set(n, {
      effector: n,
      target: n,
      iteration: 40,
      maxAngle: 0.5,
      links: [
        {
          enabled: !1,
          index: s.get(e.RightLowerLeg),
          rotationMin: new r(-180, 0, 0).multiplyScalar(
            R.DEG2RAD
          ),
          rotationMax: new r(0, 0, 0)
        },
        {
          enabled: !1,
          index: s.get(e.RightUpperLeg)
        }
      ]
    });
    const l = s.get(e.LeftToes);
    this.iks.set(l, {
      effector: l,
      target: l,
      iteration: 3,
      maxAngle: 1,
      links: [
        {
          enabled: !1,
          index: o
        }
      ]
    });
    const g = s.get(e.RightToes);
    this.iks.set(g, {
      effector: g,
      target: g,
      iteration: 3,
      maxAngle: 1,
      links: [
        {
          enabled: !1,
          index: n
        }
      ]
    });
  }
  static get(t) {
    let i = this.cache.get(t);
    return i || (i = new L(t), this.cache.set(t, i)), i;
  }
  getAndEnableIK(t) {
    return this.getTarget(t, !0);
  }
  getTarget(t, i) {
    const o = s.get(t);
    if (o == null)
      return;
    let n = this.targets.get(o);
    const l = this.iks.get(o);
    if (i)
      for (const g of l.links)
        g.enabled = !0;
    return n || (n = new y(), n.name = `${t}IK`, this.root.add(n), this.targets.set(o, n)), n;
  }
  disableAll() {
    for (const { links: t } of this.iks.values())
      for (const i of t)
        i.enabled = !1;
  }
  update() {
    for (const t of this.iks.values()) {
      const i = this.bones[t.effector], o = this.targets.get(t.target);
      if (!i || !o)
        continue;
      b.setFromMatrixPosition(o.matrixWorld);
      const n = t.iteration ?? 1;
      for (let l = 0; l < n; l++) {
        let g = !1;
        for (const { enabled: c, index: I, rotationMin: D, rotationMax: P } of t.links) {
          if (!c)
            break;
          const m = this.bones[I];
          m.matrixWorld.decompose(u, h, S), h.invert(), w.setFromMatrixPosition(i.matrixWorld), p.subVectors(w, u).applyQuaternion(h).normalize(), x.subVectors(b, u).applyQuaternion(h).normalize();
          let a = x.dot(p);
          a > 1 ? a = 1 : a < -1 && (a = -1), a = Math.acos(a), !(a < 1e-5) && (t.minAngle != null && a < t.minAngle && (a = t.minAngle), t.maxAngle != null && a > t.maxAngle && (a = t.maxAngle), k.crossVectors(p, x).normalize(), m.quaternion.multiply(h.setFromAxisAngle(k, a)), E(m.rotation, D, P), m.updateMatrixWorld(!0), g = !0);
        }
        if (!g)
          break;
      }
    }
  }
};
d(L, "cache", /* @__PURE__ */ new WeakMap());
let M = L;
export {
  M as default
};
