Standard View:
- 3Dview (default view)front viewback viewleft viewright viewtop viewbottom viewfit 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)根据场景,重新构建相机矩阵;CameraManipulator-> computeHomePosition();
(1). 计算包围球 圆心位置;
(2). 调整球心的位置,根据已有的FOV 和 frustum参数,计算出与FOV互余的角
θ
theta
θ;
(3). 并且另相机指向球心。这样就可以使得frustum能与球面相切。
(4). 根据
θ
theta
θ, 以及球半径,计算出球心到相机的距离;
(5). 重新构建相机位置矩阵,指向包络盒中心fit Z; 根据deep info 重新构建perspective matrix;
cullVisitor->clampProjectionMatrix(........);
- 部分示例
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);实现效果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)