OcclusionQueryNode: fix resetting to default query geometry

When the query geometry gets reset to its default then its
vertices have to be updated by the bounding box dimensions of
the current children of the OcclusionQueryNode.
This commit is contained in:
Daniel Trstenjak 2019-08-23 09:46:02 +02:00 committed by Julien Valentin
parent 817d92b703
commit ddb72691bc
2 changed files with 48 additions and 33 deletions

View File

@ -208,6 +208,8 @@ protected:
osg::Geometry* debugQueryGeom,
QueryGeometryState state );
void updateDefaultQueryGeometry();
osg::ref_ptr< osg::Geode > _queryGeode;
osg::ref_ptr< osg::Geode > _debugGeode;

View File

@ -625,39 +625,7 @@ BoundingSphere OcclusionQueryNode::computeBound() const
// This is the logical place to put this code, but the method is const. Cast
// away constness to compute the bounding box and modify the query geometry.
osg::OcclusionQueryNode* nonConstThis = const_cast<osg::OcclusionQueryNode*>( this );
ComputeBoundsVisitor cbv;
nonConstThis->accept( cbv );
BoundingBox bb = cbv.getBoundingBox();
const bool bbValid = bb.valid();
_queryGeometryState = bbValid ? VALID : INVALID;
osg::ref_ptr<Vec3Array> v = new Vec3Array;
v->resize( 8 );
// 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() );
geom = static_cast< osg::Geometry* >( nonConstThis->_debugGeode->getDrawable( 0 ) );
geom->setVertexArray( v.get() );
nonConstThis->updateDefaultQueryGeometry();
}
}
@ -803,6 +771,49 @@ void OcclusionQueryNode::setQueryGeometryInternal( QueryGeometry* queryGeom,
}
void OcclusionQueryNode::updateDefaultQueryGeometry()
{
if (_queryGeometryState == USER_DEFINED)
{
OSG_FATAL << "osgOQ: OcclusionQueryNode: Unexpected QueryGeometryState=USER_DEFINED." << std::endl;
return;
}
ComputeBoundsVisitor cbv;
accept( cbv );
BoundingBox bb = cbv.getBoundingBox();
const bool bbValid = bb.valid();
_queryGeometryState = bbValid ? VALID : INVALID;
osg::ref_ptr<Vec3Array> v = new Vec3Array;
v->resize( 8 );
// 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* >( _queryGeode->getDrawable( 0 ) );
geom->setVertexArray( v.get() );
geom = static_cast< osg::Geometry* >( _debugGeode->getDrawable( 0 ) );
geom->setVertexArray( v.get() );
}
void OcclusionQueryNode::releaseGLObjects( State* state ) const
{
if (_queryGeode.valid()) _queryGeode->releaseGLObjects(state);
@ -834,6 +845,8 @@ void OcclusionQueryNode::setQueryGeometry( QueryGeometry* geom )
setQueryGeometryInternal( createDefaultQueryGeometry( getName() ),
createDefaultDebugQueryGeometry(),
INVALID);
updateDefaultQueryGeometry();
}
}