2 * Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
4 * This library is open source and may be redistributed and/or modified under
5 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
6 * (at your option) any later version. The full license is in LICENSE file
7 * included with this distribution, and on the openscenegraph.org website.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * OpenSceneGraph Public License for more details.
15 * Cedric Pinson <cedric.pinson@plopbyte.net>
16 * Michael Platings <mplatings@pixelpower.com>
19#ifndef OSGANIMATION_INTERPOLATOR
20#define OSGANIMATION_INTERPOLATOR 1
23#include <osgAnimation/Keyframe>
28 template <class TYPE, class KEY>
29 class TemplateInterpolatorBase
32 typedef KEY KeyframeType;
33 typedef TYPE UsingType;
36 TemplateInterpolatorBase() {}
38 int getKeyIndexFromTime(const TemplateKeyframeContainer<KEY>& keys, double time) const
40 int key_size = keys.size();
42 osg::notify(osg::WARN) << "TemplateInterpolatorBase::getKeyIndexFromTime the container is empty, impossible to get key index from time" << std::endl;;
45 const TemplateKeyframe<KeyframeType>* keysVector = &keys.front();
50 double time1 = keysVector[mid].getTime();
63 template <class TYPE, class KEY=TYPE>
64 class TemplateStepInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
68 TemplateStepInterpolator() {}
69 void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
72 if (time >= keyframes.back().getTime())
74 result = keyframes.back().getValue();
77 else if (time <= keyframes.front().getTime())
79 result = keyframes.front().getValue();
83 int i = this->getKeyIndexFromTime(keyframes,time);
84 result = keyframes[i].getValue();
89 template <class TYPE, class KEY=TYPE>
90 class TemplateLinearInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
94 TemplateLinearInterpolator() {}
95 void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
98 if (time >= keyframes.back().getTime())
100 result = keyframes.back().getValue();
103 else if (time <= keyframes.front().getTime())
105 result = keyframes.front().getValue();
109 int i = this->getKeyIndexFromTime(keyframes,time);
110 float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime());
111 const TYPE& v1 = keyframes[i].getValue();
112 const TYPE& v2 = keyframes[i+1].getValue();
113 result = v1*(1-blend) + v2*blend;
118 template <class TYPE, class KEY=TYPE>
119 class TemplateSphericalLinearInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
122 TemplateSphericalLinearInterpolator() {}
123 void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
125 if (time >= keyframes.back().getTime())
127 result = keyframes.back().getValue();
130 else if (time <= keyframes.front().getTime())
132 result = keyframes.front().getValue();
136 int i = this->getKeyIndexFromTime(keyframes,time);
137 float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime());
138 const TYPE& q1 = keyframes[i].getValue();
139 const TYPE& q2 = keyframes[i+1].getValue();
140 result.slerp(blend,q1,q2);
145 template <class TYPE, class KEY>
146 class TemplateLinearPackedInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
150 TemplateLinearPackedInterpolator() {}
151 void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
153 if (time >= keyframes.back().getTime())
155 keyframes.back().getValue().uncompress(keyframes.mScale, keyframes.mMin, result);
158 else if (time <= keyframes.front().getTime())
160 keyframes.front().getValue().uncompress(keyframes.mScale, keyframes.mMin, result);
164 int i = this->getKeyIndexFromTime(keyframes,time);
165 float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime());
167 keyframes[i].getValue().uncompress(keyframes.mScale, keyframes.mMin, v1);
168 keyframes[i+1].getValue().uncompress(keyframes.mScale, keyframes.mMin, v2);
169 result = v1*(1-blend) + v2*blend;
174 // http://en.wikipedia.org/wiki/B%C3%A9zier_curve
175 template <class TYPE, class KEY=TYPE>
176 class TemplateCubicBezierInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
180 TemplateCubicBezierInterpolator() {}
181 void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
184 if (time >= keyframes.back().getTime())
186 result = keyframes.back().getValue().getPosition();
189 else if (time <= keyframes.front().getTime())
191 result = keyframes.front().getValue().getPosition();
195 int i = this->getKeyIndexFromTime(keyframes,time);
197 float t = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime());
198 float one_minus_t = 1.0-t;
199 float one_minus_t2 = one_minus_t * one_minus_t;
200 float one_minus_t3 = one_minus_t2 * one_minus_t;
203 TYPE v0 = keyframes[i].getValue().getPosition() * one_minus_t3;
204 TYPE v1 = keyframes[i].getValue().getControlPointIn() * (3.0 * t * one_minus_t2);
205 TYPE v2 = keyframes[i].getValue().getControlPointOut() * (3.0 * t2 * one_minus_t);
206 TYPE v3 = keyframes[i+1].getValue().getPosition() * (t2 * t);
208 result = v0 + v1 + v2 + v3;
212 typedef TemplateStepInterpolator<double, double> DoubleStepInterpolator;
213 typedef TemplateStepInterpolator<float, float> FloatStepInterpolator;
214 typedef TemplateStepInterpolator<osg::Vec2, osg::Vec2> Vec2StepInterpolator;
215 typedef TemplateStepInterpolator<osg::Vec3, osg::Vec3> Vec3StepInterpolator;
216 typedef TemplateStepInterpolator<osg::Vec3, Vec3Packed> Vec3PackedStepInterpolator;
217 typedef TemplateStepInterpolator<osg::Vec4, osg::Vec4> Vec4StepInterpolator;
218 typedef TemplateStepInterpolator<osg::Quat, osg::Quat> QuatStepInterpolator;
220 typedef TemplateLinearInterpolator<double, double> DoubleLinearInterpolator;
221 typedef TemplateLinearInterpolator<float, float> FloatLinearInterpolator;
222 typedef TemplateLinearInterpolator<osg::Vec2, osg::Vec2> Vec2LinearInterpolator;
223 typedef TemplateLinearInterpolator<osg::Vec3, osg::Vec3> Vec3LinearInterpolator;
224 typedef TemplateLinearInterpolator<osg::Vec3, Vec3Packed> Vec3PackedLinearInterpolator;
225 typedef TemplateLinearInterpolator<osg::Vec4, osg::Vec4> Vec4LinearInterpolator;
226 typedef TemplateSphericalLinearInterpolator<osg::Quat, osg::Quat> QuatSphericalLinearInterpolator;
227 typedef TemplateLinearInterpolator<osg::Matrixf, osg::Matrixf> MatrixLinearInterpolator;
229 typedef TemplateCubicBezierInterpolator<float, FloatCubicBezier > FloatCubicBezierInterpolator;
230 typedef TemplateCubicBezierInterpolator<double, DoubleCubicBezier> DoubleCubicBezierInterpolator;
231 typedef TemplateCubicBezierInterpolator<osg::Vec2, Vec2CubicBezier> Vec2CubicBezierInterpolator;
232 typedef TemplateCubicBezierInterpolator<osg::Vec3, Vec3CubicBezier> Vec3CubicBezierInterpolator;
233 typedef TemplateCubicBezierInterpolator<osg::Vec4, Vec4CubicBezier> Vec4CubicBezierInterpolator;