AnimationClip.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * AnimationClip.cpp
  3. */
  4. #include "Base.h"
  5. #include "AnimationClip.h"
  6. #include "Animation.h"
  7. #include "AnimationTarget.h"
  8. #include "Game.h"
  9. namespace gameplay
  10. {
  11. AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long startTime, unsigned long endTime)
  12. : _id(id), _animation(animation), _startTime(startTime), _endTime(endTime), _elapsedTime(0), _runningTime(0),
  13. _channelCount(animation->_channels.size()), _repeatCount(1.0f), _speed(1.0f), _isPlaying(false), _beginListeners(NULL), _endListeners(NULL)
  14. {
  15. assert(0 <= startTime && startTime <= animation->_duration && 0 <= endTime && endTime <= animation->_duration);
  16. _duration = (_endTime - _startTime);
  17. _activeDuration = _duration * _repeatCount;
  18. for (unsigned int i = 0; i < _channelCount; i++)
  19. {
  20. _values.push_back(new AnimationValue(_animation->_channels[i]->_curve->getComponentCount()));
  21. }
  22. }
  23. AnimationClip::~AnimationClip()
  24. {
  25. // Explicitly stop this clip if it's currently playing so it gets removed from the controller
  26. if (_isPlaying)
  27. {
  28. stop();
  29. }
  30. std::vector<AnimationValue*>::iterator valueIter = _values.begin();
  31. while (valueIter != _values.end())
  32. {
  33. SAFE_DELETE(*valueIter);
  34. valueIter++;
  35. }
  36. SAFE_DELETE(_beginListeners);
  37. SAFE_DELETE(_endListeners);
  38. }
  39. const char* AnimationClip::getID() const
  40. {
  41. return _id.c_str();
  42. }
  43. Animation* AnimationClip::getAnimation() const
  44. {
  45. return _animation;
  46. }
  47. unsigned long AnimationClip::getStartTime() const
  48. {
  49. return _startTime;
  50. }
  51. unsigned long AnimationClip::getEndTime() const
  52. {
  53. return _endTime;
  54. }
  55. unsigned long AnimationClip::getElaspedTime() const
  56. {
  57. return _elapsedTime;
  58. }
  59. void AnimationClip::setRepeatCount(float repeatCount)
  60. {
  61. assert(repeatCount == REPEAT_INDEFINITE || repeatCount > 0.0f);
  62. _repeatCount = repeatCount;
  63. if (repeatCount == REPEAT_INDEFINITE)
  64. {
  65. _activeDuration = _duration;
  66. }
  67. else
  68. {
  69. _activeDuration = _repeatCount * _duration;
  70. }
  71. }
  72. float AnimationClip::getRepeatCount() const
  73. {
  74. return _repeatCount;
  75. }
  76. void AnimationClip::setActiveDuration(unsigned long duration)
  77. {
  78. if (duration == REPEAT_INDEFINITE)
  79. {
  80. _repeatCount = REPEAT_INDEFINITE;
  81. _activeDuration = _duration;
  82. }
  83. else
  84. {
  85. _activeDuration = _duration;
  86. _repeatCount = (float) _activeDuration / (float) _duration;
  87. }
  88. }
  89. unsigned long AnimationClip::getActiveDuration() const
  90. {
  91. if (_repeatCount == REPEAT_INDEFINITE)
  92. return REPEAT_INDEFINITE;
  93. return _activeDuration;
  94. }
  95. void AnimationClip::setSpeed(float speed)
  96. {
  97. _speed = speed;
  98. }
  99. float AnimationClip::getSpeed() const
  100. {
  101. return _speed;
  102. }
  103. bool AnimationClip::isPlaying() const
  104. {
  105. return _isPlaying;
  106. }
  107. void AnimationClip::play()
  108. {
  109. _animation->_controller->schedule(this);
  110. }
  111. void AnimationClip::stop()
  112. {
  113. _animation->_controller->unschedule(this);
  114. _isPlaying = false;
  115. }
  116. void AnimationClip::addBeginListener(AnimationClip::Listener* listener)
  117. {
  118. if (!_beginListeners)
  119. _beginListeners = new std::vector<Listener*>;
  120. _beginListeners->push_back(listener);
  121. }
  122. void AnimationClip::addEndListener(AnimationClip::Listener* listener)
  123. {
  124. if (!_endListeners)
  125. _endListeners = new std::vector<Listener*>;
  126. _endListeners->push_back(listener);
  127. }
  128. bool AnimationClip::update(unsigned long elapsedTime)
  129. {
  130. if (!_isPlaying)
  131. onBegin();
  132. // Update elapsed time.
  133. _elapsedTime += elapsedTime;
  134. _runningTime += elapsedTime * _speed;
  135. float percentComplete = 0.0f;
  136. // Check to see if clip is complete.
  137. if (_repeatCount != REPEAT_INDEFINITE && ((_speed >= 0 && _runningTime >= (long) _activeDuration) || (_speed < 0 && _runningTime <= 0)))
  138. {
  139. _isPlaying = false;
  140. if (_speed >= 0)
  141. percentComplete = _activeDuration % _duration; // Get's the fractional part of the final repeat.
  142. else
  143. percentComplete = 0.0f; // If we are negative speed, the end value should be 0.
  144. }
  145. else
  146. {
  147. // Gets portion/fraction of the repeat.
  148. percentComplete = (float) (_runningTime % _duration);
  149. }
  150. // Add back in start time, and divide by the total animation's duration to get the actual percentage complete
  151. percentComplete = (float)(_startTime + percentComplete) / (float) _animation->_duration;
  152. // Evaluate this clip.
  153. Animation::Channel* channel = NULL;
  154. AnimationValue* value = NULL;
  155. for (unsigned int i = 0; i < _channelCount; i++)
  156. {
  157. channel = _animation->_channels[i];
  158. value = _values.at(i);
  159. // Evaluate point on curve.
  160. channel->_curve->evaluate(percentComplete, value->_currentValue);
  161. // Set the animation value on the target property.
  162. channel->_target->setAnimationPropertyValue(channel->_propertyId, value);
  163. }
  164. // When ended. Probably should move to it's own method so we can call it when the clip is ended early.
  165. if (!_isPlaying)
  166. {
  167. onEnd();
  168. }
  169. return !_isPlaying;
  170. }
  171. void AnimationClip::onBegin()
  172. {
  173. // Initialize animation to play.
  174. _isPlaying = true;
  175. _elapsedTime = 0;
  176. if (_speed > 0)
  177. {
  178. _runningTime = 0;
  179. }
  180. else
  181. {
  182. _runningTime = _activeDuration;
  183. }
  184. if (_beginListeners)
  185. {
  186. std::vector<Listener*>::iterator listener = _beginListeners->begin();
  187. while (listener != _beginListeners->end())
  188. {
  189. (*listener)->animationEvent(this, Listener::BEGIN);
  190. listener++;
  191. }
  192. }
  193. }
  194. void AnimationClip::onEnd()
  195. {
  196. if (_endListeners)
  197. {
  198. std::vector<Listener*>::iterator listener = _endListeners->begin();
  199. while (listener != _endListeners->end())
  200. {
  201. (*listener)->animationEvent(this, Listener::END);
  202. listener++;
  203. }
  204. }
  205. }
  206. }