osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthFeatures/FeatureGeometryIndex.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 #include <osgEarthFeatures/FeatureGeometryIndex>
00020 
00021 using namespace osgEarth;
00022 using namespace osgEarth::Features;
00023 
00024 //---------------------------------------------------------------------------
00025 
00026 namespace
00027 {
00028     struct FindVisitor : public osg::NodeVisitor
00029     {
00030         FindVisitor( FeatureID id )
00031             : _id(id), 
00032               _rec(0L),
00033               osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) { }
00034 
00035         void apply( osg::Node& node )
00036         {
00037             if ( _rec )
00038                 return;
00039 
00040             osg::Referenced* ref = node.getUserData();
00041             if ( ref )
00042             {
00043                 FeatureGeometryIndex* index = dynamic_cast<FeatureGeometryIndex*>( ref );
00044                 if ( index )
00045                 {
00046                     _rec = index->get( _id );
00047                     if ( _rec )
00048                         return;
00049                 }
00050             }
00051             traverse( node );
00052         }
00053 
00054         FeatureID _id;
00055         const FeatureGeometryRecord* _rec;
00056     };
00057 }
00058 
00059 FeatureGeometryQuery::FeatureGeometryQuery( osg::Node* graph ) :
00060 _graph( graph )
00061 {
00062     //nop
00063 }
00064 
00065 bool
00066 FeatureGeometryQuery::find( FeatureID id, FeatureGeometryRecord& record ) const
00067 {
00068     if ( _graph.valid() )
00069     {
00070         FindVisitor visitor( id );
00071         _graph->accept( visitor );
00072         if ( visitor._rec )
00073         {
00074             record = *(visitor._rec);
00075             return true;
00076         }
00077     }
00078     return false;
00079 }
00080 
00081 //---------------------------------------------------------------------------
00082 
00083 FeatureGeometryIndex::FeatureGeometryIndex()
00084 {
00085     //nop
00086 }
00087 
00088 const FeatureGeometryRecord*
00089 FeatureGeometryIndex::get( FeatureID fid ) const
00090 {
00091     FeatureRecords::const_iterator i = _records.find( fid );
00092     return i != _records.end () ? &(i->second) : 0L;
00093 }
00094 
00095 //---------------------------------------------------------------------------
00096 
00097 namespace
00098 {
00099     struct Collector : public osg::NodeVisitor
00100     {
00101         typedef FeatureGeometryIndexBuilder::PrimSetFeatureIdMap IdMap;
00102 
00103         Collector(const IdMap& ids, FeatureGeometryIndex::FeatureRecords& recs )
00104             : osg::NodeVisitor( osg::NodeVisitor::TRAVERSE_ALL_CHILDREN ),
00105               _recs( recs ),
00106               _ids( ids ) { }
00107 
00108         void apply( osg::Geode& geode )
00109         {
00110             for( unsigned i=0; i<geode.getNumDrawables(); ++i )
00111             {
00112                 osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
00113                 if ( geom )
00114                 {
00115                     for( unsigned j=0; j<geom->getNumPrimitiveSets(); ++j )
00116                     {
00117                         osg::PrimitiveSet* primSet = geom->getPrimitiveSet(j);
00118 
00119                         IdMap::const_iterator k = _ids.find( primSet );
00120                         if ( k != _ids.end() )
00121                         {
00122                             FeatureID fid = k->second;
00123                             FeatureGeometryRecord& rec = _recs[fid];
00124                             rec._geode = &geode;
00125                             rec._primSetsByGeometry[geom].push_back( primSet );
00126                         }
00127                     }
00128                 }
00129             }
00130             traverse( geode );
00131         }
00132 
00133         FeatureGeometryIndex::FeatureRecords& _recs;
00134         const FeatureGeometryIndexBuilder::PrimSetFeatureIdMap& _ids;
00135     };
00136 }
00137 
00138 FeatureGeometryIndexBuilder::FeatureGeometryIndexBuilder()
00139 {
00140     //nop
00141 }
00142 
00143 void
00144 FeatureGeometryIndexBuilder::add( FeatureID id, osg::PrimitiveSet* primSet )
00145 {
00146     _primSetIds[primSet] = id;
00147 }
00148 
00149 FeatureGeometryIndex*
00150 FeatureGeometryIndexBuilder::createIndex( osg::Node* node )
00151 {
00152     FeatureGeometryIndex* index = new FeatureGeometryIndex();
00153     Collector collector( _primSetIds, index->_records );
00154     node->accept( collector );
00155     return index;
00156 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines