OpenSceneGraph/include/osg/AnimationPath
Robert Osfield fe64942c54 Added a AnimationPathCallback which can update both a MatrixTransform and a
PositionAttitudeTransform, removed the equivialnt callbacks once found in these
transform classes.

Changed the NodeCallback class so its derived from osg::Object instead of
osg::Referenced to allow it to be saved out in the .osg format.

Added support for Update and Cull callbacks into the .osg file format.

Added support for AnimationPathCallback into the .osg file format.
2003-01-02 20:10:04 +00:00

193 lines
6.3 KiB
Plaintext

//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSG_ANIMATIONPATH
#define OSG_ANIMATIONPATH 1
#include <osg/Matrix>
#include <osg/Quat>
#include <osg/NodeVisitor>
#include <map>
namespace osg {
/** AnimationPath for specify the time varying transformation pathway to use when update camera and model objects.
* Subclassed from Transform::ComputeTransformCallback allows AnimationPath to
* be attached directly to Transform nodes to move subgraphs around the scene.
*/
class SG_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)
struct ControlPoint
{
ControlPoint():
_scale(1.0f,1.0f,1.0f) {}
ControlPoint(const osg::Vec3& position):
_position(position),
_rotation(),
_scale(1.0f,1.0f,1.0f) {}
ControlPoint(const osg::Vec3& position, const osg::Quat& rotation):
_position(position),
_rotation(rotation),
_scale(1.0f,1.0f,1.0f) {}
ControlPoint(const osg::Vec3& position, const osg::Quat& rotation, const osg::Vec3& scale):
_position(position),
_rotation(rotation),
_scale(scale) {}
osg::Vec3 _position;
osg::Quat _rotation;
osg::Vec3 _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 getMatrix(Matrix& matrix) const
{
matrix.makeScale(_scale);
matrix.postMult(_rotation.getMatrix());
matrix.postMult(osg::Matrix::translate(_position));
}
inline void getInverse(Matrix& matrix) const
{
matrix.makeScale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.y());
matrix.postMult(_rotation.inverse().getMatrix());
matrix.postMult(osg::Matrix::translate(-_position));
}
};
/** get the transformation matrix for a point in time.*/
bool getMatrix(double time,Matrix& matrix) const
{
ControlPoint cp;
if (!getInterpolatedControlPoint(time,cp)) return false;
cp.getMatrix(matrix);
return true;
}
/** get the inverse transformation matrix for a point in time.*/
bool getInverse(double time,Matrix& matrix) const
{
ControlPoint cp;
if (!getInterpolatedControlPoint(time,cp)) return false;
cp.getInverse(matrix);
return true;
}
/** get the local ControlPoint frame for a point in time.*/
virtual bool getInterpolatedControlPoint(double time,ControlPoint& controlPoint) const;
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;
TimeControlPointMap& getTimeControlPointMap() { return _timeControlPointMap; }
const TimeControlPointMap& getTimeControlPointMap() const { return _timeControlPointMap; }
protected:
virtual ~AnimationPath() {}
TimeControlPointMap _timeControlPointMap;
LoopMode _loopMode;
};
class SG_EXPORT AnimationPathCallback : public NodeCallback, public NodeVisitor
{
public:
AnimationPathCallback():
_timeOffset(0.0),
_timeMultiplier(1.0),
_firstTime(0.0),
_animationTime(0.0) {}
AnimationPathCallback(const AnimationPathCallback& apc,const CopyOp& copyop):
NodeCallback(apc,copyop),
_animationPath(apc._animationPath),
_timeOffset(apc._timeOffset),
_timeMultiplier(apc._timeMultiplier),
_firstTime(apc._firstTime),
_animationTime(apc._animationTime) {}
META_Object(osg,AnimationPathCallback)
AnimationPathCallback(AnimationPath* ap,double timeOffset=0.0f,double timeMultiplier=1.0f):
_animationPath(ap),
_timeOffset(timeOffset),
_timeMultiplier(timeMultiplier),
_firstTime(0.0),
_animationTime(0.0) {}
void setAnimationPath(AnimationPath* path) { _animationPath = path; }
AnimationPath* getAnimationPath() { return _animationPath.get(); }
const AnimationPath* getAnimationPath() const { return _animationPath.get(); }
/** implements the callback*/
virtual void operator()(Node* node, NodeVisitor* nv);
virtual void apply(MatrixTransform& mt);
virtual void apply(PositionAttitudeTransform& pat);
public:
ref_ptr<AnimationPath> _animationPath;
double _timeOffset;
double _timeMultiplier;
double _firstTime;
mutable double _animationTime;
};
}
#endif