Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2019
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.88 KB | None | 0 0
  1. #include "AnimProc.h"
  2.  
  3. #include "../Graphics/Animation.h"
  4. #include "../IO/Log.h"
  5.  
  6. namespace Urho3D
  7. {
  8.  
  9. /// Pulls out an interpolated keyframe from a track based on time.
  10. /// The time value of the key will be set to the given time value, overwrite if undesired.
  11. static AnimationKeyFrame ExtractKeyFrame(AnimationTrack* track, float time)
  12. {
  13. AnimationKeyFrame* prevKey = nullptr;
  14. AnimationKeyFrame* nextKey = nullptr;
  15. for (unsigned k = 0; k < track->GetNumKeyFrames(); ++k)
  16. {
  17. auto key = track->GetKeyFrame(k);
  18. if (key->time_ <= time)
  19. prevKey = key;
  20. else if (key->time_ > time && prevKey != nullptr)
  21. {
  22. nextKey = key;
  23. break;
  24. }
  25. }
  26. if (prevKey && nextKey)
  27. {
  28. const float lerpFactor = NORMALIZE(time, prevKey->time_, nextKey->time_);
  29. AnimationKeyFrame ret;
  30. ret.position_ = prevKey->position_.Lerp(nextKey->position_, lerpFactor);
  31. ret.rotation_ = prevKey->rotation_.Slerp(nextKey->rotation_, lerpFactor);
  32. ret.scale_ = prevKey->scale_.Lerp(nextKey->scale_, lerpFactor);
  33. ret.time_ = time;
  34. return ret;
  35. }
  36. else if (prevKey)
  37. {
  38. AnimationKeyFrame ret = *prevKey;
  39. ret.time_ = time;
  40. return ret;
  41. }
  42.  
  43. AnimationKeyFrame ret = track->keyFrames_.Front();
  44. ret.time_ = time;
  45. return ret;
  46. }
  47.  
  48. /// Extracts the given key indices into a new animation, that runs a specified length of time.
  49. /// Times are sliced evenly
  50. Animation* ExtractAnimation(Animation* src, const PODVector<unsigned>& keyIndices, float totalTime)
  51. {
  52. const float fracTime = totalTime / (keyIndices.Size() - 1);
  53. PODVector<float> frameTimes;
  54. frameTimes.Reserve(keyIndices.Size());
  55. float runningTime = 0.0f;
  56. for (unsigned i = 0; i < keyIndices.Size(); ++i, runningTime += fracTime)
  57. frameTimes.Push(runningTime);
  58.  
  59. return ExtractAnimation(src, keyIndices, frameTimes);
  60. }
  61.  
  62. /// Extracts the given key times into a new animation, that runs a specified length of time.
  63. /// Times are sliced evenly
  64. Animation* ExtractAnimation(Animation* src, const PODVector<float>& times, float totalTime)
  65. {
  66. const float fracTime = totalTime / (times.Size() - 1);
  67. PODVector<float> frameTimes;
  68. frameTimes.Reserve(times.Size());
  69. float runningTime = 0.0f;
  70. for (unsigned i = 0; i < times.Size(); ++i, runningTime += fracTime)
  71. frameTimes.Push(runningTime);
  72.  
  73. return ExtractAnimation(src, times, frameTimes);
  74. }
  75.  
  76. /// Extracts frames by index to create a new animation where each frame has the given times.
  77. /// ANIMATION IS EXPECTED TO BE FAT
  78. Animation* ExtractAnimation(Animation* src, const PODVector<unsigned>& keyIndices, const PODVector<float>& frameTimes)
  79. {
  80. if (src == nullptr)
  81. return nullptr;
  82.  
  83. Animation* ret = new Animation(src->GetContext());
  84.  
  85. for (unsigned t = 0; t < src->GetNumTracks(); ++t)
  86. {
  87. auto track = src->GetTrack(t);
  88. AnimationTrack* newTrack = ret->CreateTrack(track->name_);
  89. newTrack->channelMask_ = track->channelMask_;
  90.  
  91. for (unsigned i = 0; i < keyIndices.Size(); ++i)
  92. {
  93. if (auto key = track->GetKeyFrame(keyIndices[i]))
  94. {
  95. AnimationKeyFrame newKey = *key;
  96. newKey.time_ = frameTimes[i];
  97. newTrack->AddKeyFrame(newKey);
  98. }
  99. }
  100. }
  101.  
  102. ret->SetLength(frameTimes.Back());
  103. return ret;
  104. }
  105.  
  106. /// Extracts samples of given frame times into a new animation set with the specified times.
  107. Animation* ExtractAnimation(Animation* src, const PODVector<float>& times, const PODVector<float>& frameTimes)
  108. {
  109. if (src == nullptr)
  110. return nullptr;
  111.  
  112. Animation* ret = new Animation(src->GetContext());
  113.  
  114. for (unsigned t = 0; t < src->GetNumTracks(); ++t)
  115. {
  116. auto track = src->GetTrack(t);
  117. AnimationTrack* newTrack = ret->CreateTrack(track->name_);
  118. newTrack->channelMask_ = track->channelMask_;
  119.  
  120. for (unsigned i = 0; i < times.Size(); ++i)
  121. {
  122. float time = times[i];
  123. auto newKey = ExtractKeyFrame(track, time);
  124. newKey.time_ = frameTimes[i];
  125. newTrack->AddKeyFrame(newKey);
  126. }
  127. }
  128.  
  129. ret->SetLength(frameTimes.Back());
  130. return ret;
  131. }
  132.  
  133. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement