void SimpleDotVisitor::handle(osg::Drawable &drawable, int id)
{
    std::stringstream label;

    label << "<top> " << drawable.className();
    if (!drawable.getName().empty())
    {
        label << "| " << drawable.getName();
    }

    drawNode(id, "record", "solid", label.str(), "blue", "white");
}
Beispiel #2
0
    void apply(osg::Drawable& geom)
    {
        if (_hardware) {
            osgAnimation::RigGeometry* rig = dynamic_cast<osgAnimation::RigGeometry*>(&geom);
            if (rig)
                rig->setRigTransformImplementation(new MyRigTransformHardware);
        }

#if 0
        if (geom.getName() != std::string("BoundingBox")) // we disable compute of bounding box for all geometry except our bounding box
            geom.setComputeBoundingBoxCallback(new osg::Drawable::ComputeBoundingBoxCallback);
//            geom.setInitialBound(new osg::Drawable::ComputeBoundingBoxCallback);
#endif
    }
void GLObjectsVisitor::apply(osg::Drawable& drawable)
{
    if (_drawablesAppliedSet.count(&drawable)!=0) return;

    if (_checkGLErrors==osg::State::ONCE_PER_ATTRIBUTE) _renderInfo.getState()->checkGLErrors("start of Drawable::apply(osg::Drawable& drawable)");

    _drawablesAppliedSet.insert(&drawable);

    if (drawable.getStateSet())
    {
        apply(*(drawable.getStateSet()));
    }

    if (_mode&SWITCH_OFF_DISPLAY_LISTS)
    {
        drawable.setUseDisplayList(false);
    }

    if (_mode&SWITCH_ON_DISPLAY_LISTS)
    {
        drawable.setUseDisplayList(true);
    }

    if (_mode&SWITCH_ON_VERTEX_BUFFER_OBJECTS)
    {
        drawable.setUseVertexBufferObjects(true);
    }

    if (_mode&SWITCH_OFF_VERTEX_BUFFER_OBJECTS)
    {
        drawable.setUseVertexBufferObjects(false);
    }

    if (_mode&COMPILE_DISPLAY_LISTS && _renderInfo.getState() &&
        (drawable.getUseDisplayList() || drawable.getUseVertexBufferObjects()))
    {

        drawable.compileGLObjects(_renderInfo);

        if (_checkGLErrors==osg::State::ONCE_PER_ATTRIBUTE) _renderInfo.getState()->checkGLErrors("after drawable.compileGLObjects() call in Drawable::apply(osg::Drawable& drawable)  ");
    }


    if (_mode&RELEASE_DISPLAY_LISTS)
    {
        drawable.releaseGLObjects(_renderInfo.getState());
    }
}
Beispiel #4
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 #5
0
// decompose Drawable primitives into triangles, print out these triangles and computed normals.
void printTriangles(const std::string& name, osg::Drawable& drawable)
{
    std::cout<<name<<std::endl;

    osg::TriangleFunctor<NormalPrint> tf;
    drawable.accept(tf);

    std::cout<<std::endl;
}
void GLObjectsVisitor::apply(osg::Drawable& drawable)
{
    if (_drawablesAppliedSet.count(&drawable)!=0) return;

    _drawablesAppliedSet.insert(&drawable);

    if (_mode&SWITCH_OFF_DISPLAY_LISTS)
    {
        drawable.setUseDisplayList(false);
    }

    if (_mode&SWITCH_ON_DISPLAY_LISTS)
    {
        drawable.setUseDisplayList(true);
    }

    if (_mode&SWITCH_ON_VERTEX_BUFFER_OBJECTS)
    {
        drawable.setUseVertexBufferObjects(true);
    }

    if (_mode&SWITCH_OFF_VERTEX_BUFFER_OBJECTS)
    {
        drawable.setUseVertexBufferObjects(false);
    }

    if (_mode&COMPILE_DISPLAY_LISTS && _renderInfo.getState() &&
        (drawable.getUseDisplayList() || drawable.getUseVertexBufferObjects()))
    {
        drawable.compileGLObjects(_renderInfo);
    }

    if (_mode&RELEASE_DISPLAY_LISTS)
    {
        drawable.releaseGLObjects(_renderInfo.getState());
    }

    if (drawable.getStateSet())
    {
        apply(*(drawable.getStateSet()));
    }
}
CullVisitor::value_type CullVisitor::computeNearestPointInFrustum(const osg::Matrix& matrix, const osg::Polytope::PlaneList& planes,const osg::Drawable& drawable)
{
    // OSG_WARN<<"CullVisitor::computeNearestPointInFrustum("<<getTraversalNumber()<<"\t"<<planes.size()<<std::endl;

    osg::TriangleFunctor<ComputeNearestPointFunctor> cnpf;
    cnpf.set(_computed_znear, matrix, &planes);
    
    drawable.accept(cnpf);

    return cnpf._znear;
}
    virtual void apply(osg::Drawable &drawable)
    {
        if (!mTriangleMesh)
            mTriangleMesh.reset(new btTriangleMesh);

        osg::Matrixf worldMat = osg::computeLocalToWorld(getNodePath());
        osg::TriangleFunctor<GetTriangleFunctor> functor;
        functor.setTriMesh(mTriangleMesh.get());
        functor.setMatrix(worldMat);
        drawable.accept(functor);
    }
