2 * Copyright (C) 2008 Cedric Pinson <cedric.pinson@plopbyte.net>
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.
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.
15#ifndef OSGANIMATION_EASE_MOTION
16#define OSGANIMATION_EASE_MOTION 1
18#include <osg/Referenced>
26 struct OutBounceFunction
28 inline static void getValueAt(float t, float& result)
32 result = 7.5625 * t * t;
34 else if (t < (2/2.75))
37 result = 7.5625* t * t + .75;
39 else if (t < (2.5/2.75))
42 result = 7.5625 * t * t + .9375;
47 result = 7.5625* t * t + .984375;
52 struct InBounceFunction
54 inline static void getValueAt(float t, float& result)
56 OutBounceFunction::getValueAt(1-t, result);
61 struct InOutBounceFunction
63 inline static void getValueAt(float t, float& result)
67 InBounceFunction::getValueAt(t * 2, result);
72 OutBounceFunction::getValueAt(t * 2 - 1 , result);
73 result = result * 0.5 + 0.5;
81 inline static void getValueAt(float t, float& result) { result = t;}
85 struct OutQuadFunction
87 inline static void getValueAt(float t, float& result) { result = - (t * (t -2.0));}
92 inline static void getValueAt(float t, float& result) { result = t*t;}
95 struct InOutQuadFunction
97 inline static void getValueAt(float t, float& result)
101 result = 0.5 * t * t;
105 result = - 0.5 * (t * ( t - 2) - 1);
111 struct OutCubicFunction
113 inline static void getValueAt(float t, float& result) { t = t-1.0; result = t*t*t + 1;}
116 struct InCubicFunction
118 inline static void getValueAt(float t, float& result) { result = t*t*t;}
121 struct InOutCubicFunction
123 inline static void getValueAt(float t, float& result)
127 result = 0.5f * t * t * t;
130 result = 0.5 * (t * t * t + 2.0f);
136 struct InQuartFunction
138 inline static void getValueAt(float t, float& result) { result = t*t*t*t*t;}
141 struct OutQuartFunction
143 inline static void getValueAt(float t, float& result) { t = t - 1; result = - (t*t*t*t -1); }
146 struct InOutQuartFunction
148 inline static void getValueAt(float t, float& result)
152 result = 0.5*t*t*t*t;
156 result = -0.5 * (t*t*t*t -2);
162 struct OutElasticFunction
164 inline static void getValueAt(float t, float& result)
166 result = pow(2.0f, -10.0f * t) * sinf((t - 0.3f / 4.0f) * (2.0f * osg::PI) / 0.3f) + 1.0f;
170 struct InElasticFunction
172 inline static void getValueAt(float t, float& result)
174 OutElasticFunction::getValueAt(1.0f - t, result);
175 result = 1.0f - result;
179 struct InOutElasticFunction
181 inline static void getValueAt(float t, float& result)
187 result = -0.5 * (1.0f * pow(2.0f, 10.0f * t) * sinf((t - 0.45f / 4.0f) * (2.0f * osg::PI) / 0.45f));
192 result = pow(2.0f, -10.0f * t) * sinf((t - 0.45f / 4.0f) * (2.0f * osg::PI) / 0.45f) * 0.5f + 1.0f;
198 struct OutSineFunction
200 inline static void getValueAt(float t, float& result)
202 result = sinf(t * (osg::PI / 2.0f));
206 struct InSineFunction
208 inline static void getValueAt(float t, float& result)
210 result = -cosf(t * (osg::PI / 2.0f)) + 1.0f;
214 struct InOutSineFunction
216 inline static void getValueAt(float t, float& result)
218 result = -0.5f * (cosf((osg::PI * t)) - 1.0f);
223 struct OutBackFunction
225 inline static void getValueAt(float t, float& result)
228 result = t * t * ((1.70158 + 1.0f) * t + 1.70158) + 1.0f;
232 struct InBackFunction
234 inline static void getValueAt(float t, float& result)
236 result = t * t * ((1.70158 + 1.0f) * t - 1.70158);
240 struct InOutBackFunction
242 inline static void getValueAt(float t, float& result)
244 float s = 1.70158 * 1.525f;
248 result = 0.5f * (t * t * ((s + 1.0f) * t - s));
253 result = 0.5f * ((p) * t * ((s + 1.0f) * t + s) + 2.0f);
259 struct OutCircFunction
261 inline static void getValueAt(float t, float& result)
264 result = sqrt(1.0f - t * t);
268 struct InCircFunction
270 inline static void getValueAt(float t, float& result)
272 result = -(sqrt(1.0f - (t * t)) - 1.0f);
276 struct InOutCircFunction
278 inline static void getValueAt(float t, float& result)
283 result = -0.5f * (sqrt(1.0f - t * t) - 1.0f);
288 result = 0.5f * (sqrt(1 - t * t) + 1.0f);
294 struct OutExpoFunction
296 inline static void getValueAt(float t, float& result)
304 result = -powf(2.0f, -10.0f * t) + 1.0f;
309 struct InExpoFunction
311 inline static void getValueAt(float t, float& result)
319 result = powf(2.0f, 10.0f * (t - 1.0f));
324 struct InOutExpoFunction
326 inline static void getValueAt(float t, float& result)
328 if(t == 0.0f || t == 1.0f)
337 result = 0.5f * powf(2.0f, 10.0f * (t - 1.0f));
341 result = 0.5f * (-powf(2.0f, -10.0f * (t - 1.0f)) + 2.0f);
347 class Motion : public osg::Referenced
350 typedef float value_type;
356 Motion(float startValue = 0, float duration = 1, float changeValue = 1, TimeBehaviour tb = CLAMP) : _time(0), _startValue(startValue), _changeValue(changeValue), _duration(duration), _behaviour(tb) {}
358 void reset() { setTime(0);}
359 float getTime() const { return _time; }
360 float evaluateTime(float time) const
365 if (time > _duration)
374 time = fmodf(time, _duration);
380 void update(float dt)
382 _time = evaluateTime(_time + dt);
385 void setTime(float time) { _time = evaluateTime(time);}
386 void getValue(value_type& result) const { getValueAt(_time, result); }
387 value_type getValue() const
390 getValueAt(_time, result);
394 void getValueAt(float time, value_type& result) const
396 getValueInNormalizedRange(evaluateTime(time)/_duration, result);
397 result = result * _changeValue + _startValue;
399 value_type getValueAt(float time) const
402 getValueAt(evaluateTime(time), result);
406 virtual void getValueInNormalizedRange(float t, value_type& result) const = 0;
408 float getDuration() const { return _duration;}
414 TimeBehaviour _behaviour;
419 template <typename T>
420 struct MathMotionTemplate : public Motion
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); }
427 struct SamplerMotionTemplate : public Motion
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
435 if (!_sampler.getKeyframeContainer())
440 float size = _sampler.getEndTime() - _sampler.getStartTime();
441 t = t * size + _sampler.getStartTime();
442 _sampler.getValueAt(t, result);
446 struct CompositeMotion : public Motion
448 typedef std::vector<osg::ref_ptr<Motion> > MotionList;
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) {}
455 virtual void getValueInNormalizedRange(float t, value_type& result) const
457 if (_motions.empty())
460 osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange no Motion in the CompositeMotion, add motion to have result" << std::endl;
463 for (MotionList::const_iterator it = _motions.begin(); it != _motions.end(); ++it)
465 const Motion* motion = static_cast<const Motion*>(it->get());
466 float durationInRange = motion->getDuration() / getDuration();
467 if (t < durationInRange)
469 float tInRange = t/durationInRange * motion->getDuration();
470 motion->getValueAt( tInRange, result);
473 t = t - durationInRange;
475 osg::notify(osg::WARN) << "CompositeMotion::getValueInNormalizedRange did find the value in range, something wrong" << std::endl;
482 typedef MathMotionTemplate<LinearFunction > LinearMotion;
485 typedef MathMotionTemplate<OutQuadFunction > OutQuadMotion;
486 typedef MathMotionTemplate<InQuadFunction> InQuadMotion;
487 typedef MathMotionTemplate<InOutQuadFunction> InOutQuadMotion;
490 typedef MathMotionTemplate<OutCubicFunction > OutCubicMotion;
491 typedef MathMotionTemplate<InCubicFunction> InCubicMotion;
492 typedef MathMotionTemplate<InOutCubicFunction> InOutCubicMotion;
495 typedef MathMotionTemplate<OutQuartFunction > OutQuartMotion;
496 typedef MathMotionTemplate<InQuartFunction> InQuartMotion;
497 typedef MathMotionTemplate<InOutQuartFunction> InOutQuartMotion;
500 typedef MathMotionTemplate<OutBounceFunction > OutBounceMotion;
501 typedef MathMotionTemplate<InBounceFunction> InBounceMotion;
502 typedef MathMotionTemplate<InOutBounceFunction> InOutBounceMotion;
505 typedef MathMotionTemplate<OutElasticFunction > OutElasticMotion;
506 typedef MathMotionTemplate<InElasticFunction > InElasticMotion;
507 typedef MathMotionTemplate<InOutElasticFunction > InOutElasticMotion;
510 typedef MathMotionTemplate<OutSineFunction > OutSineMotion;
511 typedef MathMotionTemplate<InSineFunction > InSineMotion;
512 typedef MathMotionTemplate<InOutSineFunction > InOutSineMotion;
515 typedef MathMotionTemplate<OutBackFunction > OutBackMotion;
516 typedef MathMotionTemplate<InBackFunction > InBackMotion;
517 typedef MathMotionTemplate<InOutBackFunction > InOutBackMotion;
520 typedef MathMotionTemplate<OutCircFunction > OutCircMotion;
521 typedef MathMotionTemplate<InCircFunction > InCircMotion;
522 typedef MathMotionTemplate<InOutCircFunction > InOutCircMotion;
525 typedef MathMotionTemplate<OutExpoFunction > OutExpoMotion;
526 typedef MathMotionTemplate<InExpoFunction > InExpoMotion;
527 typedef MathMotionTemplate<InOutExpoFunction > InOutExpoMotion;