root/OpenSceneGraph/trunk/include/osgAnimation/EaseMotion @ 11009

Revision 11009, 10.9 kB (checked in by robert, 4 years ago)

From Cedric Pinson, "Here a list of changes:
Bone now inherit from MatrixTransform?. It simplify a lot the update of
Bone matrix. It helps to have the bone system more generic. eg it's now
possible to have animation data with precomputed bind matrix. The other
benefit, is now the collada plugin will be able to use osgAnimation to
display skinned mesh. Michael Plating did a great work to improve this
aspect, he is working on the collada plugin and should be able to submit
a new version soon.
The RigGeometry? has been refactored so now it works when you save and
reload RigGeometry? because the source is not touched anymore. The
benefit with this update is that it should be now possible to use a
MorphGeometry? as source for a RigGeometry?.

The bad news is that the format has changed, so i have rebuild osg-data
related to osgAnimation data, updated the blender exporter to export to
the new format.
The fbx plugin could be touched about this commit, i dont compile it so
i can't give more information about it.
The bvh plugin has been updated by Wang rui so this one is fixed with
the new code of osgAnimation.
The examples has been updated to work with the new code too...

The example osg-data/example.osg should be remove, it's an old example
that does not work.

For people using blender the blender exporter up to date is here:
http://hg.plopbyte.net/osgexport2/
it will be merge to http://hg.plopbyte.net/osgexport/ as soon as the
modification will be push in the trunk.
"

