1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2018 Robert Osfield 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 * (at your option) any later version. The full license is in LICENSE file 6 * included with this distribution, and on the openscenegraph.org website. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * OpenSceneGraph Public License for more details. 12*/ 13 14#ifndef OSG_ANIMATIONMATERIAL 15#define OSG_ANIMATIONMATERIAL 1 16 17#include <osg/Material> 18#include <osg/Callback> 19 20#include <osgPresentation/Export> 21 22#include <iosfwd> 23#include <map> 24#include <float.h> 25 26namespace osgPresentation { 27 28/** AnimationMaterial for specify the time varying transformation pathway to use when update camera and model objects. 29 * Subclassed from Transform::ComputeTransformCallback allows AnimationMaterial to 30 * be attached directly to Transform nodes to move subgraphs around the scene. 31*/ 32class OSGPRESENTATION_EXPORT AnimationMaterial : public virtual osg::Object 33{ 34 public: 35 36 AnimationMaterial():_loopMode(LOOP) {} 37 38 AnimationMaterial(const AnimationMaterial& ap, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): 39 Object(ap,copyop), 40 _timeControlPointMap(ap._timeControlPointMap), 41 _loopMode(ap._loopMode) {} 42 43 META_Object(osg,AnimationMaterial); 44 45 46 /** get the transformation matrix for a point in time.*/ 47 bool getMaterial(double time,osg::Material& material) const; 48 49 void insert(double time,osg::Material* material); 50 51 double getFirstTime() const { if (!_timeControlPointMap.empty()) return _timeControlPointMap.begin()->first; else return 0.0;} 52 double getLastTime() const { if (!_timeControlPointMap.empty()) return _timeControlPointMap.rbegin()->first; else return 0.0;} 53 double getPeriod() const { return getLastTime()-getFirstTime();} 54 55 enum LoopMode 56 { 57 SWING, 58 LOOP, 59 NO_LOOPING 60 }; 61 62 void setLoopMode(LoopMode lm) { _loopMode = lm; } 63 64 LoopMode getLoopMode() const { return _loopMode; } 65 66 67 typedef std::map<double, osg::ref_ptr<osg::Material> > TimeControlPointMap; 68 69 TimeControlPointMap& getTimeControlPointMap() { return _timeControlPointMap; } 70 71 const TimeControlPointMap& getTimeControlPointMap() const { return _timeControlPointMap; } 72 73 /** read the anumation path from a flat ascii file stream.*/ 74 void read(std::istream& in); 75 76 /** write the anumation path to a flat ascii file stream.*/ 77 void write(std::ostream& out) const; 78 79 bool requiresBlending() const; 80 81 protected: 82 83 virtual ~AnimationMaterial() {} 84 85 void interpolate(osg::Material& material, float r, const osg::Material& lhs,const osg::Material& rhs) const; 86 87 TimeControlPointMap _timeControlPointMap; 88 LoopMode _loopMode; 89 90}; 91 92 93class OSGPRESENTATION_EXPORT AnimationMaterialCallback : public osg::NodeCallback 94{ 95 public: 96 97 AnimationMaterialCallback(): 98 _useInverseMatrix(false), 99 _timeOffset(0.0), 100 _timeMultiplier(1.0), 101 _firstTime(DBL_MAX), 102 _latestTime(0.0), 103 _pause(false), 104 _pauseTime(0.0) {} 105 106 107 AnimationMaterialCallback(const AnimationMaterialCallback& apc,const osg::CopyOp& copyop): 108 osg::Object(apc, copyop), 109 osg::Callback(apc, copyop), 110 osg::NodeCallback(apc,copyop), 111 _animationMaterial(apc._animationMaterial), 112 _useInverseMatrix(apc._useInverseMatrix), 113 _timeOffset(apc._timeOffset), 114 _timeMultiplier(apc._timeMultiplier), 115 _firstTime(apc._firstTime), 116 _latestTime(apc._latestTime), 117 _pause(apc._pause), 118 _pauseTime(apc._pauseTime) {} 119 120 121 META_Object(osg,AnimationMaterialCallback); 122 123 AnimationMaterialCallback(AnimationMaterial* ap,double timeOffset=0.0f,double timeMultiplier=1.0f): 124 _animationMaterial(ap), 125 _useInverseMatrix(false), 126 _timeOffset(timeOffset), 127 _timeMultiplier(timeMultiplier), 128 _firstTime(DBL_MAX), 129 _latestTime(0.0), 130 _pause(false), 131 _pauseTime(0.0) {} 132 133 void setAnimationMaterial(AnimationMaterial* path) { _animationMaterial = path; } 134 135 AnimationMaterial* getAnimationMaterial() { return _animationMaterial.get(); } 136 137 const AnimationMaterial* getAnimationMaterial() const { return _animationMaterial.get(); } 138 139 void setTimeOffset(double offset) { _timeOffset = offset; } 140 double getTimeOffset() const { return _timeOffset; } 141 142 void setTimeMultiplier(double multiplier) { _timeMultiplier = multiplier; } 143 double getTimeMultiplier() const { return _timeMultiplier; } 144 145 void reset(); 146 147 void setPause(bool pause); 148 149 /** get the animation time that is used to specify the position along the AnimationMaterial. 150 * Animation time is computed from the formula ((_latestTime-_firstTime)-_timeOffset)*_timeMultiplier.*/ 151 double getAnimationTime() const; 152 153 /** implements the callback*/ 154 virtual void operator()(osg::Node* node, osg::NodeVisitor* nv); 155 156 void update(osg::Node& node); 157 158 public: 159 160 osg::ref_ptr<AnimationMaterial> _animationMaterial; 161 bool _useInverseMatrix; 162 double _timeOffset; 163 double _timeMultiplier; 164 double _firstTime; 165 double _latestTime; 166 bool _pause; 167 double _pauseTime; 168 169 protected: 170 171 ~AnimationMaterialCallback(){} 172 173}; 174 175} 176 177#endif 178