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 #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 }