1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
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.
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.
14#ifndef OSG_ANIMATIONPATH
15#define OSG_ANIMATIONPATH 1
24#include <osg/Callback>
28/** AnimationPath encapsulates a time varying transformation pathway. Can be
29 * used for updating camera position and model object position.
30 * AnimationPathCallback can be attached directly to Transform nodes to
31 * move subgraphs around the scene.
33class OSG_EXPORT AnimationPath : public virtual osg::Object
37 AnimationPath():_loopMode(LOOP) {}
39 AnimationPath(const AnimationPath& ap, const CopyOp& copyop=CopyOp::SHALLOW_COPY):
41 _timeControlPointMap(ap._timeControlPointMap),
42 _loopMode(ap._loopMode) {}
44 META_Object(osg,AnimationPath);
50 _scale(1.0,1.0,1.0) {}
52 ControlPoint(const osg::Vec3d& position):
55 _scale(1.0,1.0,1.0) {}
57 ControlPoint(const osg::Vec3d& position, const osg::Quat& rotation):
60 _scale(1.0,1.0,1.0) {}
62 ControlPoint(const osg::Vec3d& position, const osg::Quat& rotation, const osg::Vec3d& scale):
67 void setPosition(const osg::Vec3d& position) { _position = position; }
68 const osg::Vec3d& getPosition() const { return _position; }
70 void setRotation(const osg::Quat& rotation) { _rotation = rotation; }
71 const osg::Quat& getRotation() const { return _rotation; }
73 void setScale(const osg::Vec3d& scale) { _scale = scale; }
74 const osg::Vec3d& getScale() const { return _scale; }
76 inline void interpolate(float ratio,const ControlPoint& first, const ControlPoint& second)
78 float one_minus_ratio = 1.0f-ratio;
79 _position = first._position*one_minus_ratio + second._position*ratio;
80 _rotation.slerp(ratio,first._rotation,second._rotation);
81 _scale = first._scale*one_minus_ratio + second._scale*ratio;
84 inline void interpolate(double ratio,const ControlPoint& first, const ControlPoint& second)
86 double one_minus_ratio = 1.0-ratio;
87 _position = first._position*one_minus_ratio + second._position*ratio;
88 _rotation.slerp(ratio,first._rotation,second._rotation);
89 _scale = first._scale*one_minus_ratio + second._scale*ratio;
92 inline void getMatrix(Matrixf& matrix) const
94 matrix.makeRotate(_rotation);
95 matrix.preMultScale(_scale);
96 matrix.postMultTranslate(_position);
99 inline void getMatrix(Matrixd& matrix) const
101 matrix.makeRotate(_rotation);
102 matrix.preMultScale(_scale);
103 matrix.postMultTranslate(_position);
106 inline void getInverse(Matrixf& matrix) const
108 matrix.makeRotate(_rotation.inverse());
109 matrix.postMultScale(osg::Vec3d(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z()));
110 matrix.preMultTranslate(-_position);
113 inline void getInverse(Matrixd& matrix) const
115 matrix.makeRotate(_rotation.inverse());
116 matrix.postMultScale(osg::Vec3d(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z()));
117 matrix.preMultTranslate(-_position);
122 osg::Vec3d _position;
129 /** Given a specific time, return the transformation matrix for a point. */
130 bool getMatrix(double time,Matrixf& matrix) const
133 if (!getInterpolatedControlPoint(time,cp)) return false;
134 cp.getMatrix(matrix);
138 /** Given a specific time, return the transformation matrix for a point. */
139 bool getMatrix(double time,Matrixd& matrix) const
142 if (!getInterpolatedControlPoint(time,cp)) return false;
143 cp.getMatrix(matrix);
147 /** Given a specific time, return the inverse transformation matrix for a point. */
148 bool getInverse(double time,Matrixf& matrix) const
151 if (!getInterpolatedControlPoint(time,cp)) return false;
152 cp.getInverse(matrix);
156 bool getInverse(double time,Matrixd& matrix) const
159 if (!getInterpolatedControlPoint(time,cp)) return false;
160 cp.getInverse(matrix);
164 /** Given a specific time, return the local ControlPoint frame for a point. */
165 virtual bool getInterpolatedControlPoint(double time,ControlPoint& controlPoint) const;
167 /** Insert a control point into the AnimationPath.*/
168 void insert(double time,const ControlPoint& controlPoint);
170 double getFirstTime() const { if (!_timeControlPointMap.empty()) return _timeControlPointMap.begin()->first; else return 0.0;}
171 double getLastTime() const { if (!_timeControlPointMap.empty()) return _timeControlPointMap.rbegin()->first; else return 0.0;}
172 double getPeriod() const { return getLastTime()-getFirstTime();}
181 void setLoopMode(LoopMode lm) { _loopMode = lm; }
183 LoopMode getLoopMode() const { return _loopMode; }
186 typedef std::map<double,ControlPoint> TimeControlPointMap;
188 void setTimeControlPointMap(TimeControlPointMap& tcpm) { _timeControlPointMap=tcpm; }
190 TimeControlPointMap& getTimeControlPointMap() { return _timeControlPointMap; }
192 const TimeControlPointMap& getTimeControlPointMap() const { return _timeControlPointMap; }
194 bool empty() const { return _timeControlPointMap.empty(); }
196 void clear() { _timeControlPointMap.clear(); }
198 /** Read the animation path from a flat ASCII file stream. */
199 void read(std::istream& in);
201 /** Write the animation path to a flat ASCII file stream. */
202 void write(std::ostream& out) const;
204 /** Write the control point to a flat ASCII file stream. */
205 void write(TimeControlPointMap::const_iterator itr, std::ostream& out) const;
209 virtual ~AnimationPath() {}
211 TimeControlPointMap _timeControlPointMap;
217class OSG_EXPORT AnimationPathCallback : public NodeCallback
221 AnimationPathCallback():
222 _pivotPoint(0.0,0.0,0.0),
223 _useInverseMatrix(false),
225 _timeMultiplier(1.0),
231 AnimationPathCallback(const AnimationPathCallback& apc,const CopyOp& copyop):
233 Callback(apc, copyop),
234 NodeCallback(apc, copyop),
235 _animationPath(apc._animationPath),
236 _pivotPoint(apc._pivotPoint),
237 _useInverseMatrix(apc._useInverseMatrix),
238 _timeOffset(apc._timeOffset),
239 _timeMultiplier(apc._timeMultiplier),
240 _firstTime(apc._firstTime),
241 _latestTime(apc._latestTime),
243 _pauseTime(apc._pauseTime) {}
246 META_Object(osg,AnimationPathCallback);
248 /** Construct an AnimationPathCallback with a specified animation path.*/
249 AnimationPathCallback(AnimationPath* ap,double timeOffset=0.0,double timeMultiplier=1.0):
251 _pivotPoint(0.0,0.0,0.0),
252 _useInverseMatrix(false),
253 _timeOffset(timeOffset),
254 _timeMultiplier(timeMultiplier),
260 /** Construct an AnimationPathCallback and automatically create an animation path to produce a rotation about a point.*/
261 AnimationPathCallback(const osg::Vec3d& pivot,const osg::Vec3d& axis,float angularVelocity);
264 void setAnimationPath(AnimationPath* path) { _animationPath = path; }
265 AnimationPath* getAnimationPath() { return _animationPath.get(); }
266 const AnimationPath* getAnimationPath() const { return _animationPath.get(); }
268 inline void setPivotPoint(const Vec3d& pivot) { _pivotPoint = pivot; }
269 inline const Vec3d& getPivotPoint() const { return _pivotPoint; }
271 void setUseInverseMatrix(bool useInverseMatrix) { _useInverseMatrix = useInverseMatrix; }
272 bool getUseInverseMatrix() const { return _useInverseMatrix; }
274 void setTimeOffset(double offset) { _timeOffset = offset; }
275 double getTimeOffset() const { return _timeOffset; }
277 void setTimeMultiplier(double multiplier) { _timeMultiplier = multiplier; }
278 double getTimeMultiplier() const { return _timeMultiplier; }
281 virtual void reset();
283 void setPause(bool pause);
284 bool getPause() const { return _pause; }
286 /** Get the animation time that is used to specify the position along
287 * the AnimationPath. Animation time is computed from the formula:
288 * ((_latestTime-_firstTime)-_timeOffset)*_timeMultiplier.*/
289 virtual double getAnimationTime() const;
291 /** Implements the callback. */
292 virtual void operator()(Node* node, NodeVisitor* nv);
294 void update(osg::Node& node);
298 ref_ptr<AnimationPath> _animationPath;
299 osg::Vec3d _pivotPoint;
300 bool _useInverseMatrix;
302 double _timeMultiplier;
310 ~AnimationPathCallback(){}