Beispiel #9
0
void ShaderGenVisitor::apply(osg::Drawable &drawable)
{
    osg::StateSet *stateSet = drawable.getStateSet();
    if (stateSet)
        _state->pushStateSet(stateSet);

    update(&drawable);

    if (stateSet)
        _state->popStateSet();
}
Beispiel #10
0
void StatsVisitor::apply(osg::Drawable& drawable)
{
    if (drawable.getStateSet())
    {
        ++_numInstancedStateSet;
        _statesetSet.insert(drawable.getStateSet());
    }

    ++_numInstancedDrawable;

    drawable.accept(_instancedStats);

    _drawableSet.insert(&drawable);

    osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(&drawable);
    if (geometry)
    {
        ++_numInstancedGeometry;
        _geometrySet.insert(geometry);
    }
}
Beispiel #11
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);
        }
    }
}
    void ShaderVisitor::apply(osg::Drawable& drawable)
    {
        // non-Geometry drawable (e.g. particle system)
        bool needPop = (drawable.getStateSet() != NULL);

        if (drawable.getStateSet())
        {
            pushRequirements();
            applyStateSet(drawable.getStateSet(), drawable);
        }

        if (!mRequirements.empty())
        {
            const ShaderRequirements& reqs = mRequirements.back();
            // TODO: find a better place for the stateset
            if (reqs.mShaderRequired || mForceShaders)
                createProgram(reqs, drawable);
        }

        if (needPop)
            popRequirements();
    }
