174 lines
5.9 KiB
C++
174 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 <iosfwd>
|
|
#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 OSGPRESENTATION_EXPORT 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
|