osgEarth 2.1.1
Public Member Functions | Protected Member Functions | Protected Attributes | Friends

osgEarth::Util::GeoCell Class Reference

Inheritance diagram for osgEarth::Util::GeoCell:
Collaboration diagram for osgEarth::Util::GeoCell:

List of all members.

Public Member Functions

 GeoCell (const GeoExtent &extent, float maxRange, unsigned maxOjbects, unsigned splitDim, float splitRangeFactor, unsigned depth)
virtual bool insertObject (GeoObject *object)
bool removeObject (GeoObject *object)
bool reindexObject (GeoObject *object)
unsigned getSplitDimension () const
unsigned getMaxObjects () const
float getSplitRangeFactor () const
const GeoExtentgetExtent () const
unsigned getLastCullFrame () const
virtual osg::BoundingSphere computeBound () const
virtual void traverse (osg::NodeVisitor &nv)

Protected Member Functions

void split ()
void merge ()
void adjustCount (int delta)
bool intersects (const class osg::Polytope &tope) const
void generateBoundaries ()
void generateBoundaryGeometry ()

Protected Attributes

GeoExtent _extent
unsigned _splitDim
unsigned _maxObjects
unsigned _minObjects
float _maxRange
float _splitRangeFactor
unsigned _count
unsigned _depth
unsigned _frameStamp
std::vector< osg::Vec3d > _boundaryPoints
GeoObjectCollection _objects
osg::ref_ptr< osg::Geode > _clusterGeode
osg::ref_ptr< osg::Geode > _boundaryGeode
osg::Vec4Array * _boundaryColor

Friends

class GeoCellVisitor

Detailed Description

A group corresponding to a specific geospatial cell.

Definition at line 42 of file SpatialData.


Constructor & Destructor Documentation

GeoCell::GeoCell ( const GeoExtent extent,
float  maxRange,
unsigned  maxOjbects,
unsigned  splitDim,
float  splitRangeFactor,
unsigned  depth 
)

Definition at line 168 of file SpatialData.cpp.

                                                                             :
