#include <StencilUtils.h>
List of all members.
Static Public Member Functions |
static osg::Node * | createGeometryPass (osg::Node *geometry, int &ref_renderBin) |
static osg::Node * | createMaskPass (const osg::Vec4ub &color, int &ref_renderBin) |
static osg::Geode * | createVolume (Geometry *geom, double offset, double height, const FilterContext &context) |
Detailed Description
Definition at line 31 of file StencilUtils.h.
Member Function Documentation
static osg::Node* StencilUtils::createGeometryPass |
( |
osg::Node * |
geometry, |
|
|
int & |
ref_renderBin |
|
) |
| [static] |
static osg::Node* StencilUtils::createMaskPass |
( |
const osg::Vec4ub & |
color, |
|
|
int & |
ref_renderBin |
|
) |
| [static] |
osg::Geode * StencilUtils::createVolume |
( |
Geometry * |
geom, |
|
|
double |
offset, |
|
|
double |
height, |
|
|
const FilterContext & |
context |
|
) |
| [static] |
Definition at line 496 of file StencilUtils.cpp.
{
if ( !geom ) return 0L;
int numRings = 0;
if ( offset != 0.0 )
{
GeometryIterator i( geom );
i.traverseMultiGeometry() = true;
i.traversePolygonHoles() = true;
while( i.hasMore() )
{
Geometry* part = i.next();
for( osg::Vec3dArray::iterator j = part->begin(); j != part->end(); j++ )
{
if ( context.isGeocentric() )
{
osg::Vec3d world = context.toWorld( *j );
osg::Vec3d offset_vec = world;
offset_vec.normalize();
*j = context.toLocal( world + offset_vec * offset );
}
else
{
(*j).z() += offset;
}
}
if ( part->getType() == Geometry::TYPE_POLYGON || part->getType() == Geometry::TYPE_RING )
{
numRings++;
}
}
}
#define PARALLEL_EPSILON 0.01
GeometryIterator i( geom );
i.traverseMultiGeometry() = true;
i.traversePolygonHoles() = true;
while( i.hasMore() )
{
Geometry* part = i.next();
if ( part->size() >= 3 )
{
osg::Vec3d prevVec = part->front() - part->back();
prevVec.normalize();
for( osg::Vec3dArray::iterator j = part->begin(); part->size() >= 3 && j != part->end(); )
{
osg::Vec3d& p0 = *j;
osg::Vec3d& p1 = j+1 != part->end() ? *(j+1) : part->front();
osg::Vec3d vec = p1-p0; vec.normalize();
if ( (prevVec ^ vec).length() < PARALLEL_EPSILON )
{
j = part->erase( j );
}
else
{
++j;
prevVec = vec;
}
}
}
}
bool made_geom = true;
const SpatialReference* srs = context.profile()->getSRS();
int num_cap_verts = geom->getTotalPointCount();
int num_wall_verts = 2 * (num_cap_verts + numRings);
osg::Geometry* walls = new osg::Geometry();
osg::Vec3Array* verts = new osg::Vec3Array( num_wall_verts );
walls->setVertexArray( verts );
osg::Geometry* top_cap = new osg::Geometry();
osg::Vec3Array* top_verts = new osg::Vec3Array( num_cap_verts );
top_cap->setVertexArray( top_verts );
osg::Geometry* bottom_cap = new osg::Geometry();
osg::Vec3Array* bottom_verts = new osg::Vec3Array( num_cap_verts );
bottom_cap->setVertexArray( bottom_verts );
int wall_vert_ptr = 0;
int top_vert_ptr = 0;
int bottom_vert_ptr = 0;
GeometryIterator k( geom );
while( k.hasMore() )
{
Geometry* part = k.next();
unsigned int wall_part_ptr = wall_vert_ptr;
unsigned int top_part_ptr = top_vert_ptr;
unsigned int bottom_part_ptr = bottom_vert_ptr;
double part_len = 0.0;
GLenum prim_type = part->getType() == Geometry::TYPE_POINTSET ? GL_LINES : GL_TRIANGLE_STRIP;
for( osg::Vec3dArray::const_iterator m = part->begin(); m != part->end(); ++m )
{
osg::Vec3d extrude_vec;
if ( srs )
{
osg::Vec3d m_world = context.toWorld( *m );
if ( context.isGeocentric() )
{
osg::Vec3d p_vec = m_world;
osg::Vec3d unit_vec = p_vec;
unit_vec.normalize();
p_vec = p_vec + unit_vec*height;
extrude_vec = context.toLocal( p_vec );
}
else
{
extrude_vec.set( m_world.x(), m_world.y(), height );
extrude_vec = context.toLocal( extrude_vec );
}
}
else
{
extrude_vec.set( m->x(), m->y(), height );
}
(*top_verts)[top_vert_ptr++] = extrude_vec;
(*bottom_verts)[bottom_vert_ptr++] = *m;
part_len += wall_vert_ptr > wall_part_ptr?
(extrude_vec - (*verts)[wall_vert_ptr-2]).length() :
0.0;
int p;
p = wall_vert_ptr++;
(*verts)[p] = extrude_vec;
p = wall_vert_ptr++;
(*verts)[p] = *m;
}
if ( part->getType() == Geometry::TYPE_RING || part->getType() == Geometry::TYPE_POLYGON )
{
part_len += wall_vert_ptr > wall_part_ptr?
((*verts)[wall_part_ptr] - (*verts)[wall_vert_ptr-2]).length() :
0.0;
int p;
p = wall_vert_ptr++;
(*verts)[p] = (*verts)[wall_part_ptr];
p = wall_vert_ptr++;
(*verts)[p] = (*verts)[wall_part_ptr+1];
}
walls->addPrimitiveSet( new osg::DrawArrays(
prim_type,
wall_part_ptr, wall_vert_ptr - wall_part_ptr ) );
top_cap->addPrimitiveSet( new osg::DrawArrays(
osg::PrimitiveSet::LINE_LOOP,
top_part_ptr, top_vert_ptr - top_part_ptr ) );
std::reverse( bottom_verts->begin()+bottom_part_ptr, bottom_verts->begin()+bottom_vert_ptr );
bottom_cap->addPrimitiveSet( new osg::DrawArrays(
osg::PrimitiveSet::LINE_LOOP,
bottom_part_ptr, bottom_vert_ptr - bottom_part_ptr ) );
}
tessellate( top_cap );
tessellate( bottom_cap );
osg::Geode* geode = new osg::Geode();
geode->addDrawable( walls );
geode->addDrawable( top_cap );
geode->addDrawable( bottom_cap );
return geode;
}
The documentation for this struct was generated from the following files:
- /home/cube/sources/osgearth/src/osgEarthDrivers/model_feature_stencil/StencilUtils.h
- /home/cube/sources/osgearth/src/osgEarthDrivers/model_feature_stencil/StencilUtils.cpp