+ float value = spline(x);
+ if(target==POSITION || target==SCALE)
+ {
+ Vector3 vec;
+ vec[component] = value;
+ if(target==POSITION)
+ matrix.translate(vec);
+ else
+ matrix.scale(vec);
+ }
+ else if(target==EULER)
+ {
+ Vector3 vec;
+ vec[component] = 1.0f;
+ matrix.rotate(Geometry::Angle<float>::from_radians(value), vec);
+ }
+ else
+ 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(Geometry::Angle<float>::from_radians(value.z), Vector3(0, 0, 1));
+ matrix.rotate(Geometry::Angle<float>::from_radians(value.y), Vector3(0, 1, 0));
+ matrix.rotate(Geometry::Angle<float>::from_radians(value.x), Vector3(1, 0, 0));
+ }
+ else if(target==SCALE)
+ matrix.scale(value);
+ else
+ throw invalid_operation("ValueCurve::apply");
+}
+
+template<unsigned N>
+void Animation::ValueCurve<N>::apply(float x, KeyFrame::AnimatedUniform &uni) const
+{
+ uni.size = N;
+ typename Interpolate::Spline<double, 3, N>::Value value = spline(x);
+ for(unsigned i=0; i<N; ++i)
+ uni.values[i] = Interpolate::SplineValue<float, N>::get(value, i);
+}
+
+
+bool Animation::ExtractComponent::operator()(const KeyFrame &kf, float &value) const
+{
+ Vector3 vec;
+ if(!extract(kf, vec))
+ return false;
+
+ value = vec[index];
+ return kf.get_transform().get_mask()&mask;
+}
+
+
+template<unsigned N>
+bool Animation::ExtractUniform<N>::operator()(const KeyFrame &kf, typename Interpolate::SplineValue<float, N>::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<float, N>::make(i->second.values);
+ return true;