Code Search for Developers
 
 
  

vertexBufferNode.cpp from Equalizer - Multipipe Rendering at Krugle


Show vertexBufferNode.cpp syntax highlighted

/*  
    vertexBufferNode.cpp
    Copyright (c) 2007, Tobias Wolf <twolf@access.unizh.ch>
    All rights reserved.  
    
    Implementation of the VertexBufferNode class.
*/


#include "vertexBufferNode.h"
#include "vertexBufferLeaf.h"
#include "vertexBufferState.h"
#include "vertexData.h"


#undef NDEBUG
#include <cassert>


using namespace std;
using namespace mesh;


/*  Continue kd-tree setup, create intermediary or leaf nodes as required.  */
void VertexBufferNode::setupTree( VertexData& data, const Index start,
                                  const Index length, const Axis axis,
                                  VertexBufferData& globalData )
{
    #ifndef NDEBUG
    cout << "entering VertexBufferNode::setupTree"
         << "( " << start << ", " << length << ", " << axis << " )" << endl;
    #endif
    
    data.sort( start, length, axis );
    Index median = start + ( length / 2 );
    
    // left child will include elements smaller than the median
    Index leftLength = length / 2;
    if( leftLength > LEAF_SIZE )
        _left = new VertexBufferNode;
    else
        _left = new VertexBufferLeaf( globalData );
    
    // right child will include elements equal to or greater than the median
    Index rightLength = ( length + 1 ) / 2;
    if( rightLength > LEAF_SIZE )
        _right = new VertexBufferNode;
    else
        _right = new VertexBufferLeaf( globalData );
    
    // move to next axis and continue contruction in the child nodes
    Axis newAxis = static_cast< Axis >( ( axis + 1 ) % 3 );
    static_cast< VertexBufferNode* >
        ( _left )->setupTree( data, start, leftLength, newAxis, globalData );
    static_cast< VertexBufferNode* >
        ( _right )->setupTree( data, median, rightLength, newAxis, globalData );
}


/*  Compute the bounding sphere from the children's bounding spheres.  */
BoundingBox VertexBufferNode::updateBoundingSphere()
{
    // take the bounding boxes returned from the children
    BoundingBox leftBoundingBox = 
        static_cast< VertexBufferNode* >( _left )->updateBoundingSphere();
    BoundingBox rightBoundingBox = 
        static_cast< VertexBufferNode* >( _right )->updateBoundingSphere();
    
    // merge into new bounding box
    BoundingBox boundingBox;
    for( int i = 0; i < 3; ++i )
    {
        boundingBox[0][i] = min( leftBoundingBox[0][i], 
                                 rightBoundingBox[0][i] );
        boundingBox[1][i] = max( leftBoundingBox[1][i], 
                                 rightBoundingBox[1][i] );
    }
    
    // calculate sphere from the merged bounding box
    calculateBoundingSphere( boundingBox );
    
    #ifndef NDEBUG
    cout << "exiting VertexBufferNode::updateBoundingSphere" 
         << "( " << boundingBox[0] << ", " << boundingBox[1] << " )" << endl;
    #endif
    
    return boundingBox;
}


/*  Compute the range from the children's ranges.  */
void VertexBufferNode::updateRange()
{
    // update the children's ranges
    static_cast< VertexBufferNode* >( _left )->updateRange();
    static_cast< VertexBufferNode* >( _right )->updateRange();
    
    // set node range to min/max of the children's ranges
    _range[0] = min( _left->getRange()[0], _right->getRange()[0] );
    _range[1] = max( _left->getRange()[1], _right->getRange()[1] );
    
    #ifndef NDEBUG
    cout << "exiting VertexBufferNode::updateRange" 
         << "( " << _range[0] << ", " << _range[1] << " )" << endl;
    #endif
}


