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

Revision 9981, 10.9 kB (checked in by cedricpinson, 6 years ago)

From Serge Lages, Elastic added to EaseMotion

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            }
316            for (MotionList::const_iterator it = _motions.begin(); it != _motions.end(); it++)
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.