UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 7.47 kB
import{AnimClip as t}from"../../anim/evaluator/anim-clip.js";import{AnimEvaluator as i}from"../../anim/evaluator/anim-evaluator.js";import{AnimTrack as s}from"../../anim/evaluator/anim-track.js";import{DefaultAnimBinder as e}from"../../anim/binder/default-anim-binder.js";import{Skeleton as n}from"../../../scene/animation/skeleton.js";import{Asset as o}from"../../asset/asset.js";import{Component as a}from"../component.js";class h extends a{constructor(t,i){super(t,i),this._animations={},this._assets=[],this._loop=!0,this.animEvaluator=null,this.model=null,this.skeleton=null,this.fromSkel=null,this.toSkel=null,this.animationsIndex={},this.prevAnim=null,this.currAnim=null,this.blend=0,this.blending=!1,this.blendSpeed=0,this.activate=!0,this.speed=1}set animations(t){this._animations=t,this.onSetAnimations()}get animations(){return this._animations}set assets(t){const i=this._assets;if(i&&i.length)for(let t=0;t<i.length;t++)if(i[t]){const s=this.system.app.assets.get(i[t]);if(s){s.off("change",this.onAssetChanged,this),s.off("remove",this.onAssetRemoved,this);const t=this.animationsIndex[s.id];this.currAnim===t&&this._stopCurrentAnimation(),delete this.animations[t],delete this.animationsIndex[s.id]}}this._assets=t;const s=t.map((t=>t instanceof o?t.id:t));this.loadAnimationAssets(s)}get assets(){return this._assets}set currentTime(t){if(this.skeleton&&(this.skeleton.currentTime=t,this.skeleton.addTime(0),this.skeleton.updateGraph()),this.animEvaluator){const i=this.animEvaluator.clips;for(let s=0;s<i.length;++s)i[s].time=t}}get currentTime(){if(this.skeleton)return this.skeleton._time;if(this.animEvaluator){const t=this.animEvaluator.clips;if(t.length>0)return t[t.length-1].time}return 0}get duration(){return this.currAnim?this.animations[this.currAnim].duration:0}set loop(t){if(this._loop=t,this.skeleton&&(this.skeleton.looping=t),this.animEvaluator)for(let i=0;i<this.animEvaluator.clips.length;++i)this.animEvaluator.clips[i].loop=t}get loop(){return this._loop}play(i,s=0){if(this.enabled&&this.entity.enabled&&this.animations[i]){if(this.prevAnim=this.currAnim,this.currAnim=i,this.model){this.skeleton||this.animEvaluator||this._createAnimationController();const i=this.animations[this.prevAnim],e=this.animations[this.currAnim];if(this.blending=s>0&&!!this.prevAnim,this.blending&&(this.blend=0,this.blendSpeed=1/s),this.skeleton&&(this.blending?(this.fromSkel.animation=i,this.fromSkel.addTime(this.skeleton._time),this.toSkel.animation=e):this.skeleton.animation=e),this.animEvaluator){const i=this.animEvaluator;if(this.blending)for(;i.clips.length>1;)i.removeClip(0);else this.animEvaluator.removeClips();const s=new t(this.animations[this.currAnim],0,1,!0,this.loop);s.name=this.currAnim,s.blendWeight=this.blending?0:1,s.reset(),this.animEvaluator.addClip(s)}}this.playing=!0}}getAnimation(t){return this.animations[t]}setModel(t){t!==this.model&&(this._resetAnimationController(),this.model=t,this.animations&&this.currAnim&&this.animations[this.currAnim]&&this.play(this.currAnim))}onSetAnimations(){const t=this.entity.model;if(t){const i=t.model;i&&i!==this.model&&this.setModel(i)}if(!this.currAnim&&this.activate&&this.enabled&&this.entity.enabled){const t=Object.keys(this._animations);t.length>0&&this.play(t[0])}}_resetAnimationController(){this.skeleton=null,this.fromSkel=null,this.toSkel=null,this.animEvaluator=null}_createAnimationController(){const t=this.model,o=this.animations;let a=!1,h=!1;for(const t in o)if(o.hasOwnProperty(t)){o[t].constructor===s?h=!0:a=!0}const l=t.getGraph();a?(this.fromSkel=new n(l),this.toSkel=new n(l),this.skeleton=new n(l),this.skeleton.looping=this.loop,this.skeleton.setGraph(l)):h&&(this.animEvaluator=new i(new e(this.entity)))}loadAnimationAssets(t){if(!t||!t.length)return;const i=this.system.app.assets,s=t=>{if(t.resources.length>1)for(let i=0;i<t.resources.length;i++)this.animations[t.resources[i].name]=t.resources[i],this.animationsIndex[t.id]=t.resources[i].name;else this.animations[t.name]=t.resource,this.animationsIndex[t.id]=t.name;this.animations=this.animations},e=t=>{t.off("change",this.onAssetChanged,this),t.on("change",this.onAssetChanged,this),t.off("remove",this.onAssetRemoved,this),t.on("remove",this.onAssetRemoved,this),t.resource?s(t):(t.once("load",s,this),this.enabled&&this.entity.enabled&&i.load(t))};for(let s=0,n=t.length;s<n;s++){const n=i.get(t[s]);n?e(n):i.on(`add:${t[s]}`,e)}}onAssetChanged(t,i,s,e){if("resource"===i||"resources"===i)if("resources"===i&&s&&0===s.length&&(s=null),s){let i=!1;if(s.length>1){if(e&&e.length>1)for(let t=0;t<e.length;t++)delete this.animations[e[t].name];else delete this.animations[t.name];i=!1;for(let t=0;t<s.length;t++)this.animations[s[t].name]=s[t],i||this.currAnim!==s[t].name||this.playing&&this.enabled&&this.entity.enabled&&(i=!0,this.play(s[t].name));i||(this._stopCurrentAnimation(),this.onSetAnimations())}else{if(e&&e.length>1)for(let t=0;t<e.length;t++)delete this.animations[e[t].name];this.animations[t.name]=s[0]||s,i=!1,this.currAnim===t.name&&this.playing&&this.enabled&&this.entity.enabled&&(i=!0,this.play(t.name)),i||(this._stopCurrentAnimation(),this.onSetAnimations())}this.animationsIndex[t.id]=t.name}else{if(e.length>1)for(let t=0;t<e.length;t++)delete this.animations[e[t].name],this.currAnim===e[t].name&&this._stopCurrentAnimation();else delete this.animations[t.name],this.currAnim===t.name&&this._stopCurrentAnimation();delete this.animationsIndex[t.id]}}onAssetRemoved(t){if(t.off("remove",this.onAssetRemoved,this),this.animations){if(t.resources.length>1)for(let i=0;i<t.resources.length;i++)delete this.animations[t.resources[i].name],this.currAnim===t.resources[i].name&&this._stopCurrentAnimation();else delete this.animations[t.name],this.currAnim===t.name&&this._stopCurrentAnimation();delete this.animationsIndex[t.id]}}_stopCurrentAnimation(){if(this.currAnim=null,this.playing=!1,this.skeleton&&(this.skeleton.currentTime=0,this.skeleton.animation=null),this.animEvaluator){for(let t=0;t<this.animEvaluator.clips.length;++t)this.animEvaluator.clips[t].stop();this.animEvaluator.update(0),this.animEvaluator.removeClips()}}onEnable(){super.onEnable();const t=this.assets,i=this.system.app.assets;if(t)for(let s=0,e=t.length;s<e;s++){let e=t[s];e instanceof o||(e=i.get(e)),e&&!e.resource&&i.load(e)}if(this.activate&&!this.currAnim){const t=Object.keys(this.animations);t.length>0&&this.play(t[0])}}onBeforeRemove(){for(let t=0;t<this.assets.length;t++){let i=this.assets[t];"number"==typeof i&&(i=this.system.app.assets.get(i)),i&&(i.off("change",this.onAssetChanged,this),i.off("remove",this.onAssetRemoved,this))}this.skeleton=null,this.fromSkel=null,this.toSkel=null,this.animEvaluator=null}update(t){if(this.blending&&(this.blend+=t*this.blendSpeed,this.blend>=1&&(this.blend=1)),this.playing){const i=this.skeleton;if(null!==i&&null!==this.model){if(this.blending)i.blend(this.fromSkel,this.toSkel,this.blend);else{const s=t*this.speed;i.addTime(s),(this.speed>0&&i._time===i.animation.duration&&!this.loop||this.speed<0&&0===i._time&&!this.loop)&&(this.playing=!1)}this.blending&&1===this.blend&&(i.animation=this.toSkel.animation),i.updateGraph()}}const i=this.animEvaluator;if(i){for(let t=0;t<i.clips.length;++t){const s=i.clips[t];s.speed=this.speed,this.playing?s.resume():s.pause()}this.blending&&i.clips.length>1&&(i.clips[1].blendWeight=this.blend),i.update(t)}this.blending&&1===this.blend&&(this.blending=!1)}}export{h as AnimationComponent};