OcclusionQueryNode: ensure a valid query geometry
If the query geometry is invalid then don't do any occlusion queries and never traverse the subgraphs.
This commit is contained in:
parent
9905b90a18
commit
5624a22fe4
@ -198,6 +198,9 @@ protected:
|
||||
|
||||
bool _enabled;
|
||||
|
||||
// If the box of the query geometry is valid.
|
||||
mutable bool _validQueryGeometry;
|
||||
|
||||
// Tracks the last frame number that we performed a query.
|
||||
// User can set how many times (See setQueryFrameCount).
|
||||
typedef std::map< const osg::Camera*, unsigned int > FrameCountMap;
|
||||
|
@ -442,6 +442,7 @@ QueryGeometry::discardDeletedQueryObjects( unsigned int contextID )
|
||||
|
||||
OcclusionQueryNode::OcclusionQueryNode()
|
||||
: _enabled( true ),
|
||||
_validQueryGeometry( false ),
|
||||
_passed(false),
|
||||
_visThreshold( 500 ),
|
||||
_queryFrameCount( 5 ),
|
||||
@ -459,6 +460,7 @@ OcclusionQueryNode::~OcclusionQueryNode()
|
||||
|
||||
OcclusionQueryNode::OcclusionQueryNode( const OcclusionQueryNode& oqn, const CopyOp& copyop )
|
||||
: Group( oqn, copyop ),
|
||||
_validQueryGeometry( false ),
|
||||
_passed( false )
|
||||
{
|
||||
_enabled = oqn._enabled;
|
||||
@ -481,6 +483,14 @@ bool OcclusionQueryNode::getPassed( const Camera* camera, NodeVisitor& nv )
|
||||
return _passed;
|
||||
}
|
||||
|
||||
if ( !_validQueryGeometry )
|
||||
{
|
||||
// The box of the query geometry is invalid, return false to not traverse
|
||||
// the subgraphs.
|
||||
_passed = false;
|
||||
return _passed;
|
||||
}
|
||||
|
||||
{
|
||||
// Two situations where we want to simply do a regular traversal:
|
||||
// 1) it's the first frame for this camera
|
||||
@ -540,6 +550,9 @@ bool OcclusionQueryNode::getPassed( const Camera* camera, NodeVisitor& nv )
|
||||
|
||||
void OcclusionQueryNode::traverseQuery( const Camera* camera, NodeVisitor& nv )
|
||||
{
|
||||
if (!_validQueryGeometry)
|
||||
return;
|
||||
|
||||
bool issueQuery;
|
||||
{
|
||||
const int curFrame = nv.getTraversalNumber();
|
||||
@ -577,17 +590,28 @@ BoundingSphere OcclusionQueryNode::computeBound() const
|
||||
ComputeBoundsVisitor cbv;
|
||||
nonConstThis->accept( cbv );
|
||||
BoundingBox bb = cbv.getBoundingBox();
|
||||
const bool bbValid = bb.valid();
|
||||
_validQueryGeometry = bbValid;
|
||||
|
||||
osg::ref_ptr<Vec3Array> v = new Vec3Array;
|
||||
v->resize( 8 );
|
||||
(*v)[0] = Vec3( bb._min.x(), bb._min.y(), bb._min.z() );
|
||||
(*v)[1] = Vec3( bb._max.x(), bb._min.y(), bb._min.z() );
|
||||
(*v)[2] = Vec3( bb._max.x(), bb._min.y(), bb._max.z() );
|
||||
(*v)[3] = Vec3( bb._min.x(), bb._min.y(), bb._max.z() );
|
||||
(*v)[4] = Vec3( bb._max.x(), bb._max.y(), bb._min.z() );
|
||||
(*v)[5] = Vec3( bb._min.x(), bb._max.y(), bb._min.z() );
|
||||
(*v)[6] = Vec3( bb._min.x(), bb._max.y(), bb._max.z() );
|
||||
(*v)[7] = Vec3( bb._max.x(), bb._max.y(), bb._max.z() );
|
||||
|
||||
// Having (0,0,0) as vertices for the case of the invalid query geometry
|
||||
// still isn't quite the right thing. But the query geometry is public
|
||||
// accessible and therefore a user might expect eight vertices, so
|
||||
// it seems safer to keep eight vertices in the geometry.
|
||||
|
||||
if (bbValid)
|
||||
{
|
||||
(*v)[0] = Vec3( bb._min.x(), bb._min.y(), bb._min.z() );
|
||||
(*v)[1] = Vec3( bb._max.x(), bb._min.y(), bb._min.z() );
|
||||
(*v)[2] = Vec3( bb._max.x(), bb._min.y(), bb._max.z() );
|
||||
(*v)[3] = Vec3( bb._min.x(), bb._min.y(), bb._max.z() );
|
||||
(*v)[4] = Vec3( bb._max.x(), bb._max.y(), bb._min.z() );
|
||||
(*v)[5] = Vec3( bb._min.x(), bb._max.y(), bb._min.z() );
|
||||
(*v)[6] = Vec3( bb._min.x(), bb._max.y(), bb._max.z() );
|
||||
(*v)[7] = Vec3( bb._max.x(), bb._max.y(), bb._max.z() );
|
||||
}
|
||||
|
||||
Geometry* geom = static_cast< Geometry* >( nonConstThis->_queryGeode->getDrawable( 0 ) );
|
||||
geom->setVertexArray( v.get() );
|
||||
|
Loading…
Reference in New Issue
Block a user