Beispiel #13
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 #14
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);
    }
}
bool CullVisitor::updateCalculatedNearFar(const osg::Matrix& matrix,const osg::Drawable& drawable, bool isBillboard)
{
    const osg::BoundingBox& bb = drawable.getBound();

    value_type d_near, d_far;

    if (isBillboard)
    {
    
#ifdef TIME_BILLBOARD_NEAR_FAR_CALCULATION    
        static unsigned int lastFrameNumber = getTraversalNumber();
        static unsigned int numBillboards = 0;
        static double elapsed_time = 0.0;
        if (lastFrameNumber != getTraversalNumber())
        {
            OSG_NOTICE<<"Took "<<elapsed_time<<"ms to test "<<numBillboards<<" billboards"<<std::endl;
            numBillboards = 0;
            elapsed_time = 0.0;
            lastFrameNumber = getTraversalNumber();
        }
        osg::Timer_t start_t = osg::Timer::instance()->tick();
#endif
        
        osg::Vec3 lookVector(-matrix(0,2),-matrix(1,2),-matrix(2,2));

        unsigned int bbCornerFar = (lookVector.x()>=0?1:0) +
                       (lookVector.y()>=0?2:0) +
                       (lookVector.z()>=0?4:0);

        unsigned int bbCornerNear = (~bbCornerFar)&7;

        d_near = distance(bb.corner(bbCornerNear),matrix);
        d_far = distance(bb.corner(bbCornerFar),matrix);

        OSG_NOTICE.precision(15);

        if (false)
        {

            OSG_NOTICE<<"TESTING Billboard near/far computation"<<std::endl;

             // OSG_WARN<<"Checking corners of billboard "<<std::endl;
            // deprecated brute force way, use all corners of the bounding box.
            value_type nd_near, nd_far;
            nd_near = nd_far = distance(bb.corner(0),matrix);
            for(unsigned int i=0;i<8;++i)
            {
                value_type d = distance(bb.corner(i),matrix);
                if (d<nd_near) nd_near = d;
                if (d>nd_far) nd_far = d;
                OSG_NOTICE<<"\ti="<<i<<"\td="<<d<<std::endl;
            }

            if (nd_near==d_near && nd_far==d_far)
            {
                OSG_NOTICE<<"\tBillboard near/far computation correct "<<std::endl;
            }
            else
            {
                OSG_NOTICE<<"\tBillboard near/far computation ERROR\n\t\t"<<d_near<<"\t"<<nd_near
                                        <<"\n\t\t"<<d_far<<"\t"<<nd_far<<std::endl;
            }

        }

#ifdef TIME_BILLBOARD_NEAR_FAR_CALCULATION    
        osg::Timer_t end_t = osg::Timer::instance()->tick();
        
        elapsed_time += osg::Timer::instance()->delta_m(start_t,end_t);
        ++numBillboards;
#endif
    }
    else
    {
        // efficient computation of near and far, only taking into account the nearest and furthest
        // corners of the bounding box.
        d_near = distance(bb.corner(_bbCornerNear),matrix);
        d_far = distance(bb.corner(_bbCornerFar),matrix);
    }
    
    if (d_near>d_far)
    {
        std::swap(d_near,d_far);
        if ( !EQUAL_F(d_near, d_far) ) 
        {
            OSG_WARN<<"Warning: CullVisitor::updateCalculatedNearFar(.) near>far in range calculation,"<< std::endl;
            OSG_WARN<<"         correcting by swapping values d_near="<<d_near<<" dfar="<<d_far<< std::endl;
        }
    }

    if (d_far<0.0)
    {
        // whole object behind the eye point so discard
        return false;
    }

    if (d_near<_computed_znear) 
    {
        if (_computeNearFar==COMPUTE_NEAR_FAR_USING_PRIMITIVES)
        {
            osg::Polytope& frustum = getCurrentCullingSet().getFrustum();
            if (frustum.getResultMask())
            {
                if (isBillboard)
                {
                    // OSG_WARN<<"Adding billboard into deffered list"<<std::endl;
                
                    osg::Polytope transformed_frustum;
                    transformed_frustum.setAndTransformProvidingInverse(getProjectionCullingStack().back().getFrustum(),matrix);
                
                    // insert drawable into the deferred list of drawables which will be handled at the popProjectionMatrix().
                    _nearPlaneCandidateMap.insert(
                        DistanceMatrixDrawableMap::value_type(d_near,MatrixPlanesDrawables(matrix,&drawable,transformed_frustum)) );
                } 
                else
                {
                    // insert drawable into the deferred list of drawables which will be handled at the popProjectionMatrix().
                    _nearPlaneCandidateMap.insert(
                        DistanceMatrixDrawableMap::value_type(d_near,MatrixPlanesDrawables(matrix,&drawable,frustum)) );
                }

                // use the far point if its nearer than current znear as this is a conservative estimate of the znear
                // while the final computation for this drawable is deferred.
                if (d_far<_computed_znear)
                {
                    if (d_far>=0.0) _computed_znear = d_far;
                    else OSG_WARN<<"       1)  sett near with dnear="<<d_near<<"  dfar="<<d_far<< std::endl;
                }
            }
            else
            {
                if (d_near>=0.0) _computed_znear = d_near;
                else OSG_WARN<<"        2) sett near with d_near="<<d_near<< std::endl;
            }
        }
        else
        {
            //if (d_near<0.0) OSG_WARN<<"         3) set near with d_near="<<d_near<< std::endl;
            _computed_znear = d_near;
        }
    }

    if (d_far>_computed_zfar) _computed_zfar = d_far;


/*
    // deprecated brute force way, use all corners of the bounding box.
    updateCalculatedNearFar(bb.corner(0));
    updateCalculatedNearFar(bb.corner(1));
    updateCalculatedNearFar(bb.corner(2));
    updateCalculatedNearFar(bb.corner(3));
    updateCalculatedNearFar(bb.corner(4));
    updateCalculatedNearFar(bb.corner(5));
    updateCalculatedNearFar(bb.corner(6));
    updateCalculatedNearFar(bb.corner(7));
*/

    return true;

}
Beispiel #16
0
void osgManipulator::setDrawableToAlwaysCull(osg::Drawable& drawable)
{
    ForceCullCallback* cullCB = new ForceCullCallback;
    drawable.setCullCallback (cullCB);    
}
Beispiel #17
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;
    }
}
Beispiel #18
0
void
ProxyCullVisitor::apply(osg::Drawable& drawable)
{
    if ( isCulledByProxyFrustum(drawable) )
        return;

    _cv->pushOntoNodePath( &drawable );

    // push the node's state.
    osg::StateSet* node_state = drawable.getStateSet();
    if (node_state) _cv->pushStateSet(node_state);

    osg::RefMatrix& matrix = *_cv->getModelViewMatrix();
    const osg::BoundingBox& bb = Utils::getBoundingBox(&drawable);

    bool culledOut = false;

    if( drawable.getCullCallback() )
    {
        if (drawable.getCullCallback()->run(&drawable, _cv) == true)
            culledOut = true;
    }

    if (!culledOut)
    {
        if (drawable.isCullingActive() && isCulledByProxyFrustum(bb)) 
            culledOut = true;
    }


    if ( !culledOut && _cv->getComputeNearFarMode() && bb.valid())
    {
        if (!_cv->updateCalculatedNearFar(matrix,drawable,false))
            culledOut = true;
    }

    if (!culledOut)
    {
        // need to track how push/pops there are, so we can unravel the stack correctly.
        unsigned int numPopStateSetRequired = 0;

        // push the geoset's state on the geostate stack.
        osg::StateSet* stateset = drawable.getStateSet();
        if (stateset)
        {
            ++numPopStateSetRequired;
            _cv->pushStateSet(stateset);
        }

        osg::CullingSet& cs = _cv->getCurrentCullingSet();
        if (!cs.getStateFrustumList().empty())
        {
            osg::CullingSet::StateFrustumList& sfl = cs.getStateFrustumList();
            for(osg::CullingSet::StateFrustumList::iterator itr = sfl.begin();
                itr != sfl.end();
                ++itr)
            {
                if (itr->second.contains(bb))
                {
                    ++numPopStateSetRequired;
                    _cv->pushStateSet(itr->first.get());
                }
            }
        }

        float depth = bb.valid() ? distance(bb.center(),matrix) : 0.0f;

        if (osg::isNaN(depth))
        {
            for (osg::NodePath::const_iterator i = getNodePath().begin(); i != getNodePath().end(); ++i)
            {
                OSG_DEBUG << "        \"" << (*i)->getName() << "\"" << std::endl;
            }
        }
        else
        {
            _cv->addDrawableAndDepth(&drawable,&matrix,depth);
        }

        for(unsigned int i=0;i< numPopStateSetRequired; ++i)
        {
            _cv->popStateSet();
        }
    }

    // pop the node's state off the geostate stack.
    if (node_state) _cv->popStateSet();

    _cv->popFromNodePath();
}
Beispiel #19
0
void
SetDataVarianceVisitor::apply(osg::Drawable& drawable)
{
    drawable.setDataVariance(_value);
    traverse(drawable);
}