OpenSceneGraph/include/osgPresentation/AnimationMaterial

173 lines
5.9 KiB
C++

/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
*
* This software is open source and may be redistributed and/or modified under
* the terms of the GNU General Public License (GPL) version 2.0.
* The full license is in LICENSE.txt file included with this distribution,.
*
* This software 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
* include LICENSE.txt for more details.
*/
#ifndef OSG_ANIMATIONMATERIAL
#define OSG_ANIMATIONMATERIAL 1
#include <osg/Material>
#include <osg/NodeCallback>
#include <osgPresentation/Export>
#include <map>
#include <float.h>
namespace osgPresentation {
/** AnimationMaterial for specify the time varying transformation pathway to use when update camera and model objects.
* Subclassed from Transform::ComputeTransformCallback allows AnimationMaterial to
* be attached directly to Transform nodes to move subgraphs around the scene.
*/
class OSGPRESENTATION_EXPORT AnimationMaterial : public virtual osg::Object
{
public:
AnimationMaterial():_loopMode(LOOP) {}
AnimationMaterial(const AnimationMaterial& ap, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
Object(ap,copyop),
_timeControlPointMap(ap._timeControlPointMap),
_loopMode(ap._loopMode) {}
META_Object(osg,AnimationMaterial);
/** get the transformation matrix for a point in time.*/
bool getMaterial(double time,osg::Material& material) const;
void insert(double time,osg::Material* material);
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, osg::ref_ptr<osg::Material> > TimeControlPointMap;
TimeControlPointMap& getTimeControlPointMap() { return _timeControlPointMap; }
const TimeControlPointMap& getTimeControlPointMap() const { return _timeControlPointMap; }
/** read the anumation path from a flat ascii file stream.*/
void read(std::istream& in);
/** write the anumation path to a flat ascii file stream.*/
void write(std::ostream& out) const;
bool requiresBlending() const;
protected:
virtual ~AnimationMaterial() {}
void interpolate(osg::Material& material, float r, const osg::Material& lhs,const osg::Material& rhs) const;
TimeControlPointMap _timeControlPointMap;
LoopMode _loopMode;
};
class AnimationMaterialCallback : public osg::NodeCallback
{
public:
AnimationMaterialCallback():
_timeOffset(0.0),
_timeMultiplier(1.0),
_firstTime(DBL_MAX),
_latestTime(0.0),
_pause(false),
_pauseTime(0.0) {}
AnimationMaterialCallback(const AnimationMaterialCallback& apc,const osg::CopyOp& copyop):
osg::NodeCallback(apc,copyop),
_animationMaterial(apc._animationMaterial),
_useInverseMatrix(apc._useInverseMatrix),
_timeOffset(apc._timeOffset),
_timeMultiplier(apc._timeMultiplier),
_firstTime(apc._firstTime),
_latestTime(apc._latestTime),
_pause(apc._pause),
_pauseTime(apc._pauseTime) {}
META_Object(osg,AnimationMaterialCallback);
AnimationMaterialCallback(AnimationMaterial* ap,double timeOffset=0.0f,double timeMultiplier=1.0f):
_animationMaterial(ap),
_useInverseMatrix(false),
_timeOffset(timeOffset),
_timeMultiplier(timeMultiplier),
_firstTime(DBL_MAX),
_latestTime(0.0),
_pause(false),
_pauseTime(0.0) {}
void setAnimationMaterial(AnimationMaterial* path) { _animationMaterial = path; }
AnimationMaterial* getAnimationMaterial() { return _animationMaterial.get(); }
const AnimationMaterial* getAnimationMaterial() const { return _animationMaterial.get(); }
void setTimeOffset(double offset) { _timeOffset = offset; }
double getTimeOffset() const { return _timeOffset; }
void setTimeMultiplier(double multiplier) { _timeMultiplier = multiplier; }
double getTimeMultiplier() const { return _timeMultiplier; }
void reset();
void setPause(bool pause);
/** get the animation time that is used to specify the position along the AnimationMaterial.
* Animation time is computed from the formula ((_latestTime-_firstTime)-_timeOffset)*_timeMultiplier.*/
double getAnimationTime() const;
/** implements the callback*/
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
void update(osg::Node& node);
public:
osg::ref_ptr<AnimationMaterial> _animationMaterial;
bool _useInverseMatrix;
double _timeOffset;
double _timeMultiplier;
double _firstTime;
double _latestTime;
bool _pause;
double _pauseTime;
protected:
~AnimationMaterialCallback(){}
};
}
#endif