AnimationClip.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. #include "Base.h"
  2. #include "AnimationClip.h"
  3. #include "Animation.h"
  4. #include "AnimationTarget.h"
  5. #include "Game.h"
  6. #include "Quaternion.h"
  7. namespace gameplay
  8. {
  9. AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long startTime, unsigned long endTime)
  10. : _id(id), _animation(animation), _startTime(startTime), _endTime(endTime), _duration(_endTime - _startTime), _repeatCount(1.0f),
  11. _activeDuration(_duration * _repeatCount), _speed(1.0f), _isPlaying(false), _timeStarted(0), _elapsedTime(0), _runningTime(0),
  12. _crossFadeToClip(NULL), _crossFadeStart(0), _crossFadeOutElapsed(0), _crossFadeOutDuration(0), _blendWeight(1.0f),
  13. _isFadingOutStarted(false), _isFadingOut(false), _isFadingIn(false), _beginListeners(NULL), _endListeners(NULL)
  14. {
  15. assert(0 <= startTime && startTime <= animation->_duration && 0 <= endTime && endTime <= animation->_duration);
  16. unsigned int channelCount = _animation->_channels.size();
  17. for (unsigned int i = 0; i < channelCount; i++)
  18. {
  19. _values.push_back(new AnimationValue(_animation->_channels[i]->_curve->getComponentCount()));
  20. }
  21. }
  22. AnimationClip::~AnimationClip()
  23. {
  24. std::vector<AnimationValue*>::iterator valueIter = _values.begin();
  25. while (valueIter != _values.end())
  26. {
  27. SAFE_DELETE(*valueIter);
  28. valueIter++;
  29. }
  30. _values.clear();
  31. SAFE_RELEASE(_crossFadeToClip);
  32. SAFE_DELETE(_beginListeners);
  33. SAFE_DELETE(_endListeners);
  34. }
  35. const char* AnimationClip::getID() const
  36. {
  37. return _id.c_str();
  38. }
  39. Animation* AnimationClip::getAnimation() const
  40. {
  41. return _animation;
  42. }
  43. unsigned long AnimationClip::getStartTime() const
  44. {
  45. return _startTime;
  46. }
  47. unsigned long AnimationClip::getEndTime() const
  48. {
  49. return _endTime;
  50. }
  51. unsigned long AnimationClip::getElaspedTime() const
  52. {
  53. return _elapsedTime;
  54. }
  55. void AnimationClip::setRepeatCount(float repeatCount)
  56. {
  57. assert(repeatCount == REPEAT_INDEFINITE || repeatCount > 0.0f);
  58. _repeatCount = repeatCount;
  59. if (repeatCount == REPEAT_INDEFINITE)
  60. {
  61. _activeDuration = _duration;
  62. }
  63. else
  64. {
  65. _activeDuration = _repeatCount * _duration;
  66. }
  67. }
  68. float AnimationClip::getRepeatCount() const
  69. {
  70. return _repeatCount;
  71. }
  72. void AnimationClip::setActiveDuration(unsigned long duration)
  73. {
  74. if (duration == REPEAT_INDEFINITE)
  75. {
  76. _repeatCount = REPEAT_INDEFINITE;
  77. _activeDuration = _duration;
  78. }
  79. else
  80. {
  81. _activeDuration = _duration;
  82. _repeatCount = (float) _activeDuration / (float) _duration;
  83. }
  84. }
  85. unsigned long AnimationClip::getActiveDuration() const
  86. {
  87. if (_repeatCount == REPEAT_INDEFINITE)
  88. return REPEAT_INDEFINITE;
  89. return _activeDuration;
  90. }
  91. void AnimationClip::setSpeed(float speed)
  92. {
  93. _speed = speed;
  94. }
  95. float AnimationClip::getSpeed() const
  96. {
  97. return _speed;
  98. }
  99. void AnimationClip::setBlendWeight(float blendWeight)
  100. {
  101. _blendWeight = blendWeight;
  102. }
  103. float AnimationClip::getBlendWeight() const
  104. {
  105. return _blendWeight;
  106. }
  107. bool AnimationClip::isPlaying() const
  108. {
  109. return _isPlaying;
  110. }
  111. void AnimationClip::play()
  112. {
  113. _animation->_controller->schedule(this);
  114. _timeStarted = Game::getGameTime();
  115. }
  116. void AnimationClip::stop()
  117. {
  118. _animation->_controller->unschedule(this);
  119. if (_isPlaying)
  120. {
  121. _isPlaying = false;
  122. onEnd();
  123. }
  124. }
  125. void AnimationClip::crossFade(AnimationClip* clip, unsigned long duration)
  126. {
  127. assert(clip);
  128. if (clip->_isPlaying && clip->_isFadingOut)
  129. {
  130. clip->_isFadingOut = false;
  131. clip->_crossFadeToClip->_isFadingIn = false;
  132. SAFE_RELEASE(clip->_crossFadeToClip);
  133. }
  134. // If I already have a clip I'm fading too.. release it.
  135. if (_crossFadeToClip)
  136. SAFE_RELEASE(_crossFadeToClip);
  137. // Assign the clip we're fading to, and increase its ref count.
  138. _crossFadeToClip = clip;
  139. _crossFadeToClip->addRef();
  140. // Set the fade in clip to fading in, and set the duration of the fade in.
  141. _crossFadeToClip->_isFadingIn = true;
  142. // Set this clip to fade out, and reset the elapsed time for the fade out.
  143. _isFadingOut = true;
  144. _crossFadeOutElapsed = 0;
  145. _crossFadeOutDuration = duration;
  146. _crossFadeStart = (Game::getGameTime() - _timeStarted);
  147. _isFadingOutStarted = true;
  148. if (!_isPlaying)
  149. play();
  150. _crossFadeToClip->play();
  151. }
  152. void AnimationClip::addBeginListener(AnimationClip::Listener* listener)
  153. {
  154. if (!_beginListeners)
  155. _beginListeners = new std::vector<Listener*>;
  156. _beginListeners->push_back(listener);
  157. }
  158. void AnimationClip::addEndListener(AnimationClip::Listener* listener)
  159. {
  160. if (!_endListeners)
  161. _endListeners = new std::vector<Listener*>;
  162. _endListeners->push_back(listener);
  163. }
  164. bool AnimationClip::update(unsigned long elapsedTime)
  165. {
  166. float speed = _speed;
  167. if (!_isPlaying)
  168. {
  169. onBegin();
  170. _elapsedTime = Game::getGameTime() - _timeStarted;
  171. _runningTime = _elapsedTime * speed;
  172. }
  173. else
  174. {
  175. // Update elapsed time.
  176. _elapsedTime += elapsedTime;
  177. _runningTime += elapsedTime * speed;
  178. }
  179. float percentComplete = 0.0f;
  180. // Check to see if clip is complete.
  181. if (_repeatCount != REPEAT_INDEFINITE && ((_speed >= 0 && _runningTime >= (long) _activeDuration) || (_speed < 0 && _runningTime <= 0)))
  182. {
  183. _isPlaying = false;
  184. if (_speed >= 0)
  185. {
  186. percentComplete = _activeDuration % _duration; // Get's the fractional part of the final repeat.
  187. if (percentComplete == 0.0f)
  188. percentComplete = _duration;
  189. }
  190. else
  191. {
  192. percentComplete = 0.0f; // If we are negative speed, the end value should be 0.
  193. }
  194. }
  195. else
  196. {
  197. // Gets portion/fraction of the repeat.
  198. percentComplete = (float) (_runningTime % _duration);
  199. }
  200. // Add back in start time, and divide by the total animation's duration to get the actual percentage complete
  201. percentComplete = (float)(_startTime + percentComplete) / (float) _animation->_duration;
  202. if (_isFadingOut)
  203. {
  204. if (_isFadingOutStarted) // Calculate elapsed time since the fade out begin.
  205. {
  206. _crossFadeOutElapsed = (_elapsedTime - _crossFadeStart) * speed;
  207. _isFadingOutStarted = false;
  208. }
  209. else
  210. {
  211. // continue tracking elapsed time.
  212. _crossFadeOutElapsed += elapsedTime * speed;
  213. }
  214. if (_crossFadeOutElapsed < _crossFadeOutDuration)
  215. {
  216. float tempBlendWeight = (float) (_crossFadeOutDuration - _crossFadeOutElapsed) / (float) _crossFadeOutDuration;
  217. _crossFadeToClip->_blendWeight = (1.0f - tempBlendWeight);
  218. // adjust the clip your blending to's weight to be a percentage of your current blend weight
  219. if (_isFadingIn)
  220. {
  221. _crossFadeToClip->_blendWeight *= _blendWeight;
  222. _blendWeight -= _crossFadeToClip->_blendWeight;
  223. }
  224. else
  225. {
  226. _blendWeight = tempBlendWeight;
  227. }
  228. }
  229. else
  230. { // Fade done.
  231. _crossFadeToClip->_blendWeight = 1.0f;
  232. if (_isFadingIn)
  233. _crossFadeToClip->_blendWeight *= _blendWeight;
  234. _crossFadeToClip->_isFadingIn = false;
  235. SAFE_RELEASE(_crossFadeToClip);
  236. _blendWeight = 0.0f;
  237. _isFadingOut = false;
  238. _isPlaying = false;
  239. }
  240. }
  241. // Evaluate this clip.
  242. Animation::Channel* channel = NULL;
  243. AnimationValue* value = NULL;
  244. AnimationTarget* target = NULL;
  245. unsigned int channelCount = _animation->_channels.size();
  246. for (unsigned int i = 0; i < channelCount; i++)
  247. {
  248. channel = _animation->_channels[i];
  249. target = channel->_target;
  250. value = _values[i];
  251. // Get the current value.
  252. target->getAnimationPropertyValue(channel->_propertyId, value);
  253. bool isHighest = false;
  254. // My channel priority has changed if my priority is greater than the active animation count.
  255. if (!target->_highestPriority)
  256. {
  257. target->_highestPriority = channel;
  258. value->_isFirstActing = true;
  259. }
  260. if (_blendWeight != 0.0f)
  261. {
  262. // Evaluate point on Curve.
  263. channel->_curve->evaluate(percentComplete, value->_interpolatedValue);
  264. if (!channel->_curve->_quaternionOffset)
  265. {
  266. if (value->_isFirstActing)
  267. {
  268. unsigned int componentCount = value->_componentCount;
  269. for (unsigned int j = 0; j < componentCount; j++)
  270. {
  271. if (_blendWeight != 1.0f)
  272. value->_interpolatedValue[j] *= _blendWeight;
  273. value->_currentValue[j] = value->_interpolatedValue[j];
  274. }
  275. }
  276. else
  277. {
  278. unsigned int componentCount = value->_componentCount;
  279. for (unsigned int j = 0; j < componentCount; j++)
  280. {
  281. if (_blendWeight != 1.0f)
  282. value->_interpolatedValue[j] *= _blendWeight;
  283. value->_currentValue[j] += value->_interpolatedValue[j];
  284. }
  285. }
  286. }
  287. else
  288. { //We have Quaternions!!!
  289. unsigned int quaternionOffset = *(channel->_curve->_quaternionOffset);
  290. if (value->_isFirstActing)
  291. {
  292. unsigned int j = 0;
  293. for (; j < quaternionOffset; j++)
  294. {
  295. if (_blendWeight != 1.0f)
  296. value->_interpolatedValue[j] *= _blendWeight;
  297. value->_currentValue[j] = value->_interpolatedValue[j];
  298. }
  299. // We are at the index for a quaternion component. Handle the next for components as a whole quaternion.
  300. Quaternion* interpolatedQuaternion = (Quaternion*) (value->_interpolatedValue + j);
  301. Quaternion* currentQuaternion = (Quaternion*) (value->_currentValue + j);
  302. // If we have a blend weight, we apply it by slerping from the identity to our interpolated value at the given weight.
  303. if (_blendWeight != 1.0f)
  304. Quaternion::slerp(Quaternion::identity(), *interpolatedQuaternion, _blendWeight, interpolatedQuaternion);
  305. // Add in contribution.
  306. currentQuaternion->set(*interpolatedQuaternion);
  307. unsigned int componentCount = value->_componentCount;
  308. for (j += 4; j < componentCount; j++)
  309. {
  310. if (_blendWeight != 1.0f)
  311. value->_interpolatedValue[j] *= _blendWeight;
  312. value->_currentValue[j] = value->_interpolatedValue[j];
  313. }
  314. }
  315. else
  316. {
  317. unsigned int j = 0;
  318. for (; j < quaternionOffset; j++)
  319. {
  320. if (_blendWeight != 1.0f)
  321. value->_interpolatedValue[j] *= _blendWeight;
  322. value->_currentValue[j] += value->_interpolatedValue[j];
  323. }
  324. // We are at the index for a quaternion component. Handle the next for components as a whole quaternion.
  325. Quaternion* interpolatedQuaternion = (Quaternion*) (value->_interpolatedValue + j);
  326. Quaternion* currentQuaternion = (Quaternion*) (value->_currentValue + j);
  327. // If we have a blend weight, we apply it by slerping from the identity to our interpolated value at the given weight.
  328. if (_blendWeight != 1.0f)
  329. Quaternion::slerp(Quaternion::identity(), *interpolatedQuaternion, _blendWeight, interpolatedQuaternion);
  330. // Add in contribution.
  331. currentQuaternion->multiply(*interpolatedQuaternion);
  332. unsigned int componentCount = value->_componentCount;
  333. for (j += 4; j < componentCount; j++)
  334. {
  335. if (_blendWeight != 1.0f)
  336. value->_interpolatedValue[j] *= _blendWeight;
  337. value->_currentValue[j] += value->_interpolatedValue[j];
  338. }
  339. }
  340. }
  341. }
  342. else if (value->_isFirstActing)
  343. {
  344. if (!channel->_curve->_quaternionOffset)
  345. {
  346. memset(value->_currentValue, 0.0f, value->_componentCount);
  347. }
  348. else
  349. {
  350. unsigned int quaternionOffset = *(channel->_curve->_quaternionOffset);
  351. unsigned int j = 0;
  352. for (; j < quaternionOffset; j++)
  353. {
  354. value->_currentValue[j] = 0.0f;
  355. }
  356. // We are at the index for a quaternion component. Handle the next for components as a whole quaternion.
  357. Quaternion* currentQuaternion = (Quaternion*) (value->_currentValue + j);
  358. // Set it to identity.
  359. currentQuaternion->setIdentity();
  360. unsigned int componentCount = value->_componentCount;
  361. for (j += 4; j < componentCount; j++)
  362. {
  363. value->_currentValue[j] = 0.0f;
  364. }
  365. }
  366. }
  367. // Set the animation value on the target property.
  368. target->setAnimationPropertyValue(channel->_propertyId, value);
  369. }
  370. // When ended. Probably should move to it's own method so we can call it when the clip is ended early.
  371. if (!_isPlaying)
  372. {
  373. onEnd();
  374. // Notify end listeners if any.
  375. if (_endListeners)
  376. {
  377. std::vector<Listener*>::iterator listener = _endListeners->begin();
  378. while (listener != _endListeners->end())
  379. {
  380. (*listener)->animationEvent(this, Listener::END);
  381. listener++;
  382. }
  383. }
  384. }
  385. return !_isPlaying;
  386. }
  387. void AnimationClip::onBegin()
  388. {
  389. // Initialize animation to play.
  390. _isPlaying = true;
  391. _elapsedTime = 0;
  392. if (_speed > 0)
  393. {
  394. _runningTime = 0;
  395. }
  396. else
  397. {
  398. _runningTime = _activeDuration;
  399. }
  400. // Notify begin listeners.. if any.
  401. if (_beginListeners)
  402. {
  403. std::vector<Listener*>::iterator listener = _beginListeners->begin();
  404. while (listener != _beginListeners->end())
  405. {
  406. (*listener)->animationEvent(this, Listener::BEGIN);
  407. listener++;
  408. }
  409. }
  410. }
  411. void AnimationClip::onEnd()
  412. {
  413. AnimationValue* value;
  414. Animation::Channel* channel = NULL;
  415. AnimationTarget* target = NULL;
  416. unsigned int channelCount = _animation->_channels.size();
  417. for (unsigned int i = 0; i < channelCount; i++)
  418. {
  419. value = _values[i];
  420. if (value->_isFirstActing)
  421. {
  422. channel = _animation->_channels[i];
  423. target = channel->_target;
  424. target->_highestPriority = NULL;
  425. value->_isFirstActing = false;
  426. }
  427. }
  428. _blendWeight = 1.0f;
  429. _timeStarted = 0;
  430. }
  431. }