RevLine 
[9093]1/*  -*-c++-*-
2 *  Copyright (C) 2008 Cedric Pinson <mornifle@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
15#ifndef OSGANIMATION_EASE_MOTION_H
16#define OSGANIMATION_EASE_MOTION_H
17
[9370]18#include <osg/Referenced>
19#include <osg/ref_ptr>
20#include <osg/Notify>
21#include <osg/Math>
22#include <vector>
23
[9093]24namespace osgAnimation {
25
26
27    struct OutBounceFunction
28    {
29        inline static void getValueAt(float t, float& result)
30        {
31            if ((t) < (1/2.75))
32            {
33                result = 7.5625 * t * t;
34            }
35            else if (t < (2/2.75))
36            {
37                t = t - (1.5/2.75);
38                result = 7.5625* t * t + .75;
39            }
40            else if (t < (2.5/2.75))
41            {
42                t = t - (2.25/2.75);
43                result = 7.5625 * t * t + .9375;
44            }
45            else
46            {
47                t = t - (2.625/2.75);
48                result = 7.5625* t * t + .984375;
49            }
50        }
51    };
52
53    struct InBounceFunction
54    {
55        inline static void getValueAt(float t, float& result)
56        {
57            OutBounceFunction::getValueAt(1-t, result);
58            result = 1 - result;
59        }
60    };
61
62    struct InOutBounceFunction
63    {
64        inline static void getValueAt(float t, float& result)
65        {
66            if (t < 0.5)
67            {
68                InBounceFunction::getValueAt(t * 2, result);
69                result *= 0.5;
70            }
71            else
72            {
73                OutBounceFunction::getValueAt(t * 2 - 1 , result);
74                result = result * 0.5 + 0.5;
75            }
76        }
77    };
78
[9286]79
80    /// Linear function
81    struct LinearFunction
82    {
83        inline static void getValueAt(float t, float& result) { result = t;}
84    };
85
[9093]86 
[9286]87    /// Quad function
[9093]88    struct OutQuadFunction
89    {
90        inline static void getValueAt(float t, float& result) { result = - (t * (t -2.0));}
91    };
92
93    struct InQuadFunction
94    {
95        inline static void getValueAt(float t, float& result) { result = t*t;}
96    };
97    struct InOutQuadFunction
98    {
99        inline static void getValueAt(float t, float& result)
100        {
101            t = t * 2.0;
102            if (t < 1.0)
103                result = 0.5 * t * t;
104            else
105            {
106                t = t - 1.0;
107                result = - 0.5 * t * ( t - 2) - 1;
108            }
109        }
110    };
111
112
[9286]113    /// Cubic function
[9093]114    struct OutCubicFunction
115    {
116        inline static void getValueAt(float t, float& result) { t = t-1.0; result = t*t*t + 1;}
117    };
118    struct InCubicFunction
119    {
120        inline static void getValueAt(float t, float& result) { result = t*t*t;}
121    };
122    struct InOutCubicFunction
123    {
124        inline static void getValueAt(float t, float& result)
125        {
126            t = t * 2;
127            if (t < 1.0)
128                result = 0.5 * t * t * t;
129            else {
130                t = t - 2;
131                result = 0.5 * t * t * t + 2;
132            }
133        }
134    };
135 
[9286]136
137    /// Quart function
138    struct InQuartFunction
139    {
140        inline static void getValueAt(float t, float& result) { result = t*t*t*t*t;}
141    };
142
143    struct OutQuartFunction
144    {
145        inline static void getValueAt(float t, float& result) { t = t - 1; result = - (t*t*t*t -1); }
146    };
147
148    struct InOutQuartFunction
149    {
150        inline static void getValueAt(float t, float& result)
151        {
152            t = t * 2.0;
153            if ( t < 1)
154                result = 0.5*t*t*t*t;
155            else
156            {
157                t -= 2.0;
158                result = -0.5 * (t*t*t*t -2);
159            }
160        }
161    };
162
[9981]163    /// Elastic function
164    struct OutElasticFunction
165    {
166        inline static void getValueAt(float t, float& result)
167        {
168            result = pow(2.0f, -10.0f * t) * sinf((t - 0.3f / 4.0f) * (2.0f * osg::PI) / 0.3f) + 1.0f;
169        }
170    };
[9286]171
[9981]172    struct InElasticFunction
173    {
174        inline static void getValueAt(float t, float& result)
175        {
176            OutElasticFunction::getValueAt(1.0f - t, result);
177            result = 1.0f - result;
178        }
179    };
[9286]180
[9981]181    struct InOutElasticFunction
182    {
183        inline static void getValueAt(float t, float& result)
184        {
185            t *= 2.0f;
186            if (t < 1.0f)
187            {
188                t -= 1.0f;
189                result =  -0.5 * (1.0f * pow(2.0f, 10.0f * t) * sinf((t - 0.45f / 4.0f) * (2.0f * osg::PI) / 0.45f));
190            }
191            else
192            {
193                t -= 1.0f;
194                result = pow(2.0f, -10.0f * t) * sinf((t - 0.45f / 4.0f) * (2.0f * osg::PI) / 0.45f) * 0.5f + 1.0f;
195            }
196        }
197    };
198
199
[9370]200    class Motion : public osg::Referenced
[9093]201    {
202    public:
203        typedef float value_type;
204        enum TimeBehaviour
205        {
206            CLAMP,
[9388]207            LOOP
[9093]208        };
[9370]209        Motion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : _time(0), _startValue(startValue), _changeValue(changeValue), _duration(duration), _behaviour(tb) {}
[9093]210        virtual ~Motion() {}
211        void reset() { setTime(0);}
212        float getTime() const { return _time; }
[9370]213        float evaluateTime(float time) const
[9093]214        {
215            switch (_behaviour)
216            {
217            case CLAMP:
[9370]218                if (time > _duration)
219                    time = _duration;
220                else if (time < 0.0)
221                    time = 0.0;
[9093]222                break;
223            case LOOP:
[9370]224                if (time <= 0)
225                    time = 0;
226                else
227                    time = fmodf(time, _duration);
[9093]228                break;
229            }
[9370]230            return time;
[9093]231        }
[9370]232
233        void update(float dt)
234        {
235            _time = evaluateTime(_time + dt);
236        }
[9093]237   
[9370]238        void setTime(float time) { _time = evaluateTime(time);}
[9093]239        void getValue(value_type& result) const { getValueAt(_time, result); }
240        value_type getValue() const
241        {
242            value_type result;
243            getValueAt(_time, result);
244            return result;
245        }
246
247        void getValueAt(float time, value_type& result) const
248        {
[9370]249            getValueInNormalizedRange(evaluateTime(time)/_duration, result);
250            result = result * _changeValue + _startValue;
[9093]251        }
252        value_type getValueAt(float time) const
253        {
254            value_type result;
[9370]255            getValueAt(evaluateTime(time), result);
[9093]256            return result;
257        }
258
259        virtual void getValueInNormalizedRange(float t, value_type& result) const = 0;
260
[9370]261        float getDuration() const { return _duration;}
[9093]262    protected:     
263        float _time;
[9370]264        float _startValue;
265        float _changeValue;
266        float _duration;
[9093]267        TimeBehaviour _behaviour;
268    };
269
270
[9286]271
[9093]272    template <typename T>
273    struct MathMotionTemplate : public Motion
274    {
275        MathMotionTemplate(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : Motion(startValue, duration, changeValue, tb) {}
276        virtual void getValueInNormalizedRange(float t, value_type& result) const { T::getValueAt(t, result); }
277    };
278
279    template <class T>
280    struct SamplerMotionTemplate : public Motion
281    {
282        T _sampler;
283        SamplerMotionTemplate(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : Motion(startValue, duration, changeValue, tb) {}
284        T& getSampler() { return _sampler;}
285        const T& getSampler() const { return _sampler;}
286        virtual void getValueInNormalizedRange(float t, value_type& result) const
287        {
288            if (!_sampler.getKeyframeContainer())
289            {
290                result = 0;
291                return;
292            }
293            float size = _sampler.getEndTime() - _sampler.getStartTime();
294            t = t * size + _sampler.getStartTime();
295            _sampler.getValueAt(t, result);
296        }
297    };
298
[9370]299    struct CompositeMotion : public Motion
300    {
301        typedef std::vector<osg::ref_ptr<Motion> > MotionList;
302        MotionList _motions;
303       
304        MotionList& getMotionList() { return _motions; }
305        const MotionList& getMotionList() const { return _motions; }
306        CompositeMotion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : Motion(startValue, duration, changeValue, tb) {}
[9093]307
[9370]308        virtual void getValueInNormalizedRange(float t, value_type& result) const
309        {
310            if (_motions.empty())
311            {
312                result = 0;
313                osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange no Motion in the CompositeMotion, add motion to have result" << std::endl;
314                return;
315            }
[11009]316            for (MotionList::const_iterator it = _motions.begin(); it != _motions.end(); ++it)
[9370]317            {
318                const Motion* motion = static_cast<const Motion*>(it->get());
319                float durationInRange = motion->getDuration() / getDuration();
320                if (t < durationInRange)
321                {
322                    float tInRange = t/durationInRange * motion->getDuration();
323                    motion->getValueAt( tInRange, result);
324                    return;
325                } else
326                    t = t - durationInRange;
327            }
328            osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange did find the value in range, something wrong" << std::endl;
329            result = 0;
330        }
331    };
[9093]332
[9370]333
[9093]334    // linear
335    typedef MathMotionTemplate<LinearFunction > LinearMotion;
336
[9286]337    // quad
338    typedef MathMotionTemplate<OutQuadFunction > OutQuadMotion;
339    typedef MathMotionTemplate<InQuadFunction> InQuadMotion;
340    typedef MathMotionTemplate<InOutQuadFunction> InOutQuadMotion;
341
[9093]342    // cubic
343    typedef MathMotionTemplate<OutCubicFunction > OutCubicMotion;
344    typedef MathMotionTemplate<InCubicFunction> InCubicMotion;
345    typedef MathMotionTemplate<InOutCubicFunction> InOutCubicMotion;
346
[9286]347    // quart
348    typedef MathMotionTemplate<OutQuartFunction > OutQuartMotion;
349    typedef MathMotionTemplate<InQuartFunction> InQuartMotion;
350    typedef MathMotionTemplate<InOutQuartFunction> InOutQuartMotion;
[9093]351
[9286]352
[9093]353    // bounce
354    typedef MathMotionTemplate<OutBounceFunction > OutBounceMotion;
355    typedef MathMotionTemplate<InBounceFunction> InBounceMotion;
356    typedef MathMotionTemplate<InOutBounceFunction> InOutBounceMotion;
357
[9981]358    // elastic
359    typedef MathMotionTemplate<OutElasticFunction > OutElasticMotion;
360    typedef MathMotionTemplate<InElasticFunction > InElasticMotion;
361    typedef MathMotionTemplate<InOutElasticFunction > InOutElasticMotion;
[9093]362
363}
364
365#endif
Note: See TracBrowser for help on using the browser.