3-osg 标准视图切换
实现功能
Standard View:
- 3Dview (default view)
- front view
- back view
- left view
- right view
- top view
- bottom view
- fit view
实现思路
说到视图变换,不得先说说MVP变换, 这里MVP 并不是(most value palyer _) 而是指的3D场景到显示窗口的三个变换矩阵; Model matrix, View Matrix, and Projection Matix;
前面直接用了OSG封装好的Camer类以及 Camera Manipulator; 这里使用标准视图,那么这个变换矩阵将手动指定; 数学原理将在其它博文分享;
- 使用 View Matrix 前6种调整视图变换;
- 本质上就是创建相机坐标系,并且指定相机指向中心坐标为(0, 0 , 0)
- View Matrix 就是从世界坐标系到相机坐标系的变换矩阵;
- 简单说一下:最本质的是场景中的实体都在世界坐标系表示的,现在需要转换相机坐标系下表示;View Matrix实际上就是从世界坐标系到相机坐标系的变换矩阵;
首先构建相机坐标系: R, U, D 分别表示相机坐标系X,Y,Z在世界坐标系下的轴向。P表示位置,至于P采用负数,是因为我们希望在操作时,屏幕内物体移动与我们操作方向一致。
T = [ R x U x D x − P x R y U y D y − P y R z U z D z − P z 0 0 0 1 ] T = \left[ \begin{matrix} R_x & U_x & D_x & -P_x\\ R_y & U_y & D_y & -P_y\\ R_z & U_z & D_z & -P_z\\ 0 & 0 & 0 & 1 \end{matrix} \right] T=⎣⎢⎢⎡RxRyRz0UxUyUz0DxDyDz0−Px−Py−Pz1⎦⎥⎥⎤
T 也就是我们能从Camera Manipulator中获取的的相机位置矩阵。则viewMatrix = T − 1 T^{-1} T−1
- fit view;
- 重置相机指向中心位置;即center(0, 0, 0)
- 根据场景,重新构建相机矩阵;
(1). 计算包围球 圆心位置;
(2). 调整球心的位置,根据已有的FOV 和 frustum参数,计算出与FOV互余的角 θ \theta θ;
(3). 并且另相机指向球心。这样就可以使得frustum能与球面相切。
(4). 根据 θ \theta θ, 以及球半径,计算出球心到相机的距离;
(5). 重新构建相机位置矩阵,指向包络盒中心 - fit Z; 根据deep info 重新构建perspective matrix;
- 部分示例
osg::Vec3d eye;
osg::Vec3d center(0.0, 0.0, 0.0);
osg::Vec3d up;
switch (type) {
case SV_Front:
{
eye = osg::Vec3d(0, -112, 0);
up = osg::Vec3d(0, 0, 1);
}
break;
//此处省略..................
case SV_ISO_X:
{
_trackball->computeHomePosition(_viewer->getCamera(), true);
_trackball->getHomePosition(eye, center, up);
}
break;
default:
break;
}
_trackball->setTransformation(eye, center, up);