osgEarth 2.1.1
Public Member Functions | Private Types | Private Member Functions | Private Attributes | Friends

osgEarth::Util::Controls::ControlNodeBin Class Reference

List of all members.

Public Member Functions

 ControlNodeBin ()
void addNode (ControlNode *node)
void setFading (bool value)

Private Types

typedef std::pair< float,
osg::ref_ptr< ControlNode > > 
ControlNodePair
typedef std::multimap< float,
osg::ref_ptr< ControlNode > > 
ControlNodeCollection
typedef std::pair< Control
*, ControlNodeCollection::iterator > 
ControlIndexPair
typedef std::map< Control
*, ControlNodeCollection::iterator > 
ControlIndex
typedef std::map< ControlNode
*, osg::MatrixTransform * > 
RenderNodeTable
typedef std::pair< ControlNode
*, osg::MatrixTransform * > 
RenderNodePair

Private Member Functions

void draw (const ControlContext &context, bool newContext, int bin)
osg::Group * getControlGroup () const

Private Attributes

ControlNodeCollection _controlNodes
ControlIndex _index
RenderNodeTable _renderNodes
osg::ref_ptr< osg::Group > _group
std::vector< osg::BoundingBox > _taken
bool _sortByDistance
bool _fading
bool _sortingEnabled

Friends

class ControlCanvas
class ControlNode

Detailed Description

Internal class that renders ControlNode objects found in the scene graph. There is no need to instantiate or access this object directly.

Definition at line 622 of file Controls.


Member Typedef Documentation

typedef std::map<Control*, ControlNodeCollection::iterator> osgEarth::Util::Controls::ControlNodeBin::ControlIndex [private]

Definition at line 639 of file Controls.

typedef std::pair<Control*, ControlNodeCollection::iterator> osgEarth::Util::Controls::ControlNodeBin::ControlIndexPair [private]

Definition at line 638 of file Controls.

typedef std::multimap<float, osg::ref_ptr<ControlNode> > osgEarth::Util::Controls::ControlNodeBin::ControlNodeCollection [private]

Definition at line 635 of file Controls.

typedef std::pair<float, osg::ref_ptr<ControlNode> > osgEarth::Util::Controls::ControlNodeBin::ControlNodePair [private]

Definition at line 634 of file Controls.

typedef std::pair<ControlNode*, osg::MatrixTransform*> osgEarth::Util::Controls::ControlNodeBin::RenderNodePair [private]

Definition at line 643 of file Controls.

typedef std::map<ControlNode*, osg::MatrixTransform*> osgEarth::Util::Controls::ControlNodeBin::RenderNodeTable [private]

Definition at line 642 of file Controls.


Constructor & Destructor Documentation

ControlNodeBin::ControlNodeBin ( )

Definition at line 1886 of file Controls.cpp.

                               :
_sortingEnabled( true ),
_sortByDistance( true ),
_fading        ( true )
{
    _group = new Group();

    osg::StateSet* stateSet = _group->getOrCreateStateSet();

    osg::Program* program = new osg::Program();
    program->addShader( new osg::Shader( osg::Shader::VERTEX, s_controlVertexShader ) );
    program->addShader( new osg::Shader( osg::Shader::FRAGMENT, s_labelControlFragmentShader ) );
    stateSet->setAttributeAndModes( program, osg::StateAttribute::ON );

    osg::Uniform* defaultOpacity = new osg::Uniform( osg::Uniform::FLOAT, "opacity" );
    defaultOpacity->set( 1.0f );
    stateSet->addUniform( defaultOpacity );

    osg::Uniform* defaultVisibleTime = new osg::Uniform( osg::Uniform::FLOAT, "visibleTime" );
    defaultVisibleTime->set( 0.0f );
    stateSet->addUniform( defaultVisibleTime );    
}

Member Function Documentation

void ControlNodeBin::addNode ( ControlNode node)

Registers a control node with this bin.

Definition at line 2090 of file Controls.cpp.

