Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "AnimProc.h"
- #include "../Graphics/Animation.h"
- #include "../IO/Log.h"
- namespace Urho3D
- {
- /// Pulls out an interpolated keyframe from a track based on time.
- /// The time value of the key will be set to the given time value, overwrite if undesired.
- static AnimationKeyFrame ExtractKeyFrame(AnimationTrack* track, float time)
- {
- AnimationKeyFrame* prevKey = nullptr;
- AnimationKeyFrame* nextKey = nullptr;
- for (unsigned k = 0; k < track->GetNumKeyFrames(); ++k)
- {
- auto key = track->GetKeyFrame(k);
- if (key->time_ <= time)
- prevKey = key;
- else if (key->time_ > time && prevKey != nullptr)
- {
- nextKey = key;
- break;
- }
- }
- if (prevKey && nextKey)
- {
- const float lerpFactor = NORMALIZE(time, prevKey->time_, nextKey->time_);
- AnimationKeyFrame ret;
- ret.position_ = prevKey->position_.Lerp(nextKey->position_, lerpFactor);
- ret.rotation_ = prevKey->rotation_.Slerp(nextKey->rotation_, lerpFactor);
- ret.scale_ = prevKey->scale_.Lerp(nextKey->scale_, lerpFactor);
- ret.time_ = time;
- return ret;
- }
- else if (prevKey)
- {
- AnimationKeyFrame ret = *prevKey;
- ret.time_ = time;
- return ret;
- }
- AnimationKeyFrame ret = track->keyFrames_.Front();
- ret.time_ = time;
- return ret;
- }
- /// Extracts the given key indices into a new animation, that runs a specified length of time.
- /// Times are sliced evenly
- Animation* ExtractAnimation(Animation* src, const PODVector<unsigned>& keyIndices, float totalTime)
- {
- const float fracTime = totalTime / (keyIndices.Size() - 1);
- PODVector<float> frameTimes;
- frameTimes.Reserve(keyIndices.Size());
- float runningTime = 0.0f;
- for (unsigned i = 0; i < keyIndices.Size(); ++i, runningTime += fracTime)
- frameTimes.Push(runningTime);
- return ExtractAnimation(src, keyIndices, frameTimes);
- }
- /// Extracts the given key times into a new animation, that runs a specified length of time.
- /// Times are sliced evenly
- Animation* ExtractAnimation(Animation* src, const PODVector<float>& times, float totalTime)
- {
- const float fracTime = totalTime / (times.Size() - 1);
- PODVector<float> frameTimes;
- frameTimes.Reserve(times.Size());
- float runningTime = 0.0f;
- for (unsigned i = 0; i < times.Size(); ++i, runningTime += fracTime)
- frameTimes.Push(runningTime);
- return ExtractAnimation(src, times, frameTimes);
- }
- /// Extracts frames by index to create a new animation where each frame has the given times.
- /// ANIMATION IS EXPECTED TO BE FAT
- Animation* ExtractAnimation(Animation* src, const PODVector<unsigned>& keyIndices, const PODVector<float>& frameTimes)
- {
- if (src == nullptr)
- return nullptr;
- Animation* ret = new Animation(src->GetContext());
- for (unsigned t = 0; t < src->GetNumTracks(); ++t)
- {
- auto track = src->GetTrack(t);
- AnimationTrack* newTrack = ret->CreateTrack(track->name_);
- newTrack->channelMask_ = track->channelMask_;
- for (unsigned i = 0; i < keyIndices.Size(); ++i)
- {
- if (auto key = track->GetKeyFrame(keyIndices[i]))
- {
- AnimationKeyFrame newKey = *key;
- newKey.time_ = frameTimes[i];
- newTrack->AddKeyFrame(newKey);
- }
- }
- }
- ret->SetLength(frameTimes.Back());
- return ret;
- }
- /// Extracts samples of given frame times into a new animation set with the specified times.
- Animation* ExtractAnimation(Animation* src, const PODVector<float>& times, const PODVector<float>& frameTimes)
- {
- if (src == nullptr)
- return nullptr;
- Animation* ret = new Animation(src->GetContext());
- for (unsigned t = 0; t < src->GetNumTracks(); ++t)
- {
- auto track = src->GetTrack(t);
- AnimationTrack* newTrack = ret->CreateTrack(track->name_);
- newTrack->channelMask_ = track->channelMask_;
- for (unsigned i = 0; i < times.Size(); ++i)
- {
- float time = times[i];
- auto newKey = ExtractKeyFrame(track, time);
- newKey.time_ = frameTimes[i];
- newTrack->AddKeyFrame(newKey);
- }
- }
- ret->SetLength(frameTimes.Back());
- return ret;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement