/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Patrick Boenzli co-programmer: Benjamin Grauer 2005-04-17: Benjamin Grauer Rewritte all functions, so it will fit into the Animation-class */ #include "animation3d.h" #include "stdincl.h" #include "vector.h" #include "p_node.h" using namespace std; Animation3D::Animation3D(PNode* object) { this->object = object; // create a new List this->keyFrameList = new tList(); KeyFrame3D* tmpKeyFrame = new KeyFrame3D; tmpKeyFrame->position = Vector(); tmpKeyFrame->direction = Quaternion(); keyFrameList->add(tmpKeyFrame); this->currentKeyFrame = tmpKeyFrame; this->nextKeyFrame = tmpKeyFrame; this->animFunc = &Animation3D::linear; } Animation3D::~Animation3D(void) { // delete all the KeyFrames tIterator* itKF = keyFrameList->getIterator(); KeyFrame3D* enumKF = itKF->nextElement(); while (enumKF) { delete enumKF; enumKF = itKF->nextElement(); } delete itKF; delete this->keyFrameList; } void Animation3D::rewind(void) { this->currentKeyFrame = keyFrameList->firstElement(); this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement()); this->localTime = 0.0; } void Animation3D::addKeyFrame(Vector position, Quaternion direction, float duration = 1.0, ANIM_FUNCTION animFunc) { // some small check if (duration <= 0.0) duration = 1.0; KeyFrame3D* tmpKeyFrame; if (bHasKeys) { tmpKeyFrame = new KeyFrame3D; if (this->currentKeyFrame == this->nextKeyFrame) this->nextKeyFrame = tmpKeyFrame; this->keyFrameList->add(tmpKeyFrame); } else { tmpKeyFrame = this->keyFrameList->firstElement(); bHasKeys = true; this->setAnimFunc(animFunc); } tmpKeyFrame->position = position; tmpKeyFrame->direction = direction; tmpKeyFrame->duration = duration; tmpKeyFrame->animFunc = animFunc; } void Animation3D::tick(float dt) { if (this->bRunning) { this->localTime += dt; if (localTime >= this->currentKeyFrame->duration) { // switching to the next Key-Frame this->localTime -= this->currentKeyFrame->duration; this->currentKeyFrame = this->nextKeyFrame; // checking, if we should still Play the animation if (this->currentKeyFrame == this->keyFrameList->lastElement()) { switch (this->postInfinity) { case ANIM_INF_CONSTANT: this->localTime = 0.0; this->bRunning = false; break; case ANIM_INF_REWIND: break; } } this->nextKeyFrame = this->keyFrameList->nextElement(this->nextKeyFrame); this->setAnimFunc(this->currentKeyFrame->animFunc); if( this->currentKeyFrame->animFunc == ANIM_NEG_EXP) { this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position; this->deltaT = 1/this->currentKeyFrame->duration * logf(1.0 + 600.0/this->tmpVect.len()); } } /* now animate it */ (this->*animFunc)(this->localTime); /* switch( this->movMode) { case LINEAR: *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position; *this->tmpVect = *this->tmpVect * this->localTime / this->currentFrame->time; this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect); *this->lastPosition = *this->tmpVect; break; case EXP: break; case NEG_EXP: *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position; *this->tmpVect = *this->tmpVect * (1 - expf(- this->localTime * this->deltaT)); this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect); *this->lastPosition = *this->tmpVect; break; case SIN: *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position; *this->tmpVect = *this->tmpVect * 0.5*(1 - cos(M_PI * this->localTime / this->currentFrame->time)); this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect); *this->lastPosition = *this->tmpVect; break; case COS: break; case QUADRATIC: *this->tmpVect = *this->currentFrame->position - *this->lastFrame->position; *this->tmpVect = *this->tmpVect * 1/3 * ldexpf(this->localTime, 3); break; default: break; } */ } } void Animation3D::setAnimFunc(ANIM_FUNCTION animFunc) { switch (animFunc) { default: case ANIM_CONSTANT: this->animFunc = &Animation3D::constant; break; case ANIM_LINEAR: this->animFunc = &Animation3D::linear; break; case ANIM_SINE: this->animFunc = &Animation3D::sine; break; case ANIM_COSINE: this->animFunc = &Animation3D::cosine; break; case ANIM_EXP: this->animFunc = &Animation3D::exp; break; case ANIM_NEG_EXP: this->animFunc = &Animation3D::negExp; break; case ANIM_QUADRATIC: this->animFunc = &Animation3D::quadratic; break; case ANIM_RANDOM: this->animFunc = &Animation3D::random; break; } } void Animation3D::constant(float timePassed) const { this->object->setRelCoor(this->currentKeyFrame->position); /* this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position; this->tmpVect = this->tmpVect * this->localTime / this->currentKeyFrame->duration; this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect); this->lastPosition = this->tmpVect; */ } void Animation3D::linear(float timePassed) const { this->object->setRelCoor(this->currentKeyFrame->position + (this->nextKeyFrame->position - this->currentKeyFrame->position) * (timePassed/this->currentKeyFrame->duration)); } void Animation3D::sine(float timePassed) const { } void Animation3D::cosine(float timePassed) const { } void Animation3D::exp(float timePassed) const { } void Animation3D::negExp(float timePassed) const { } void Animation3D::quadratic(float timePassed) const { } void Animation3D::random(float timePassed) const { }