From 332352298ef41b8ac3a4c57b467dd146c0b05e0b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 2 Jul 2018 01:01:27 +0300 Subject: [PATCH] Support slopes in keyframe interpolation --- source/animation.cpp | 48 +++++++++++++++++++++++++++++++++++--------- source/animation.h | 10 ++++++++- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/source/animation.cpp b/source/animation.cpp index c7e23b8e..f0e2630a 100644 --- a/source/animation.cpp +++ b/source/animation.cpp @@ -43,13 +43,23 @@ const string &Animation::get_uniform_name(unsigned i) const } void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame &kf) +{ + add_keyframe(t, kf, 1.0f, 1.0f); +} + +void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame &kf, float slope) +{ + add_keyframe(t, kf, slope, slope); +} + +void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame &kf, float ss, float es) { RefPtr kfr(&kf); kfr.keep(); - add_keyframe(t, kfr); + add_keyframe(t, kfr, ss, es); } -void Animation::add_keyframe(const Time::TimeDelta &t, const RefPtr &kf) +void Animation::add_keyframe(const Time::TimeDelta &t, const RefPtr &kf, float ss, float es) { if(!keyframes.empty() && tkeyframes.begin()), event_iter(animation->events.begin()), + x(0), end(false) { } @@ -272,6 +287,9 @@ Animation::Iterator &Animation::Iterator::operator+=(const Time::TimeDelta &t) iter = next; } + x = time_since_keyframe/iter->delta_t; + x += (iter->start_slope-1)*((x-2)*x+1)*x + (1-iter->end_slope)*(1-x)*x*x; + return *this; } @@ -298,7 +316,7 @@ Matrix Animation::Iterator::get_matrix() const if(!iter->prev) return iter->keyframe->get_matrix(); - return iter->matrix.get(time_since_keyframe/iter->delta_t); + return iter->matrix.get(x); } KeyFrame::AnimatedUniform Animation::Iterator::get_uniform(unsigned i) const @@ -312,10 +330,9 @@ KeyFrame::AnimatedUniform Animation::Iterator::get_uniform(unsigned i) const } unsigned size = animation->uniforms[i].size; - float t = time_since_keyframe/iter->delta_t; KeyFrame::AnimatedUniform result(size, 0.0f); for(unsigned j=0; jprev->uniforms[i].values[j]*(1-t)+iter->uniforms[i].values[j]*t; + result.values[j] = iter->prev->uniforms[i].values[j]*(1-x)+iter->uniforms[i].values[j]*x; return result; } @@ -336,7 +353,7 @@ Matrix Animation::Iterator::get_pose_matrix(unsigned link) const // We must redo the base point correction since interpolation throws it off // XXX This should probably be done on local matrices - Matrix result = iter->pose_matrices[link].get(time_since_keyframe/iter->delta_t); + Matrix result = iter->pose_matrices[link].get(x); const Vector3 &base = animation->armature->get_link(link).get_base(); Vector3 new_base = result*base; result = Matrix::translation(base-new_base)*result; @@ -358,6 +375,8 @@ Animation::Loader::Loader(Animation &a, Collection &c): void Animation::Loader::init() { + start_slope = 1; + end_slope = 1; add("armature", &Animation::armature); add("event", &Loader::event); add("event", &Loader::event1i); @@ -369,6 +388,7 @@ void Animation::Loader::init() add("keyframe", &Loader::keyframe); add("keyframe", &Loader::keyframe_inline); add("looping", &Animation::looping); + add("slopes", &Loader::slopes); } void Animation::Loader::event(const string &n) @@ -408,7 +428,9 @@ void Animation::Loader::interval(float t) void Animation::Loader::keyframe(const string &n) { - obj.add_keyframe(current_time, get_collection().get(n)); + obj.add_keyframe(current_time, get_collection().get(n), start_slope, end_slope); + start_slope = end_slope; + end_slope = 1; } void Animation::Loader::keyframe_inline() @@ -419,7 +441,15 @@ void Animation::Loader::keyframe_inline() else load_sub(*kf); - obj.add_keyframe(current_time, kf); + obj.add_keyframe(current_time, kf, start_slope, end_slope); + start_slope = end_slope; + end_slope = 1; +} + +void Animation::Loader::slopes(float s, float e) +{ + start_slope = s; + end_slope = e; } } // namespace GL diff --git a/source/animation.h b/source/animation.h index 3404f45b..e3fb79ee 100644 --- a/source/animation.h +++ b/source/animation.h @@ -25,6 +25,8 @@ public: { private: Time::TimeDelta current_time; + float start_slope; + float end_slope; public: Loader(Animation &); @@ -41,6 +43,7 @@ public: void interval(float); void keyframe(const std::string &); void keyframe_inline(); + void slopes(float, float); }; private: @@ -70,6 +73,8 @@ private: const TimedKeyFrame *prev; Time::TimeDelta time; Time::TimeDelta delta_t; + float start_slope; + float end_slope; RefPtr keyframe; MatrixInterpolation matrix; std::vector uniforms; @@ -102,6 +107,7 @@ public: std::vector::const_iterator iter; std::vector::const_iterator event_iter; Time::TimeDelta time_since_keyframe; + float x; bool end; public: @@ -135,8 +141,10 @@ public: const std::string &get_uniform_name(unsigned) const; void add_keyframe(const Time::TimeDelta &, const KeyFrame &); + void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float); + void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float, float); private: - void add_keyframe(const Time::TimeDelta &, const RefPtr &); + void add_keyframe(const Time::TimeDelta &, const RefPtr &, float, float); void prepare_keyframe(TimedKeyFrame &); public: void add_event(const Time::TimeDelta &, const std::string &, const Variant & = Variant()); -- 2.43.0