]> git.tdb.fi Git - libs/gl.git/blobdiff - source/animation.cpp
Implement an event system for animations
[libs/gl.git] / source / animation.cpp
index 2f78d1eafad574b4d1c060a8209d0527309cc393..744262d84781ae40e0b2c42b604b1b2badb516cf 100644 (file)
@@ -3,6 +3,7 @@
 #include <msp/datafile/collection.h>
 #include <msp/time/units.h>
 #include "animation.h"
 #include <msp/datafile/collection.h>
 #include <msp/time/units.h>
 #include "animation.h"
+#include "animationeventobserver.h"
 #include "armature.h"
 #include "error.h"
 #include "pose.h"
 #include "armature.h"
 #include "error.h"
 #include "pose.h"
@@ -71,6 +72,15 @@ void Animation::add_keyframe(const Time::TimeDelta &t, const RefPtr<const KeyFra
        prepare_keyframe(tkf);
 }
 
        prepare_keyframe(tkf);
 }
 
+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);
+}
+
 void Animation::set_looping(bool l)
 {
        looping = l;
 void Animation::set_looping(bool l)
 {
        looping = l;
@@ -234,6 +244,7 @@ Animation::UniformInfo::UniformInfo(const string &n, unsigned s):
 Animation::Iterator::Iterator(const Animation &a):
        animation(&a),
        iter(animation->keyframes.begin()),
 Animation::Iterator::Iterator(const Animation &a):
        animation(&a),
        iter(animation->keyframes.begin()),
+       event_iter(animation->events.begin()),
        end(false)
 { }
 
        end(false)
 { }
 
@@ -263,6 +274,24 @@ Animation::Iterator &Animation::Iterator::operator+=(const Time::TimeDelta &t)
        return *this;
 }
 
        return *this;
 }
 
+void Animation::Iterator::dispatch_events(AnimationEventObserver &observer)
+{
+       vector<Event>::const_iterator events_end = animation->events.end();
+       if(end)
+       {
+               for(; event_iter!=events_end; ++event_iter)
+                       observer.animation_event(0, event_iter->name, event_iter->value);
+       }
+       else if(event_iter!=events_end)
+       {
+               Time::TimeDelta t = time_since_keyframe;
+               if(iter->prev)
+                       t += iter->prev->time;
+               for(; (event_iter!=events_end && event_iter->time<=t); ++event_iter)
+                       observer.animation_event(0, event_iter->name, event_iter->value);
+       }
+}
+
 Matrix Animation::Iterator::get_matrix() const
 {
        if(!iter->prev)
 Matrix Animation::Iterator::get_matrix() const
 {
        if(!iter->prev)
@@ -329,12 +358,48 @@ Animation::Loader::Loader(Animation &a, Collection &c):
 void Animation::Loader::init()
 {
        add("armature", &Animation::armature);
 void Animation::Loader::init()
 {
        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("interval", &Loader::interval);
        add("keyframe", &Loader::keyframe);
        add("keyframe", &Loader::keyframe_inline);
        add("looping", &Animation::looping);
 }
 
+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<float, 2>(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::keyframe(const string &n)
 {
        obj.add_keyframe(current_time, get_collection().get<KeyFrame>(n));
 void Animation::Loader::keyframe(const string &n)
 {
        obj.add_keyframe(current_time, get_collection().get<KeyFrame>(n));