osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarth/DrapeableNode.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 
00020 #include <osgEarth/DrapeableNode>
00021 #include <osgEarth/Utils>
00022 #include <osgEarth/FindNode>
00023 
00024 using namespace osgEarth;
00025 
00026 DrapeableNode::DrapeableNode( MapNode* mapNode, bool draped ) :
00027 _mapNode  ( mapNode ),
00028 _newDraped( draped ),
00029 _draped   ( false ),
00030 _dirty    ( false )
00031 {
00032     // create a container group that will house the culler. This culler
00033     // allows a draped node, which sits under the MapNode's OverlayDecorator,
00034     // to "track" the traversal state of the DrapeableNode itself.
00035     _nodeContainer = new osg::Group();
00036     _nodeContainer->setCullCallback( new CullNodeByFrameNumber() );
00037     _nodeContainer->setStateSet( this->getOrCreateStateSet() ); // share the stateset
00038 }
00039 
00040 void
00041 DrapeableNode::applyChanges()
00042 {    
00043     if ( _newDraped != _draped )
00044     {
00045         setDrapedImpl( _newDraped );
00046     }
00047 
00048     if ( _newNode.valid() )
00049     {
00050         setNodeImpl( _newNode.get() );
00051         _newNode = 0L;
00052     }
00053 }
00054 
00055 void
00056 DrapeableNode::setNode( osg::Node* node )
00057 {
00058     _newNode = node;
00059     if ( !_dirty )
00060     {
00061         _dirty = true;
00062         ADJUST_UPDATE_TRAV_COUNT( this, 1 );
00063     }
00064 }
00065 
00066 void
00067 DrapeableNode::setDraped( bool draped )
00068 {
00069     _newDraped = draped;
00070     if ( !_dirty )
00071     {
00072         _dirty = true;
00073         ADJUST_UPDATE_TRAV_COUNT( this, 1 );
00074     }
00075 }
00076 
00077 void
00078 DrapeableNode::setNodeImpl( osg::Node* node )
00079 {
00080     if ( _node.valid() )
00081     {
00082         if ( _draped && _mapNode.valid() )
00083         {
00084             _mapNode->getOverlayGroup()->removeChild( _nodeContainer.get() );
00085             _mapNode->updateOverlayGraph();
00086         }
00087         else
00088         {
00089             this->removeChild( _node.get() );
00090         }
00091     }
00092 
00093     _node = node;
00094     _nodeContainer->removeChildren( 0, _nodeContainer->getNumChildren() );
00095 
00096     if ( _node.valid() )
00097     {
00098         if ( _draped && _mapNode.valid() )
00099         {
00100             _nodeContainer->addChild( _node.get() );
00101             _mapNode->getOverlayGroup()->addChild( _nodeContainer.get() );
00102             _mapNode->updateOverlayGraph();
00103         }
00104         else
00105         {
00106             this->addChild( _node.get() );
00107         }
00108     }
00109 }
00110 
00111 void
00112 DrapeableNode::setDrapedImpl( bool value )
00113 {
00114     if ( _draped != value )
00115     {
00116         osg::ref_ptr<osg::Node> save = _node.get();
00117         if ( save.valid() )
00118             setNode( 0L );
00119 
00120         _draped = value;
00121 
00122         if ( save.valid() )
00123             setNode( save.get() );
00124     }
00125 }
00126 
00127 
00128 void
00129 DrapeableNode::traverse( osg::NodeVisitor& nv )
00130 {
00131     if ( _draped && nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR && _node.valid() && _mapNode.valid() )
00132     {
00133         CullNodeByFrameNumber* cb = static_cast<CullNodeByFrameNumber*>(_nodeContainer->getCullCallback());
00134         cb->_frame = nv.getFrameStamp()->getFrameNumber();
00135     }
00136 
00137     if ( nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR )
00138     {
00139         if ( _dirty )
00140         {
00141             applyChanges();
00142 
00143             _dirty = false;
00144             ADJUST_UPDATE_TRAV_COUNT( this, -1 );
00145         }
00146 
00147         // traverse the subgraph
00148         if ( _nodeContainer.valid() && this->getNumChildrenRequiringUpdateTraversal() > 0 )
00149         {
00150             _nodeContainer->accept( nv );
00151         }
00152     }
00153 
00154     osg::Group::traverse( nv );
00155 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines