bool OcclusionQueryNode::getPassed( const osg::Camera* camera, float distanceToEyePoint ) { if ( !_enabled ) // Queries are not enabled. The caller should be osgUtil::CullVisitor, // return true to traverse the subgraphs. return true; // In the future, we could hold a reference directly to the QueryDrawable // to avoid the dynamic_cast. QueryGeometry* qg = dynamic_cast< QueryGeometry* >( _queryGeode->getDrawable( 0 ) ); if (qg == NULL) { osg::notify( osg::FATAL ) << "osgOQ: OcclusionQueryNode: No QueryGeometry." << std::endl; // Something's broke. Return true so we at least render correctly. return true; } // If the distance to the bounding sphere shell is positive, retrieve // the results. Others (we're inside the BS shell) we are considered // to have passed and don't need to retrieve the query. const osg::BoundingSphere& bs = getBound(); float distance = distanceToEyePoint - bs._radius; _passed = ( distance <= 0.f ); if (!_passed) { int result = qg->getNumPixels( camera ); _passed = ( (unsigned int)(result) > _visThreshold ); } return _passed; }
void OcclusionQueryNode::releaseGLObjects( osg::State* state ) const { // Query object discard and deletion is handled by QueryGeometry support class. OcclusionQueryNode* nonConstThis = const_cast< OcclusionQueryNode* >( this ); QueryGeometry* qg = dynamic_cast< QueryGeometry* >( nonConstThis->_queryGeode->getDrawable( 0 ) ); qg->releaseGLObjects( state ); }
bool OcclusionQueryNode::getPassed( const Camera* camera, NodeVisitor& nv ) { if ( !_enabled ) // Queries are not enabled. The caller should be osgUtil::CullVisitor, // return true to traverse the subgraphs. return true; { // Two situations where we want to simply do a regular traversal: // 1) it's the first frame for this camera // 2) we haven't rendered for an abnormally long time (probably because we're an out-of-range LOD child) // In these cases, assume we're visible to avoid blinking. OpenThreads::ScopedLock<OpenThreads::Mutex> lock( _frameCountMutex ); const unsigned int& lastQueryFrame( _frameCountMap[ camera ] ); if( ( lastQueryFrame == 0 ) || ( (nv.getTraversalNumber() - lastQueryFrame) > (_queryFrameCount + 1) ) ) return true; } if (_queryGeode->getDrawable( 0 ) == NULL) { OSG_FATAL << "osgOQ: OcclusionQueryNode: No QueryGeometry." << std::endl; // Something's broke. Return true so we at least render correctly. return true; } QueryGeometry* qg = static_cast< QueryGeometry* >( _queryGeode->getDrawable( 0 ) ); // Get the near plane for the upcoming distance calculation. float nearPlane; const osg::Matrix& proj( camera->getProjectionMatrix() ); if( ( proj(3,3) != 1. ) || ( proj(2,3) != 0. ) || ( proj(1,3) != 0. ) || ( proj(0,3) != 0.) ) nearPlane = proj(3,2) / (proj(2,2)-1.); // frustum / perspective else nearPlane = (proj(3,2)+1.) / proj(2,2); // ortho // If the distance from the near plane to the bounding sphere shell is positive, retrieve // the results. Otherwise (near plane inside the BS shell) we are considered // to have passed and don't need to retrieve the query. const osg::BoundingSphere& bs = getBound(); float distanceToEyePoint = nv.getDistanceToEyePoint( bs._center, false ); float distance = distanceToEyePoint - nearPlane - bs._radius; _passed = ( distance <= 0.f ); if (!_passed) { int result = qg->getNumPixels( camera ); _passed = ( (unsigned int)(result) > _visThreshold ); } return _passed; }
double S2NearCursor::distanceBetween(const QueryGeometry &field, const BSONObj &obj) { S2Point us = field.getCentroid(); S2Point them; S2Polygon polygon; S2Polyline line; S2Cell point; if (GeoJSONParser::parsePolygon(obj, &polygon)) { them = polygon.Project(us); } else if (GeoJSONParser::parseLineString(obj, &line)) { int tmp; them = line.Project(us, &tmp); } else if (GeoJSONParser::parsePoint(obj, &point)) { them = point.GetCenter(); } else { warning() << "unknown geometry: " << obj.toString(); } S1Angle angle(us, them); return angle.radians() * _params.radius; }