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); } }
inline bool CheckAndMultiplyBoxIfWithinPolytope ( osg::BoundingBox & bb, osg::Matrix & m, osg::Polytope &p ) { if( !bb.valid() ) return false; osg::Vec3 o = bb._min * m, s[3]; for( int i = 0; i < 3; i ++ ) s[i] = osg::Vec3( m(i,0), m(i,1), m(i,2) ) * ( bb._max[i] - bb._min[i] ); for( osg::Polytope::PlaneList::iterator it = p.getPlaneList().begin(); it != p.getPlaneList().end(); ++it ) { float dist = it->distance( o ), dist_min = dist, dist_max = dist; for( int i = 0; i < 3; i ++ ) { dist = it->dotProductNormal( s[i] ); if( dist < 0 ) dist_min += dist; else dist_max += dist; } if( dist_max < 0 ) return false; } bb._max = bb._min = o; #if 1 for( int i = 0; i < 3; i ++ ) for( int j = 0; j < 3; j ++ ) if( s[i][j] < 0 ) bb._min[j] += s[i][j]; else bb._max[j] += s[i][j]; #else b.expandBy( o + s[0] ); b.expandBy( o + s[1] ); b.expandBy( o + s[2] ); b.expandBy( o + s[0] + s[1] ); b.expandBy( o + s[0] + s[2] ); b.expandBy( o + s[1] + s[2] ); b.expandBy( o + s[0] + s[1] + s[2] ); #endif #if ( IGNORE_OBJECTS_LARGER_THAN_HEIGHT > 0 ) if( bb._max[2] - bb._min[2] > IGNORE_OBJECTS_LARGER_THAN_HEIGHT ) // ignore huge objects return false; #endif return true; }
void MinimalShadowMap::ViewData::cutScenePolytope ( const osg::Matrix & transform, const osg::Matrix & inverse, const osg::BoundingBox & bb ) { _sceneReceivingShadowPolytopePoints.clear(); if( bb.valid() ) { osg::Polytope polytope; polytope.setToBoundingBox( bb ); polytope.transformProvidingInverse( inverse ); _sceneReceivingShadowPolytope.cut( polytope ); _sceneReceivingShadowPolytope.getPoints ( _sceneReceivingShadowPolytopePoints ); } else _sceneReceivingShadowPolytope.clear(); }
void MinimalShadowMap::ViewData::trimProjection ( osg::Matrixd & projectionMatrix, osg::BoundingBox bb, unsigned int trimMask ) { #if 1 if( !bb.valid() || !( trimMask & (1|2|4|8|16|32) ) ) return; double l = -1, r = 1, b = -1, t = 1, n = 1, f = -1; #if 0 // make sure bounding box does not extend beyond unit frustum clip range for( int i = 0; i < 3; i ++ ) { if( bb._min[i] < -1 ) bb._min[i] = -1; if( bb._max[i] > 1 ) bb._max[i] = 1; } #endif if( trimMask & 1 ) l = bb._min[0]; if( trimMask & 2 ) r = bb._max[0]; if( trimMask & 4 ) b = bb._min[1]; if( trimMask & 8 ) t = bb._max[1]; if( trimMask & 16 ) n = -bb._min[2]; if( trimMask & 32 ) f = -bb._max[2]; projectionMatrix.postMult( osg::Matrix::ortho( l,r,b,t,n,f ) ); #else if( !bb.valid() || !( trimMask & (1|2|4|8|16|32) ) ) return; double l, r, t, b, n, f; bool ortho = projectionMatrix.getOrtho( l, r, b, t, n, f ); if( !ortho && !projectionMatrix.getFrustum( l, r, b, t, n, f ) ) return; // rotated or skewed or other crooked projection - give up // make sure bounding box does not extend beyond unit frustum clip range for( int i = 0; i < 3; i ++ ) { if( bb._min[i] < -1 ) bb._min[i] = -1; if( bb._max[i] > 1 ) bb._max[i] = 1; } osg::Matrix projectionToView = osg::Matrix::inverse( projectionMatrix ); osg::Vec3 min = osg::Vec3( bb._min[0], bb._min[1], bb._min[2] ) * projectionToView; osg::Vec3 max = osg::Vec3( bb._max[0], bb._max[1], bb._max[2] ) * projectionToView; if( trimMask & 16 ) { // trim near if( !ortho ) { // recalc frustum corners on new near plane l *= -min[2] / n; r *= -min[2] / n; b *= -min[2] / n; t *= -min[2] / n; } n = -min[2]; } if( trimMask & 32 ) // trim far f = -max[2]; if( !ortho ) { min[0] *= -n / min[2]; min[1] *= -n / min[2]; max[0] *= -n / max[2]; max[1] *= -n / max[2]; } if( l < r ) { // check for inverted X range if( l < min[0] && ( trimMask & 1 ) ) l = min[0]; if( r > max[0] && ( trimMask & 2 ) ) r = max[0]; } else { if( l > min[0] && ( trimMask & 1 ) ) l = min[0]; if( r < max[0] && ( trimMask & 2 ) ) r = max[0]; } if( b < t ) { // check for inverted Y range if( b < min[1] && ( trimMask & 4 ) ) b = min[1]; if( t > max[1] && ( trimMask & 8 ) ) t = max[1]; } else { if( b > min[1] && ( trimMask & 4 ) ) b = min[1]; if( t < max[1] && ( trimMask & 8 ) ) t = max[1]; } if( ortho ) projectionMatrix.makeOrtho( l, r, b, t, n, f ); else projectionMatrix.makeFrustum( l, r, b, t, n, f ); #endif }