From ff85f90d33023d908c534b0bf5d9a65e9fc2cce2 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 8 Jun 2019 01:30:11 +0300 Subject: [PATCH] Make animation curve creation more generic --- source/animation.cpp | 71 ++++++++++++++++++++++++++++---------------- source/animation.h | 17 +++++++++-- 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/source/animation.cpp b/source/animation.cpp index dbdd05ba..4be00d73 100644 --- a/source/animation.cpp +++ b/source/animation.cpp @@ -107,51 +107,57 @@ void Animation::create_curves() delete *i; curves.clear(); - typedef ValueCurve<3>::Knot Knot; - vector positions; - vector eulers; - vector scales; - for(vector::const_iterator i=keyframes.begin(); i!=keyframes.end(); ++i) - { - positions.push_back(Knot(i->time/Time::sec, i->keyframe->get_transform().get_position())); - const Transform::AngleVector3 &euler = i->keyframe->get_transform().get_euler(); - eulers.push_back(Knot(i->time/Time::sec, Vector3(euler.x.radians(), euler.y.radians(), euler.z.radians()))); - scales.push_back(Knot(i->time/Time::sec, i->keyframe->get_transform().get_scale())); - } - curves.reserve(3+uniforms.size()); - curves.push_back(new ValueCurve<3>(POSITION, positions)); - curves.push_back(new ValueCurve<3>(EULER, eulers)); - curves.push_back(new ValueCurve<3>(SCALE, scales)); + create_curve<3>(POSITION, &extract_position); + create_curve<3>(EULER, &extract_euler); + create_curve<3>(SCALE, &extract_scale); for(vector::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i) { if(i->size==1) - create_uniform_curve<1>(i->name); + create_curve<1>(UNIFORM, ExtractUniform<1>(i->name)); else if(i->size==2) - create_uniform_curve<2>(i->name); + create_curve<2>(UNIFORM, ExtractUniform<2>(i->name)); else if(i->size==3) - create_uniform_curve<3>(i->name); + create_curve<3>(UNIFORM, ExtractUniform<3>(i->name)); else if(i->size==4) - create_uniform_curve<4>(i->name); + create_curve<4>(UNIFORM, ExtractUniform<4>(i->name)); } } -template -void Animation::create_uniform_curve(const string &name) +template +void Animation::create_curve(CurveTarget target, const T &extract) { typedef typename ValueCurve::Knot Knot; vector knots; for(vector::const_iterator i=keyframes.begin(); i!=keyframes.end(); ++i) { - const KeyFrame::UniformMap &kf_uniforms = i->keyframe->get_uniforms(); - const KeyFrame::UniformMap::const_iterator j = kf_uniforms.find(name); - if(j!=kf_uniforms.end()) - knots.push_back(Knot(i->time/Time::sec, Interpolate::SplineValue::make(j->second.values))); + typename Interpolate::SplineValue::Type value; + if(extract(*i->keyframe, value)) + knots.push_back(Knot(i->time/Time::sec, value)); } - curves.push_back(new ValueCurve(UNIFORM, knots)); + curves.push_back(new ValueCurve(target, knots)); +} + +bool Animation::extract_position(const KeyFrame &kf, Vector3 &value) +{ + value = kf.get_transform().get_position(); + return true; +} + +bool Animation::extract_euler(const KeyFrame &kf, Vector3 &value) +{ + const Transform::AngleVector3 &euler = kf.get_transform().get_euler(); + value = Vector3(euler.x.radians(), euler.y.radians(), euler.z.radians()); + return true; +} + +bool Animation::extract_scale(const KeyFrame &kf, Vector3 &value) +{ + value = kf.get_transform().get_scale(); + return true; } void Animation::add_event(const Time::TimeDelta &t, const string &n, const Variant &v) @@ -222,6 +228,19 @@ void Animation::ValueCurve::apply(float x, KeyFrame::AnimatedUniform &uni) co } +template +bool Animation::ExtractUniform::operator()(const KeyFrame &kf, typename Interpolate::SplineValue::Type &value) const +{ + const KeyFrame::UniformMap &kf_uniforms = kf.get_uniforms(); + const KeyFrame::UniformMap::const_iterator i = kf_uniforms.find(name); + if(i==kf_uniforms.end()) + return false; + + value = Interpolate::SplineValue::make(i->second.values); + return true; +} + + Animation::UniformInfo::UniformInfo(const string &n, unsigned s): name(n), size(s) diff --git a/source/animation.h b/source/animation.h index 83b369bf..92c177b6 100644 --- a/source/animation.h +++ b/source/animation.h @@ -86,6 +86,16 @@ private: virtual void apply(float, KeyFrame::AnimatedUniform &) const; }; + template + struct ExtractUniform + { + const std::string &name; + + ExtractUniform(const std::string &n): name(n) { } + + bool operator()(const KeyFrame &, typename Interpolate::SplineValue::Type &) const; + }; + struct TimedKeyFrame { Time::TimeDelta time; @@ -156,8 +166,11 @@ private: void add_keyframe(const Time::TimeDelta &, const RefPtr &, float, float); void prepare_keyframe(TimedKeyFrame &); void create_curves(); - template - void create_uniform_curve(const std::string &); + template + void create_curve(CurveTarget target, const T &); + static bool extract_position(const KeyFrame &, Vector3 &); + static bool extract_euler(const KeyFrame &, Vector3 &); + static bool extract_scale(const KeyFrame &, Vector3 &); public: void add_event(const Time::TimeDelta &, const std::string &, const Variant & = Variant()); -- 2.43.0