AnimationMaterial 5.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
/* -*-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