Target 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. #ifndef OSGANIMATION_TARGET
  15. #define OSGANIMATION_TARGET 1
  16. #include <vector>
  17. #include <osg/Quat>
  18. #include <osg/Vec3>
  19. #include <osg/Vec2>
  20. #include <osg/Vec4>
  21. #include <osg/Referenced>
  22. #include <osgAnimation/Export>
  23. namespace osgAnimation
  24. {
  25. class Channel;
  26. class OSGANIMATION_EXPORT Target : public osg::Referenced
  27. {
  28. public:
  29. Target();
  30. virtual ~Target() {}
  31. void reset() { _weight = 0; _priorityWeight = 0; }
  32. int getCount() const { return referenceCount(); }
  33. float getWeight() const { return _weight; }
  34. protected:
  35. float _weight;
  36. float _priorityWeight;
  37. int _lastPriority;
  38. };
  39. template <class T>
  40. class TemplateTarget : public Target
  41. {
  42. public:
  43. TemplateTarget() : _target() {}
  44. TemplateTarget(const T& v) { setValue(v); }
  45. TemplateTarget(const TemplateTarget& v) { setValue(v.getValue()); }
  46. inline void lerp(float t, const T& a, const T& b);
  47. /**
  48. * The priority is used to detect a change of priority
  49. * It's important to update animation target in priority
  50. * order. eg:
  51. * all animation with priority 1
  52. * all animation with priority 0
  53. * all animation with priority -1
  54. * ...
  55. */
  56. void update(float weight, const T& val, int priority)
  57. {
  58. if (_weight || _priorityWeight)
  59. {
  60. if (_lastPriority != priority)
  61. {
  62. // change in priority
  63. // add to weight with the same previous priority cumulated weight
  64. _weight += _priorityWeight * (1.0 - _weight);
  65. _priorityWeight = 0;
  66. _lastPriority = priority;
  67. }
  68. _priorityWeight += weight;
  69. float t = (1.0 - _weight) * weight / _priorityWeight;
  70. lerp(t, _target, val);
  71. }
  72. else
  73. {
  74. _priorityWeight = weight;
  75. _lastPriority = priority;
  76. _target = val;
  77. }
  78. }
  79. const T& getValue() const { return _target; }
  80. void setValue(const T& value) { _target = value; }
  81. protected:
  82. T _target;
  83. };
  84. template <class T>
  85. inline void TemplateTarget<T>::lerp(float t, const T& a, const T& b)
  86. {
  87. _target = a * (1.0f - t) + b * t;
  88. }
  89. template <>
  90. inline void TemplateTarget<osg::Quat>::lerp(float t, const osg::Quat& a, const osg::Quat& b)
  91. {
  92. if (a.asVec4() * b.asVec4() < 0.0)
  93. {
  94. _target = a * (1.0f - t) + b * -t;
  95. }
  96. else
  97. {
  98. _target = a * (1.0f - t) + b * t;
  99. }
  100. osg::Quat::value_type len2 = _target.length2();
  101. if ( len2 != 1.0 && len2 != 0.0)
  102. _target *= 1.0/sqrt(len2);
  103. }
  104. typedef TemplateTarget<osg::Matrixf> MatrixTarget;
  105. typedef TemplateTarget<osg::Quat> QuatTarget;
  106. typedef TemplateTarget<osg::Vec3> Vec3Target;
  107. typedef TemplateTarget<osg::Vec4> Vec4Target;
  108. typedef TemplateTarget<osg::Vec2> Vec2Target;
  109. typedef TemplateTarget<float> FloatTarget;
  110. typedef TemplateTarget<double> DoubleTarget;
  111. }
  112. #endif