From 6f08e25c0575032a478858ceceb58203ccb9cc8f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 9 Sep 2010 08:47:12 +0000 Subject: [PATCH] From Nathan Monteleone and Robert Osfield, submission email from Nathan: "I discovered a problem with POINT_ROT_EYE billboards in IntersectionVisitor: because we pass in just the model matrix to Billboard::computeBillboardMatrix, the billboard gets the wrong up vector. It really needs to take the view matrix into account to get the correct up vector. This version of IntersectionVisitor.cpp is made against today's SVN. It corrects the problem by computing the billboard matrix using the complete modelview, and then multiplies by the inverse of the view matrix before pushing onto IntersectionVisitor's model stack. The only code I changed is in apply(Billboard&)." notes from Robert, refactored the matrix multiplication code and the use of RefMatrix to make Nathan's changes more efficient. --- src/osgUtil/IntersectionVisitor.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/osgUtil/IntersectionVisitor.cpp b/src/osgUtil/IntersectionVisitor.cpp index c0ba40f45..74dae41bc 100644 --- a/src/osgUtil/IntersectionVisitor.cpp +++ b/src/osgUtil/IntersectionVisitor.cpp @@ -250,12 +250,17 @@ void IntersectionVisitor::apply(osg::Billboard& billboard) for(unsigned int i = 0; i < billboard.getNumDrawables(); i++ ) { const osg::Vec3& pos = billboard.getPosition(i); - osg::ref_ptr billboard_matrix = _modelStack.empty() ? - new osg::RefMatrix : - new osg::RefMatrix(*_modelStack.back()); + osg::ref_ptr billboard_matrix = new osg::RefMatrix; + if (getViewMatrix()) + { + if (getModelMatrix()) billboard_matrix->mult( *getModelMatrix(), *getViewMatrix() ); + else billboard_matrix->set( *getViewMatrix() ); + } + else if (getModelMatrix()) billboard_matrix->set( *getModelMatrix() ); billboard.computeMatrix(*billboard_matrix,eye_local,pos); - + + if (getViewMatrix()) billboard_matrix->postMult( osg::Matrix::inverse(*getViewMatrix()) ); pushModelMatrix(billboard_matrix.get()); // now push an new intersector clone transform to the new local coordinates