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