{
    // if we see a node with a non-zero priority, assume we're sorting
    // by priority.
    if ( controlNode->getPriority() != 0.0f )
        _sortByDistance = false;

    // record the node in priority order.
    ControlNodeCollection::iterator ptr = _controlNodes.insert(
        ControlNodePair( -controlNode->getPriority(), controlNode ) );

    // record it in the index.
    _index.insert( ControlIndexPair(controlNode->getControl(), ptr) );

    // create and cache a transform/geode pair for the node. the xform will position
    // the geode in 2D space.
    osg::MatrixTransform* xform = new osg::MatrixTransform();
    osg::Geode* geode = new osg::Geode();
    xform->addChild( geode );
    _renderNodes.insert( RenderNodePair(controlNode, xform) );

    // put it in the render graph.
    _group->addChild( xform );
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ControlNodeBin::draw ( const ControlContext context,
bool  newContext,
int  bin 
) [private]

Definition at line 1916 of file Controls.cpp.

{
    const osg::Viewport* vp = context._vp.get();
    osg::Vec2f surfaceSize( context._vp->width(), context._vp->height() );

    // we don't really need to keep this list in the object, but that prevents it from having to
    // reallocate it each time
    _taken.clear();

    ControlNodeCollection* drawList = 0L;
    ControlNodeCollection byDepth;

    if ( _sortingEnabled && _sortByDistance )
    {
        for( ControlNodeCollection::iterator i = _controlNodes.begin(); i != _controlNodes.end(); i++) 
        {
            ControlNode* node = i->second.get();
            if ( node->getNumParents() == 0 )
            {
              _renderNodes.erase( node );
              _controlNodes.erase( i );
            }
            else
            {
                ControlNode::PerViewData& nodeData = node->getData( context._view );
                byDepth.insert( ControlNodePair(nodeData._screenPos.z(), node) );
            }
        }

        drawList = &byDepth;
    }
    else
    {
        drawList = &_controlNodes;
    }

    for( ControlNodeCollection::iterator i = drawList->begin(); i != drawList->end(); ) 
    {
        ControlNode* node = i->second.get();
        osg::MatrixTransform* xform = _renderNodes[node];

        // check to see if the node as removed
        bool nodeActive = node->getNumParents() > 0;

        if ( nodeActive )
        {
          ControlNode::PerViewData& nodeData = node->getData( context._view );
          Control* control = node->getControl();

          // if the context changed (e.g., viewport resize), we need to mark all nodes as dirty
          // even if they're obscured...that way they will regenerate properly next time
          if ( newContext )
          {
              control->dirty();
          }

          bool visible = true;

          if ( context._frameStamp->getFrameNumber() - nodeData._visitFrame > 2 )
          {
              visible = false;
          }

          else if ( nodeData._obscured == false )
          {
              const osg::Vec3f& nPos = nodeData._screenPos;
              const osg::Vec2f& size = control->renderSize();

              // calculate the rendering offset based on alignment:
              float x, y;

              if ( node->anchorPoint().isSet() )
              {
                  //TODO!!
              }
              else
              {
                  x =
                    control->horizAlign() == Control::ALIGN_LEFT  ? nPos.x() - size.x() :
                    control->horizAlign() == Control::ALIGN_RIGHT ? nPos.x() :
                    nPos.x() - size.x()*0.5;

                  y =
                    control->vertAlign() == Control::ALIGN_BOTTOM ? nPos.y() :
                    control->vertAlign() == Control::ALIGN_TOP    ? nPos.y() + size.y() :
                    nPos.y() + size.y()*0.5;
              }

              xform->setMatrix( osg::Matrixd::translate(x, y-context._vp->height(), 0) );

              osg::BoundingBox bbox( x, y, 0.0, x+size.x(), y+size.y(), 1.0 );
              if ( _sortingEnabled )
              {
                  // prevent overlap.
                  for( std::vector<osg::BoundingBox>::iterator u = _taken.begin(); u != _taken.end(); ++u )
                  {
                      if ( u->intersects( bbox ) )
                      {
                          nodeData._obscured = true;
                          break;
                      }
                  }
              }

              if ( nodeData._obscured == false )
              {
                  if ( _sortingEnabled )
                    _taken.push_back( bbox );

                  // the geode holding this node's geometry:
                  osg::Geode* geode = static_cast<osg::Geode*>( xform->getChild(0) );

                  // if the control changed, we need to rebuild its drawables:
                  if ( control->isDirty() )
                  {
                      // clear out the geode:
                      geode->removeDrawables( 0, geode->getNumDrawables() );

                      // calculate the size of the control in screen space:
                      osg::Vec2f dummySize;
                      control->calcSize( context, dummySize );
                      control->calcFill( context );

                      // only need to do this if the control has children ... (pos is always 0,0)
                      control->calcPos( context, osg::Vec2f(0,0), size );
                   
                      // build the drawables for the geode and insert them:
                      DrawableList drawables;
                      control->draw( context, drawables );

                      for( DrawableList::iterator j = drawables.begin(); j != drawables.end(); ++j )
                      {
                          j->get()->setDataVariance( osg::Object::DYNAMIC );

                          osg::StateSet* stateSet = j->get()->getOrCreateStateSet();
                          stateSet->setRenderBinDetails( bin++, "RenderBin" );
                          geode->addDrawable( j->get() );
                      }
                  }

                  if ( _fading )
                  {
                      // update the "visible time" uniform if it's changed. this will cause the
                      // shader to "fade in" the label when it becomes visible.
                      if ( !nodeData._uniform.valid() )
                      {
                          nodeData._uniform = new osg::Uniform( osg::Uniform::FLOAT, "visibleTime" );
                          geode->getOrCreateStateSet()->addUniform( nodeData._uniform.get() );
                      }

                      float oldValue;
                      nodeData._uniform->get( oldValue );
                      if ( oldValue != nodeData._visibleTime )
                          nodeData._uniform->set( nodeData._visibleTime );
                  }
              }

              visible = !nodeData._obscured;
          }
          
          // adjust the visibility
          xform->setNodeMask( visible ? ~0 : 0 );

          ++i;
        }
        else
        {
          _renderNodes.erase( node );
          _controlNodes.erase( i++ );
        }
    }
}

Here is the call graph for this function:

osg::Group* osgEarth::Util::Controls::ControlNodeBin::getControlGroup ( ) const [inline, private]

Definition at line 656 of file Controls.

{ return _group.get(); }
void ControlNodeBin::setFading ( bool  value)

Whether to fade-in controls when they appear in view (default=true)

Definition at line 1910 of file Controls.cpp.

{
    _fading = value;
}

Friends And Related Function Documentation

friend class ControlCanvas [friend]

Definition at line 652 of file Controls.

friend class ControlNode [friend]

Definition at line 653 of file Controls.


Member Data Documentation

Definition at line 636 of file Controls.

Definition at line 649 of file Controls.

osg::ref_ptr<osg::Group> osgEarth::Util::Controls::ControlNodeBin::_group [private]

Definition at line 646 of file Controls.

Definition at line 640 of file Controls.

Definition at line 644 of file Controls.

Definition at line 648 of file Controls.

Definition at line 650 of file Controls.

std::vector<osg::BoundingBox> osgEarth::Util::Controls::ControlNodeBin::_taken [private]

Definition at line 647 of file Controls.


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