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

Revision 10877, 9.1 kB (checked in by cedricpinson, 5 years ago)

From Cedric Pinson,
Add check in RigTransformSoftware? if bones are null
Indent TimelineAnimationManager?
Add check for NaN in UpdateCallback?.cpp
Fix TimelineAnimationManager? clear target (a refactore of Timeline is require for futur)
Fix Computation of bounding box for RigGeometry?

RevLine 
[9093]1/*  -*-c++-*-
[10527]2 *  Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
[9093]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.
[10527]13 *
14 * Authors:
15 *         Cedric Pinson <cedric.pinson@plopbyte.net>
16 *         Michael Platings <mplatings@pixelpower.com>
17 */
[9093]18
[10877]19#ifndef OSGANIMATION_INTERPOLATOR
20#define OSGANIMATION_INTERPOLATOR 1
[9093]21
[9531]22#include <osg/Notify>
[9093]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, float time) const
42        {
43            // todo use a cache
44            int key_size = keys.size();
[9531]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            }
[9093]49            const TemplateKeyframe<KeyframeType>* keysVector = &keys.front();
[9531]50            for (int i = 0; i < key_size-1; i++)
[9093]51            {
52                float time0 = keysVector[i].getTime();
53                float time1 = keysVector[i+1].getTime();
[9456]54
[9093]55                if ( time >= time0 && time < time1 )
56                {
57                    _lastKeyAccess = i;
58                    return i;
59                }
60            }
[9531]61            osg::notify(osg::WARN) << time << " first key " << keysVector[0].getTime() << " last key " << keysVector[key_size-1].getTime() << std::endl;
[9093]62            return -1;
63        }
64    };
65
66
67    template <class TYPE, class KEY=TYPE>
[10527]68    class TemplateStepInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
69    {
70    public:
71
72        TemplateStepInterpolator() {}
73        void getValue(const TemplateKeyframeContainer<KEY>& keyframes, float 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 = getKeyIndexFromTime(keyframes,time);
[10552]88            result = keyframes[i].getValue();
[10527]89        }
90    };
91
92
93    template <class TYPE, class KEY=TYPE>
[9093]94    class TemplateLinearInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
95    {
96    public:
97
98        TemplateLinearInterpolator() {}
99        void getValue(const TemplateKeyframeContainer<KEY>& keyframes, float 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 = 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, float 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 = 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, float 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 = 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, float 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 = 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().getTangentPoint1() * (3.0 * t * one_minus_t2);
209            TYPE v2 = keyframes[i].getValue().getTangentPoint2() * (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
[10527]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
[9093]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
232    typedef TemplateCubicBezierInterpolator<float, FloatCubicBezier > FloatCubicBezierInterpolator;
233    typedef TemplateCubicBezierInterpolator<double, DoubleCubicBezier> DoubleCubicBezierInterpolator;
234    typedef TemplateCubicBezierInterpolator<osg::Vec2, Vec2CubicBezier> Vec2CubicBezierInterpolator;
235    typedef TemplateCubicBezierInterpolator<osg::Vec3, Vec3CubicBezier> Vec3CubicBezierInterpolator;
236    typedef TemplateCubicBezierInterpolator<osg::Vec4, Vec4CubicBezier> Vec4CubicBezierInterpolator;
237
238}
239#endif
Note: See TracBrowser for help on using the browser.