Added code to better compute the view frustum that is appropriate for a traversed

subgraph.
This commit is contained in:
Robert Osfield 2007-05-15 17:04:57 +00:00
parent 881ba2ed2f
commit 1e0af35900
3 changed files with 88 additions and 7 deletions

View File

@ -188,6 +188,11 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac
/** Add an attribute which is positioned relative to the modelview matrix.*/
inline void addPositionedTextureAttribute(unsigned int textureUnit, osg::RefMatrix* matrix,const osg::StateAttribute* attr);
/** compute near plane based on the polgon intersection of primtives in near plane candidate list of drawables.
* Note, you have to set ComputeNearFarMode to COMPUTE_NEAR_FAR_USING_PRIMITIVES to be able to near plane candidate drawables to be recorded by the cull traversal. */
void computeNearPlane();
/** Re-implement CullStack's popProjectionMatrix() adding clamping of the projection matrix to
* the computed near and far.*/
virtual void popProjectionMatrix();

View File

@ -11,6 +11,7 @@
* OpenSceneGraph Public License for more details.
*/
#include <osg/ComputeBoundsVisitor>
#include <osg/Texture2D>
#include <osg/CoordinateSystemNode>
#include <osg/TexEnv>
@ -337,7 +338,7 @@ void OverlayNode::traverse_OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeV
void OverlayNode::traverse_VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeVisitor& nv)
{
osg::notify(osg::NOTICE)<<"OverlayNode::traverse() - VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY"<<std::endl;
// osg::notify(osg::NOTICE)<<"OverlayNode::traverse() - VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY"<<std::endl;
if (nv.getVisitorType() != osg::NodeVisitor::CULL_VISITOR)
@ -355,9 +356,78 @@ void OverlayNode::traverse_VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeVis
OverlayData& overlayData = getOverlayData(cv);
if (_overlaySubgraph.valid())
{
// get the bounds of the model.
osg::ComputeBoundsVisitor cbbv(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
_overlaySubgraph->accept(cbbv);
Group::traverse(nv);
osg::notify(osg::NOTICE)<<" "<<&overlayData<<std::endl;
osg::Matrix pm = *(cv->getProjectionMatrix());
osgUtil::CullVisitor::value_type znear = cv->getCalculatedNearPlane();
osgUtil::CullVisitor::value_type zfar = cv->getCalculatedFarPlane();
// osg::notify(osg::NOTICE)<<" before znear ="<<znear<<"\t zfar ="<<zfar<<std::endl;
cv->computeNearPlane();
znear = cv->getCalculatedNearPlane();
zfar = cv->getCalculatedFarPlane();
// osg::notify(osg::NOTICE)<<" after znear ="<<znear<<"\t zfar ="<<zfar<<std::endl;
// osg::notify(osg::NOTICE)<<" before clamp pm="<<pm<<std::endl;
cv->clampProjectionMatrixImplementation(pm, znear,zfar);
// osg::notify(osg::NOTICE)<<" after clamp pm="<<pm<<std::endl;
osg::Matrix MVP = *(cv->getModelViewMatrix()) * pm;
osg::Matrix inverseMVP;
inverseMVP.invert(MVP);
// osg::notify(osg::NOTICE)<<" MVP="<<MVP<<std::endl;
// osg::notify(osg::NOTICE)<<" inverseMVP="<<inverseMVP<<std::endl;
typedef std::vector<osg::Vec3d> Corners;
Corners corners;
corners.push_back(osg::Vec3d(-1.0,-1.0,-1.0));
corners.push_back(osg::Vec3d(1.0,-1.0,-1.0));
corners.push_back(osg::Vec3d(1.0,1.0,-1.0));
corners.push_back(osg::Vec3d(-1.0,1.0,1.0));
corners.push_back(osg::Vec3d(-1.0,-1.0,1.0));
corners.push_back(osg::Vec3d(1.0,-1.0,1.0));
corners.push_back(osg::Vec3d(1.0,1.0,1.0));
corners.push_back(osg::Vec3d(-1.0,1.0,1.0));
osg::Vec3d center;
for(Corners::iterator itr = corners.begin();
itr != corners.end();
++itr)
{
*itr = *itr * inverseMVP;
center += *itr;
// osg::notify(osg::NOTICE)<<" corner ="<<*itr<<std::endl;
}
center /= 8.0;
double diagonal = (corners[0]-corners[7]).length();
osg::notify(osg::NOTICE)<<" center ="<<center<<" diagonal ="<<diagonal<<std::endl;
}
else
{
Group::traverse(nv);
}
// osg::notify(osg::NOTICE)<<" "<<&overlayData<<std::endl;
}
void OverlayNode::traverse_VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY(osg::NodeVisitor& nv)

View File

@ -173,13 +173,12 @@ float CullVisitor::getDistanceFromEyePoint(const osg::Vec3& pos, bool withLODSca
else return dist;
}
void CullVisitor::popProjectionMatrix()
void CullVisitor::computeNearPlane()
{
if (!_nearPlaneCandidateMap.empty())
{
// osg::Timer_t start_t = osg::Timer::instance()->tick();
osg::Timer_t start_t = osg::Timer::instance()->tick();
// update near from defferred list of drawables
unsigned int numTests = 0;
@ -197,9 +196,16 @@ void CullVisitor::popProjectionMatrix()
}
}
// osg::Timer_t end_t = osg::Timer::instance()->tick();
osg::Timer_t end_t = osg::Timer::instance()->tick();
// osg::notify(osg::NOTICE)<<"Took "<<osg::Timer::instance()->delta_m(start_t,end_t)<<"ms to test "<<numTests<<" out of "<<_nearPlaneCandidateMap.size()<<std::endl;
_nearPlaneCandidateMap.clear();
}
}
void CullVisitor::popProjectionMatrix()
{
computeNearPlane();
if (_computeNearFar && _computed_zfar>=_computed_znear)
{