X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fanimation.cpp;h=37f583d5ec53b43324e67f7fcd1237a25bbefa80;hp=dbdd05bafd741262910b1832a10a8590dd1ce88b;hb=HEAD;hpb=025016d7628be9c43b20999325dcbaae5cb3c3b8 diff --git a/source/animation.cpp b/source/animation.cpp deleted file mode 100644 index dbdd05ba..00000000 --- a/source/animation.cpp +++ /dev/null @@ -1,391 +0,0 @@ -#include -#include -#include -#include -#include "animation.h" -#include "animationeventobserver.h" -#include "armature.h" -#include "error.h" -#include "pose.h" - -using namespace std; - -namespace Msp { -namespace GL { - -Animation::Animation(): - armature(0), - looping(false) -{ } - -// Avoid synthesizing ~RefPtr in files including animation.h -Animation::~Animation() -{ } - -void Animation::set_armature(const Armature &a) -{ - if(!keyframes.empty() && &a!=armature) - throw invalid_operation("Animation::set_armature"); - armature = &a; -} - -unsigned Animation::get_slot_for_uniform(const string &n) const -{ - for(unsigned i=0; i=uniforms.size()) - throw out_of_range("Animation::get_uniform_name"); - return uniforms[i].name; -} - -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, ss, es); - create_curves(); -} - -void Animation::add_keyframe(const Time::TimeDelta &t, const RefPtr &kf, float ss, float es) -{ - if(keyframes.empty() && t!=Time::zero) - throw invalid_argument("Animation::add_keyframe"); - if(!keyframes.empty() && tget_pose() && armature && kf->get_pose()->get_armature()!=armature) - throw invalid_argument("Animation::add_keyframe"); - - const KeyFrame::UniformMap &kf_uniforms = kf->get_uniforms(); - for(vector::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i) - { - KeyFrame::UniformMap::const_iterator j = kf_uniforms.find(i->name); - if(j!=kf_uniforms.end() && j->second.size!=i->size) - throw invalid_argument("Animation::add_keyframe"); - } - - if(kf->get_pose() && !armature) - armature = kf->get_pose()->get_armature(); - - TimedKeyFrame tkf; - tkf.time = t; - tkf.start_slope = ss; - tkf.end_slope = es; - tkf.keyframe = kf; - - keyframes.push_back(tkf); - - for(KeyFrame::UniformMap::const_iterator i=kf_uniforms.begin(); i!=kf_uniforms.end(); ++i) - { - bool found = false; - for(vector::const_iterator j=uniforms.begin(); (!found && j!=uniforms.end()); ++j) - found = (j->name==i->first); - - if(!found) - uniforms.push_back(UniformInfo(i->first, i->second.size)); - } -} - -void Animation::create_curves() -{ - for(vector::iterator i=curves.begin(); i!=curves.end(); ++i) - 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)); - - for(vector::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i) - { - if(i->size==1) - create_uniform_curve<1>(i->name); - else if(i->size==2) - create_uniform_curve<2>(i->name); - else if(i->size==3) - create_uniform_curve<3>(i->name); - else if(i->size==4) - create_uniform_curve<4>(i->name); - } -} - -template -void Animation::create_uniform_curve(const string &name) -{ - 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))); - } - - curves.push_back(new ValueCurve(UNIFORM, knots)); -} - -void Animation::add_event(const Time::TimeDelta &t, const string &n, const Variant &v) -{ - Event event; - event.time = t; - event.name = n; - event.value = v; - events.push_back(event); -} - -const Time::TimeDelta &Animation::get_duration() const -{ - if(keyframes.empty()) - return Time::zero; - - return keyframes.back().time; -} - -void Animation::set_looping(bool l) -{ - looping = l; -} - - -Animation::Curve::Curve(CurveTarget t): - target(t) -{ } - - -template -Animation::ValueCurve::ValueCurve(CurveTarget t, const vector &k): - Curve(t), - spline(Interpolate::LinearSpline(k)) -{ } - -template -void Animation::ValueCurve::apply(float, Matrix &) const -{ - throw invalid_operation("ValueCurve::apply"); -} - -template<> -void Animation::ValueCurve<3>::apply(float x, Matrix &matrix) const -{ - Vector3 value = spline(x); - if(target==POSITION) - matrix.translate(value); - else if(target==EULER) - { - matrix.rotate(value.z, Vector3(0, 0, 1)); - matrix.rotate(value.y, Vector3(0, 1, 0)); - matrix.rotate(value.x, Vector3(1, 0, 0)); - } - else if(target==SCALE) - matrix.scale(value); - else - throw invalid_operation("ValueCurve::apply"); -} - -template -void Animation::ValueCurve::apply(float x, KeyFrame::AnimatedUniform &uni) const -{ - uni.size = N; - typename Interpolate::Spline::Value value = spline(x); - for(unsigned i=0; i::get(value, i); -} - - -Animation::UniformInfo::UniformInfo(const string &n, unsigned s): - name(n), - size(s) -{ } - - -Animation::Iterator::Iterator(const Animation &a): - animation(&a), - event_iter(animation->events.begin()), - end(false) -{ -} - -Animation::Iterator &Animation::Iterator::operator+=(const Time::TimeDelta &t) -{ - const Time::TimeDelta &duration = animation->get_duration(); - if(!duration) - return *this; - - elapsed += t; - if(animation->looping) - { - while(elapsed>=duration) - elapsed -= duration; - } - else if(elapsed>=duration) - { - end = true; - elapsed = duration; - } - - return *this; -} - -void Animation::Iterator::dispatch_events(AnimationEventObserver &observer) -{ - for(; (event_iter!=animation->events.end() && event_iter->time<=elapsed); ++event_iter) - observer.animation_event(0, event_iter->name, event_iter->value); -} - -Matrix Animation::Iterator::get_matrix() const -{ - Matrix matrix; - for(unsigned i=0; i<3; ++i) - animation->curves[i]->apply(elapsed/Time::sec, matrix); - return matrix; -} - -KeyFrame::AnimatedUniform Animation::Iterator::get_uniform(unsigned i) const -{ - if(i>=animation->uniforms.size()) - throw out_of_range("Animation::Iterator::get_uniform"); - - KeyFrame::AnimatedUniform uni(animation->uniforms[i].size, 0.0f); - animation->curves[3+i]->apply(elapsed/Time::sec, uni); - return uni; -} - -Matrix Animation::Iterator::get_pose_matrix(unsigned link) const -{ - if(!animation->armature) - throw invalid_operation("Animation::Iterator::get_pose_matrix"); - if(link>animation->armature->get_max_link_index()) - throw out_of_range("Animation::Iterator::get_pose_matrix"); - - throw logic_error("pose animations are currently unimplemented"); -} - - -Animation::Loader::Loader(Animation &a): - DataFile::CollectionObjectLoader(a, 0) -{ - init(); -} - -Animation::Loader::Loader(Animation &a, Collection &c): - DataFile::CollectionObjectLoader(a, &c) -{ - init(); -} - -void Animation::Loader::init() -{ - start_slope = 1; - end_slope = 1; - add("armature", &Animation::armature); - add("event", &Loader::event); - add("event", &Loader::event1i); - add("event", &Loader::event1f); - add("event", &Loader::event2f); - add("event", &Loader::event3f); - add("event", &Loader::event4f); - add("interval", &Loader::interval); - add("keyframe", &Loader::keyframe); - add("keyframe", &Loader::keyframe_inline); - add("looping", &Animation::looping); - add("slopes", &Loader::slopes); -} - -void Animation::Loader::finish() -{ - obj.create_curves(); -} - -void Animation::Loader::event(const string &n) -{ - obj.add_event(current_time, n); -} - -void Animation::Loader::event1i(const string &n, int v) -{ - obj.add_event(current_time, n, v); -} - -void Animation::Loader::event1f(const string &n, float v) -{ - obj.add_event(current_time, n, v); -} - -void Animation::Loader::event2f(const string &n, float v0, float v1) -{ - obj.add_event(current_time, n, LinAl::Vector(v0, v1)); -} - -void Animation::Loader::event3f(const string &n, float v0, float v1, float v2) -{ - obj.add_event(current_time, n, Vector3(v0, v1, v2)); -} - -void Animation::Loader::event4f(const string &n, float v0, float v1, float v2, float v3) -{ - obj.add_event(current_time, n, Vector4(v0, v1, v2, v3)); -} - -void Animation::Loader::interval(float t) -{ - current_time += t*Time::sec; -} - -void Animation::Loader::keyframe(const string &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() -{ - RefPtr kf = new KeyFrame; - if(coll) - load_sub(*kf, get_collection()); - else - load_sub(*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 -} // namespace Msp