Beispiel #1
0
void
AllocateAndMergeBufferObjectsVisitor::apply(osg::Drawable& drawable)
{
    osg::Geometry* geom = drawable.asGeometry();
    if ( geom )
    {
        // We disable vbo's and then re-enable them to enable sharing of all the arrays.
        geom->setUseDisplayList( false );
        geom->setUseVertexBufferObjects( false );
        geom->setUseVertexBufferObjects( true );
    }
    traverse(drawable);
}
Beispiel #2
0
void
BuildTopologyVisitor::apply(osg::Drawable& drawable)
{
    osg::Geometry* geom = drawable.asGeometry();
    if (geom)
    {
        osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray());
        if (verts)
        {
            apply(&drawable, verts);
        }
    }
}
Beispiel #3
0
void
VertexCacheOptimizer::apply(osg::Drawable& drawable)
{
    if (drawable.getDataVariance() == osg::Object::DYNAMIC)
        return;

    osg::Geometry* geom = drawable.asGeometry();

    if ( geom )
    {
        if ( geom->getDataVariance() == osg::Object::DYNAMIC )
            return;

        // vertex cache optimizations currently only support surface geometries.
        // all or nothing in the geode.
        osg::Geometry::PrimitiveSetList& psets = geom->getPrimitiveSetList();
        for( osg::Geometry::PrimitiveSetList::iterator i = psets.begin(); i != psets.end(); ++i )
        {
            switch( (*i)->getMode() )
            {
            case GL_TRIANGLES:
            case GL_TRIANGLE_FAN:
            case GL_TRIANGLE_STRIP:
            case GL_QUADS:
            case GL_QUAD_STRIP:
            case GL_POLYGON:
                break;

            default:
                return;
            }
        }
    }

    //OE_NOTICE << LC << "VC optimizing..." << std::endl;

    // passed the test; run the optimizer.
    osgUtil::VertexCacheVisitor vcv;
    drawable.accept( vcv );
    vcv.optimizeVertices();

    osgUtil::VertexAccessOrderVisitor vaov;
    drawable.accept( vaov );
    vaov.optimizeOrder();

    traverse( drawable );
}
Beispiel #4
0
void StatsVisitor::apply(osg::Drawable& drawable)
{
    if (drawable.getStateSet())
    {
        apply(*drawable.getStateSet());
    }

    ++_numInstancedDrawable;

    drawable.accept(_instancedStats);

    _drawableSet.insert(&drawable);

    osg::Geometry* geometry = drawable.asGeometry();
    if (geometry)
    {
        ++_numInstancedGeometry;
        _geometrySet.insert(geometry);

        ++_numInstancedFastGeometry;
        _fastGeometrySet.insert(geometry);
    }
}
Beispiel #5
0
void
GeometryClamper::apply(osg::Drawable& drawable)
{
    if ( !_terrainSRS.valid() )
        return;

    osg::Geometry* geom = drawable.asGeometry();
    if ( !geom )
        return;

    const osg::Matrixd& local2world = _matrixStack.back();
    osg::Matrix world2local;
    world2local.invert( local2world );

    const osg::EllipsoidModel* em = _terrainSRS->getEllipsoid();
    osg::Vec3d n_vector(0,0,1), start, end, msl;

    bool isGeocentric = _terrainSRS->isGeographic();

    osgUtil::IntersectionVisitor iv( _lsi.get() );

    double r = std::min( em->getRadiusEquator(), em->getRadiusPolar() );

    unsigned count = 0;

bool geomDirty = false;
    osg::Vec3Array*  verts = static_cast<osg::Vec3Array*>(geom->getVertexArray());
    osg::FloatArray* zOffsets = 0L;

    // if preserve-Z is on, check for our elevations array. Create it if is doesn't
    // already exist.
    bool buildZOffsets = false;
    if ( _preserveZ )
    {
        osg::UserDataContainer* udc = geom->getOrCreateUserDataContainer();
        unsigned n = udc->getUserObjectIndex( ZOFFSETS_NAME );
        if ( n < udc->getNumUserObjects() )
        {
            zOffsets = dynamic_cast<osg::FloatArray*>(udc->getUserObject(n));
        }

        else
        {
            zOffsets = new osg::FloatArray();
            zOffsets->setName( ZOFFSETS_NAME );
            zOffsets->reserve( verts->size() );
            udc->addUserObject( zOffsets );
            buildZOffsets = true;
        }
    }

    for( unsigned k=0; k<verts->size(); ++k )
    {
        osg::Vec3d vw = (*verts)[k];
        vw = vw * local2world;

        if ( isGeocentric )
        {
            // normal to the ellipsoid:
            n_vector = em->computeLocalUpVector(vw.x(),vw.y(),vw.z());

            // if we need to build to z-offsets array, calculate the z offset now:
            if ( buildZOffsets || _scale != 1.0 )
            {
                double lat,lon,hae;
                em->convertXYZToLatLongHeight(vw.x(), vw.y(), vw.z(), lat, lon, hae);

                if ( buildZOffsets )
                {
                    zOffsets->push_back( (*verts)[k].z() );
                }

                if ( _scale != 1.0 )
                {
                    msl = vw - n_vector*hae;
                }
            }
        }

        else if ( buildZOffsets ) // flat map
        {
            zOffsets->push_back( float(vw.z()) );
        }

        _lsi->reset();
        _lsi->setStart( vw + n_vector*r*_scale );
        _lsi->setEnd( vw - n_vector*r );
        _lsi->setIntersectionLimit( _lsi->LIMIT_NEAREST );

        _terrainPatch->accept( iv );

        if ( _lsi->containsIntersections() )
        {
            osg::Vec3d fw = _lsi->getFirstIntersection().getWorldIntersectPoint();
            if ( _scale != 1.0 )
            {
                osg::Vec3d delta = fw - msl;
                fw += delta*_scale;
            }
            if ( _offset != 0.0 )
            {
                fw += n_vector*_offset;
            }
            if ( _preserveZ && (zOffsets != 0L) )
            {
                fw += n_vector * (*zOffsets)[k];
            }

            (*verts)[k] = (fw * world2local);
            geomDirty = true;
            ++count;
        }
    }

    if ( geomDirty )
    {
        geom->dirtyBound();
        if ( geom->getUseVertexBufferObjects() )
        {
            verts->getVertexBufferObject()->setUsage( GL_DYNAMIC_DRAW_ARB );
            verts->dirty();
        }
        else
        {
            geom->dirtyDisplayList();
        }

        OE_DEBUG << LC << "clamped " << count << " verts." << std::endl;
    }
}