123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * OpenSceneGraph Public License for more details.
- */
- #ifndef OSG_ANIMATIONPATH
- #define OSG_ANIMATIONPATH 1
- #include <map>
- #include <istream>
- #include <float.h>
- #include <osg/Matrixf>
- #include <osg/Matrixd>
- #include <osg/Quat>
- #include <osg/Callback>
- namespace osg {
- /** AnimationPath encapsulates a time varying transformation pathway. Can be
- * used for updating camera position and model object position.
- * AnimationPathCallback can be attached directly to Transform nodes to
- * move subgraphs around the scene.
- */
- class OSG_EXPORT AnimationPath : public virtual osg::Object
- {
- public:
- AnimationPath():_loopMode(LOOP) {}
- AnimationPath(const AnimationPath& ap, const CopyOp& copyop=CopyOp::SHALLOW_COPY):
- Object(ap,copyop),
- _timeControlPointMap(ap._timeControlPointMap),
- _loopMode(ap._loopMode) {}
- META_Object(osg,AnimationPath);
- class ControlPoint
- {
- public:
- ControlPoint():
- _scale(1.0,1.0,1.0) {}
- ControlPoint(const osg::Vec3d& position):
- _position(position),
- _rotation(),
- _scale(1.0,1.0,1.0) {}
- ControlPoint(const osg::Vec3d& position, const osg::Quat& rotation):
- _position(position),
- _rotation(rotation),
- _scale(1.0,1.0,1.0) {}
- ControlPoint(const osg::Vec3d& position, const osg::Quat& rotation, const osg::Vec3d& scale):
- _position(position),
- _rotation(rotation),
- _scale(scale) {}
- void setPosition(const osg::Vec3d& position) { _position = position; }
- const osg::Vec3d& getPosition() const { return _position; }
- void setRotation(const osg::Quat& rotation) { _rotation = rotation; }
- const osg::Quat& getRotation() const { return _rotation; }
- void setScale(const osg::Vec3d& scale) { _scale = scale; }
- const osg::Vec3d& getScale() const { return _scale; }
- inline void interpolate(float ratio,const ControlPoint& first, const ControlPoint& second)
- {
- float one_minus_ratio = 1.0f-ratio;
- _position = first._position*one_minus_ratio + second._position*ratio;
- _rotation.slerp(ratio,first._rotation,second._rotation);
- _scale = first._scale*one_minus_ratio + second._scale*ratio;
- }
- inline void interpolate(double ratio,const ControlPoint& first, const ControlPoint& second)
- {
- double one_minus_ratio = 1.0-ratio;
- _position = first._position*one_minus_ratio + second._position*ratio;
- _rotation.slerp(ratio,first._rotation,second._rotation);
- _scale = first._scale*one_minus_ratio + second._scale*ratio;
- }
- inline void getMatrix(Matrixf& matrix) const
- {
- matrix.makeRotate(_rotation);
- matrix.preMultScale(_scale);
- matrix.postMultTranslate(_position);
- }
- inline void getMatrix(Matrixd& matrix) const
- {
- matrix.makeRotate(_rotation);
- matrix.preMultScale(_scale);
- matrix.postMultTranslate(_position);
- }
- inline void getInverse(Matrixf& matrix) const
- {
- matrix.makeRotate(_rotation.inverse());
- matrix.postMultScale(osg::Vec3d(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z()));
- matrix.preMultTranslate(-_position);
- }
- inline void getInverse(Matrixd& matrix) const
- {
- matrix.makeRotate(_rotation.inverse());
- matrix.postMultScale(osg::Vec3d(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z()));
- matrix.preMultTranslate(-_position);
- }
- protected:
- osg::Vec3d _position;
- osg::Quat _rotation;
- osg::Vec3d _scale;
- };
- /** Given a specific time, return the transformation matrix for a point. */
- bool getMatrix(double time,Matrixf& matrix) const
- {
- ControlPoint cp;
- if (!getInterpolatedControlPoint(time,cp)) return false;
- cp.getMatrix(matrix);
- return true;
- }
- /** Given a specific time, return the transformation matrix for a point. */
- bool getMatrix(double time,Matrixd& matrix) const
- {
- ControlPoint cp;
- if (!getInterpolatedControlPoint(time,cp)) return false;
- cp.getMatrix(matrix);
- return true;
- }
- /** Given a specific time, return the inverse transformation matrix for a point. */
- bool getInverse(double time,Matrixf& matrix) const
- {
- ControlPoint cp;
- if (!getInterpolatedControlPoint(time,cp)) return false;
- cp.getInverse(matrix);
- return true;
- }
- bool getInverse(double time,Matrixd& matrix) const
- {
- ControlPoint cp;
- if (!getInterpolatedControlPoint(time,cp)) return false;
- cp.getInverse(matrix);
- return true;
- }
- /** Given a specific time, return the local ControlPoint frame for a point. */
- virtual bool getInterpolatedControlPoint(double time,ControlPoint& controlPoint) const;
- /** Insert a control point into the AnimationPath.*/
- void insert(double time,const ControlPoint& controlPoint);
- double getFirstTime() const { if (!_timeControlPointMap.empty()) return _timeControlPointMap.begin()->first; else return 0.0;}
- double getLastTime() const { if (!_timeControlPointMap.empty()) return _timeControlPointMap.rbegin()->first; else return 0.0;}
- double getPeriod() const { return getLastTime()-getFirstTime();}
- enum LoopMode
- {
- SWING,
- LOOP,
- NO_LOOPING
- };
- void setLoopMode(LoopMode lm) { _loopMode = lm; }
- LoopMode getLoopMode() const { return _loopMode; }
- typedef std::map<double,ControlPoint> TimeControlPointMap;
- void setTimeControlPointMap(TimeControlPointMap& tcpm) { _timeControlPointMap=tcpm; }
- TimeControlPointMap& getTimeControlPointMap() { return _timeControlPointMap; }
- const TimeControlPointMap& getTimeControlPointMap() const { return _timeControlPointMap; }
- bool empty() const { return _timeControlPointMap.empty(); }
- void clear() { _timeControlPointMap.clear(); }
- /** Read the animation path from a flat ASCII file stream. */
- void read(std::istream& in);
- /** Write the animation path to a flat ASCII file stream. */
- void write(std::ostream& out) const;
- /** Write the control point to a flat ASCII file stream. */
- void write(TimeControlPointMap::const_iterator itr, std::ostream& out) const;
- protected:
- virtual ~AnimationPath() {}
- TimeControlPointMap _timeControlPointMap;
- LoopMode _loopMode;
- };
- class OSG_EXPORT AnimationPathCallback : public NodeCallback
- {
- public:
- AnimationPathCallback():
- _pivotPoint(0.0,0.0,0.0),
- _useInverseMatrix(false),
- _timeOffset(0.0),
- _timeMultiplier(1.0),
- _firstTime(DBL_MAX),
- _latestTime(0.0),
- _pause(false),
- _pauseTime(0.0) {}
- AnimationPathCallback(const AnimationPathCallback& apc,const CopyOp& copyop):
- Object(apc, copyop),
- Callback(apc, copyop),
- NodeCallback(apc, copyop),
- _animationPath(apc._animationPath),
- _pivotPoint(apc._pivotPoint),
- _useInverseMatrix(apc._useInverseMatrix),
- _timeOffset(apc._timeOffset),
- _timeMultiplier(apc._timeMultiplier),
- _firstTime(apc._firstTime),
- _latestTime(apc._latestTime),
- _pause(apc._pause),
- _pauseTime(apc._pauseTime) {}
- META_Object(osg,AnimationPathCallback);
- /** Construct an AnimationPathCallback with a specified animation path.*/
- AnimationPathCallback(AnimationPath* ap,double timeOffset=0.0,double timeMultiplier=1.0):
- _animationPath(ap),
- _pivotPoint(0.0,0.0,0.0),
- _useInverseMatrix(false),
- _timeOffset(timeOffset),
- _timeMultiplier(timeMultiplier),
- _firstTime(DBL_MAX),
- _latestTime(0.0),
- _pause(false),
- _pauseTime(0.0) {}
- /** Construct an AnimationPathCallback and automatically create an animation path to produce a rotation about a point.*/
- AnimationPathCallback(const osg::Vec3d& pivot,const osg::Vec3d& axis,float angularVelocity);
- void setAnimationPath(AnimationPath* path) { _animationPath = path; }
- AnimationPath* getAnimationPath() { return _animationPath.get(); }
- const AnimationPath* getAnimationPath() const { return _animationPath.get(); }
- inline void setPivotPoint(const Vec3d& pivot) { _pivotPoint = pivot; }
- inline const Vec3d& getPivotPoint() const { return _pivotPoint; }
- void setUseInverseMatrix(bool useInverseMatrix) { _useInverseMatrix = useInverseMatrix; }
- bool getUseInverseMatrix() const { return _useInverseMatrix; }
- void setTimeOffset(double offset) { _timeOffset = offset; }
- double getTimeOffset() const { return _timeOffset; }
- void setTimeMultiplier(double multiplier) { _timeMultiplier = multiplier; }
- double getTimeMultiplier() const { return _timeMultiplier; }
- virtual void reset();
- void setPause(bool pause);
- bool getPause() const { return _pause; }
- /** Get the animation time that is used to specify the position along
- * the AnimationPath. Animation time is computed from the formula:
- * ((_latestTime-_firstTime)-_timeOffset)*_timeMultiplier.*/
- virtual double getAnimationTime() const;
- /** Implements the callback. */
- virtual void operator()(Node* node, NodeVisitor* nv);
- void update(osg::Node& node);
- public:
- ref_ptr<AnimationPath> _animationPath;
- osg::Vec3d _pivotPoint;
- bool _useInverseMatrix;
- double _timeOffset;
- double _timeMultiplier;
- double _firstTime;
- double _latestTime;
- bool _pause;
- double _pauseTime;
- protected:
- ~AnimationPathCallback(){}
- };
- }
- #endif
|