osgEarth 2.1.1
|
Public Member Functions | |
osg::Node * | operator() (const GeometryList &geoms, const Style *style) |
Definition at line 45 of file GeometrySymbolizer.
osg::Node * GeometrySymbolizer::GeometrySymbolizerOperator::operator() | ( | const GeometryList & | geoms, |
const Style * | style | ||
) |
Definition at line 33 of file GeometrySymbolizer.cpp.
{ osg::ref_ptr<osg::Geode> geode = new osg::Geode; for (GeometryList::const_iterator it = geometryList.begin(); it != geometryList.end(); ++it) { Geometry* geometry = *it; if (!geometry) continue; GeometryIterator geomIterator( geometry ); geomIterator.traverseMultiGeometry() = true; geomIterator.traversePolygonHoles() = true; while( geomIterator.hasMore() ) { Geometry* part = geomIterator.next(); if (!part) continue; osg::ref_ptr<osg::Geometry> osgGeom = new osg::Geometry; osg::PrimitiveSet::Mode primMode = osg::PrimitiveSet::POINTS; osg::Vec4 color = osg::Vec4(1.0, 0.0, 1.0, 1.); switch( part->getType()) { case Geometry::TYPE_POINTSET: { primMode = osg::PrimitiveSet::POINTS; const PointSymbol* point = style->getSymbol<PointSymbol>(); if (point) { color = point->fill()->color(); float size = point->size().value(); osgGeom->getOrCreateStateSet()->setAttributeAndModes( new osg::Point(size) ); } } break; case Geometry::TYPE_LINESTRING: { primMode = osg::PrimitiveSet::LINE_STRIP; const LineSymbol* line = style->getSymbol<LineSymbol>(); if (line) { color = line->stroke()->color(); float size = line->stroke()->width().value(); osgGeom->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth(size)); } } break; case Geometry::TYPE_RING: { primMode = osg::PrimitiveSet::LINE_LOOP; const LineSymbol* line = style->getSymbol<LineSymbol>(); if (line) { color = line->stroke()->color(); float size = line->stroke()->width().value(); osgGeom->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth(size)); } } break; case Geometry::TYPE_POLYGON: { primMode = osg::PrimitiveSet::LINE_LOOP; // loop will tessellate into polys const PolygonSymbol* poly = style->getSymbol<PolygonSymbol>(); if (poly) { color = poly->fill()->color(); } } break; default: break; } osg::Material* material = new osg::Material; material->setDiffuse(osg::Material::FRONT_AND_BACK, color); if ( part->getType() == Geometry::TYPE_POLYGON && static_cast<Polygon*>(part)->getHoles().size() > 0 ) { Polygon* poly = static_cast<Polygon*>(geometry); int totalPoints = poly->getTotalPointCount(); osg::Vec3Array* allPoints = new osg::Vec3Array( totalPoints ); int offset = 0; for( RingCollection::const_iterator h = poly->getHoles().begin(); h != poly->getHoles().end(); ++h ) { Geometry* hole = h->get(); std::copy( hole->begin(), hole->end(), allPoints->begin() + offset ); osgGeom->addPrimitiveSet( new osg::DrawArrays( primMode, offset, hole->size() ) ); offset += hole->size(); } osgGeom->setVertexArray( allPoints ); } else { osgGeom->setVertexArray( part->toVec3Array() ); osgGeom->addPrimitiveSet( new osg::DrawArrays( primMode, 0, part->size() ) ); } // tessellate all polygon geometries. Tessellating each geometry separately // with TESS_TYPE_GEOMETRY is much faster than doing the whole bunch together // using TESS_TYPE_DRAWABLE. if ( part->getType() == Geometry::TYPE_POLYGON) { osgUtil::Tessellator tess; tess.setTessellationType( osgUtil::Tessellator::TESS_TYPE_GEOMETRY ); tess.setWindingType( osgUtil::Tessellator::TESS_WINDING_POSITIVE ); tess.retessellatePolygons( *osgGeom ); } osgGeom->getOrCreateStateSet()->setAttributeAndModes(material); geode->addDrawable(osgGeom); } } if (geode->getNumDrawables()) return geode.release(); return 0; }