osgEarth 2.1.1
Public Member Functions | Public Attributes

MeshManager Class Reference

Inheritance diagram for MeshManager:
Collaboration diagram for MeshManager:

List of all members.

Public Member Functions

 MeshManager (Manifold *manifold, Map *map)
NodeIndex addNode (const osg::Vec3d &manifoldCoord)
NodeIndex addNode (const MeshNode &node)
void removeNode (NodeIndex index)
void queueForRefresh (Diamond *d)
void queueForSplit (Diamond *d, float priority)
void queueForMerge (Diamond *d, float priority)
void queueForImage (Diamond *d, float priority)
void update ()
const MeshNodenode (NodeIndex i)

Public Attributes

osg::ref_ptr< Manifold_manifold
osg::ref_ptr< Map_map
DiamondQueue _dirtyQueue
DiamondPriorityQueue _splitQueue
DiamondPriorityQueue _mergeQueue
DiamondJobList _imageQueue
std::vector< MeshNode_nodes
std::queue< NodeIndex_freeList
Level _minGeomLevel
Level _minActiveLevel
Level _maxActiveLevel
CullSettings _cullSettings
int _maxJobsPerFrame
osg::ref_ptr< TaskService_imageService
osg::ref_ptr< osg::Geode > _amrGeode
osg::ref_ptr< AMRGeometry_amrGeom
AMRDrawableList _amrDrawList

Detailed Description

Definition at line 69 of file MeshManager.


Constructor & Destructor Documentation

MeshManager::MeshManager ( Manifold manifold,
Map map 
)

Construct the manager that will manage the mesh for the specified manifold.

Definition at line 41 of file MeshManager.cpp.

                                                       :
_manifold( manifold ),
_map( map ),
_minGeomLevel( 1 ),
_minActiveLevel( 0 ),
_maxActiveLevel( MAX_ACTIVE_LEVEL ),
_maxJobsPerFrame( MAX_JOBS_PER_FRAME )
{
    // fire up a task service to load textures.
    _imageService = new TaskService( "Image Service", 16 );

    _amrGeom = new AMRGeometry();
    _amrGeom->setDataVariance( osg::Object::DYNAMIC );

    _amrGeode = new osg::Geode();
    _amrGeode->addDrawable( _amrGeom.get() );
    _amrGeode->getOrCreateStateSet()->setAttributeAndModes( new osg::CullFace( osg::CullFace::BACK ), 1 );

    // set up the manifold framework.
    manifold->initialize( this );
}

Here is the call graph for this function:


Member Function Documentation

NodeIndex MeshManager::addNode ( const osg::Vec3d &  manifoldCoord)

Add a shared vertex (and its normal) to the mesh.

Definition at line 85 of file MeshManager.cpp.

{
    return addNode( _manifold->createNode( manifoldCoord ) );
}

Here is the caller graph for this function:

NodeIndex MeshManager::addNode ( const MeshNode node)

Definition at line 64 of file MeshManager.cpp.

{
    NodeIndex result;

    if ( _freeList.empty() )
    {
        _nodes.push_back( node );
        result = _nodes.size()-1;
    }
    else
    {
        NodeIndex ni = _freeList.front();
        _freeList.pop();
        _nodes[ni] = node;
        result = ni;
    }

    return result;
}

Here is the call graph for this function:

const MeshNode& MeshManager::node ( NodeIndex  i) [inline]

gets a vertex

Definition at line 99 of file MeshManager.

{ return _nodes[i]; }

Here is the caller graph for this function:

void MeshManager::queueForImage ( Diamond d,
float  priority 
)

queue a diamond for background texture load

Definition at line 126 of file MeshManager.cpp.

{
    if ( !d->_queuedForImage && !d->_imageRequest.valid() )
    {
        //OE_NOTICE << "REQ: " << d->_key->str() << " queueing request..." << std::endl;
        d->_imageRequest = new ImageRequest( _map->getImageLayerAt(0), d->_key );
        _imageService->add( d->_imageRequest.get() );
        _imageQueue.push_back( DiamondJob( d, priority ) ); //.insert( DiamondJob( d, priority ) );
        d->_queuedForImage = true;
    }
}

Here is the caller graph for this function:

void MeshManager::queueForMerge ( Diamond d,
float  priority 
)

queue a diamond for a merge operation (delete children)

Definition at line 115 of file MeshManager.cpp.

{
    if ( !d->_queuedForMerge )
    {
        //OE_NOTICE << "q merge: " << d->_name << std::endl;
        _mergeQueue.push( DiamondJob( d, priority ) );
        d->_queuedForMerge = true;
    }
}

Here is the caller graph for this function:

void MeshManager::queueForRefresh ( Diamond d)

add a diamond to the dirty list, b/c its primitive set needs refreshing

Definition at line 97 of file MeshManager.cpp.

{
    //OE_NOTICE << d->_name << ": queued for refresh." << std::endl;
    _dirtyQueue.push( d );
}

Here is the caller graph for this function:

void MeshManager::queueForSplit ( Diamond d,
float  priority 
)

queue a diamond for a split operation (seed children)

Definition at line 104 of file MeshManager.cpp.

{    
    if ( !d->_queuedForSplit )
    {
        //OE_NOTICE << "q split: " << d->_name << std::endl;        
        _splitQueue.push( DiamondJob( d, priority ) );
        d->_queuedForSplit = true;
    }
}

Here is the caller graph for this function:

void MeshManager::removeNode ( NodeIndex  index)

Remove a shared vertex from the mesh.

Definition at line 91 of file MeshManager.cpp.

{
    _freeList.push( ni );
}

Here is the caller graph for this function:

void MeshManager::update ( )

process the dirty list, refreshing dirty primitive sets.

