void ComputeAABBOnBoneVisitor::serializeBoundingBox(const osg::BoundingBox &bb, const osg::Matrix &transform, osgAnimation::Bone &b, float ratio) { osg::Vec3 center = bb.center(); double halfLenghtX = (bb._max.x() - bb._min.x()) * 0.50; double halfLenghtY = (bb._max.y() - bb._min.y()) * 0.50; double halfLenghtZ = (bb._max.z() - bb._min.z()) * 0.50; halfLenghtX *= ratio; halfLenghtY *= ratio; halfLenghtZ *= ratio; osg::BoundingBox serializedBB; serializedBB.expandBy(osg::Vec3(center.x() - halfLenghtX, center.y() + halfLenghtY, center.z() + halfLenghtZ) * transform); serializedBB.expandBy(osg::Vec3(center.x() - halfLenghtX, center.y() + halfLenghtY, center.z() - halfLenghtZ) * transform); serializedBB.expandBy(osg::Vec3(center.x() - halfLenghtX, center.y() - halfLenghtY, center.z() - halfLenghtZ) * transform); serializedBB.expandBy(osg::Vec3(center.x() - halfLenghtX, center.y() - halfLenghtY, center.z() + halfLenghtZ) * transform); serializedBB.expandBy(osg::Vec3(center.x() + halfLenghtX, center.y() + halfLenghtY, center.z() + halfLenghtZ) * transform); serializedBB.expandBy(osg::Vec3(center.x() + halfLenghtX, center.y() + halfLenghtY, center.z() - halfLenghtZ) * transform); serializedBB.expandBy(osg::Vec3(center.x() + halfLenghtX, center.y() - halfLenghtY, center.z() - halfLenghtZ) * transform); serializedBB.expandBy(osg::Vec3(center.x() + halfLenghtX, center.y() - halfLenghtY, center.z() + halfLenghtZ) * transform); b.setUserValue("AABBonBone_min", serializedBB._min); b.setUserValue("AABBonBone_max", serializedBB._max); }
osg::Vec3 Curve::mapTo( const osg::Vec3 p, osg::BoundingBox originRect, osg::BoundingBox newRect ) { osg::Vec3 newPos = p-originRect.center(); osg::Vec3 originSpace = originRect._max-originRect._min; osg::Vec3 scaleFactor = (newRect._max-newRect._min); if ( originSpace.x() ) scaleFactor.x() /= originSpace.x(); else scaleFactor.x() = 0.0; if ( originSpace.y() ) scaleFactor.y() /= originSpace.y(); else scaleFactor.y() = 0.0; if ( originSpace.z() ) scaleFactor.z() /= originSpace.z(); else scaleFactor.z() = 0.0; newPos = osg::Vec3(newPos.x()*scaleFactor.x(), newPos.y()*scaleFactor.y(), newPos.z()*scaleFactor.z()); return newPos+newRect.center(); }
bool DebugShadowMap::ViewData::DebugBoundingBox ( const osg::BoundingBox & bb, const char * name ) { bool result = false; #if defined( _DEBUG ) || defined( DEBUG ) if( !name ) name = ""; osg::BoundingBox & bb_prev = _boundingBoxMap[ std::string( name ) ]; result = bb.center() != bb_prev.center() || bb.radius() != bb_prev.radius(); if( result ) std::cout << "Box<" << name << "> (" << ( bb._max._v[0] + bb._min._v[0] ) * 0.5 << " " << ( bb._max._v[1] + bb._min._v[1] ) * 0.5 << " " << ( bb._max._v[2] + bb._min._v[2] ) * 0.5 << ") [" << ( bb._max._v[0] - bb._min._v[0] ) << " " << ( bb._max._v[1] - bb._min._v[1] ) << " " << ( bb._max._v[2] - bb._min._v[2] ) << "] " << std::endl; bb_prev = bb; #endif return result; }
void MxCore::lookAtAndFit( const osg::BoundingBox& bb ) { // We'll get the view matrix to project the bounding box, so pre-configure it // to point at the box center. Eye position doesn't matter at this point (we // compute the eye position at the end of the function). osg::Vec3d newDir = bb.center() - _position; newDir.normalize(); setDir( newDir ); // Ttransform the bounding box vertices into eye space, // then determine their x and y extents. We'll compare the eye // space bb aspect ratio against the projection _aspect to // determine the critical axis to fit. osg::ref_ptr< osg::Vec3Array > corners = new osg::Vec3Array; corners->resize( 8 ); ( *corners )[ 0 ].set( bb._min ); ( *corners )[ 1 ].set( bb._max.x(), bb._min.y(), bb._min.z() ); ( *corners )[ 2 ].set( bb._max.x(), bb._min.y(), bb._max.z() ); ( *corners )[ 3 ].set( bb._min.x(), bb._min.y(), bb._max.z() ); ( *corners )[ 4 ].set( bb._max ); ( *corners )[ 5 ].set( bb._min.x(), bb._max.y(), bb._max.z() ); ( *corners )[ 6 ].set( bb._min.x(), bb._max.y(), bb._min.z() ); ( *corners )[ 7 ].set( bb._max.x(), bb._max.y(), bb._min.z() ); osgwTools::transform( getInverseMatrix(), corners.get() ); // The 'corners' array of bb verts are now in eye space. // Determine max and min values for eye space x and y osg::Vec2 minEC( FLT_MAX, FLT_MAX ), maxEC( FLT_MIN, FLT_MIN ); unsigned int idx; for( idx=0; idx<8; idx++ ) { const osg::Vec3& v( ( *corners )[ idx ] ); minEC[ 0 ] = osg::minimum< float >( v.x(), minEC[ 0 ] ); minEC[ 1 ] = osg::minimum< float >( v.y(), minEC[ 1 ] ); maxEC[ 0 ] = osg::maximum< float >( v.x(), maxEC[ 0 ] ); maxEC[ 1 ] = osg::maximum< float >( v.y(), maxEC[ 1 ] ); } // aspect is width (x) over height (y). const double ecWidth( maxEC[ 0 ] - minEC[ 0 ] ); const double ecHeight( maxEC[ 1 ] - minEC[ 1 ] ); const double ecAspect = ecWidth / ecHeight; // We'll store half the extent of interest into a dummy bounding sphere's radius. // We'll store the analogous fov in bestFov. osg::BoundingSphere bs; double bestFov; if( ecAspect > _aspect ) { // Fit eye space x to the view bs.radius() = ecWidth * .5; bestFov = _aspect * _fovy; } else { // Fit eye space y to the view bs.radius() = ecHeight * .5; bestFov = _fovy; } // The wrap-up code sets the eye position at the best distance from // the bb center. Extra distance is added in to account for the fact // that the input bound probably has a larger radius than the eye coord // bound that we're passing to computeInitialDistanceFromFOVY(). const double extraDistance = bb.radius() - bs.radius(); const double distance = extraDistance + osgwMx::computeInitialDistanceFromFOVY( bs, bestFov ); setPosition( bs.center() - ( newDir * distance ) ); }