|
osgEarth::GeoExtent getExtent(osgViewer::Viewer* view)
{
// Get the corners of all points on the view frustum. Mostly modified from osgthirdpersonview
osg::Matrixd proj = view->getCamera()->getProjectionMatrix();
osg::Matrixd mv = view->getCamera()->getViewMatrix();
osg::Matrixd invmv = osg::Matrixd::inverse( mv );
double nearPlane = proj(3,2) / (proj(2,2)-1.0);
double farPlane = proj(3,2) / (1.0+proj(2,2));
// Get the sides of the near plane.
double nLeft = nearPlane * (proj(2,0)-1.0) / proj(0,0);
double nRight = nearPlane * (1.0+proj(2,0)) / proj(0,0);
double nTop = nearPlane * (1.0+proj(2,1)) / proj(1,1);
double nBottom = nearPlane * (proj(2,1)-1.0) / proj(1,1);
// Get the sides of the far plane.
double fLeft = farPlane * (proj(2,0)-1.0) / proj(0,0);
double fRight = farPlane * (1.0+proj(2,0)) / proj(0,0);
double fTop = farPlane * (1.0+proj(2,1)) / proj(1,1);
double fBottom = farPlane * (proj(2,1)-1.0) / proj(1,1);
double dist = farPlane - nearPlane;
std::vector< osg::Vec3d > verts;
verts.reserve(9);
// Include origin?
/erts.push_back(osg::Vec3d(0., 0., 0. ));
verts.push_back(osg::Vec3d( nLeft, nBottom, -nearPlane ));
verts.push_back(osg::Vec3d( nRight, nBottom, -nearPlane ));
verts.push_back(osg::Vec3d( nRight, nTop, -nearPlane ));
verts.push_back(osg::Vec3d( nLeft, nTop, -nearPlane ));
verts.push_back(osg::Vec3d( fLeft, fBottom, -farPlane ));
verts.push_back(osg::Vec3d( fRight, fBottom, -farPlane ));
verts.push_back(osg::Vec3d( fRight, fTop, -farPlane ));
verts.push_back(osg::Vec3d( fLeft, fTop, -farPlane ));
const osgEarth::SpatialReference* srs = osgEarth::SpatialReference::create("epsg:4326");
// Compute the bounding sphere of the frustum.
osg::BoundingSphered bs;
for (unsigned int i = 0; i < verts.size(); i++)
{
osg::Vec3d world = verts[i] * invmv;
bs.expandBy( world );
}
// Get the center of the bounding sphere
osgEarth::GeoPoint center;
center.fromWorld(srs, bs.center());
double radiusDegrees = bs.radius() /= 111000.0;
double minLon = center.x() - radiusDegrees;
double minLat = osg::clampAbove(center.y() - radiusDegrees, -90.0);
double maxLon = center.x() + radiusDegrees;
double maxLat = osg::clampBelow(center.y() + radiusDegrees, 90.0);
osgEarth::GeoExtent extent(srs, minLon, minLat, maxLon, maxLat);
extent.normalize();
return extent;
}
|
|