/*  Render the node by rendering the children.  */
void VertexBufferNode::render( VertexBufferState& state, 
                               bool performCulling ) const
{
    if( performCulling )
    {
        // out of range check (_range is node range, range is render range)
        const Range range = state.getRange();
        if( _range[0] >= range[1] || _range[1] < range[0] )
            return;
        
        // bounding sphere culling (if culler present)
        Culler* culler = state.getCuller();
        if( culler )
        {
            switch( culler->testSphere( _boundingSphere ) )
            {
            case vmml::VISIBILITY_FULL:
                // if fully visible and fully in range, bypass further culling
                if( _range[0] >= range[0] && _range[1] < range[1] )
                {
                    _left->render( state, false );
                    _right->render( state, false );
                    return;
                }
                // partial range, fall through to partial visibility
            case vmml::VISIBILITY_PARTIAL:
                break;
            case vmml::VISIBILITY_NONE:
                // no further rendering to be done
                return;
            }
        }
    }
    
    _left->render( state );
    _right->render( state );
}


/*  Read node from memory and continue with remaining nodes.  */
void VertexBufferNode::fromMemory( char** addr, VertexBufferData& globalData )
{
    // read node itself   
    size_t nodeType;
    memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) );
    assert( nodeType == NODE_TYPE );
    VertexBufferBase::fromMemory( addr, globalData );
    
    // read left child (peek ahead)
    memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) );
    assert( nodeType == NODE_TYPE || nodeType == LEAF_TYPE );
    *addr -= sizeof( size_t );
    if( nodeType == NODE_TYPE )
        _left = new VertexBufferNode;
    else
        _left = new VertexBufferLeaf( globalData );
    static_cast< VertexBufferNode* >( _left )->fromMemory( addr, globalData );
    
    // read right child (peek ahead)
    memRead( reinterpret_cast< char* >( &nodeType ), addr, sizeof( size_t ) );
    assert( nodeType == NODE_TYPE || nodeType == LEAF_TYPE );
    *addr -= sizeof( size_t );
    if( nodeType == NODE_TYPE )
        _right = new VertexBufferNode;
    else
        _right = new VertexBufferLeaf( globalData );
    static_cast< VertexBufferNode* >( _right )->fromMemory( addr, globalData );
}


/*  Write node to output stream and continue with remaining nodes.  */
void VertexBufferNode::toStream( ostream& os )
{
    size_t nodeType = NODE_TYPE;
    os.write( reinterpret_cast< char* >( &nodeType ), sizeof( size_t ) );
    VertexBufferBase::toStream( os );
    static_cast< VertexBufferNode* >( _left )->toStream( os );
    static_cast< VertexBufferNode* >( _right )->toStream( os );
}


/*  Destructor, clears up children as well.  */
VertexBufferNode::~VertexBufferNode()
{
    delete static_cast< VertexBufferNode* >( _left );
    delete static_cast< VertexBufferNode* >( _right );
}




See more files for this project here

Equalizer - Multipipe Rendering

Equalizer is a programming interface and resource management system for scalable graphics applications for clusters and shared memory systems. It is build upon a scalable programming interface solving the problems common to any multipipe application.

Project homepage: http://sourceforge.net/projects/equalizer
Programming language(s): C,C++
License: lgpl21

  eqPly.app/
    Contents/
      MacOS/
      Info.plist
  Makefile
  README
  channel.cpp
  channel.h
  config.cpp
  config.h
  eqPly.cpp
  eqPly.h
  frameData.h
  initData.cpp
  initData.h
  localInitData.cpp
  localInitData.h
  logo.rgb
  main.cpp
  node.cpp
  node.h
  pipe.cpp
  pipe.h
  ply.h
  plyfile.cpp
  rockerArm.ply
  tracker.cpp
  tracker.h
  typedefs.h
  vertexBufferBase.h
  vertexBufferData.h
  vertexBufferLeaf.cpp
  vertexBufferLeaf.h
  vertexBufferNode.cpp
  vertexBufferNode.h
  vertexBufferRoot.cpp
  vertexBufferRoot.h
  vertexBufferState.h
  vertexData.cpp
  vertexData.h
  window.cpp
  window.h