/* -*-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 #include #include #include #include #include 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 > 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(): _useInverseMatrix(false), _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::Object(apc, copyop), osg::Callback(apc, 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; bool _useInverseMatrix; double _timeOffset; double _timeMultiplier; double _firstTime; double _latestTime; bool _pause; double _pauseTime; protected: ~AnimationMaterialCallback(){} }; } #endif