OpenSceneGraph/include/osg/AnimationPath
Robert Osfield 792bba05b9 Added new Matrixf and Matrixd implementations.
Made Matrix be a typedef to either Matrixf or Matrixd.  Defaults to Matrixf.

Converted the osgGA::MatrixManipulators and osgProducer::Viewer/OsgCameraGroup
across to using exclusively Matrixd for internal computations and passing betwen
Manipulators, Producer and SceneView. Note, SceneView still uses Matrix internally
so will depend on what is set as the default in include/osg/Matrix.

Added the ability to osgProducer::setDone/getDone(), kept done() as the
method that the viewer main loop uses for detecting the exit condition.
2003-09-05 22:35:34 +00:00

236 lines
7.8 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 <osg/Matrixf>
#include <osg/Matrixd>
#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(Matrixf& matrix) const
{
matrix.makeScale(_scale);
matrix.postMult(osg::Matrixf::rotate(_rotation));
matrix.postMult(osg::Matrixf::translate(_position));
}
inline void getMatrix(Matrixd& matrix) const
{
matrix.makeScale(_scale);
matrix.postMult(osg::Matrixd::rotate(_rotation));
matrix.postMult(osg::Matrixd::translate(_position));
}
inline void getInverse(Matrixf& matrix) const
{
matrix.makeScale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.y());
matrix.postMult(osg::Matrixf::rotate(_rotation.inverse()));
matrix.postMult(osg::Matrixf::translate(-_position));
}
inline void getInverse(Matrixd& matrix) const
{
matrix.makeScale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.y());
matrix.postMult(osg::Matrixd::rotate(_rotation.inverse()));
matrix.postMult(osg::Matrixd::translate(-_position));
}
};
/** get the transformation matrix for a point in time.*/
bool getMatrix(double time,Matrixf& matrix) const
{
ControlPoint cp;
if (!getInterpolatedControlPoint(time,cp)) return false;
cp.getMatrix(matrix);
return true;
}
/** get the transformation matrix for a point in time.*/
bool getMatrix(double time,Matrixd& 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,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;
}
/** 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