How to Calculate the Bounding Box of an osg::node

 

OSG Code Example

 

 

     

     

    This example function illustrates one possible method of calculating a tight bounding box on a given  osg::Node :

     

    • How to create and derive a class from an osg osg::NodeVisitor
    • How to use an osg::NodeVisitor on a given node
    • How to take account  of any   osg::MatrixTransform in the osg::Node children
    • How to create and use a osg::BoundingBox
    • How to get the number of  osg::Drawable's from an osg::Geode
    • How to traverse the osg::Drawable's and retrieve/use each osg::Drawable of  each  osg::Geode
    • How to retrieve a osg::BoundingBox from an  osg::Drawable
    • How to retrieve athe osg::Matrix  from a osg::MatrixTransform node

     

    Note this code/example is based on a several postings to the OSG mailing list and has been mangled into this form by myself

     

     

 




 

 

Code :

--

// +----------------------------------------------------------------------------------+

// |

// |  Simple Node Visitor to calculate the Bounding Box extents of the visited Node

// |    

// |    

// |  usage example:  

// |    

// |    

// |    CcalculateBoundingBox bbox ;

// |    

// |    node->accept( bbox  );

// |    

// |    osg::BoundingBox boxExtents = bboxCalc.bbox();

// |    

// +----------------------------------------------------------------------------------+

 

#include <osg/NodeVisitor>

#include <osg/BoundingBox>

#include <osg/BoundingSphere>

#include <osg/MatrixTransform>

#include <osg/Billboard>

 

 

class  CcalculateBoundingBox : public osg::NodeVisitor {

 

public:

 

     CcalculateBoundingBox() : NodeVisitor( NodeVisitor::TRAVERSE_ALL_CHILDREN ) {

     // ----------------------------------------------------------------------

     //

     //     Default Public Class Constructor

     //

     // ----------------------------------------------------------------------

                                      

            m_transformMatrix.makeIdentity();

     

            }

            

     

       

    virtual ~CcalculateBoundingBox() {}

 

 

    virtual

    void apply( osg::Geode &geode ) {

    // -------------------------------------------

    //

    //   Handle nodes of the type osg::Geode

    //

    // -------------------------------------------

    

        osg::BoundingBox bbox;

        

        //

        // update bounding box for each drawable

        //

        for(  unsigned int i = 0; i < geode.getNumDrawables(); ++i ){

            

            //

            // expand the overall bounding box

            //

 

            bbox.expandBy( geode.getDrawable( i )->getBound());

            }

 

        //

        // transform corners by current matrix

        //

        osg::BoundingBox bboxTrans;

        

        for( unsigned int i = 0; i < 8; ++i ) {

        

            osg::Vec3 xvec = bbox.corner( i ) * m_transformMatrix;

        

            bboxTrans.expandBy( xvec );

 

            }

 

        //

        // update the overall bounding box size

        //

        m_boundingBox.expandBy( bboxTrans );

 

        //

        // continue traversing through the graph

        //

        traverse( geode );

        

        } // ::apply(osg::Geode &geode)

        

 

    virtual

    void apply( osg::MatrixTransform &node ) {

    // ---------------------------------------------------------

    //

    //   Handle nodes of the type osg::MatrixTransform

    //

    // ---------------------------------------------------------

 

        m_transformMatrix *= node.getMatrix();

 

        //

        // continue traversing through the graph

        //

        traverse( node );

 

        } // ::apply(osg::MatrixTransform &node)

        

         

    virtual

    void apply( osg::Billboard &node ){

    // -----------------------------------------------

    //

    //    Handle nodes of the type osg::Billboard

    //

    // -----------------------------------------------

    

        //

        // important to handle billboard so that its size will

        // not affect the geode size continue traversing the graph

        //

        traverse( node );

 

    } // ::apply(osg::MatrixTransform &node)

    

    

    //

    // return teh bounding box     

    //

    osg::BoundingBox &getBoundBox() { return m_boundingBox; }  

 

protected :

 

    osg::BoundingBox m_boundingBox;          // the overall resultant bounding box

    osg::Matrix      m_transformMatrix;      // the current transform matrix

 

 

};  // class  CcalculateBoundingBox

 

 

 

     

Copyright 2004-2005 Gordon Tomlinson  All Rights Reserved.

All logos, trademarks and copyrights in this site are property of their respective owner.