osgEarth 2.1.1
|
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 #ifndef OSGEARTH_FINDNODE 00021 #define OSGEARTH_FINDNODE 1 00022 00023 namespace osgEarth 00024 { 00028 template<typename T> 00029 class FindTopMostNodeOfTypeVisitor : public osg::NodeVisitor 00030 { 00031 public: 00032 FindTopMostNodeOfTypeVisitor(): 00033 osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), 00034 _foundNode(0) 00035 {} 00036 00037 void apply(osg::Node& node) 00038 { 00039 T* result = dynamic_cast<T*>(&node); 00040 if (result) 00041 { 00042 _foundNode = result; 00043 } 00044 else 00045 { 00046 traverse(node); 00047 } 00048 } 00049 00050 T* _foundNode; 00051 }; 00052 00057 template<typename T> 00058 T* findTopMostNodeOfType(osg::Node* node) 00059 { 00060 if (!node) return 0; 00061 00062 FindTopMostNodeOfTypeVisitor<T> fnotv; 00063 fnotv.setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN); 00064 node->accept(fnotv); 00065 00066 return fnotv._foundNode; 00067 } 00068 00073 template<typename T> 00074 T* findFirstParentOfType(osg::Node* node) 00075 { 00076 if (!node) return 0; 00077 00078 FindTopMostNodeOfTypeVisitor<T> fnotv; 00079 fnotv.setTraversalMode(osg::NodeVisitor::TRAVERSE_PARENTS); 00080 node->accept(fnotv); 00081 00082 return fnotv._foundNode; 00083 } 00084 00089 template<typename T> 00090 T* findRelativeNodeOfType(osg::Node* node) 00091 { 00092 if ( !node ) return 0; 00093 T* result = findFirstParentOfType<T>( node ); 00094 if ( !result ) 00095 result = findTopMostNodeOfType<T>( node ); 00096 return result; 00097 } 00098 00103 #define ADJUST_UPDATE_TRAV_COUNT( NODE, DELTA ) \ 00104 { \ 00105 int oldCount = NODE ->getNumChildrenRequiringUpdateTraversal(); \ 00106 if ( oldCount + DELTA >= 0 ) \ 00107 NODE ->setNumChildrenRequiringUpdateTraversal( (unsigned int)(oldCount + DELTA ) ); \ 00108 } 00109 } 00110 00111 #endif //OSGEARTH_FINDNODE