246 lines
4.8 KiB
C++
246 lines
4.8 KiB
C++
|
|
#include "animator.hpp"
|
|
#include "object.hpp"
|
|
#include "std.hpp"
|
|
|
|
Animator::Animator(Animator* t) : _seqs(t->_seqs)
|
|
{
|
|
_objs.resize(t->_objs.size());
|
|
_anims.resize(t->_anims.size());
|
|
|
|
for (int k = 0; k < t->_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<Object*>& 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 < t->_seqs.size(); ++n) {
|
|
_seqs.push_back(t->_seqs[n]);
|
|
for (int k = 0; k < _objs.size(); ++k) {
|
|
int j;
|
|
for (j = 0; j < t->_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();
|
|
}
|