Interpolator 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. * Authors:
  15. * Cedric Pinson <cedric.pinson@plopbyte.net>
  16. * Michael Platings <mplatings@pixelpower.com>
  17. */
  18. #ifndef OSGANIMATION_INTERPOLATOR
  19. #define OSGANIMATION_INTERPOLATOR 1
  20. #include <osg/Notify>
  21. #include <osgAnimation/Keyframe>
  22. namespace osgAnimation
  23. {
  24. template <class TYPE, class KEY>
  25. class TemplateInterpolatorBase
  26. {
  27. public:
  28. typedef KEY KeyframeType;
  29. typedef TYPE UsingType;
  30. public:
  31. TemplateInterpolatorBase() {}
  32. int getKeyIndexFromTime(const TemplateKeyframeContainer<KEY>& keys, double time) const
  33. {
  34. int key_size = keys.size();
  35. if (!key_size) {
  36. osg::notify(osg::WARN) << "TemplateInterpolatorBase::getKeyIndexFromTime the container is empty, impossible to get key index from time" << std::endl;;
  37. return -1;
  38. }
  39. const TemplateKeyframe<KeyframeType>* keysVector = &keys.front();
  40. int k = 0;
  41. int l = key_size;
  42. int mid = key_size/2;
  43. while(mid != k){
  44. double time1 = keysVector[mid].getTime();
  45. if(time1 < time){
  46. k = mid;
  47. } else {
  48. l = mid;
  49. }
  50. mid = (l+k)/2;
  51. }
  52. return k;
  53. }
  54. };
  55. template <class TYPE, class KEY=TYPE>
  56. class TemplateStepInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
  57. {
  58. public:
  59. TemplateStepInterpolator() {}
  60. void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
  61. {
  62. if (time >= keyframes.back().getTime())
  63. {
  64. result = keyframes.back().getValue();
  65. return;
  66. }
  67. else if (time <= keyframes.front().getTime())
  68. {
  69. result = keyframes.front().getValue();
  70. return;
  71. }
  72. int i = this->getKeyIndexFromTime(keyframes,time);
  73. result = keyframes[i].getValue();
  74. }
  75. };
  76. template <class TYPE, class KEY=TYPE>
  77. class TemplateLinearInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
  78. {
  79. public:
  80. TemplateLinearInterpolator() {}
  81. void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
  82. {
  83. if (time >= keyframes.back().getTime())
  84. {
  85. result = keyframes.back().getValue();
  86. return;
  87. }
  88. else if (time <= keyframes.front().getTime())
  89. {
  90. result = keyframes.front().getValue();
  91. return;
  92. }
  93. int i = this->getKeyIndexFromTime(keyframes,time);
  94. float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime());
  95. const TYPE& v1 = keyframes[i].getValue();
  96. const TYPE& v2 = keyframes[i+1].getValue();
  97. result = v1*(1-blend) + v2*blend;
  98. }
  99. };
  100. template <class TYPE, class KEY=TYPE>
  101. class TemplateSphericalLinearInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
  102. {
  103. public:
  104. TemplateSphericalLinearInterpolator() {}
  105. void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
  106. {
  107. if (time >= keyframes.back().getTime())
  108. {
  109. result = keyframes.back().getValue();
  110. return;
  111. }
  112. else if (time <= keyframes.front().getTime())
  113. {
  114. result = keyframes.front().getValue();
  115. return;
  116. }
  117. int i = this->getKeyIndexFromTime(keyframes,time);
  118. float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime());
  119. const TYPE& q1 = keyframes[i].getValue();
  120. const TYPE& q2 = keyframes[i+1].getValue();
  121. result.slerp(blend,q1,q2);
  122. }
  123. };
  124. template <class TYPE, class KEY>
  125. class TemplateLinearPackedInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
  126. {
  127. public:
  128. TemplateLinearPackedInterpolator() {}
  129. void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
  130. {
  131. if (time >= keyframes.back().getTime())
  132. {
  133. keyframes.back().getValue().uncompress(keyframes.mScale, keyframes.mMin, result);
  134. return;
  135. }
  136. else if (time <= keyframes.front().getTime())
  137. {
  138. keyframes.front().getValue().uncompress(keyframes.mScale, keyframes.mMin, result);
  139. return;
  140. }
  141. int i = this->getKeyIndexFromTime(keyframes,time);
  142. float blend = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime());
  143. TYPE v1,v2;
  144. keyframes[i].getValue().uncompress(keyframes.mScale, keyframes.mMin, v1);
  145. keyframes[i+1].getValue().uncompress(keyframes.mScale, keyframes.mMin, v2);
  146. result = v1*(1-blend) + v2*blend;
  147. }
  148. };
  149. // http://en.wikipedia.org/wiki/B%C3%A9zier_curve
  150. template <class TYPE, class KEY=TYPE>
  151. class TemplateCubicBezierInterpolator : public TemplateInterpolatorBase<TYPE,KEY>
  152. {
  153. public:
  154. TemplateCubicBezierInterpolator() {}
  155. void getValue(const TemplateKeyframeContainer<KEY>& keyframes, double time, TYPE& result) const
  156. {
  157. if (time >= keyframes.back().getTime())
  158. {
  159. result = keyframes.back().getValue().getPosition();
  160. return;
  161. }
  162. else if (time <= keyframes.front().getTime())
  163. {
  164. result = keyframes.front().getValue().getPosition();
  165. return;
  166. }
  167. int i = this->getKeyIndexFromTime(keyframes,time);
  168. float t = (time - keyframes[i].getTime()) / ( keyframes[i+1].getTime() - keyframes[i].getTime());
  169. float one_minus_t = 1.0-t;
  170. float one_minus_t2 = one_minus_t * one_minus_t;
  171. float one_minus_t3 = one_minus_t2 * one_minus_t;
  172. float t2 = t * t;
  173. TYPE v0 = keyframes[i].getValue().getPosition() * one_minus_t3;
  174. TYPE v1 = keyframes[i].getValue().getControlPointIn() * (3.0 * t * one_minus_t2);
  175. TYPE v2 = keyframes[i].getValue().getControlPointOut() * (3.0 * t2 * one_minus_t);
  176. TYPE v3 = keyframes[i+1].getValue().getPosition() * (t2 * t);
  177. result = v0 + v1 + v2 + v3;
  178. }
  179. };
  180. typedef TemplateStepInterpolator<double, double> DoubleStepInterpolator;
  181. typedef TemplateStepInterpolator<float, float> FloatStepInterpolator;
  182. typedef TemplateStepInterpolator<osg::Vec2, osg::Vec2> Vec2StepInterpolator;
  183. typedef TemplateStepInterpolator<osg::Vec3, osg::Vec3> Vec3StepInterpolator;
  184. typedef TemplateStepInterpolator<osg::Vec3, Vec3Packed> Vec3PackedStepInterpolator;
  185. typedef TemplateStepInterpolator<osg::Vec4, osg::Vec4> Vec4StepInterpolator;
  186. typedef TemplateStepInterpolator<osg::Quat, osg::Quat> QuatStepInterpolator;
  187. typedef TemplateLinearInterpolator<double, double> DoubleLinearInterpolator;
  188. typedef TemplateLinearInterpolator<float, float> FloatLinearInterpolator;
  189. typedef TemplateLinearInterpolator<osg::Vec2, osg::Vec2> Vec2LinearInterpolator;
  190. typedef TemplateLinearInterpolator<osg::Vec3, osg::Vec3> Vec3LinearInterpolator;
  191. typedef TemplateLinearInterpolator<osg::Vec3, Vec3Packed> Vec3PackedLinearInterpolator;
  192. typedef TemplateLinearInterpolator<osg::Vec4, osg::Vec4> Vec4LinearInterpolator;
  193. typedef TemplateSphericalLinearInterpolator<osg::Quat, osg::Quat> QuatSphericalLinearInterpolator;
  194. typedef TemplateLinearInterpolator<osg::Matrixf, osg::Matrixf> MatrixLinearInterpolator;
  195. typedef TemplateCubicBezierInterpolator<float, FloatCubicBezier > FloatCubicBezierInterpolator;
  196. typedef TemplateCubicBezierInterpolator<double, DoubleCubicBezier> DoubleCubicBezierInterpolator;
  197. typedef TemplateCubicBezierInterpolator<osg::Vec2, Vec2CubicBezier> Vec2CubicBezierInterpolator;
  198. typedef TemplateCubicBezierInterpolator<osg::Vec3, Vec3CubicBezier> Vec3CubicBezierInterpolator;
  199. typedef TemplateCubicBezierInterpolator<osg::Vec4, Vec4CubicBezier> Vec4CubicBezierInterpolator;
  200. }
  201. #endif