AnimationClip.cpp 18 KB

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