3

我有一个 OpenGL 应用程序,它实现了用于导航 3D 环境的导航功能,例如 Orbit、Walk、Pan、Rotate 等。所有这些都完美无缺,使用gluPerspectivegluLookAt设置起来相当简单。

glMatrixMode GL_PROJECTION
   glLoadIdentity
   gluPerspective m_ViewAngle, m_AspectRatio, m_ClipDistance_Near, m_ClipDistance_Far          

   glMatrixMode GL_MODELVIEW
   glLoadIdentity
   gluLookAt m_Eye.X, m_Eye.Y, m_Eye.Z, m_Focus.X, m_Focus.Y, m_Focus.Z, m_ViewUP.X, m_ViewUP.Y, m_ViewUP.Z

   glCallList DisplayListIndex

类似于 CAD 软件中典型的ZoomExtentsZoomToFit命令,从任意视点(视图方向)​​,我希望能够进行缩放,以便 (1) 整个 3D 环境可见,以及 (2) 3D 环境模型填充整个视口(考虑到视口的当前大小,尽可能大)。

我知道环境的边界框(范围)(最小 XYZ,最大 XYZ)。但是,对于给定的 ViewAngle 和 AspectRatio 以及环境范围,我无法得出眼睛和焦点位置应该是什么。

也许有比使用gluLookAt更简单的方法来实现这一点。任何帮助表示赞赏!

4

2 回答 2

2

实际上它可以做得“更容易”。

您需要做的是将模型投影到平面上。然后,确定最高点和最低点(顶部 y、底部 y、最左边的 x、最右边的 x),最后确定需要多少缩放才能使这个矩形适合您实际需要的矩形。

您需要投影的平面是屏幕平面。

幸运的是,你已经在这样做了。

因此,使用您已经设置的矩阵变换模型的每个点,并确定最大点。

计算您需要多少缩放才能将其放在屏幕上。并将此缩放应用于对象的缩放

就是这样

于 2009-08-14T08:10:41.857 回答
1

将整个事物近似为一个球体,并应用以下公式乘以像素与模型单元的比率。您可以通过在已知 z 坐标处渲染单位球体来计算像素与模型单位的比率。球体的好处是,无论您从哪里看,它的宽度始终是直径。有关详细信息,请参阅透视投影

替代文字

编辑: sphere 的好处是它独立于方向。无论是盒子还是球体,您都需要指定相机矢量和向上矢量的方向。一旦你有了它,唯一的未知数就是从眼睛的角度来看的深度 z。从那里您可以通过以下方式计算眼睛的位置:

 eye := (center.x, center.y, center.z) - depth * (camera.x, camera.y, camera.z)

从公式中,Bx := Ax * Bz / Az 可以推导出Bz := Bx * Az / Ax.

让我将模型坐标 1.0 定义为 1.0m。假设距离 100.0m 的半径为 1.0m 的球体看起来有 20 像素宽。

Bz := 1.0 * 100.0 / 10
Bz := 10.0

现在假设您的边界框是 200.0m 宽,这使得 Ax 为 100.0,而您的屏幕宽度为 1024pixel,这使得 Bx 为 512pixel。

Az := (Ax / Bx) * Bz
Az := (100.0/512.0) * 10.0
Az := 1.953m

在上面的 m 和像素之间的单位转换被 Bz 吸收。

假设上向量为(0, 0, 1),相机向量为(1, 0, 0),中心为(0, 0, 0)。

eye := center - depth * camera
eye := (0, 0, 0) - 1.953 * (1, 0, 0)
eye := (-1.953, 0, 0)
于 2009-06-24T23:09:36.843 回答