root/OpenSceneGraph/trunk/include/osgAnimation/Interpolator @ 13041

Revision 13041, 9.2 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*  -*-c++-*-
2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
3 *
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.
8 *
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.
13 *
14 * Authors:
15 *         Cedric Pinson <cedric.pinson@plopbyte.net>
16 *         Michael Platings <mplatings@pixelpower.com>
17 */
18
19#ifndef OSGANIMATION_INTERPOLATOR
20#define OSGANIMATION_INTERPOLATOR 1
21
22#include <osg/Notify>
23#include <osgAnimation/Keyframe>
24
25namespace osgAnimation
26{
27
28    template <class TYPE, class KEY>
29    class TemplateInterpolatorBase
30    {
31    public:
32        typedef KEY KeyframeType;
33        typedef TYPE UsingType;
34
35    public:
36        mutable int _lastKeyAccess;
37
38        TemplateInterpolatorBase() : _lastKeyAccess(-1) {}
39
40        void reset() { _lastKeyAccess = -1; }
41        int getKeyIndexFromTime(const TemplateKeyframeContainer<KEY>& keys, double time) const
42        {
43            // todo use a cache
44            int key_size = keys.size();
45            if (!key_size) {
46                osg::notify(osg::WARN) << "TemplateInterpolatorBase::getKeyIndexFromTime the container is empty, impossible to get key index from time" << std::endl;;
47                return -1;
48            }
49            const TemplateKeyframe<KeyframeType>* keysVector = &keys.front();
50            for (int i = 0; i < key_size-1; i++)
51            {
52                double time0 = keysVector[i].getTime();
53                double time1 = keysVector[i+1].getTime();
54
55                if ( time >= time0 && time < time1 )
56                {
57                    _lastKeyAccess = i;
58                    return i;
59                }
60            }
61            osg::notify(osg::WARN) << time << " first key " << keysVector[0].getTime() << " last key " << keysVector[key_size-1].getTime() << std::endl;
62            return -1;
63        }
64    };
65
66
67    template <class TYPE, class KEY=TYPE>
68    class TemplateStepInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
69    {
70    public:
71
72        TemplateStepInterpolator() {}
73        void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
74        {
75
76            if (time >= keyframes.back().getTime())
77            {
78                result = keyframes.back().getValue();
79                return;
80            }
81            else if (time <= keyframes.front().getTime())
82            {
83                result = keyframes.front().getValue();
84                return;
85            }
86
87            int i = this->getKeyIndexFromTime(keyframes,time);
88            result = keyframes[i].getValue();
89        }
90    };
91
92
93    template <class TYPE, class KEY=TYPE>
94    class TemplateLinearInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
95    {
96    public:
97
98        TemplateLinearInterpolator() {}
99        void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
100        {
101
102            if (time >= keyframes.back().getTime())
103            {
104                result = keyframes.back().getValue();
105                return;
106            }
107            else if (time <= keyframes.front().getTime())
108            {
109                result = keyframes.front().getValue();
110                return;
111            }
112
113            int i = this->getKeyIndexFromTime(keyframes,time);
114            float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() -  keyframes[i].getTime());
115            const TYPE& v1 =  keyframes[i].getValue();
116            const TYPE& v2 =  keyframes[i+1].getValue();
117            result = v1*(1-blend) + v2*blend;
118        }
119    };
120
121
122    template <class TYPE, class KEY=TYPE>
123    class TemplateSphericalLinearInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
124    {
125    public:
126        TemplateSphericalLinearInterpolator() {}
127        void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
128        {
129            if (time >= keyframes.back().getTime())
130            {
131                result = keyframes.back().getValue();
132                return;
133            }
134            else if (time <= keyframes.front().getTime())
135            {
136                result = keyframes.front().getValue();
137                return;
138            }
139
140            int i = this->getKeyIndexFromTime(keyframes,time);
141            float blend = (time -  keyframes[i].getTime()) / ( keyframes[i+1].getTime() -  keyframes[i].getTime());
142            const TYPE& q1 =  keyframes[i].getValue();
143            const TYPE& q2 =  keyframes[i+1].getValue();
144            result.slerp(blend,q1,q2);
145        }
146    };
147
148
149    template <class TYPE, class KEY>
150    class TemplateLinearPackedInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
151    {
152    public:
153
154        TemplateLinearPackedInterpolator() {}
155        void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
156        {
157            if (time >= keyframes.back().getTime())
158            {
159                keyframes.back().getValue().uncompress(keyframes.mScale, keyframes.mMin, result);
160                return;
161            }
162            else if (time <= keyframes.front().getTime())
163            {
164                keyframes.front().getValue().uncompress(keyframes.mScale, keyframes.mMin, result);
165                return;
166            }
167
168            int i = this->getKeyIndexFromTime(keyframes,time);
169            float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() -  keyframes[i].getTime());
170            TYPE v1,v2;
171            keyframes[i].getValue().uncompress(keyframes.mScale, keyframes.mMin, v1);
172            keyframes[i+1].getValue().uncompress(keyframes.mScale, keyframes.mMin, v2);
173            result = v1*(1-blend) + v2*blend;
174        }
175    };
176
177
178    // http://en.wikipedia.org/wiki/B%C3%A9zier_curve
179    template <class TYPE, class KEY=TYPE>
180    class TemplateCubicBezierInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
181    {
182    public:
183
184        TemplateCubicBezierInterpolator() {}
185        void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
186        {
187
188            if (time >= keyframes.back().getTime())
189            {
190                result = keyframes.back().getValue().getPosition();
191                return;
192            }
193            else if (time <= keyframes.front().getTime())
194            {
195                result = keyframes.front().getValue().getPosition();
196                return;
197            }
198
199            int i = this->getKeyIndexFromTime(keyframes,time);
200
201            float t = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() -  keyframes[i].getTime());
202            float one_minus_t = 1.0-t;
203            float one_minus_t2 = one_minus_t * one_minus_t;
204            float one_minus_t3 = one_minus_t2 * one_minus_t;
205            float t2 = t * t;
206
207            TYPE v0 = keyframes[i].getValue().getPosition() * one_minus_t3;
208            TYPE v1 = keyframes[i].getValue().getControlPointIn() * (3.0 * t * one_minus_t2);
209            TYPE v2 = keyframes[i].getValue().getControlPointOut() * (3.0 * t2 * one_minus_t);
210            TYPE v3 = keyframes[i+1].getValue().getPosition() * (t2 * t);
211
212            result = v0 + v1 + v2 + v3;
213        }
214    };
215
216    typedef TemplateStepInterpolator<double, double> DoubleStepInterpolator;
217    typedef TemplateStepInterpolator<float, float> FloatStepInterpolator;
218    typedef TemplateStepInterpolator<osg::Vec2, osg::Vec2> Vec2StepInterpolator;
219    typedef TemplateStepInterpolator<osg::Vec3, osg::Vec3> Vec3StepInterpolator;
220    typedef TemplateStepInterpolator<osg::Vec3, Vec3Packed> Vec3PackedStepInterpolator;
221    typedef TemplateStepInterpolator<osg::Vec4, osg::Vec4> Vec4StepInterpolator;
222    typedef TemplateStepInterpolator<osg::Quat, osg::Quat> QuatStepInterpolator;
223
224    typedef TemplateLinearInterpolator<double, double> DoubleLinearInterpolator;
225    typedef TemplateLinearInterpolator<float, float> FloatLinearInterpolator;
226    typedef TemplateLinearInterpolator<osg::Vec2, osg::Vec2> Vec2LinearInterpolator;
227    typedef TemplateLinearInterpolator<osg::Vec3, osg::Vec3> Vec3LinearInterpolator;
228    typedef TemplateLinearInterpolator<osg::Vec3, Vec3Packed> Vec3PackedLinearInterpolator;
229    typedef TemplateLinearInterpolator<osg::Vec4, osg::Vec4> Vec4LinearInterpolator;
230    typedef TemplateSphericalLinearInterpolator<osg::Quat, osg::Quat> QuatSphericalLinearInterpolator;
231    typedef TemplateLinearInterpolator<osg::Matrixf, osg::Matrixf> MatrixLinearInterpolator;
232
233    typedef TemplateCubicBezierInterpolator<float, FloatCubicBezier > FloatCubicBezierInterpolator;
234    typedef TemplateCubicBezierInterpolator<double, DoubleCubicBezier> DoubleCubicBezierInterpolator;
235    typedef TemplateCubicBezierInterpolator<osg::Vec2, Vec2CubicBezier> Vec2CubicBezierInterpolator;
236    typedef TemplateCubicBezierInterpolator<osg::Vec3, Vec3CubicBezier> Vec3CubicBezierInterpolator;
237    typedef TemplateCubicBezierInterpolator<osg::Vec4, Vec4CubicBezier> Vec4CubicBezierInterpolator;
238
239}
240#endif
Note: See TracBrowser for help on using the browser.