Definition at line 155 of file MeshManager.cpp.

{
    int j;

    // process the split queue. these are diamonds that have requested to be split into
    // all four children.
    for( j=0; j<_maxJobsPerFrame && !_splitQueue.empty(); ++j )
    //if( !_splitQueue.empty() )
    {
        Diamond* d = _splitQueue.top()._d.get();
        if ( d->_status == ACTIVE && d->referenceCount() > 1 )
        {
            if ( d->_queuedForSplit )
            {
                //OE_NOTICE << "split: " << d->_name << "\n";
                d->split();
                d->_queuedForSplit = false;
                d->_queuedForMerge = false;
            }
            else
            {
                //OE_WARN << d->_name << " was in the split Q, but NOT marked for splitting!" << std::endl;
            }
        }
        else
        {
            // the diamond was removed while in the queue. ignore it.
        }
        _splitQueue.pop();
    }

    // process the merge queue. these are diamonds that have requested that all their
    // children be removed.
    // FUTURE: process jobs until we reach some sort of time quota?

    for( j=0; j<_maxJobsPerFrame && !_mergeQueue.empty(); ++j )
    {
        Diamond* d = _mergeQueue.top()._d.get();
        if ( d->_status == ACTIVE && d->referenceCount() > 1 )
        {
            if ( d->_queuedForMerge )
            {
                //OE_NOTICE << "merge: " << d->_name << "\n";

                //TODO: when you merge, children are recursively merged..thus the merge
                //may take some time. rather it might be better to traverse and schedule
                //child merges first.?
                d->merge();
                d->_queuedForMerge = false;
                d->_queuedForSplit = false;
            }
            else
            {
                //this means that the diamond was once queued for a merge, but then
                // passed cull again.
                //OE_WARN << d->_name << " was in the merge Q, but NOT marked for merging!" << std::endl;
            }
        }
        _mergeQueue.pop();
    }

    // process the texture image request queue.
    j=0;
    for( DiamondJobList::iterator i = _imageQueue.begin(); i != _imageQueue.end() && j < _maxJobsPerFrame; ++j )
    //if( _imageQueue.size() > 0 )
    {
        bool increment = true;
        bool remove = true;

        Diamond* d = i->_d.get();

        if ( d->_status == ACTIVE && d->referenceCount() > 1 && d->_imageRequest.valid() )
        {
            if ( d->_imageRequest->isCompleted() )
            {
                //OE_NOTICE << "REQ: " << d->_key->str() << " completed" << std::endl;
                osg::Texture2D* tex = 0L;
                
#ifdef USE_DEBUG_TEXTURES

                tex = new osg::Texture2D();
                tex->setImage( createDebugImage() );

#else

                GeoImage* geoImage = dynamic_cast<GeoImage*>( d->_imageRequest->getResult() );
                if ( geoImage )
                {
                    tex = new osg::Texture2D();
                    tex->setImage( geoImage->getImage() );
                }

#endif // USE_DEBUG_TEXTURES

                if ( tex )
                {
                    tex->setWrap( osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE );
                    tex->setWrap( osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE );
                    tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR );
                    tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
                    d->_stateSet->setTextureAttributeAndModes( 0, tex, osg::StateAttribute::ON );
                    d->_stateSet->dirty(); // bump revision number so that users of this stateset can detect the change
                    d->_hasFinalImage = true;

#ifdef OUTLINE_TEXTURES

                    outlineTexture( tex->getImage() );
#endif
                }

                remove = true;
            }

            else
            {
                remove = false;
            }
        }


        if ( remove )
        {
            d->_imageRequest = 0L;
            d->_queuedForImage = false;
            i = _imageQueue.erase( i );
        }
        else
        {
            ++i;
        }
    }

#ifdef USE_DIRTY_QUEUE

    // process the dirty diamond queue. these are diamonds that have been changed and
    // need a new primitive set.
    // NOTE: we need to process the entire dirty queue each frame.
    while( _dirtyQueue.size() > 0 )
    {
        Diamond* d = _dirtyQueue.front().get();

        if ( d->_status == ACTIVE && d->referenceCount() > 1 )
        {
            // first, check to see whether the diamond's target stateset is ready. if so,
            // install it and mark it up to date.
            if ( d->_targetStateSetOwner->_stateSet->outOfSyncWith( d->_targetStateSetRevision ) )
            {            
                d->_amrDrawable->_stateSet = d->_targetStateSetOwner->_stateSet.get();

                d->_currentStateSetOwner = d->_targetStateSetOwner;
                d->_targetStateSetOwner->_stateSet->sync( d->_targetStateSetRevision );
            }

            // rebuild the primitives now.
            d->refreshDrawable();
        }
        _dirtyQueue.pop();
    }

#endif

    //OE_NOTICE << "dq size = " << _dirtyQueue.size() << "; splits = " << _splitQueue.size() << "; merges = " << _mergeQueue.size() << std::endl;
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 135 of file MeshManager.

osg::ref_ptr<osg::Geode> MeshManager::_amrGeode

Definition at line 133 of file MeshManager.

Definition at line 134 of file MeshManager.

Definition at line 128 of file MeshManager.

Definition at line 109 of file MeshManager.

Definition at line 115 of file MeshManager.

Definition at line 112 of file MeshManager.

Definition at line 131 of file MeshManager.

Definition at line 106 of file MeshManager.

osg::ref_ptr<Map> MeshManager::_map

Definition at line 107 of file MeshManager.

Definition at line 126 of file MeshManager.

Definition at line 129 of file MeshManager.

Definition at line 111 of file MeshManager.

Definition at line 123 of file MeshManager.

Definition at line 119 of file MeshManager.

Definition at line 114 of file MeshManager.

Definition at line 110 of file MeshManager.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines