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

Revision 13041, 15.0 kB (checked in by robert, 2 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
15#ifndef OSGANIMATION_EASE_MOTION
16#define OSGANIMATION_EASE_MOTION 1
17
18#include <osg/Referenced>
19#include <osg/ref_ptr>
20#include <osg/Notify>
21#include <osg/Math>
22#include <vector>
23
24namespace osgAnimation
25{
26    struct OutBounceFunction
27    {
28        inline static void getValueAt(float t, float& result)
29        {
30            if ((t) < (1/2.75))
31            {
32                result = 7.5625 * t * t;
33            }
34            else if (t < (2/2.75))
35            {
36                t = t - (1.5/2.75);
37                result = 7.5625* t * t + .75;
38            }
39            else if (t < (2.5/2.75))
40            {
41                t = t - (2.25/2.75);
42                result = 7.5625 * t * t + .9375;
43            }
44            else
45            {
46                t = t - (2.625/2.75);
47                result = 7.5625* t * t + .984375;
48            }
49        }
50    };
51
52    struct InBounceFunction
53    {
54        inline static void getValueAt(float t, float& result)
55        {
56            OutBounceFunction::getValueAt(1-t, result);
57            result = 1 - result;
58        }
59    };
60
61    struct InOutBounceFunction
62    {
63        inline static void getValueAt(float t, float& result)
64        {
65            if (t < 0.5)
66            {
67                InBounceFunction::getValueAt(t * 2, result);
68                result *= 0.5;
69            }
70            else
71            {
72                OutBounceFunction::getValueAt(t * 2 - 1 , result);
73                result = result * 0.5 + 0.5;
74            }
75        }
76    };
77
78    /// Linear function
79    struct LinearFunction
80    {
81        inline static void getValueAt(float t, float& result) { result = t;}
82    };
83
84    /// Quad function
85    struct OutQuadFunction
86    {
87        inline static void getValueAt(float t, float& result) { result = - (t * (t -2.0));}
88    };
89
90    struct InQuadFunction
91    {
92        inline static void getValueAt(float t, float& result) { result = t*t;}
93    };
94
95    struct InOutQuadFunction
96    {
97        inline static void getValueAt(float t, float& result)
98        {
99            t *= 2.0;
100            if (t < 1.0)
101                result = 0.5 * t * t;
102            else
103            {
104                t -= 1.0;
105                result = - 0.5 * (t * ( t - 2) - 1);
106            }
107        }
108    };
109
110    /// Cubic function
111    struct OutCubicFunction
112    {
113        inline static void getValueAt(float t, float& result) { t = t-1.0; result = t*t*t + 1;}
114    };
115
116    struct InCubicFunction
117    {
118        inline static void getValueAt(float t, float& result) { result = t*t*t;}
119    };
120
121    struct InOutCubicFunction
122    {
123        inline static void getValueAt(float t, float& result)
124        {
125            t *= 2.0f;
126            if (t < 1.0f)
127                result = 0.5f * t * t * t;
128            else {
129                t -= 2.0f;
130                result = 0.5 * (t * t * t + 2.0f);
131            }
132        }
133    };
134
135    /// Quart function
136    struct InQuartFunction
137    {
138        inline static void getValueAt(float t, float& result) { result = t*t*t*t*t;}
139    };
140
141    struct OutQuartFunction
142    {
143        inline static void getValueAt(float t, float& result) { t = t - 1; result = - (t*t*t*t -1); }
144    };
145
146    struct InOutQuartFunction
147    {
148        inline static void getValueAt(float t, float& result)
149        {
150            t = t * 2.0;
151            if ( t < 1)
152                result = 0.5*t*t*t*t;
153            else
154            {
155                t -= 2.0;
156                result = -0.5 * (t*t*t*t -2);
157            }
158        }
159    };
160
161    /// Elastic function
162    struct OutElasticFunction
163    {
164        inline static void getValueAt(float t, float& result)
165        {
166            result = pow(2.0f, -10.0f * t) * sinf((t - 0.3f / 4.0f) * (2.0f * osg::PI) / 0.3f) + 1.0f;
167        }
168    };
169
170    struct InElasticFunction
171    {
172        inline static void getValueAt(float t, float& result)
173        {
174            OutElasticFunction::getValueAt(1.0f - t, result);
175            result = 1.0f - result;
176        }
177    };
178
179    struct InOutElasticFunction
180    {
181        inline static void getValueAt(float t, float& result)
182        {
183            t *= 2.0f;
184            if (t < 1.0f)
185            {
186                t -= 1.0f;
187                result =  -0.5 * (1.0f * pow(2.0f, 10.0f * t) * sinf((t - 0.45f / 4.0f) * (2.0f * osg::PI) / 0.45f));
188            }
189            else
190            {
191                t -= 1.0f;
192                result = pow(2.0f, -10.0f * t) * sinf((t - 0.45f / 4.0f) * (2.0f * osg::PI) / 0.45f) * 0.5f + 1.0f;
193            }
194        }
195    };
196
197    // Sine function
198    struct OutSineFunction
199    {
200        inline static void getValueAt(float t, float& result)
201        {
202            result = sinf(t * (osg::PI / 2.0f));
203        }
204    };
205
206    struct InSineFunction
207    {
208        inline static void getValueAt(float t, float& result)
209        {
210            result = -cosf(t * (osg::PI / 2.0f)) + 1.0f;
211        }
212    };
213
214    struct InOutSineFunction
215    {
216        inline static void getValueAt(float t, float& result)
217        {
218            result = -0.5f * (cosf((osg::PI * t)) - 1.0f);
219        }
220    };
221
222    // Back function
223    struct OutBackFunction
224    {
225        inline static void getValueAt(float t, float& result)
226        {
227            t -= 1.0f;
228            result = t * t * ((1.70158 + 1.0f) * t + 1.70158) + 1.0f;
229        }
230    };
231
232    struct InBackFunction
233    {
234        inline static void getValueAt(float t, float& result)
235        {
236            result = t * t * ((1.70158 + 1.0f) * t - 1.70158);
237        }
238    };
239
240    struct InOutBackFunction
241    {
242        inline static void getValueAt(float t, float& result)
243        {
244            float s = 1.70158 * 1.525f;
245            t *= 2.0f;
246            if (t < 1.0f)
247            {
248                result = 0.5f * (t * t * ((s + 1.0f) * t - s));
249            }
250            else
251            {
252                float p = t -= 2.0f;
253                result = 0.5f * ((p) * t * ((s + 1.0f) * t + s) + 2.0f);
254            }
255        }
256    };
257
258    // Circ function
259    struct OutCircFunction
260    {
261        inline static void getValueAt(float t, float& result)
262        {
263            t -= 1.0f;
264            result = sqrt(1.0f - t * t);
265        }
266    };
267
268    struct InCircFunction
269    {
270        inline static void getValueAt(float t, float& result)
271        {
272            result = -(sqrt(1.0f - (t * t)) - 1.0f);
273        }
274    };
275
276    struct InOutCircFunction
277    {
278        inline static void getValueAt(float t, float& result)
279        {
280            t *= 2.0f;
281            if (t < 1.0f)
282            {
283                result = -0.5f * (sqrt(1.0f - t * t) - 1.0f);
284            }
285            else
286            {
287                t -= 2.0f;
288                result = 0.5f * (sqrt(1 - t * t) + 1.0f);
289            }
290        }
291    };
292
293    // Expo function
294    struct OutExpoFunction
295    {
296        inline static void getValueAt(float t, float& result)
297        {
298            if(t == 1.0f)
299            {
300                result = 0.0f;
301            }
302            else
303            {
304                result = -powf(2.0f, -10.0f * t) + 1.0f;
305            }
306        }
307    };
308
309    struct InExpoFunction
310    {
311        inline static void getValueAt(float t, float& result)
312        {
313            if(t == 0.0f)
314            {
315                result = 0.0f;
316            }
317            else
318            {
319                result = powf(2.0f, 10.0f * (t - 1.0f));
320            }
321        }
322    };
323
324    struct InOutExpoFunction
325    {
326        inline static void getValueAt(float t, float& result)
327        {
328            if(t == 0.0f || t == 1.0f)
329            {
330                result = 0.0f;
331            }
332            else
333            {
334                t *= 2.0f;
335                if(t < 1.0f)
336                {
337                    result = 0.5f * powf(2.0f, 10.0f * (t - 1.0f));
338                }
339                else
340                {
341                    result = 0.5f * (-powf(2.0f, -10.0f * (t - 1.0f)) + 2.0f);
342                }
343            }
344        }
345    };
346
347    class Motion : public osg::Referenced
348    {
349    public:
350        typedef float value_type;
351        enum TimeBehaviour
352        {
353            CLAMP,
354            LOOP
355        };
356        Motion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : _time(0), _startValue(startValue), _changeValue(changeValue), _duration(duration), _behaviour(tb) {}
357        virtual ~Motion() {}
358        void reset() { setTime(0);}
359        float getTime() const { return _time; }
360        float evaluateTime(float time) const
361        {
362            switch (_behaviour)
363            {
364            case CLAMP:
365                if (time > _duration)
366                    time = _duration;
367                else if (time < 0.0)
368                    time = 0.0;
369                break;
370            case LOOP:
371                if (time <= 0)
372                    time = 0;
373                else
374                    time = fmodf(time, _duration);
375                break;
376            }
377            return time;
378        }
379
380        void update(float dt)
381        {
382            _time = evaluateTime(_time + dt);
383        }
384
385        void setTime(float time) { _time = evaluateTime(time);}
386        void getValue(value_type& result) const { getValueAt(_time, result); }
387        value_type getValue() const
388        {
389            value_type result;
390            getValueAt(_time, result);
391            return result;
392        }
393
394        void getValueAt(float time, value_type& result) const
395        {
396            getValueInNormalizedRange(evaluateTime(time)/_duration, result);
397            result = result * _changeValue + _startValue;
398        }
399        value_type getValueAt(float time) const
400        {
401            value_type result;
402            getValueAt(evaluateTime(time), result);
403            return result;
404        }
405
406        virtual void getValueInNormalizedRange(float t, value_type& result) const = 0;
407
408        float getDuration() const { return _duration;}
409    protected:
410        float _time;
411        float _startValue;
412        float _changeValue;
413        float _duration;
414        TimeBehaviour _behaviour;
415    };
416
417
418
419    template <typename T>
420    struct MathMotionTemplate : public Motion
421    {
422        MathMotionTemplate(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : Motion(startValue, duration, changeValue, tb) {}
423        virtual void getValueInNormalizedRange(float t, value_type& result) const { T::getValueAt(t, result); }
424    };
425
426    template <class T>
427    struct SamplerMotionTemplate : public Motion
428    {
429        T _sampler;
430        SamplerMotionTemplate(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : Motion(startValue, duration, changeValue, tb) {}
431        T& getSampler() { return _sampler;}
432        const T& getSampler() const { return _sampler;}
433        virtual void getValueInNormalizedRange(float t, value_type& result) const
434        {
435            if (!_sampler.getKeyframeContainer())
436            {
437                result = 0;
438                return;
439            }
440            float size = _sampler.getEndTime() - _sampler.getStartTime();
441            t = t * size + _sampler.getStartTime();
442            _sampler.getValueAt(t, result);
443        }
444    };
445
446    struct CompositeMotion : public Motion
447    {
448        typedef std::vector<osg::ref_ptr<Motion> > MotionList;
449        MotionList _motions;
450
451        MotionList& getMotionList() { return _motions; }
452        const MotionList& getMotionList() const { return _motions; }
453        CompositeMotion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : Motion(startValue, duration, changeValue, tb) {}
454
455        virtual void getValueInNormalizedRange(float t, value_type& result) const
456        {
457            if (_motions.empty())
458            {
459                result = 0;
460                osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange no Motion in the CompositeMotion, add motion to have result" << std::endl;
461                return;
462            }
463            for (MotionList::const_iterator it = _motions.begin(); it != _motions.end(); ++it)
464            {
465                const Motion* motion = static_cast<const Motion*>(it->get());
466                float durationInRange = motion->getDuration() / getDuration();
467                if (t < durationInRange)
468                {
469                    float tInRange = t/durationInRange * motion->getDuration();
470                    motion->getValueAt( tInRange, result);
471                    return;
472                } else
473                    t = t - durationInRange;
474            }
475            osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange did find the value in range, something wrong" << std::endl;
476            result = 0;
477        }
478    };
479
480
481    // linear
482    typedef MathMotionTemplate<LinearFunction > LinearMotion;
483
484    // quad
485    typedef MathMotionTemplate<OutQuadFunction > OutQuadMotion;
486    typedef MathMotionTemplate<InQuadFunction> InQuadMotion;
487    typedef MathMotionTemplate<InOutQuadFunction> InOutQuadMotion;
488
489    // cubic
490    typedef MathMotionTemplate<OutCubicFunction > OutCubicMotion;
491    typedef MathMotionTemplate<InCubicFunction> InCubicMotion;
492    typedef MathMotionTemplate<InOutCubicFunction> InOutCubicMotion;
493
494    // quart
495    typedef MathMotionTemplate<OutQuartFunction > OutQuartMotion;
496    typedef MathMotionTemplate<InQuartFunction> InQuartMotion;
497    typedef MathMotionTemplate<InOutQuartFunction> InOutQuartMotion;
498
499    // bounce
500    typedef MathMotionTemplate<OutBounceFunction > OutBounceMotion;
501    typedef MathMotionTemplate<InBounceFunction> InBounceMotion;
502    typedef MathMotionTemplate<InOutBounceFunction> InOutBounceMotion;
503
504    // elastic
505    typedef MathMotionTemplate<OutElasticFunction > OutElasticMotion;
506    typedef MathMotionTemplate<InElasticFunction > InElasticMotion;
507    typedef MathMotionTemplate<InOutElasticFunction > InOutElasticMotion;
508
509    // sine
510    typedef MathMotionTemplate<OutSineFunction > OutSineMotion;
511    typedef MathMotionTemplate<InSineFunction > InSineMotion;
512    typedef MathMotionTemplate<InOutSineFunction > InOutSineMotion;
513
514    // back
515    typedef MathMotionTemplate<OutBackFunction > OutBackMotion;
516    typedef MathMotionTemplate<InBackFunction > InBackMotion;
517    typedef MathMotionTemplate<InOutBackFunction > InOutBackMotion;
518
519    // circ
520    typedef MathMotionTemplate<OutCircFunction > OutCircMotion;
521    typedef MathMotionTemplate<InCircFunction > InCircMotion;
522    typedef MathMotionTemplate<InOutCircFunction > InOutCircMotion;
523
524    // expo
525    typedef MathMotionTemplate<OutExpoFunction > OutExpoMotion;
526    typedef MathMotionTemplate<InExpoFunction > InExpoMotion;
527    typedef MathMotionTemplate<InOutExpoFunction > InOutExpoMotion;
528}
529
530#endif
Note: See TracBrowser for help on using the browser.