/* 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: ... */ #include "simple_animation.h" #include "stdincl.h" #include "p_node.h" #include "vector.h" using namespace std; /** \brief standard constructor \param the point of the object \param and the orientation of it \param at this time */ KeyFrame::KeyFrame(Vector* point, Quaternion* orientation, float time) { this->setRelCoor(point); this->setRelDir(orientation); this->time = time; } /** \brief standard constructor \param the point of the object \param and the orientation of it \param at this time \param function of the velocity of the movement */ KeyFrame::KeyFrame(Vector* point, Quaternion* orientation, float time, movementMode mode) { this->setRelCoor(point); this->setRelDir(orientation); this->time = time; this->mode = mode; } /** \brief standard deconstructor */ KeyFrame::~KeyFrame() { } /** \brief sets the important properties of a Keyframe \param the point of the object \param and the orientation of it \param at this time */ void KeyFrame::set(Vector* point, Quaternion* orientation, float time) { this->setRelCoor(point); this->setRelDir(orientation); this->time = time; } /** \brief sets the important properties of a Keyframe \param the point of the object \param and the orientation of it \param at this time \param function of the velocity of the movement */ void KeyFrame::set(Vector* point, Quaternion* orientation, float time, movementMode mode) { this->setRelCoor(point); this->setRelDir(orientation); this->time = time; this->mode = mode; } /** \brief standard constructor */ SimpleAnimation::SimpleAnimation (PNode* parent) { this->setClassName ("SimpleAnimation"); this->frames = new tList(); this->localTime = 0; this->bRunning = false; this->parent = parent; this->currentFrame = NULL; this->lastFrame = NULL; this->tmpVect = new Vector(); } /** \brief standard deconstructor */ SimpleAnimation::~SimpleAnimation () { tIterator* iterator = this->frames->getIterator(); KeyFrame* frame = iterator->nextElement(); while( frame != NULL) { delete frame; frame = iterator->nextElement(); } delete iterator; delete this->frames; } /** \brief adds a keyframe with properties \param the point of the object \param and the orientation of it \param at this time */ void SimpleAnimation::addKeyFrame(Vector* point, Quaternion* orientation, float time) { KeyFrame* frame = new KeyFrame(point, orientation, time); this->frames->add(frame); } /** \brief adds a keyframe with properties \param the point of the object \param and the orientation of it \param at this time \param function of the velocity of the movement */ void SimpleAnimation::addKeyFrame(Vector* point, Quaternion* orientation, float time, movementMode mode) { KeyFrame* frame = new KeyFrame(point, orientation, time, mode); this->frames->add(frame); } /** \brief adds a already defined keyframe \param the keyframe to add */ void SimpleAnimation::addKeyFrame(KeyFrame* frame) { if( frame != NULL) this->frames->add(frame); } /** \brief clear the list of keyframes, deleting all keyframes included */ void SimpleAnimation::reset() { tIterator* iterator = this->frames->getIterator(); KeyFrame* frame = iterator->nextElement(); while( frame != NULL) { delete frame; frame = iterator->nextElement(); } delete iterator; delete this->frames; this->frames = new tList(); this->localTime = 0; this->bRunning = false; this->currentFrame = NULL; this->lastFrame = NULL; } /** \brief starts the animation, therefore listens to tick signals */ void SimpleAnimation::start() { if( this->bRunning) { PRINTF(2)("SimpleAnimatin is already running. You are trying to start it again.\n"); return; } this->localTime = 0; this->lastFrame = this->frames->firstElement(); this->currentFrame = this->frames->nextElement(this->currentFrame); this->bRunning = true; } /** \brief stops the animation, immune to tick signals */ void SimpleAnimation::stop() { this->bRunning = false; } /** \brief stops and then starts the animation from begining */ void SimpleAnimation::restart() { this->localTime = 0; this->lastFrame = this->frames->firstElement(); this->currentFrame = this->frames->nextElement(this->currentFrame); this->bRunning = true; } /** \brief pauses the animation until resumed */ void SimpleAnimation::pause() { this->bRunning = false; } /** \brief resumes a pause, if not paused, no effect */ void SimpleAnimation::resume() { this->bRunning = true; } /** \brief heart beat, next animation step */ void SimpleAnimation::tick(float time) { if( !this->bRunning) return; this->localTime += time; /* first get the current frame via time-stamps */ while( this->localTime > this->currentFrame->time) { printf("SimpleAnimation::tick(...) - changing Frame"); this->lastFrame = this->currentFrame; this->currentFrame = this->frames->nextElement(this->currentFrame); this->localTime -= this->currentFrame->time; } /* now animate it */ switch( this->mode) { case LINEAR: *this->tmpVect = this->currentFrame->getAbsCoor() - this->lastFrame->getAbsCoor(); *this->tmpVect = *this->tmpVect * this->localTime / this->currentFrame->time; //this->setAbsCoordinate(this->tmpVect); break; case EXP: break; case NEG_EXP: *this->tmpVect = this->currentFrame->getAbsCoor() - this->lastFrame->getAbsCoor(); *this->tmpVect = *this->tmpVect * (1 - exp(- this->localTime / this->currentFrame->time)); break; case SIN: *this->tmpVect = this->currentFrame->getAbsCoor() - this->lastFrame->getAbsCoor(); *this->tmpVect = *this->tmpVect * (1 - cos(- this->localTime / this->currentFrame->time)); break; case COS: break; case QUADRATIC: *this->tmpVect = this->currentFrame->getAbsCoor() - this->lastFrame->getAbsCoor(); *this->tmpVect = *this->tmpVect * 1/3 * ldexpf(this->localTime, 3); break; default: break; } }