_extent( extent ),
_maxRange( maxRange ),
_maxObjects( maxObjects ),
_splitDim( splitDim ),
_splitRangeFactor( splitRangeFactor ),
_depth( depth ),
_minObjects( (maxObjects/10)*8 ), // 80%
_count( 0 ),
_boundaryPoints( 10 ),
_frameStamp( 0 )
{
    generateBoundaries();
    //generateBoundaryGeometry();

    // Disable OSG's culling so we can do our own custom culling.
    this->setCullingActive( false );
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Function Documentation

void GeoCell::adjustCount ( int  delta) [protected]

Definition at line 354 of file SpatialData.cpp.

{
    _count += delta;

    if ( _depth > 0 && getNumParents() > 0 )
    {
        static_cast<GeoCell*>(getParent(0))->adjustCount( delta );        

#if 0
        if ( !_clusterGeode.valid() )
        {
            _clusterGeode = makeClusterGeode( _extent, _count );
        }
        else
        {
            osgText::Text* t = static_cast<osgText::Text*>( _clusterGeode->getDrawable(0) );
            std::stringstream buf;
            buf << _count;
            t->setText( buf.str() );
        }
#endif
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

osg::BoundingSphere GeoCell::computeBound ( ) const [virtual]

Definition at line 238 of file SpatialData.cpp.

{
    osg::BoundingSphere bs;
    for( unsigned i=0; i<10; ++i )
        bs.expandBy( _boundaryPoints[i] );
    return bs;
}
void GeoCell::generateBoundaries ( ) [protected]

Definition at line 189 of file SpatialData.cpp.

{
    const osg::EllipsoidModel* em = _extent.getSRS()->getEllipsoid();
    static const double hae =  1e6;
    static const double hbe = -1e5;

    // find the geodetic center:
    osg::Vec3d gcenter;
    _extent.getCentroid( gcenter.x(), gcenter.y() );

    // convert to a geocentric vector:
    osg::Vec3d center;
    em->convertLatLongHeightToXYZ(
        osg::DegreesToRadians(gcenter.y()), osg::DegreesToRadians(gcenter.x()), 0.0, center.x(), center.y(), center.z());

    osg::Vec3d centerVec = center;
    centerVec.normalize();

    // find the 4 geodetic corners:
    osg::Vec3d gcorner[4];
    gcorner[0].set( _extent.xMin(), _extent.yMin(), 0.0 );
    gcorner[1].set( _extent.xMin(), _extent.yMax(), 0.0 );
    gcorner[2].set( _extent.xMax(), _extent.yMax(), 0.0 );
    gcorner[3].set( _extent.xMax(), _extent.yMin(), 0.0 );

    // and convert those to geocentric vectors:
    osg::Vec3d corner[4];
    osg::Vec3d cornerVec[4];
    for(unsigned i=0; i<4; ++i )
    {
        em->convertLatLongHeightToXYZ(
            osg::DegreesToRadians(gcorner[i].y()), osg::DegreesToRadians(gcorner[i].x()), 0.0,
            corner[i].x(), corner[i].y(), corner[i].z() );
        cornerVec[i] = corner[i];
        cornerVec[i].normalize();
    }   
    
    // now extrude the center and corners up and down to get the boundary points:
    unsigned p = 0;
    _boundaryPoints[p++] = center + centerVec*hae;
    _boundaryPoints[p++] = center +centerVec*hbe;
    for( unsigned i=0; i<4; ++i )
    {
        _boundaryPoints[p++] = corner[i] + cornerVec[i]*hae;
        _boundaryPoints[p++] = corner[i] + cornerVec[i]*hbe;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GeoCell::generateBoundaryGeometry ( ) [protected]

Definition at line 247 of file SpatialData.cpp.

{
    osg::Geometry* g = new osg::Geometry();

    osg::Vec3Array* v = new osg::Vec3Array(10);
    for( unsigned i=0; i<10; ++i )
        (*v)[i] = _boundaryPoints[i];
    g->setVertexArray( v );

    osg::DrawElementsUByte* el = new osg::DrawElementsUByte( GL_QUADS );
    el->push_back( 7 ); el->push_back( 5 ); el->push_back( 4 ); el->push_back( 6 );
    el->push_back( 9 ); el->push_back( 7 ); el->push_back( 6 ); el->push_back( 8 );
    el->push_back( 3 ); el->push_back( 9 ); el->push_back( 8 ); el->push_back( 2 );
    el->push_back( 5 ); el->push_back( 3 ); el->push_back( 2 ); el->push_back( 4 );
    //el->push_back( 2 ); el->push_back( 8 ); el->push_back( 6 ); el->push_back( 4 ); //top
    //el->push_back( 9 ); el->push_back( 3 ); el->push_back( 5 ); el->push_back( 7 ); // bottom
    g->addPrimitiveSet( el );

    osg::Vec4Array* c = new osg::Vec4Array(1);
    (*c)[0].set( 1, 1, 1, 0.25 );
    g->setColorArray( c );
    g->setColorBinding( osg::Geometry::BIND_OVERALL );

    _boundaryColor = c;

    g->setDataVariance( osg::Object::DYNAMIC );
    g->setUseDisplayList( false );
    g->setUseVertexBufferObjects( true );

    osg::StateSet* set = g->getOrCreateStateSet();
    set->setMode( GL_BLEND, 1 );
    set->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
    set->setAttribute( new osg::PolygonOffset(1,1), 1 );

    _boundaryGeode = new osg::Geode();
    _boundaryGeode->addDrawable( g );
}
const GeoExtent& osgEarth::Util::GeoCell::getExtent ( ) const [inline]

the extent of this cell

Definition at line 72 of file SpatialData.

{ return _extent; }

Here is the caller graph for this function:

unsigned osgEarth::Util::GeoCell::getLastCullFrame ( ) const [inline]

gets the frame number of the last time this cell passed cull

Definition at line 75 of file SpatialData.

{ return _frameStamp; }
unsigned osgEarth::Util::GeoCell::getMaxObjects ( ) const [inline]

The maximum number of objects this cell can hold before splitting

Definition at line 66 of file SpatialData.

{ return _maxObjects; }
unsigned osgEarth::Util::GeoCell::getSplitDimension ( ) const [inline]

The number of rows and columns into which this cell will split

Definition at line 63 of file SpatialData.

{ return _splitDim; }
float osgEarth::Util::GeoCell::getSplitRangeFactor ( ) const [inline]

Child cells have a maximum LOD range of this cell's max range times this factor.

Definition at line 69 of file SpatialData.

{ return _splitRangeFactor; }
bool GeoCell::insertObject ( GeoObject object) [virtual]

Adds an object to this geocell graph.

Reimplemented in osgEarth::Util::GeoGraph.

Definition at line 379 of file SpatialData.cpp.

{
    osg::Vec3d location;
    if ( object->getLocation(location) && _extent.contains(location.x(), location.y()) )
    {
        object->_cell = this;
        _objects.insert( std::make_pair(object->getPriority(), object) );

        if ( _objects.size() > _maxObjects )
        {
            GeoObjectCollection::iterator low = _objects.begin();
            GeoObject* lowPriObject = low->second.get();
            
            if ( getNumChildren() == 0 )
                split();

            lowPriObject->getLocation(location);
            unsigned index = getIndex(_extent, location, _splitDim, _splitDim);
            bool insertedOK = static_cast<GeoCell*>(getChild(index))->insertObject( lowPriObject );
            if ( insertedOK )
            {
                // remove it from this cell.
                _objects.erase( low );
            }
            else
            {
                // should never ever happen..
                OE_WARN << LC << "Object insertion failed" << std::endl;
                return false;
            }
        }
        return true;
    }
    else
    {
        return false;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool GeoCell::intersects ( const class osg::Polytope &  tope) const [protected]

Definition at line 286 of file SpatialData.cpp.

{
    const osg::Polytope::PlaneList& planes = tope.getPlaneList();
    for( osg::Polytope::PlaneList::const_iterator i = planes.begin(); i != planes.end(); ++i )
    {
        if ( i->intersect( _boundaryPoints ) < 0 )
            return false;
    }
    return true;
}
void GeoCell::merge ( ) [protected]

Definition at line 477 of file SpatialData.cpp.

{
    //NYI //TODO
}
bool GeoCell::reindexObject ( GeoObject object)

Re-index an object withing the geocell graph based on a new position.

Definition at line 483 of file SpatialData.cpp.

{
    GeoCell* owner = object->getGeoCell();
    if ( owner )
    {
        osg::Vec3d location;
        if ( object->getLocation(location) && !owner->_extent.contains(location.x(), location.y()) )
        {
            // first remove from its current cell
            owner->removeObject( object );

            GeoCell* cell = dynamic_cast<GeoCell*>( owner->getParent(0) );
            while( cell )
            {
                if ( cell->getExtent().contains(location.x(), location.y()) )
                {
                    if ( cell->insertObject( object ) )
                        return true;
                }
                cell = dynamic_cast<GeoCell*>( cell->getParent(0) );
            }
        }

        // no change
        return true;
    }
    else
    {
        return insertObject( object );
    }
}

Here is the call graph for this function:

bool GeoCell::removeObject ( GeoObject object)

Removes an object from this geocell graph.

Definition at line 448 of file SpatialData.cpp.

{
    if ( object->_cell.get() == this )
    {
        object->_cell = 0L;
        _objects.erase( findObject(_objects, object) );
        adjustCount( -1 );

        // if we just fell beneath the threshold, pull one up from below.
        if ( _objects.size() == _minObjects-1 )
        {
            //TODO.
        }

        // TODO: rebalance, merge the tree, etc.
        return true;
    }
    else
    {
        for( unsigned i=0; i<getNumChildren(); ++i )
        {
            if ( static_cast<GeoCell*>(getChild(i))->removeObject( object ) )
                return true;
        }
    }
    return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GeoCell::split ( ) [protected]

Definition at line 419 of file SpatialData.cpp.

{
    // the max LOD range for children of this cell:
    float newRange = _maxRange * _splitRangeFactor;

    // first create all the child cells:
    double xInterval = _extent.width() / (double)_splitDim;
    double yInterval = _extent.height() / (double)_splitDim;

    for( unsigned row=0; row<_splitDim; ++row )
    {
        for( unsigned col=0; col<_splitDim; ++col )
        {
            GeoExtent cellExtent(
                _extent.getSRS(),
                _extent.xMin() + xInterval*(double)col,
                _extent.yMin() + yInterval*(double)row,
                _extent.xMin() + xInterval*(double)(col+1),
                _extent.yMin() + yInterval*(double)(row+1) );

            this->addChild(
                new GeoCell(cellExtent, newRange, _maxObjects, _splitDim, _splitRangeFactor, _depth+1),
                0.0f,
                newRange );
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GeoCell::traverse ( osg::NodeVisitor &  nv) [virtual]

Definition at line 225 of file Patch.cpp.

{
    if (!_trile[0][0].valid())
        return;
    if (nv.getTraversalMode() == NodeVisitor::TRAVERSE_ALL_CHILDREN)
    {
        std::for_each(&_trile[0][0], &_trile[1][3] + 1, MyNodeAcceptOp(nv));
        std::for_each(&_strip[0][0], &_strip[3][3] + 1, MyNodeAcceptOp(nv));
        return;
    }
    if (nv.getTraversalMode() != NodeVisitor::TRAVERSE_ACTIVE_CHILDREN)
        return;
    float epsilon[4];
    int res[4]; // Resolution of each edge / trile.
    // Get error value for edges
    Vec3 eye = nv.getViewPoint();
    for (int i = 0; i < 4; ++i)
    {
        epsilon[i] = getEdgeError(eye, i);
        if (epsilon[i] > _errorThreshold)
            res[i] = 1;
        else
            res[i] = 0;
    }

    for (int i = 0; i < 4; ++i)
        _trile[res[i]][i]->accept(nv);
    // Now choose a strip
    for (int i = 0; i < 4; ++i)
    {
        // One neighbor is trile i; the other is clockwise.
        int neighbor = (i - 1 + 4) % 4;
        int strip = res[neighbor] * 2 + res[i];
        _strip[strip][i]->accept(nv);
    }
}

Here is the call graph for this function:


Friends And Related Function Documentation

friend class GeoCellVisitor [friend]

Definition at line 110 of file SpatialData.


Member Data Documentation

osg::Vec4Array* osgEarth::Util::GeoCell::_boundaryColor [protected]

Definition at line 108 of file SpatialData.

osg::ref_ptr<osg::Geode> osgEarth::Util::GeoCell::_boundaryGeode [protected]

Definition at line 107 of file SpatialData.

std::vector<osg::Vec3d> osgEarth::Util::GeoCell::_boundaryPoints [protected]

Definition at line 101 of file SpatialData.

osg::ref_ptr<osg::Geode> osgEarth::Util::GeoCell::_clusterGeode [protected]

Definition at line 106 of file SpatialData.

unsigned osgEarth::Util::GeoCell::_count [protected]

Definition at line 90 of file SpatialData.

unsigned osgEarth::Util::GeoCell::_depth [protected]

Definition at line 91 of file SpatialData.

Definition at line 84 of file SpatialData.

Definition at line 92 of file SpatialData.

Definition at line 86 of file SpatialData.

Definition at line 88 of file SpatialData.

Definition at line 87 of file SpatialData.

Definition at line 104 of file SpatialData.

unsigned osgEarth::Util::GeoCell::_splitDim [protected]

Definition at line 85 of file SpatialData.

Definition at line 89 of file SpatialData.


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