我有一个OpenGL应用程序,它可以实现导航功能,如Orbit,Walk,Pan,Rotate等,用于导航3D环境。所有这一切都完美无瑕,并且使用 gluPerspective 和 gluLookAt 设置相当直接。
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软件中的典型 ZoomExtents 或 ZoomToFit 命令类似,从任意视点(视图方向),我希望能够进行缩放,以便 (1)整个3D环境是可见的,并且 (2)3D环境模型填充整个视口(在给定视口的当前大小的情况下尽可能大)。
我知道环境的边界框(范围)(最小XYZ,最大XYZ)。但是,我无法为给定的ViewAngle和AspectRatio以及环境范围推导出Eye和Focus的位置。
也许有一种比 gluLookAt 更容易实现这一目标的方法。任何帮助表示赞赏!
答案 0 :(得分:2)
实际上它可以做得更“容易”。
您需要做的是将模型投影到飞机上。然后,确定最高点和最低点(顶部y,底部y,最左边x,最右边x),最后确定在实际需要的矩形中需要多少缩放比例。
您需要投影的平面是屏幕平面。
幸运的是,你已经这样做了。
因此,使用您已设定的矩阵变换模型的每个点,并确定最大点。
计算您需要在屏幕上显示多少缩放比例。并将此缩放应用于对象的缩放
多数民众赞成
答案 1 :(得分:0)
将整个事物近似为一个球体并应用以下公式乘以除以像素 - 模型 - 单位比率。 您可以通过在已知z坐标处渲染单位球体来计算像素与模型单位比率。关于球体的好处是它的宽度总是直径,无论你从哪里看。有关详细信息,请参阅perspective projection。
编辑:关于球体的好处是它与方向无关。无论是框还是球体,您都需要指定摄像机矢量的方向和向上矢量。一旦你拥有了它,唯一未知的是从眼睛的角度来看的深度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,屏幕宽度为1024像素,这使得Bx为512像素。
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)