import { EventEmitter } from '@feng3d/event'; import { AnimationAction, AnimationBlendMode, AnimationMixer } from '../../thirdparty/three/imports'; import { Node3D } from '../core/Node3D'; import { AnimationAction3D } from './AnimationAction3D'; import { AnimationClip3D } from './AnimationClip3D'; export interface AnimationMixer3DEventMap { loop: { action: AnimationAction3D, loopDelta: number } finished: { action: AnimationAction3D, loopDelta: number } } export class AnimationMixer3D extends EventEmitter { _animationMixer: AnimationMixer; model: Node3D; get timeScale() { return this._animationMixer.timeScale; } set timeScale(v) { this._animationMixer.timeScale = v; } constructor(model: Node3D) { super(); this.model = model; this._animationMixer = new AnimationMixer(this.model._group); this._animationMixer.addEventListener('loop', this._onLoop); this._animationMixer.addEventListener('finished', this._onFinished); } destory() { this._animationMixer.removeEventListener('loop', this._onLoop); this._animationMixer.removeEventListener('finished', this._onFinished); this._animationMixer = null; this.model = null; } clipAction(clip: AnimationClip3D, root?: Node3D, blendMode?: AnimationBlendMode) { const action = this._animationMixer.clipAction(clip._animationClip, root?._group, blendMode); const animationAction = AnimationAction3D.get(action); return animationAction; } update(deltaTime: number) { this._animationMixer.update(deltaTime); } private _onLoop = (event: { type: 'loop', target: AnimationMixer, action?: AnimationAction, loopDelta?: number }) => { this.emit(event.type, { action: AnimationAction3D.get(event.action), loopDelta: event.loopDelta }); }; private _onFinished = (event: { type: 'finished', target: AnimationMixer, action?: AnimationAction, loopDelta?: number }) => { this.emit(event.type, { action: AnimationAction3D.get(event.action), loopDelta: event.loopDelta }); }; }