Show
Ignore:
Timestamp:
07/16/08 17:58:15 (6 years ago)
Author:
robert
Message:

Refactored the MultiTextureControl? node callback so that the update is now
done as an update callback, with the elevation aquired via a cull callback

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgmultitexturecontrol/osgmultitexturecontrol.cpp

    r8366 r8610  
    9393            _previousFrame(-1), 
    9494            _previousTime(0.0), 
     95            _currentElevation(0.0), 
    9596            _mtc(mtc), 
    9697            _elevations(elevations), 
     
    99100        /** Callback method called by the NodeVisitor when visiting a node.*/ 
    100101        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) 
    101         {  
    102             if (!nv->getFrameStamp() || _previousFrame==nv->getFrameStamp()->getFrameNumber()) 
     102        { 
     103            if (nv->getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR) 
    103104            { 
    104                 // we've already updated for this frame so no need to do it again, just traverse children. 
    105                 traverse(node,nv); 
    106                 return; 
     105 
     106                float deltaTime = 0.01f; 
     107                if (_previousFrame!=-1) 
     108                { 
     109                    deltaTime = float(nv->getFrameStamp()->getReferenceTime() - _previousTime); 
     110                } 
     111 
     112                _previousTime = nv->getFrameStamp()->getReferenceTime(); 
     113                _previousFrame = nv->getFrameStamp()->getFrameNumber(); 
     114 
     115                if (_mtc.valid() && !_elevations.empty()) 
     116                { 
     117                    unsigned int index = _mtc->getNumTextureWeights()-1; 
     118                    for(unsigned int i=0; i<_elevations.size(); ++i) 
     119                    { 
     120                        if (_currentElevation>_elevations[i])  
     121                        { 
     122                            index = i; 
     123                            break; 
     124                        } 
     125                    } 
     126 
     127                    float delta = std::min(deltaTime/_animationTime, 1.0f); 
     128 
     129                    for(unsigned int i=0; i<_mtc->getNumTextureWeights(); ++i) 
     130                    { 
     131                        float currentValue = _mtc->getTextureWeight(i); 
     132                        float desiredValue = (i==index) ? 1.0f : 0.0f; 
     133                        if (desiredValue != currentValue) 
     134                        { 
     135                            if (currentValue<desiredValue) 
     136                            { 
     137                                desiredValue = std::min(currentValue + delta, desiredValue); 
     138                            } 
     139                            else 
     140                            { 
     141                                desiredValue = std::max(currentValue - delta, desiredValue); 
     142                            } 
     143 
     144                            _mtc->setTextureWeight(i, desiredValue); 
     145                        } 
     146                    } 
     147 
     148                } 
    107149            } 
    108              
    109             OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
    110              
    111             float deltaTime = 0.01f; 
    112             if (_previousFrame!=-1) 
     150            else if (nv->getVisitorType()==osg::NodeVisitor::CULL_VISITOR) 
    113151            { 
    114                 deltaTime = float(nv->getFrameStamp()->getReferenceTime() - _previousTime); 
     152                _currentElevation = nv->getViewPoint().z(); 
     153 
     154                osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(node); 
     155                if (csn)  
     156                { 
     157                    osg::EllipsoidModel* em = csn->getEllipsoidModel(); 
     158                    if (em) 
     159                    { 
     160                        double X = nv->getViewPoint().x(); 
     161                        double Y = nv->getViewPoint().y(); 
     162                        double Z = nv->getViewPoint().z(); 
     163                        double latitude, longitude; 
     164                        em->convertXYZToLatLongHeight(X,Y,Z,latitude, longitude, _currentElevation); 
     165                    } 
     166                } 
     167 
    115168            } 
    116              
    117             _previousTime = nv->getFrameStamp()->getReferenceTime(); 
    118             _previousFrame = nv->getFrameStamp()->getFrameNumber(); 
    119  
    120             double elevation = nv->getViewPoint().z(); 
    121          
    122             osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(node); 
    123             if (csn)  
    124             { 
    125                 osg::EllipsoidModel* em = csn->getEllipsoidModel(); 
    126                 if (em) 
    127                 { 
    128                     double X = nv->getViewPoint().x(); 
    129                     double Y = nv->getViewPoint().y(); 
    130                     double Z = nv->getViewPoint().z(); 
    131                     double latitude, longitude; 
    132                     em->convertXYZToLatLongHeight(X,Y,Z,latitude, longitude, elevation); 
    133                 } 
    134             } 
    135          
    136             if (_mtc.valid() && !_elevations.empty()) 
    137             { 
    138                 unsigned int index = _mtc->getNumTextureWeights()-1; 
    139                 for(unsigned int i=0; i<_elevations.size(); ++i) 
    140                 { 
    141                     if (elevation>_elevations[i])  
    142                     { 
    143                         index = i; 
    144                         break; 
    145                     } 
    146                 } 
    147                  
    148                 float delta = std::min(deltaTime/_animationTime, 1.0f); 
    149                  
    150                 for(unsigned int i=0; i<_mtc->getNumTextureWeights(); ++i) 
    151                 { 
    152                     float currentValue = _mtc->getTextureWeight(i); 
    153                     float desiredValue = (i==index) ? 1.0f : 0.0f; 
    154                     if (desiredValue != currentValue) 
    155                     { 
    156                         if (currentValue<desiredValue) 
    157                         { 
    158                             desiredValue = std::min(currentValue + delta, desiredValue); 
    159                         } 
    160                         else 
    161                         { 
    162                             desiredValue = std::max(currentValue - delta, desiredValue); 
    163                         } 
    164                      
    165                         _mtc->setTextureWeight(i, desiredValue); 
    166                     } 
    167                 } 
    168                  
    169             } 
    170          
     169 
    171170            traverse(node,nv); 
    172171        } 
     
    175174        double                                          _previousTime; 
    176175        float                                           _animationTime; 
     176        double                                          _currentElevation; 
     177         
    177178        osg::observer_ptr<osgFX::MultiTextureControl>   _mtc; 
    178179        Elevations                                      _elevations; 
    179          
    180         OpenThreads::Mutex                              _mutex; 
    181180}; 
    182181 
     
    354353 
    355354        // assign to the most appropriate node (the CoordinateSystemNode is best as it provides the elevation on the globe.) 
    356         if (csn) csn->setCullCallback(elbc);     
    357         else if (mtc) mtc->setCullCallback(elbc); 
    358         else rootnode->setCullCallback(elbc); 
     355        // note we must assign callback as both an update and cull callback, as update callback to do the update of 
     356        // the the osgFX::MultiTextureControl node a thread safe way, and as a cull callback to gather the camera 
     357        // position information. 
     358        osg::Node* nodeToAssignCallbackTo = csn ? csn : (mtc ? mtc : rootnode); 
     359        nodeToAssignCallbackTo->setUpdateCallback(elbc);     
     360        nodeToAssignCallbackTo->setCullCallback(elbc);     
    359361 
    360362        // add a viewport to the viewer and attach the scene graph.