| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- #include "Base.h"
- #include "Animation.h"
- #include "AnimationController.h"
- #include "AnimationClip.h"
- #include "AnimationTarget.h"
- #include "Game.h"
- #include "Transform.h"
- #include "Properties.h"
- #define ANIMATION_DEFAULT_CLIP_SUFFIX "__default__clip"
- #define ANIMATION_INDEFINITE_STR "INDEFINITE"
- #define ANIMATION_DEFAULT_CLIP 0
- #define ANIMATION_ROTATE_OFFSET 0
- #define ANIMATION_SRT_OFFSET 3
- namespace gameplay
- {
- Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, unsigned int type)
- : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0), _defaultClip(NULL), _clips(NULL)
- {
- createChannel(target, propertyId, keyCount, keyTimes, keyValues, type);
- }
- Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
- : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0), _defaultClip(NULL), _clips(NULL)
- {
- createChannel(target, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
- }
- Animation::~Animation()
- {
- if (_clips != NULL)
- {
- std::vector<AnimationClip*>::iterator clipIter = _clips->begin();
-
- while (clipIter != _clips->end())
- {
- AnimationClip* clip = *clipIter;
- clip->stop();
- SAFE_RELEASE(clip);
- clipIter++;
- }
- _clips->clear();
- }
- SAFE_DELETE(_clips);
- SAFE_DELETE(_defaultClip);
- /*vector<Channel*>::iterator channelIter = _channels.begin();
- while (channelIter != _channels.end())
- {
- Animation::Channel* channel = *channelIter;
- channel->_target->removeChannel(channel);
- SAFE_RELEASE(channel);
- channelIter++;
- }*/
- _channels.clear();
- }
- Animation::Channel::Channel(Animation* animation, AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration)
- : _animation(animation), _target(target), _propertyId(propertyId), _curve(curve), _duration(duration)
- {
- // get property component count, and ensure the property exists on the AnimationTarget by getting the property component count.
- assert(_target->getAnimationPropertyComponentCount(propertyId));
- _animation->addRef();
- _target->addChannel(this);
- }
- Animation::Channel::~Channel()
- {
- _animation->removeChannel(this);
- SAFE_RELEASE(_animation);
- SAFE_DELETE(_curve);
- }
- const char* Animation::getId() const
- {
- return _id.c_str();
- }
- unsigned long Animation::getDuration() const
- {
- return _duration;
- }
- void Animation::createClips(const char* animationFile)
- {
- assert(animationFile);
- Properties* pAnim = Properties::create(animationFile);
- assert(pAnim);
- Properties* animation = pAnim->getNextNamespace();
- int frameCount = animation->getInt("frameCount");
- const Properties* pClip = animation->getNextNamespace();
- while (pClip != NULL)
- {
- int begin = pClip->getInt("begin");
- int end = pClip->getInt("end");
- AnimationClip* clip = createClip(pClip->getId(), ((float) begin / frameCount) * _duration, ((float) end / frameCount) * _duration);
- const char* repeat = pClip->getString("repeatCount");
- if (repeat)
- {
- if (strcmp(repeat, ANIMATION_INDEFINITE_STR) == 0)
- {
- clip->setRepeatCount(AnimationClip::REPEAT_INDEFINITE);
- }
- else
- {
- float value;
- sscanf(repeat, "%f", &value);
- clip->setRepeatCount(value);
- }
- }
- const char* speed = pClip->getString("speed");
- if (speed)
- {
- float value;
- sscanf(speed, "%f", &value);
- clip->setSpeed(value);
- }
- pClip = animation->getNextNamespace();
- }
- SAFE_DELETE(pAnim);
- }
- AnimationClip* Animation::createClip(const char* id, unsigned long start, unsigned long end)
- {
- if (_clips != NULL && findClip(id) != NULL)
- {
- return NULL;
- }
-
- AnimationClip* clip = new AnimationClip(id, this, start, end);
- addClip(clip);
- return clip;
- }
- AnimationClip* Animation::getClip(const char* id)
- {
- // If id is NULL return the default clip.
- if (id == NULL)
- {
- if (_defaultClip == NULL)
- createDefaultClip();
- return _defaultClip;
- }
- else
- {
- return findClip(id);
- }
- }
- void Animation::play(const char* id)
- {
- // If id is NULL, play the default clip.
- if (id == NULL)
- {
- if (_defaultClip == NULL)
- createDefaultClip();
-
- _defaultClip->play();
- }
- else
- {
- // Find animation clip.. and play.
- AnimationClip* clip = findClip(id);
- if (clip != NULL)
- {
- clip->play();
- }
- }
- }
- void Animation::stop(const char* id)
- {
- // If id is NULL, play the default clip.
- if (id == NULL)
- {
- if (_defaultClip == NULL)
- createDefaultClip();
- _defaultClip->stop();
- }
- else
- {
- // Find animation clip.. and play.
- AnimationClip* clip = findClip(id);
- if (clip != NULL)
- {
- clip->stop();
- }
- }
- }
- Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, unsigned int type)
- {
- unsigned int propertyComponentCount = target->getAnimationPropertyComponentCount(propertyId);
- assert(propertyComponentCount > 0);
- Curve* curve = new Curve(keyCount, propertyComponentCount);
- if (target->_targetType == AnimationTarget::TRANSFORM)
- {
- switch (propertyId)
- {
- case Transform::ANIMATE_ROTATE:
- case Transform::ANIMATE_ROTATE_TRANSLATE:
- curve->addQuaternionOffset(ANIMATION_ROTATE_OFFSET);
- break;
- case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
- curve->addQuaternionOffset(ANIMATION_SRT_OFFSET);
- break;
- }
- }
- unsigned long lowest = keyTimes[0];
- unsigned long duration = keyTimes[keyCount-1] - lowest;
- float* normalizedKeyTimes = new float[keyCount];
- normalizedKeyTimes[0] = 0.0f;
- curve->setPoint(0, normalizedKeyTimes[0], keyValues, (Curve::InterpolationType) type);
- unsigned int pointOffset = propertyComponentCount;
- unsigned int i = 1;
- for (; i < keyCount - 1; i++)
- {
- normalizedKeyTimes[i] = (float) (keyTimes[i] - lowest) / (float) duration;
- curve->setPoint(i, normalizedKeyTimes[i], (keyValues + pointOffset), (Curve::InterpolationType) type);
- pointOffset += propertyComponentCount;
- }
- i = keyCount - 1;
- normalizedKeyTimes[i] = 1.0f;
- curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type);
- SAFE_DELETE(normalizedKeyTimes);
- Channel* channel = new Channel(this, target, propertyId, curve, duration);
- addChannel(channel);
- return channel;
- }
- Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned long* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
- {
- unsigned int propertyComponentCount = target->getAnimationPropertyComponentCount(propertyId);
- assert(propertyComponentCount > 0);
- Curve* curve = new Curve(keyCount, propertyComponentCount);
- if (target->_targetType == AnimationTarget::TRANSFORM)
- {
- switch (propertyId)
- {
- case Transform::ANIMATE_ROTATE:
- case Transform::ANIMATE_ROTATE_TRANSLATE:
- curve->addQuaternionOffset(ANIMATION_ROTATE_OFFSET);
- break;
- case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
- curve->addQuaternionOffset(ANIMATION_SRT_OFFSET);
- break;
- }
- }
-
- unsigned long lowest = keyTimes[0];
- unsigned long duration = keyTimes[keyCount-1] - lowest;
- float* normalizedKeyTimes = new float[keyCount];
-
- normalizedKeyTimes[0] = 0.0f;
- curve->setPoint(0, normalizedKeyTimes[0], keyValues, (Curve::InterpolationType) type, keyInValue, keyOutValue);
- unsigned int pointOffset = propertyComponentCount;
- unsigned int i = 1;
- for (; i < keyCount - 1; i++)
- {
- normalizedKeyTimes[i] = (float) (keyTimes[i] - lowest) / (float) duration;
- curve->setPoint(i, normalizedKeyTimes[i], (keyValues + pointOffset), (Curve::InterpolationType) type, (keyInValue + pointOffset), (keyOutValue + pointOffset));
- pointOffset += propertyComponentCount;
- }
- i = keyCount - 1;
- normalizedKeyTimes[i] = 1.0f;
- curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type, keyInValue + pointOffset, keyOutValue + pointOffset);
- SAFE_DELETE(normalizedKeyTimes);
- Channel* channel = new Channel(this, target, propertyId, curve, duration);
- addChannel(channel);
- return channel;
- }
- void Animation::addChannel(Channel* channel)
- {
- _channels.push_back(channel);
-
- if (channel->_duration > _duration)
- _duration = channel->_duration;
- }
- void Animation::removeChannel(Channel* channel)
- {
- std::vector<Animation::Channel*>::iterator itr = _channels.begin();
- while (itr != _channels.end())
- {
- Animation::Channel* chan = *itr;
- if (channel == chan)
- {
- _channels.erase(itr);
- itr = _channels.end();
- }
- else
- {
- itr++;
- }
- }
- if (_channels.empty())
- _controller->destroyAnimation(this);
- }
- void Animation::createDefaultClip()
- {
- std::string clipId = _id + ANIMATION_DEFAULT_CLIP_SUFFIX;
- _defaultClip = new AnimationClip(clipId.c_str(), this, 0.0f, _duration);
- }
- void Animation::addClip(AnimationClip* clip)
- {
- if (_clips == NULL)
- _clips = new std::vector<AnimationClip*>;
- _clips->push_back(clip);
- }
- AnimationClip* Animation::findClip(const char* id) const
- {
- if (_clips)
- {
- AnimationClip* clip = NULL;
- unsigned int clipCount = _clips->size();
- for (unsigned int i = 0; i < clipCount; i++)
- {
- clip = _clips->at(i);
- if (clip->_id.compare(id) == 0)
- {
- return _clips->at(i);
- }
- }
- }
- return NULL;
- }
- }
|