How to  Change the Color of an osg::Node's Geometry

 

OSG Code Example 2

 

 

     

     

    This example class  illustrates one possible method of  changing the color of all the geometry of an  osg::Node and its children:

     

    • How to create and derive a class from an osg osg::NodeVisitor
    • How to use the osg::NodeVisitor to traverse all the children
    • How to use an osg::NodeVisitor on a given node
    • 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::Drawables of  each  osg::Geode
    • How to retrieve the osg::Geometry  from the osg::Drawables
    • How to use the member function ::asGeometry to get a pointer of type osg::Geometry without the need for a dynamic cast ( in other words is quicker )
    • How to retrieve the osg::Vec4Array from the  osg::Geometry  instance
    • How to retrieve the size/number of color entries in the  osg::Geometry's color  osg::Vec4Array
    • How to set/chnage  the color of  each entry int the osg::Vec4Array
    • How to set the color to BIND all
    • How to add Color if the osg::Geometry does not have any color arrays

     

     

     

 




 

 

Code :

--

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

// |

// |  Simple Node Visitor to set the color for  all the Geometry of the given Node

// |    

// |    

// |  usage example:  

// |    

// |    

// |    CcolorVisitor  newColor;

// |    

// |    newColor.setColor( 1.0f, 0.0f, 0.0f );

// |    

// |    node->accept( newColor );

// |    

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

 

//

// Required OSG header includes

//

#include <osg/array>

#include <osg/geode>

#include <osg/Geometry>

#include <osg/NodeVisitor>

#include <osg/Vec4>

 

 

class  CcolorVisitor : public osg::NodeVisitor {

 

public :

 

 

 

    CcolorVisitor() : NodeVisitor( NodeVisitor::TRAVERSE_ALL_CHILDREN ) {

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

    //

    // Default Ctors overide the default node visitor mode so all

    // children are visited

    //

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

 

        //

        // Default to a white color

        //

        m_color.set( 1.0, 1.0, 1.0, 1.0 );

 

        m_colorArrays = new osg::Vec4Array;

 

        m_colorArrays->push_back( m_color );    

 

        };

 

        

    CcolorVisitor( const osg::Vec4 &color ) : NodeVisitor( NodeVisitor::TRAVERSE_ALL_CHILDREN ) {

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

    //

    // Overloaded Ctor initialised with the Color

    // Also override the visitor to traverse all the nodes children

    //

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

 

        m_color = m_color;

 

        m_colorArrays = new osg::Vec4Array;

 

        m_colorArrays->push_back( m_color );    

 

        

        };

    

    

        

    virtual ~CcolorVisitor(){};

 

 

    virtual

    void apply ( osg::Node &node ){

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

    //

    //  Handle traversal of osg::Node node types

    //

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

 

    traverse( node );

 

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

    

 

    virtual

    void apply( osg::Geode &geode ){

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

    //

    //  Handle traversal of osg::Geode node types

    //

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

    osg::StateSet *state   = NULL;

    unsigned int    vertNum = 0;

 

    //  

    //  We need to iterate through all the drawables check if

    //  the contain any geometry that we will need to process

    //

    unsigned int numGeoms = geode.getNumDrawables();

 

 

    for( unsigned int geodeIdx = 0; geodeIdx < numGeoms; geodeIdx++ ) {

 

        //

        // Use 'asGeometry' as its supposed to be faster than a dynamic_cast

        // every little saving counts

        //

       osg::Geometry *curGeom = geode.getDrawable( geodeIdx )->asGeometry();

 

 

        //

        // Only process if the drawable is geometry

        //

        if ( curGeom ) {

            

            

           osg::Vec4Array *colorArrays = dynamic_cast< osg::Vec4Array *>(curGeom->getColorArray());

 

           if ( colorArrays ) {

                

               for ( unsigned int i = 0; i < colorArrays->size(); i++ ) {

                    

                    osg::Vec4 *color = &colorArrays->operator [](i);

                    

                    //

                    // could also use *color = m_color

                    //

                    color->set( m_color._v[0], m_color._v[1], m_color._v[2], m_color._v[3]);

                                        

                    }

                }   

                else{            

                    curGeom->setColorArray( m_colorArrays.get());

                    curGeom->setColorBinding( osg::Geometry::BIND_OVERALL );            

                    }                  

                }

 

            }

        

    } // apply( osg::Geode    

 

 

    void

    setColor( const float r, const float g, const float b, const float a = 1.0f ){

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

    //

    // Set the color to change apply to the nodes geometry

    //

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

 

        osg::Vec4 *c = &m_colorArrays->operator []( 0 );

 

        m_color.set( r,g,b,a );

        

        *c = m_color;

 

 

       } // setColor( r,g,b,a )

 

 

    void

    setColor( const osg::Vec4 &color  ){

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

    //

    // Set the color to change apply to the nodes geometry

    //

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

 

        osg::Vec4 *c = &m_colorArrays->operator []( 0 );

 

        m_color = color;

        

        *c = m_color;

 

 

       } // setColor( vec4 )

 

 

 

 

 

private :

 

 

    osg::Vec4 m_color;

    osg::ref_ptr< osg::Vec4Array > m_colorArrays;

 

 

 }; // class CcolorVisitor

 

 

 

     

Copyright 2004-2005 Gordon Tomlinson  All Rights Reserved.

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