AnimationPath 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSG_ANIMATIONPATH
  14. #define OSG_ANIMATIONPATH 1
  15. #include <map>
  16. #include <istream>
  17. #include <float.h>
  18. #include <osg/Matrixf>
  19. #include <osg/Matrixd>
  20. #include <osg/Quat>
  21. #include <osg/Callback>
  22. namespace osg {
  23. /** AnimationPath encapsulates a time varying transformation pathway. Can be
  24. * used for updating camera position and model object position.
  25. * AnimationPathCallback can be attached directly to Transform nodes to
  26. * move subgraphs around the scene.
  27. */
  28. class OSG_EXPORT AnimationPath : public virtual osg::Object
  29. {
  30. public:
  31. AnimationPath():_loopMode(LOOP) {}
  32. AnimationPath(const AnimationPath& ap, const CopyOp& copyop=CopyOp::SHALLOW_COPY):
  33. Object(ap,copyop),
  34. _timeControlPointMap(ap._timeControlPointMap),
  35. _loopMode(ap._loopMode) {}
  36. META_Object(osg,AnimationPath);
  37. class ControlPoint
  38. {
  39. public:
  40. ControlPoint():
  41. _scale(1.0,1.0,1.0) {}
  42. ControlPoint(const osg::Vec3d& position):
  43. _position(position),
  44. _rotation(),
  45. _scale(1.0,1.0,1.0) {}
  46. ControlPoint(const osg::Vec3d& position, const osg::Quat& rotation):
  47. _position(position),
  48. _rotation(rotation),
  49. _scale(1.0,1.0,1.0) {}
  50. ControlPoint(const osg::Vec3d& position, const osg::Quat& rotation, const osg::Vec3d& scale):
  51. _position(position),
  52. _rotation(rotation),
  53. _scale(scale) {}
  54. void setPosition(const osg::Vec3d& position) { _position = position; }
  55. const osg::Vec3d& getPosition() const { return _position; }
  56. void setRotation(const osg::Quat& rotation) { _rotation = rotation; }
  57. const osg::Quat& getRotation() const { return _rotation; }
  58. void setScale(const osg::Vec3d& scale) { _scale = scale; }
  59. const osg::Vec3d& getScale() const { return _scale; }
  60. inline void interpolate(float ratio,const ControlPoint& first, const ControlPoint& second)
  61. {
  62. float one_minus_ratio = 1.0f-ratio;
  63. _position = first._position*one_minus_ratio + second._position*ratio;
  64. _rotation.slerp(ratio,first._rotation,second._rotation);
  65. _scale = first._scale*one_minus_ratio + second._scale*ratio;
  66. }
  67. inline void interpolate(double ratio,const ControlPoint& first, const ControlPoint& second)
  68. {
  69. double one_minus_ratio = 1.0-ratio;
  70. _position = first._position*one_minus_ratio + second._position*ratio;
  71. _rotation.slerp(ratio,first._rotation,second._rotation);
  72. _scale = first._scale*one_minus_ratio + second._scale*ratio;
  73. }
  74. inline void getMatrix(Matrixf& matrix) const
  75. {
  76. matrix.makeRotate(_rotation);
  77. matrix.preMultScale(_scale);
  78. matrix.postMultTranslate(_position);
  79. }
  80. inline void getMatrix(Matrixd& matrix) const
  81. {
  82. matrix.makeRotate(_rotation);
  83. matrix.preMultScale(_scale);
  84. matrix.postMultTranslate(_position);
  85. }
  86. inline void getInverse(Matrixf& matrix) const
  87. {
  88. matrix.makeRotate(_rotation.inverse());
  89. matrix.postMultScale(osg::Vec3d(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z()));
  90. matrix.preMultTranslate(-_position);
  91. }
  92. inline void getInverse(Matrixd& matrix) const
  93. {
  94. matrix.makeRotate(_rotation.inverse());
  95. matrix.postMultScale(osg::Vec3d(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z()));
  96. matrix.preMultTranslate(-_position);
  97. }
  98. protected:
  99. osg::Vec3d _position;
  100. osg::Quat _rotation;
  101. osg::Vec3d _scale;
  102. };
  103. /** Given a specific time, return the transformation matrix for a point. */
  104. bool getMatrix(double time,Matrixf& matrix) const
  105. {
  106. ControlPoint cp;
  107. if (!getInterpolatedControlPoint(time,cp)) return false;
  108. cp.getMatrix(matrix);
  109. return true;
  110. }
  111. /** Given a specific time, return the transformation matrix for a point. */
  112. bool getMatrix(double time,Matrixd& matrix) const
  113. {
  114. ControlPoint cp;
  115. if (!getInterpolatedControlPoint(time,cp)) return false;
  116. cp.getMatrix(matrix);
  117. return true;
  118. }
  119. /** Given a specific time, return the inverse transformation matrix for a point. */
  120. bool getInverse(double time,Matrixf& matrix) const
  121. {
  122. ControlPoint cp;
  123. if (!getInterpolatedControlPoint(time,cp)) return false;
  124. cp.getInverse(matrix);
  125. return true;
  126. }
  127. bool getInverse(double time,Matrixd& matrix) const
  128. {
  129. ControlPoint cp;
  130. if (!getInterpolatedControlPoint(time,cp)) return false;
  131. cp.getInverse(matrix);
  132. return true;
  133. }
  134. /** Given a specific time, return the local ControlPoint frame for a point. */
  135. virtual bool getInterpolatedControlPoint(double time,ControlPoint& controlPoint) const;
  136. /** Insert a control point into the AnimationPath.*/
  137. void insert(double time,const ControlPoint& controlPoint);
  138. double getFirstTime() const { if (!_timeControlPointMap.empty()) return _timeControlPointMap.begin()->first; else return 0.0;}
  139. double getLastTime() const { if (!_timeControlPointMap.empty()) return _timeControlPointMap.rbegin()->first; else return 0.0;}
  140. double getPeriod() const { return getLastTime()-getFirstTime();}
  141. enum LoopMode
  142. {
  143. SWING,
  144. LOOP,
  145. NO_LOOPING
  146. };
  147. void setLoopMode(LoopMode lm) { _loopMode = lm; }
  148. LoopMode getLoopMode() const { return _loopMode; }
  149. typedef std::map<double,ControlPoint> TimeControlPointMap;
  150. void setTimeControlPointMap(TimeControlPointMap& tcpm) { _timeControlPointMap=tcpm; }
  151. TimeControlPointMap& getTimeControlPointMap() { return _timeControlPointMap; }
  152. const TimeControlPointMap& getTimeControlPointMap() const { return _timeControlPointMap; }
  153. bool empty() const { return _timeControlPointMap.empty(); }
  154. void clear() { _timeControlPointMap.clear(); }
  155. /** Read the animation path from a flat ASCII file stream. */
  156. void read(std::istream& in);
  157. /** Write the animation path to a flat ASCII file stream. */
  158. void write(std::ostream& out) const;
  159. /** Write the control point to a flat ASCII file stream. */
  160. void write(TimeControlPointMap::const_iterator itr, std::ostream& out) const;
  161. protected:
  162. virtual ~AnimationPath() {}
  163. TimeControlPointMap _timeControlPointMap;
  164. LoopMode _loopMode;
  165. };
  166. class OSG_EXPORT AnimationPathCallback : public NodeCallback
  167. {
  168. public:
  169. AnimationPathCallback():
  170. _pivotPoint(0.0,0.0,0.0),
  171. _useInverseMatrix(false),
  172. _timeOffset(0.0),
  173. _timeMultiplier(1.0),
  174. _firstTime(DBL_MAX),
  175. _latestTime(0.0),
  176. _pause(false),
  177. _pauseTime(0.0) {}
  178. AnimationPathCallback(const AnimationPathCallback& apc,const CopyOp& copyop):
  179. Object(apc, copyop),
  180. Callback(apc, copyop),
  181. NodeCallback(apc, copyop),
  182. _animationPath(apc._animationPath),
  183. _pivotPoint(apc._pivotPoint),
  184. _useInverseMatrix(apc._useInverseMatrix),
  185. _timeOffset(apc._timeOffset),
  186. _timeMultiplier(apc._timeMultiplier),
  187. _firstTime(apc._firstTime),
  188. _latestTime(apc._latestTime),
  189. _pause(apc._pause),
  190. _pauseTime(apc._pauseTime) {}
  191. META_Object(osg,AnimationPathCallback);
  192. /** Construct an AnimationPathCallback with a specified animation path.*/
  193. AnimationPathCallback(AnimationPath* ap,double timeOffset=0.0,double timeMultiplier=1.0):
  194. _animationPath(ap),
  195. _pivotPoint(0.0,0.0,0.0),
  196. _useInverseMatrix(false),
  197. _timeOffset(timeOffset),
  198. _timeMultiplier(timeMultiplier),
  199. _firstTime(DBL_MAX),
  200. _latestTime(0.0),
  201. _pause(false),
  202. _pauseTime(0.0) {}
  203. /** Construct an AnimationPathCallback and automatically create an animation path to produce a rotation about a point.*/
  204. AnimationPathCallback(const osg::Vec3d& pivot,const osg::Vec3d& axis,float angularVelocity);
  205. void setAnimationPath(AnimationPath* path) { _animationPath = path; }
  206. AnimationPath* getAnimationPath() { return _animationPath.get(); }
  207. const AnimationPath* getAnimationPath() const { return _animationPath.get(); }
  208. inline void setPivotPoint(const Vec3d& pivot) { _pivotPoint = pivot; }
  209. inline const Vec3d& getPivotPoint() const { return _pivotPoint; }
  210. void setUseInverseMatrix(bool useInverseMatrix) { _useInverseMatrix = useInverseMatrix; }
  211. bool getUseInverseMatrix() const { return _useInverseMatrix; }
  212. void setTimeOffset(double offset) { _timeOffset = offset; }
  213. double getTimeOffset() const { return _timeOffset; }
  214. void setTimeMultiplier(double multiplier) { _timeMultiplier = multiplier; }
  215. double getTimeMultiplier() const { return _timeMultiplier; }
  216. virtual void reset();
  217. void setPause(bool pause);
  218. bool getPause() const { return _pause; }
  219. /** Get the animation time that is used to specify the position along
  220. * the AnimationPath. Animation time is computed from the formula:
  221. * ((_latestTime-_firstTime)-_timeOffset)*_timeMultiplier.*/
  222. virtual double getAnimationTime() const;
  223. /** Implements the callback. */
  224. virtual void operator()(Node* node, NodeVisitor* nv);
  225. void update(osg::Node& node);
  226. public:
  227. ref_ptr<AnimationPath> _animationPath;
  228. osg::Vec3d _pivotPoint;
  229. bool _useInverseMatrix;
  230. double _timeOffset;
  231. double _timeMultiplier;
  232. double _firstTime;
  233. double _latestTime;
  234. bool _pause;
  235. double _pauseTime;
  236. protected:
  237. ~AnimationPathCallback(){}
  238. };
  239. }
  240. #endif