var b = Object.defineProperty;
var B = (p, e, t) => e in p ? b(p, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[e] = t;
var n = (p, e, t) => (B(p, typeof e != "symbol" ? e + "" : e, t), t);
var T = (p, e, t) => new Promise((c, o) => {
  var s = (d) => {
    try {
      g(t.next(d));
    } catch (A) {
      o(A);
    }
  }, f = (d) => {
    try {
      g(t.throw(d));
    } catch (A) {
      o(A);
    }
  }, g = (d) => d.done ? c(d.value) : Promise.resolve(d.value).then(s, f);
  g((t = t.apply(p, e)).next());
});
import * as i from "three";
import { DigitalStateMachine as x } from "./DigitalStateMachine.js";
import { Trace as L } from "./Trace.js";
const S = 300;
class G {
  constructor(e, t) {
    n(this, "model");
    n(this, "keyframesManager");
    n(this, "keyframes");
    n(this, "items");
    n(this, "effects");
    n(this, "digitalPlayground");
    n(this, "state");
    n(this, "animationFrameId");
    n(this, "curveLine");
    n(this, "effectsGroup");
    n(this, "effectObjects");
    n(this, "container");
    n(this, "mixer");
    n(this, "action");
    n(this, "itemMatrixMap");
    n(this, "trace");
    // 用于跟踪已处理的needRender keyframeIndex
    n(this, "processedNeedRenderKeyframeIndices", /* @__PURE__ */ new Set());
    // 跟踪已绑定到骨骼的 keyframe 道具（key: itemKey, value: item object）
    n(this, "attachedItems", /* @__PURE__ */ new Map());
    // 缓存 RightHand 骨骼
    n(this, "rightHandBone", null);
    this.model = e, this.model.visible = !1, this.model.mixer = null, this.mixer = new i.AnimationMixer(this.model), this.action = null, this.keyframesManager = new x(), this.keyframes = [], this.items = [], this.effects = [], this.digitalPlayground = t, this.state = {
      currentTime: 0,
      currentAnimation: null,
      currentAnimationRepeat: !1,
      playing: !1
    }, this.animationFrameId = null, this.itemMatrixMap = /* @__PURE__ */ new Map(), this.trace = new L(), this.curveLine = new i.Line(), this.curveLine.material = new i.LineBasicMaterial({ color: 14467195, linewidth: 5 }), this.effectsGroup = new i.Group(), this.effectObjects = /* @__PURE__ */ new Map(), this.container = new i.Group(), this.container.add(this.model), this.container.add(this.curveLine), this.container.add(this.effectsGroup);
  }
  playAnimation({ animation: e, repeat: t, switchDuration: c }) {
    const o = this.action, s = this.mixer.clipAction(e);
    s.reset(), t ? (s.setLoop(i.LoopRepeat, 1 / 0), s.clampWhenFinished = !1) : (s.setLoop(i.LoopOnce, 1), s.clampWhenFinished = !0), o && (s.enabled = !0, s.setEffectiveTimeScale(1), s.crossFadeFrom(o, c / 1e3, !0)), s.play(), o && o !== s && setTimeout(() => {
      o !== this.action && o.stop();
    }, c), this.action = s;
  }
  pauseAnimation() {
    this.action && (this.action.paused = !0), this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null), this.state.playing = !1;
  }
  stopAnimation() {
    this.state.currentAnimation = null, this.mixer.stopAllAction(), this.state.playing = !1;
  }
  continueAnimation() {
    this.action && (this.action.paused = !1), this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null), this.keyframes.length > 0 && this.play(), this.state.playing = !0;
  }
  attachItem() {
  }
  init() {
    this.state.currentTime = 0, this.model.position.copy(new i.Vector3().fromArray(this.keyframes[0].position)), this.model.quaternion.copy(new i.Quaternion().fromArray(this.keyframes[0].quaternion)), this.model.visible = this.keyframes[0].visible;
  }
  reset() {
    this.state.currentTime = 0, this.keyframes && this.keyframes.length > 0 && (this.model.position.copy(new i.Vector3().fromArray(this.keyframes[0].position)), this.model.quaternion.copy(new i.Quaternion().fromArray(this.keyframes[0].quaternion))), this.model.visible = !1, this.container.visible = !1, this.animationFrameId && cancelAnimationFrame(this.animationFrameId), this.stopAnimation(), this.clearTrace(), this.detachAllKeyframeItems(), this.state.playing = !1;
  }
  play(e) {
    return T(this, null, function* () {
      this.clearProcessedNeedRenderKeyframeIndices();
      const { keyframes: t, items: c, effects: o } = e || {};
      return this.keyframes = t || this.keyframes, this.items = c || this.items, this.effects = o || this.effects, this.state.currentAnimation = null, this.state.currentAnimationRepeat = !1, this.state.playing = !0, new Promise((s) => {
        this.state.currentTime || this.init();
        let f = null;
        for (const u of this.items) {
          const h = this.digitalPlayground.getDigitalItem(u.model);
          if (h) {
            let a = null;
            const I = this.model.children[0].children.find((l) => l instanceof i.Bone), w = this.model.children[0].children.find((l) => l instanceof i.SkinnedMesh);
            if (!I || !w)
              throw new Error("模型骨骼缺失");
            if (this.model.children[0].children[2].traverse((l) => {
              l instanceof i.Bone && l.name === "RightHand" && (a = l);
            }), !a)
              throw new Error("没有找到绑定的骨骼");
            a.add(h);
            const F = new i.Vector3(), r = new i.Quaternion(), m = new i.Vector3();
            new i.Matrix4().fromArray(u.initialMatrix).decompose(F, r, m), h.position.copy(F), h.quaternion.copy(r), h.scale.copy(m), h.updateMatrixWorld(!0);
          }
        }
        const g = /* @__PURE__ */ new Map(), d = new i.TextureLoader();
        for (const u of this.effects)
          if (u.type === "frameSequence") {
            const h = u.keyframes;
            for (const a of h)
              d.load(a.image, (I) => {
                I.name = a.image, g.set(a.image, I);
              });
          }
        const A = (u) => {
          var w, F;
          f === null && (f = u);
          const h = u - f;
          f = u, this.state.currentTime += h;
          const a = this.keyframesManager.getStateByTime(this.state.currentTime, this.keyframes, "model");
          this.trace.addPoint(a.translation);
          const I = new i.BufferGeometry().setFromPoints(this.trace.tracePoints);
          if (this.curveLine.geometry = I, this.model.position.copy(a.translation), this.model.quaternion.copy(a.quaternion), this.model.scale.copy(a.scale), this.model.visible = a.visible, a.isFinal) {
            this.model.visible = !1, this.container.visible = !1, this.stopAnimation(), this.model.needsRender = !0, s(!0), this.animationFrameId !== null && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null);
            return;
          } else if (a.animation) {
            const r = this.digitalPlayground.getAnimation(a.animation.url), m = a.animation.needRender, y = a.animation.repeat !== this.state.currentAnimationRepeat;
            (r !== this.state.currentAnimation || y || m && !this.hasProcessedNeedRenderForTimestamp(a.keyframeIndex)) && (m && r === this.state.currentAnimation && this.markNeedRenderProcessedForTimestamp(a.keyframeIndex), this.state.currentAnimation = r, this.state.currentAnimationRepeat = a.animation.repeat, this.playAnimation({
              animation: r,
              repeat: a.animation.repeat,
              switchDuration: (w = a.animation.switchDuration) != null ? w : S
            })), this.mixer.update(h / 1e3), a.animation.isOver === !0 && (this.action.paused = !0, this.action.time = this.state.currentAnimation.duration, this.mixer.update(0));
          }
          this.updateKeyframeItems((F = a.animation) == null ? void 0 : F.item);
          for (const r of this.items) {
            const m = this.digitalPlayground.getDigitalItem(r.model);
            m && (this.keyframesManager.getStateByTime(this.state.currentTime, r.keyframes, "item").visible === !0 ? m.visible = !0 : m.visible = !1);
          }
          for (let r = 0; r < this.effects.length; r++) {
            const m = this.effects[r];
            if (m.type === "frameSequence") {
              const y = m.type + r;
              if (!this.effectObjects.has(y)) {
                const P = new i.PlaneGeometry(1, 1), R = new i.MeshBasicMaterial({
                  transparent: !0
                }), k = new i.Mesh(P, R);
                k.rotateX(-Math.PI / 2), k.position.copy(new i.Vector3().fromArray(m.position)), this.effectObjects.set(y, k), this.effectsGroup.add(k);
              }
              const l = this.effectObjects.get(y), v = this.keyframesManager.getStateByTime(this.state.currentTime, this.effects[r].keyframes, "effect"), M = g.get(v.image);
              l.material.map = M, l.visible = v.visible;
            }
          }
          this.model.needsRender = !0, this.animationFrameId = requestAnimationFrame(A);
        };
        this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null), this.animationFrameId = requestAnimationFrame(A);
      });
    });
  }
  // 用于分段时 更新轨迹
  traceUpDate() {
    this.trace.clear();
    for (let e = 0; e <= this.state.currentTime; e += 100) {
      const t = this.keyframesManager.getStateByTime(e, this.keyframes, "model");
      this.trace.addPoint(t.translation);
      const c = new i.BufferGeometry().setFromPoints(this.trace.tracePoints);
      this.curveLine.geometry = c;
    }
  }
  // 清楚轨迹
  clearTrace() {
    this.trace.clear();
    const e = new i.BufferGeometry().setFromPoints(this.trace.tracePoints);
    this.curveLine.geometry = e;
  }
  // 清理已处理的keyframeIndex记录（可选，在适当的时候调用）
  clearProcessedNeedRenderKeyframeIndices() {
    this.processedNeedRenderKeyframeIndices.clear();
  }
  // 检查指定keyframeIndex的needRender是否已经处理过
  hasProcessedNeedRenderForTimestamp(e) {
    return this.processedNeedRenderKeyframeIndices.has(e);
  }
  // 标记指定keyframeIndex的needRender已经处理过
  markNeedRenderProcessedForTimestamp(e) {
    this.processedNeedRenderKeyframeIndices.add(e);
  }
  // 获取并缓存 RightHand 骨骼
  getRightHandBone() {
    var e;
    return this.rightHandBone ? this.rightHandBone : ((e = this.model.children[0].children.find((t) => t instanceof i.Bone)) == null || e.traverse((t) => {
      t instanceof i.Bone && t.name === "RightHand" && (this.rightHandBone = t);
    }), this.rightHandBone);
  }
  // 根据当前帧的 items 动态绑定/解绑道具
  updateKeyframeItems(e) {
    var o;
    const t = (e == null ? void 0 : e.url) || null;
    for (const [s, f] of this.attachedItems)
      t !== s && ((o = f.parent) == null || o.remove(f), this.attachedItems.delete(s));
    if (!t)
      return;
    const c = this.getRightHandBone();
    if (c && !this.attachedItems.has(t)) {
      const s = this.digitalPlayground.getDigitalItem(t);
      s && (c.add(s), this.attachedItems.set(t, s));
    }
  }
  // 解绑所有 keyframe 道具
  detachAllKeyframeItems() {
    var e;
    for (const [, t] of this.attachedItems)
      (e = t.parent) == null || e.remove(t);
    this.attachedItems.clear();
  }
}
export {
  G as DigitalHuman
};
