bool CullVisitor::updateCalculatedNearFar(const osg::Matrix& matrix,const osg::BoundingBox& bb) { // efficient computation of near and far, only taking into account the nearest and furthest // corners of the bounding box. value_type d_near = distance(bb.corner(_bbCornerNear),matrix); value_type d_far = distance(bb.corner(_bbCornerFar),matrix); if (d_near>d_far) { std::swap(d_near,d_far); if ( !EQUAL_F(d_near, d_far) ) { OSG_WARN<<"Warning: CullVisitor::updateCalculatedNearFar(.) near>far in range calculation,"<< std::endl; OSG_WARN<<" correcting by swapping values d_near="<<d_near<<" dfar="<<d_far<< std::endl; } } if (d_far<0.0) { // whole object behind the eye point so disguard return false; } if (d_near<_computed_znear) _computed_znear = d_near; if (d_far>_computed_zfar) _computed_zfar = d_far; return true; }
void ComputeBoundsVisitor::applyBoundingBox(const osg::BoundingBox& bbox) { if (_matrixStack.empty()) _bb.expandBy(bbox); else if (bbox.valid()) { const osg::Matrix& matrix = _matrixStack.back(); _bb.expandBy(bbox.corner(0) * matrix); _bb.expandBy(bbox.corner(1) * matrix); _bb.expandBy(bbox.corner(2) * matrix); _bb.expandBy(bbox.corner(3) * matrix); _bb.expandBy(bbox.corner(4) * matrix); _bb.expandBy(bbox.corner(5) * matrix); _bb.expandBy(bbox.corner(6) * matrix); _bb.expandBy(bbox.corner(7) * matrix); } }
void HorizonTileCuller::set(const osg::BoundingBox& bbox) { // Adjust the horizon ellipsoid based on the minimum Z value of the tile; // necessary because a tile that's below the ellipsoid (ocean floor, e.g.) // may be visible even if it doesn't pass the horizon-cone test. In such // cases we need a more conservative ellipsoid. double zMin = bbox.corner(0).z(); if ( zMin < 0.0 ) { _horizonProto.setEllipsoid( osg::EllipsoidModel(_radiusEquator + zMin, _radiusPolar + zMin) ); } // consider the uppermost 4 points of the tile-aligned bounding box. // (the last four corners of the bbox are the "zmax" corners.) for(unsigned i=0; i<4; ++i) { _points[i] = bbox.corner(4+i) * _local2world; } }
void HorizonTileCuller::set(const SpatialReference* srs, const osg::Matrix& local2world, const osg::BoundingBox& bbox) { if (!_horizon.valid() && srs->isGeographic()) { _horizon = new Horizon(); } if (_horizon.valid()) { _horizon->setEllipsoid(*srs->getEllipsoid()); //_radiusPolar = srs->getEllipsoid()->getRadiusPolar(); //_radiusEquator = srs->getEllipsoid()->getRadiusEquator(); //_local2world = local2world; // Adjust the horizon ellipsoid based on the minimum Z value of the tile; // necessary because a tile that's below the ellipsoid (ocean floor, e.g.) // may be visible even if it doesn't pass the horizon-cone test. In such // cases we need a more conservative ellipsoid. double zMin = (double)std::min( bbox.corner(0).z(), 0.0f ); zMin = std::max(zMin, -25000.0); // approx the lowest point on earth * 2 _horizon->setEllipsoid( osg::EllipsoidModel( srs->getEllipsoid()->getRadiusEquator() + zMin, srs->getEllipsoid()->getRadiusPolar() + zMin) ); // consider the uppermost 4 points of the tile-aligned bounding box. // (the last four corners of the bbox are the "zmax" corners.) for(unsigned i=0; i<4; ++i) { _points[i] = bbox.corner(4+i) * local2world; } //_bs.set(bbox.center() * _local2world, bbox.radius()); } }
osg::Vec3f InspectorIH::updateBBox( osg::Drawable* p_drawable, const osg::Matrix& accumat, bool hastransformnode ) { osg::Vec3f dims; // update the bbox for visualization if ( p_drawable ) { const osg::BoundingBox bb = p_drawable->getBound(); // update the bbox lines osg::Vec3Array* p_vertices = static_cast< osg::Vec3Array* >( _p_linesGeom->getVertexArray() ); ( *p_vertices )[ 0 ] = bb.corner( 0 ) * accumat; ( *p_vertices )[ 1 ] = bb.corner( 1 ) * accumat; ( *p_vertices )[ 2 ] = bb.corner( 2 ) * accumat; ( *p_vertices )[ 3 ] = bb.corner( 3 ) * accumat; ( *p_vertices )[ 4 ] = bb.corner( 4 ) * accumat; ( *p_vertices )[ 5 ] = bb.corner( 5 ) * accumat; ( *p_vertices )[ 6 ] = bb.corner( 6 ) * accumat; ( *p_vertices )[ 7 ] = bb.corner( 7 ) * accumat; _p_linesGeom->setVertexArray( p_vertices ); osg::Vec3f max = bb.corner( 7 ); osg::Vec3f min = bb.corner( 0 ); // get the original dimensions dims = max - min; // set the bbox color // if the geode has no transform nodes in the node path then we draw it white if ( hastransformnode ) { osg::Vec4Array* colors = new osg::Vec4Array; colors->push_back( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) ); _p_linesGeom->setColorArray( colors ); _p_linesGeom->setColorBinding( osg::Geometry::BIND_OVERALL ); } else // ... otherwise yellow { osg::Vec4Array* colors = new osg::Vec4Array; colors->push_back( osg::Vec4( 1.0f, 1.0f, 0.0f, 1.0f ) ); _p_linesGeom->setColorArray( colors ); _p_linesGeom->setColorBinding( osg::Geometry::BIND_OVERALL ); } } else { // let the box disappear when no intersection detected osg::Vec3Array* p_vertices = static_cast< osg::Vec3Array* >( _p_linesGeom->getVertexArray() ); ( *p_vertices )[ 0 ] = osg::Vec3(); ( *p_vertices )[ 1 ] = osg::Vec3(); ( *p_vertices )[ 2 ] = osg::Vec3(); ( *p_vertices )[ 3 ] = osg::Vec3(); ( *p_vertices )[ 4 ] = osg::Vec3(); ( *p_vertices )[ 5 ] = osg::Vec3(); ( *p_vertices )[ 6 ] = osg::Vec3(); ( *p_vertices )[ 7 ] = osg::Vec3(); _p_linesGeom->setVertexArray( p_vertices ); } return dims; }