#include "std.h" #include "animator.h" #include "object.h" Animator::Animator( Animator *t ):_seqs( t->_seqs ){ _objs.resize( t->_objs.size() ); _anims.resize( t->_anims.size() ); for( int k=0;k_objs.size();++k ){ _objs[k]=t->_objs[k]->getLastCopy(); _anims[k].keys=t->_anims[k].keys; } reset(); } Animator::Animator( Object *obj,int frames ){ addObjs( obj ); _anims.resize( _objs.size() ); addSeq( frames ); reset(); } Animator::Animator( const vector &objs,int frames ):_objs(objs){ _anims.resize( _objs.size() ); addSeq( frames ); reset(); } void Animator::reset(){ _seq=_mode=_seq_len=_time=_speed=_trans_time=_trans_speed=0; } void Animator::addObjs( Object *obj ){ _objs.push_back( obj ); for( Entity *e=obj->GetChildren();e;e=e->GetSuccessor() ){ addObjs( e->getObject() ); } } void Animator::addSeq( int frames ){ Seq seq; seq.frames=frames; _seqs.push_back( seq ); for( int k=0;k<_objs.size();++k ){ Object *obj=_objs[k]; _anims[k].keys.push_back( obj->getAnimation() ); obj->setAnimation( Animation() ); } } void Animator::addSeqs( Animator *t ){ for( int n=0;n_seqs.size();++n ){ _seqs.push_back( t->_seqs[n] ); for( int k=0;k<_objs.size();++k ){ int j; for( j=0;j_objs.size();++j ){ if( _objs[k]->getName()==t->_objs[j]->getName() ) break; } if( j==t->_objs.size() ){ _anims[k].keys.push_back( Animation() ); continue; } _anims[k].keys.push_back( t->_anims[j].keys[n] ); } } } void Animator::extractSeq( int first,int last,int seq ){ Seq sq; sq.frames=last-first; _seqs.push_back( sq ); for( int k=0;k<_objs.size();++k ){ Animation &keys=_anims[k].keys[seq]; _anims[k].keys.push_back( Animation( keys,first,last ) ); } } void Animator::updateAnim(){ for( int k=0;k<_objs.size();++k ){ Object *obj=_objs[k]; const Animation &keys=_anims[k].keys[_seq]; if( keys.numPositionKeys() ){ obj->SetLocalPosition( keys.getPosition( _time ) ); } if( keys.numScaleKeys() ){ obj->SetLocalScale( keys.getScale( _time ) ); } if( keys.numRotationKeys() ){ obj->SetLocalRotation( keys.getRotation( _time ) ); } } } void Animator::updateTrans(){ for( int k=0;k<_objs.size();++k ){ Object *obj=_objs[k]; const Anim &anim=_anims[k]; if( anim.pos ) obj->SetLocalPosition( (anim.dest_pos-anim.src_pos)*_trans_time+anim.src_pos ); if( anim.scl ) obj->SetLocalScale( (anim.dest_scl-anim.src_scl)*_trans_time+anim.src_scl ); if( anim.rot ) obj->SetLocalRotation( anim.src_rot.slerpTo( anim.dest_rot,_trans_time ) ); } } void Animator::beginTrans(){ for( int k=0;k<_objs.size();++k ){ Object *obj=_objs[k]; Anim &anim=_anims[k]; const Animation &keys=_anims[k].keys[_seq]; if( anim.pos=!!keys.numPositionKeys() ){ anim.src_pos=obj->GetLocalPosition(); anim.dest_pos=keys.getPosition( _time ); } if( anim.scl=!!keys.numScaleKeys() ){ anim.src_scl=obj->GetLocalScale(); anim.dest_scl=keys.getScale( _time ); } if( anim.rot=!!keys.numRotationKeys() ){ anim.src_rot=obj->GetLocalRotation(); anim.dest_rot=keys.getRotation( _time ); } } } void Animator::setAnimTime( float time,int seq ){ if( seq<0 || seq>_seqs.size() ) return; _mode=0; _speed=0; _seq=seq; _seq_len=_seqs[_seq].frames; //Ok, mod the anim time! _time=fmod( time,_seq_len ); //if( time<0 || time>_seq_len ) time=fmod( time,_seq_len ); //_time=time; if( _time<0 ) _time+=+_seq_len; updateAnim(); } void Animator::animate( int mode,float speed,int seq,float trans ){ if( !mode && !speed ){ _mode=0;return; } if( seq<0 || seq>=_seqs.size() ) return; _seq=seq; _mode=mode; _seq_len=_seqs[_seq].frames; _speed=speed; _time=_speed>=0 ? 0 : _seq_len; if( trans<=0 ){ updateAnim(); if( !_speed ) _mode=0; return; } _mode|=0x8000; _trans_time=0; _trans_speed=1/trans; beginTrans(); } void Animator::update( float elapsed ){ if( !_mode ) return; if( _mode&0x8000 ){ _trans_time+=_trans_speed*elapsed; if( _trans_time<1 ){ updateTrans(); return; } _mode&=0x7fff; if( !_mode || !_speed ){ updateAnim(); _mode=0; return; } } //do anim... _time+=_speed*elapsed; switch( _mode ){ case ANIM_MODE_LOOP: _time=fmod( _time,_seq_len ); if( _time<0 ) _time+=_seq_len; break; case ANIM_MODE_PINGPONG: _time=fmod( _time,_seq_len*2 ); if( _time<0 ) _time+=_seq_len*2; if( _time>=_seq_len ){ _time=_seq_len-(_time-_seq_len);_speed=-_speed; } break; case ANIM_MODE_ONESHOT: if( _time<0 ){ _time=0;_mode=0; } else if( _time>=_seq_len ){ _time=_seq_len;_mode=0; } break; } updateAnim(); }