void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame &kf, float slope)
{
- add_keyframe(t, kf, slope, slope);
+ add_keyframe(t, &kf, slope, slope, false);
+ create_curves();
}
-void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame &kf, float, float)
+void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame &kf, float ss, float es)
{
- add_keyframe(t, kf);
+ add_keyframe(t, &kf, ss, es, false);
+ create_curves();
}
void Animation::add_control_keyframe(const KeyFrame &kf)
add_keyframe(keyframes.back().time, &kf, true, false);
}
+void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame *kf, float ss, float es, bool owned)
+{
+ if(keyframes.empty())
+ return add_keyframe(t, kf, false, owned);
+
+ if(keyframes.back().control)
+ throw invalid_operation("Animation::add_keyframe");
+
+ const KeyFrame &last = *keyframes.back().keyframe;
+ const Transform &trn = kf->get_transform();
+ const Transform &last_trn = last.get_transform();
+ const KeyFrame::UniformMap &kf_unis = kf->get_uniforms();
+ const KeyFrame::UniformMap &last_unis = last.get_uniforms();
+ for(unsigned i=1; i<=2; ++i)
+ {
+ float x = (i==1 ? ss/3 : 1-es/3);
+ KeyFrame *ckf = new KeyFrame;
+ Transform ctrn;
+ ctrn.set_position(last_trn.get_position()*(1-x)+trn.get_position()*x);
+ const Transform::AngleVector3 &e1 = last_trn.get_euler();
+ const Transform::AngleVector3 &e2 = trn.get_euler();
+ ctrn.set_euler(Transform::AngleVector3(e1.x*(1-x)+e2.x*x, e1.y*(1-x)+e2.y*x, e1.z*(1-x)+e2.z*x));
+ ctrn.set_scale(last_trn.get_scale()*(1-x)+trn.get_scale()*x);
+ ckf->set_transform(ctrn);
+
+ for(KeyFrame::UniformMap::const_iterator j=kf_unis.begin(); j!=kf_unis.end(); ++j)
+ {
+ KeyFrame::UniformMap::const_iterator k = last_unis.find(j->first);
+ if(k==last_unis.end())
+ continue;
+
+ KeyFrame::AnimatedUniform uni(j->second.size, 0.0f);
+ for(unsigned c=0; c<uni.size; ++c)
+ uni.values[c] = k->second.values[c]*(1-x)+j->second.values[c]*x;
+
+ ckf->set_uniform(j->first, uni);
+ }
+
+ add_keyframe(t, ckf, true, true);
+ }
+
+ add_keyframe(t, kf, false, owned);
+}
+
void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame *kf, bool c, bool owned)
{
if(c && keyframes.empty())
{
start_slope = 1;
end_slope = 1;
+ slopes_set = 0;
add("armature", &Animation::armature);
add("control_keyframe", &Loader::control_keyframe);
add("control_keyframe", &Loader::control_keyframe_inline);
obj.create_curves();
}
+void Animation::Loader::check_slopes_and_control(bool s, bool c)
+{
+ if(s && c)
+ throw logic_error("can't use both slopes and control keyframes in same segment");
+}
+
+void Animation::Loader::add_kf(const KeyFrame *kf, bool c, bool owned)
+{
+ if(slopes_set && !c)
+ obj.add_keyframe(current_time, kf, start_slope, end_slope, owned);
+ else
+ obj.add_keyframe(current_time, kf, c, owned);
+
+ start_slope = end_slope;
+ end_slope = 1;
+ slopes_set = (slopes_set<<1)&3;
+}
+
void Animation::Loader::load_kf(const string &n, bool c)
{
- obj.add_keyframe(current_time, &get_collection().get<KeyFrame>(n), c, false);
+ add_kf(&get_collection().get<KeyFrame>(n), c, false);
}
void Animation::Loader::load_kf_inline(bool c)
else
load_sub(*kf);
- obj.add_keyframe(current_time, *kf, c, true);
+ add_kf(kf.get(), c, true);
kf.release();
}
void Animation::Loader::control_keyframe(const string &n)
{
+ slopes_set &= 1;
+ check_slopes_and_control(slopes_set, true);
load_kf(n, true);
}
void Animation::Loader::control_keyframe_inline()
{
+ slopes_set &= 1;
+ check_slopes_and_control(slopes_set, true);
load_kf_inline(true);
}
void Animation::Loader::slopes(float s, float e)
{
+ check_slopes_and_control(true, (!obj.keyframes.empty() && obj.keyframes.back().control));
+
start_slope = s;
end_slope = e;
+ slopes_set = 1;
}
} // namespace GL
Time::TimeDelta current_time;
float start_slope;
float end_slope;
+ int slopes_set;
public:
Loader(Animation &);
void init();
virtual void finish();
+ void check_slopes_and_control(bool, bool);
+ void add_kf(const KeyFrame *, bool, bool);
void load_kf(const std::string &, bool);
void load_kf_inline(bool);
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);
+ DEPRECATED void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float);
+ DEPRECATED void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float, float);
void add_control_keyframe(const KeyFrame &);
private:
+ void add_keyframe(const Time::TimeDelta &, const KeyFrame *, float, float, bool);
void add_keyframe(const Time::TimeDelta &, const KeyFrame *, bool, bool);
void prepare_keyframe(TimedKeyFrame &);
void create_curves();