OpenSceneGraph/include/osg/AnimationPath
Robert Osfield f36bc69c58 Made the more of the OSG's referenced object desctructors protected to ensure
that they arn't created on the stack inappropriately.

Split the implemention of Matrix up so that it is a simple no referenced counted
class and can be safefly created on the stack.  To support referenced counting a
seperate subclass now exists, this is RefMatrix which inherits from both Matrix and
Object.
2003-01-10 09:25:42 +00:00

195 lines
6.2 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/NodeCallback>
#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:
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);
public:
ref_ptr<AnimationPath> _animationPath;
double _timeOffset;
double _timeMultiplier;
double _firstTime;
mutable double _animationTime;
protected:
~AnimationPathCallback(){}
};
}
#endif