Hey Robert,

 

After some investigation, I finally found a solution to our intersection
problems with the billboard nodes.

 

Below is my implementation of an intersection visitor that can give
feedback back to LOD nodes for proper active child traversal.  This
implementation is only what serves our needs, and possibly breaks some
of the features that you've put in intersectors (such as proper
coordinate frame lookup).  Nonetheless, I thought you might find it
useful if you have any plans to implement an intersection visitor that
can employ eye information for better interaction with LOD objects and
billboards that use the recent implementation of the POINT_ROT_EYE mode.

 

Regards,

Chase

 

 

 

#include <osg/PagedLOD>

#include <osg/Billboard>

#include <osg/Transform>

 

class LodIntersectionVisitor : public osgUtil::IntersectionVisitor

{

public:

    LodIntersectionVisitor( const osg::Matrixd& view, float lod_scale =
1.0, osgUtil::Intersector* intersector=0, ReadCallback* readCallback=0 )

      : osgUtil::IntersectionVisitor( intersector, readCallback ),
lod_scale(lod_scale)

    {

        pushViewMatrix(new osg::RefMatrix(view));

        eye = osg::Matrix::inverse(view).getTrans();

    }

 

    osg::Vec3 getEyePoint() const;

    float getDistanceToEyePoint( const osg::Vec3&, bool ) const;

    float getDistanceFromEyePoint( const osg::Vec3&, bool ) const;

 

    void apply(osg::PagedLOD& plod);

            

    // Makes use of eyeposition information to produce a model matrix
and

    // transform the intersector's space into the billboard's space.

    void apply(osg::Billboard& billboard);

 

private:

    osg::Vec3 eye;

    float lod_scale;

 

};

 

osg::Vec3 LodIntersectionVisitor::getEyePoint() const

{

    // This code needs verification.

 

    osg::Vec3 eye_point = eye;

    

    if( getModelMatrix() ) eye_point = eye_point * osg::Matrix::inverse(
*getModelMatrix() );

 

    return eye_point;

}

 

float LodIntersectionVisitor::getDistanceToEyePoint(const osg::Vec3&
pos, bool with_scale) const

{

    if (with_scale) 

        return (pos-getEyePoint()).length()*lod_scale;

    else 

        return (pos-getEyePoint()).length();

}

 

float LodIntersectionVisitor::getDistanceFromEyePoint(const osg::Vec3&
pos, bool with_scale) const

{

    // Are getDistanceTo and getDistanceFrom really equivalent?

    return getDistanceToEyePoint(pos, with_scale);

}

 

void LodIntersectionVisitor::apply(osg::PagedLOD& plod)

{

    // Treat PagedLODs as regular LODs, as the base apply() method for

    // PagedLODs only acts upon the highest level of detail, regardless
of

    // what is actually visible.

    osg::LOD& lod = plod;

    osgUtil::IntersectionVisitor::apply(lod);

}

 

void LodIntersectionVisitor::apply(osg::Billboard& billboard)

{

    if (!enter(billboard)) return;

 

    osg::Vec3 eye_local = getEyePoint();

 

    osg::Matrixd model_view = getModelMatrix() ? *getModelMatrix() :
osg::Matrixd;

 

    // ROT_TO_EYE mode expects a Model view matrix with something like M
= M1*M2*...*MN * View, so tack the view on

    // before making the billboard compute its transformation.  This
properly puts intersection data in the

    // billboard's reference frame.

    // getViewMatrix() is invariantly defined based on the rules of the
constructor.

    model_view.postMult( *getViewMatrix() );

 

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

    {

        osg::Matrixd bb_matrix(model_view);

 

        const osg::Vec3& pos = billboard.getPosition(i);

        billboard.computeMatrix( bb_matrix, eye_local, pos );

 

        // Remove the view matrix from the model data.

        bb_matrix.postMult( osg::Matrix::inverse( *getViewMatrix() ));

        

        osgUtil::Intersector* intersector = getIntersector();

 

        

        // Have to push the model matrix to ensure that the intersector
clone is properly placed into the

        // Billboard's coordinate frame.

        pushModelMatrix( new osg::RefMatrix(bb_matrix) );

 

        // now push an new intersector clone transform to the new local
coordinates

        push_clone();

        

        intersect( billboard.getDrawable(i) );

 

        // pop the clone.

        pop_clone();

          

        popModelMatrix();

      }

 

    leave();

}

 

_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

Reply via email to