openGL设置透视摄像机距离基于椭圆体模型上的边界框

时间:2014-08-17 17:03:33

标签: opengl math graphics geometry openscenegraph

我有一个透视相机,我正在使用它来观察由地球模型组成的3D场景。地球模型是椭圆形的。我想基于模型上的某个边界框来概述这个模型,即基本上我想对这个3D模型进行简单的2D概述。我想为此计算相机距离。

A simple diagram describing the same enter image description here

我实际上在开放场景图中这样做,所以我可以得到一个osg :: BoundingBox用于所需的场景/区域。

我使用一种非常简单的方法来计算距离。

distanceVertical = ((boundingBox.yMax - boundingBox.ymin)/2.0)/ tan(fovy/2)
distanceHorizontal = ((boundingBox.xMax - boundingBox.xmin)/2.0)/ tan(fovx/2)

cameraDistance = max(distanceVertical, distanceHorizontal)

这个计算都在世界空间,但不知怎的,它没有给我正确的距离。我在计算这个错误吗?

1 个答案:

答案 0 :(得分:0)

请注意,您无法使用宽高比将fovy(您为setProjectionMatrixAsPerspective提供的那个)直接翻译为fovx。这将假设投影是'#34;曲线"但事实并非如此,它与相机保持平坦距离。

有了这些信息,你必须找到另一种方法来计算你的情况下的x大小distanceHorizontal

由于您正在使用边界框,因此请注意,只有当摄像机位于与框中心对齐的z时,这才会起作用,因为边界框是轴对齐的。

// Assuming you fetch the aspectRatio and the fovy from the camera...
double aspectRatio = 1.0;
double fovy = degreeToRadian( 45.0 );
{
  double fovyDeg;
  double zNear; // discarded
  double zFar; // discarded
  camera->getProjectionMatrixAsPerspective( fovyDeg, aspectRatio, zNear, zFar );
  fovy = degreeToRadian( fovyDeg );
}


double halfSizeY = ((boundingBox.yMax - boundingBox.ymin) / 2.0);
double halfSizeX = ((boundingBox.xMax - boundingBox.xmin) / 2.0);

// Prevent a division by 0. 
if ( halfSizeX   == 0.0 ) halfSizeX   = 0.0001;
if ( aspectRatio == 0.0 ) aspectRatio = 0.0001;

double itemSizeRatio = halfSizeY / halfSizeX;
double distanceVertical   = halfSizeY / tan(fovy/2);
// The horizontal should be computed from the vertical value, and not from a fovx
double distanceHorizontal = distanceVertical * itemSizeRatio / aspectRatio;

cameraDistance = max(distanceVertical, distanceHorizontal);

我还没有尝试过这个解决方案,但我曾经不得不在这些方面实施一些东西。这种逻辑似乎在纸上起作用。