在D3D中实现第一人称视角控制
439701吧
全部回复
仅看楼主
level 7
439702 楼主
在D3D中实现第一人称视角控制 http://game.chinaitlab.com/devdoc/28097.html
--------------------------------------------------------------------------------
     这两天做了第一人称视角控制,就像quake一样用鼠标控制方向,用键盘控制左右前后。鼠标和键盘用directinput控制输入。
    
     首先,我们可以知道d3d的view矩阵有三个组成部分,分别是三个向量:眼睛所在点、眼看着的点、向上的方向。
    
     所以,我们首先定义三个向量:
    
     D3DXVECTOR3 VDot,VAtPoint,VUp;
    
     赋予初值:
    
     VDot=D3DXVECTOR3( 2.0f, 0.0f, 2.0f );
     VAtPoint=D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
     VUp=D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
    
     输入到VIEW矩阵matView:
    
     void SetView()
     {
         D3DXMatrixLookAtLH( &matView,&VDot, &VAtPoint, &VUp );
     }
    
     下面就可以开始做键盘控制前进、后退、左移、右移了:我们可以看到在这些控制中,VUp向量是不可以变化的,否则就会有斜着看的效果,只要同时控制VDot和VAtPoint两点的位置就可以了。
    
     由上图,a点就是VDot,b点就是VPoint,ac就是VUp向量。首先,我们计算前进后退:前进后退实际上就是沿着ab的方向同时移动a点和b点:
    
     第一步,计算向量ab: D3DXVec3Subtract(&ab,&VAtPoint,&VDot);
    
     第二步,计算移动的方向和步长: D3DXVec3Normalize(&pOut2,&ab);
     pOut2.x*=u; pOut2.y*=u; pOut2.z*=u;
    
     第三步,将移动的位置加到a和b两点中去,就可得到新的前后位置。
     pOut=VDot;
     D3DXVec3Add(&VDot,&pOut,&pOut2);
     pOut=VAtPoint;
     D3DXVec3Add(&VAtPoint,&pOut,&pOut2);//*/
     SetView();
    
     接下来,我们计算左右移动,实际上就是沿着abc面的法线n同时移动a和b点:
    
     第一步,计算abc面的法线向量n:D3DXVec3Cross(&pOut,&ab,&ac);
    
     其它步骤同上:
     D3DXVec3Normalize(&pOut2,&pOut);
     pOut2.x*=u;pOut2.y*=u;pOut2.z*=u;
     pOut=VDot;
     D3DXVec3Add(&VDot,&pOut,&pOut2);
     pOut=VAtPoint;
     D3DXVec3Add(&VAtPoint,&pOut,&pOut2);

2011年05月10日 19点05分 1
level 7
439702 楼主
     SetView();
    
     接下来的鼠标控制方向就不是那么简单了,它涉及到围绕空间的轴旋转空间某点,简单来说这里就是固定a点,使b点绕经过a点的一条轴线旋转:
    
     我们把方向分为水平旋转和垂直旋转,其它的方向都是这两个方向的叠加。要绕任意轴旋转变换,我们要知道旋转轴在空间的一点(VDot)和其方向数(a,b,c)(注意这里的abc和上面的不同,这里是数值而不是点),就可以求出变换矩阵。
    
     首先,是水平方向旋转,这是VAtPoint绕VUp旋转的结果:
    
     方向数必须是标准化的,即是长度为1。 D3DXVec3Normalize(&pOut,&ac);
     a=pOut.x;b=pOut.y;c=pOut.z;
     v=(float)sqrt(c*c+b*b);
    
     把VDot点移至原点:
     R=D3DXMATRIX(1,0,0,0,
                  0,1,0,0,
                  0,0,1,0,
                  -VDot.x,-VDot.y,-VDot.z,1);
     //D3DXMatrixMultiply(&R,&R2,&RT);
     R2=R;
    
    
     把现在的ab旋转至ZXO面,原来的变换矩阵是这样的:
    
     D3DXMATRIX(1,0,0,0,
                0,cos(j1),sin(j1),0,
                0,-sin(j1),cos(j1),0,
                0,0,0,1);
    
     但因为cos(j1)=c/v;sin(j1)=b/v;所以变为下面的矩阵
    
     RT=D3DXMATRIX(1,0,0,0,
                   0,c/v,b/v,0,
                   0,-b/v,c/v,0,
                   0,0,0,1);
     D3DXMatrixMultiply(&R,&R2,&RT);R2=R;
    
     同理:
    
    
     cos(j2)=v/|OA|=v/1=v (OA已经标准化了) sin(j2)=-a/|OA|=a;所以得到下面的矩阵:
    
     RT=D3DXMATRIX(v,0,a,0,
                   0,1,0,0,
                   -a,0,v,0,

2011年05月10日 19点05分 2
level 7
439702 楼主
                   0,0,0,1);
     D3DXMatrixMultiply(&R,&R2,&RT);R2=R;
    
     这时我们就可以使VAtPoint绕VUp旋转变为在新坐标系中绕Z轴转u角(弧度表示)
     RT=D3DXMATRIX((float)cos(u),(float)sin(u),0,0,
                   -(float)sin(u),(float)cos(u),0,0,
                   0,0,1,0,
                   0,0,0,1);
     D3DXMatrixMultiply(&R,&R2,&RT);R2=R;
    
     接下来进行逆变换;
     RT=D3DXMATRIX(v,0,-a,0,
                   0,1,0,0,
                   a,0,v,0,
                   0,0,0,1);
     D3DXMatrixMultiply(&R,&R2,&RT);R2=R;
    
     RT=D3DXMATRIX(1,0,0,0,
                   0,c/v,-b/v,0,
                   0,b/v,c/v,0,
                   0,0,0,1);
     D3DXMatrixMultiply(&R,&R2,&RT);R2=R;
    
     RT=D3DXMATRIX(1,0,0,0,
                   0,1,0,0,
                   0,0,1,0,
                   VDot.x,VDot.y,VDot.z,1);
     D3DXMatrixMultiply(&R,&R2,&RT);
    
     这时得到的R就是VAtPoint绕VUp旋转的变换矩阵
     D3DXVec3Transform(&Vtemp,&VAtPoint,&R);
     VAtPoint.x=Vtemp.x;VAtPoint.y=Vtemp.y;
     VAtPoint.z=Vtemp.z;
     SetView();
    
     而垂直方向的旋转原理上是一样的,但不是绕VUp旋转,而是绕abc面的法线旋转,所以开始应该先计算法线并标准化:
    
     D3DXVec3Cross(&pOut2,&ab,&VUp);
     D3DXVec3Normalize(&pOut,&pOut2);
    
     剩下的同上,但是为了限制向上和向下的范围(0    
     s1=D3DXVec3Length(&ab)*D3DXVec3Length(&VUp);
     s1=(float)acos(D3DXVec3Dot(&ab,&VUp)/s1);
     if(u>0)
     {
         if(s1<=0.018)
             return;
     }//1度
     else if(s1>=3.124)
         return;//179度
    
     这样,第一人称视角的矩阵控制就完成了。

2011年05月10日 19点05分 3
level 7
439702 楼主
2011年09月18日 04点09分 4
level 7
439702 楼主
从世界坐标系到观察坐标系的变换,该变换时摄像机变换至坐标系原点并使摄像机光轴沿着z轴正方向。
视图坐标的变换矩阵可以通过如下的D3DX函数计算得到:
D3DXMATRIX *D3DXMatrixLookAtLH(
D3DXMATRIX* pOut, // 指向返回的视图矩阵
CONST D3DXVECTOR3* pEye, // 照相机在世界坐标系的位置
CONST D3DXVECTOR3* pAt, // 照相机在世界坐标系的目标点
CONST D3DXVECTOR3* pUp // 世界坐标系的上方向(0, 1, 0) );
pEye参数指定照相机在世界坐标系中的位置,pAt参数指定照相机所观察的世界坐标系中的一个目标点,pUp参数指定3D世界中的上方向,通常设Y轴正方向为上方向,即取值为(0,1,0)。
问题:从该函数这几个参数怎么知道摄像机光轴在哪里?
http://topic.csdn.net/u/20090523/16/b75eb768-979b-4dc8-950b-243a871fd222.html
2011年09月18日 05点09分 5
level 7
439702 楼主
2011年09月18日 05点09分 6
level 7
439702 楼主
Direct3D中实现图元的鼠标拾取http://dev.gameres.com/Program/Visual/3D/pick_2004_529.htm
2011年09月19日 22点09分 7
level 7
439702 楼主
通过渲染到浮点纹理实现三维对象拾取http://edu.gamfe.com/t/24250.html
2011年09月19日 23点09分 8
level 7
439702 楼主
2011年09月20日 02点09分 9
level 7
DirectX拾取技术http://topic.csdn.net/t/20060302/17/4588837.html
D3DXVec3Unproject可以把屏幕坐标还原成3D空间的坐标。
D3DXIntersect可以对mesh进行多边形级别的pick,不过其原理还是一个空间映射和几何求交的问题。

2011年09月20日 15点09分 10
level 7
439702 楼主
请教如何在屏幕2D坐标与空间3D坐标之间转换http://topic.csdn.net/t/20041023/11/3483705.html
2011年09月21日 12点09分 11
level 7
439702 楼主
DirectX中关于鼠标拾取的问题一:D3DXIntersect();http://hi.baidu.com/ardic/blog/item/e27be9cb4d2b4381c8176835.html
2011年09月23日 07点09分 12
level 7
439702 楼主
3D模型下的鼠标拣选和碰撞检测-射线与圆的相交算法 .http://blog.csdn.net/dotnet90/article/details/6124865
2011年09月23日 19点09分 13
level 7
439702 楼主
3D图形学中的光线和包围盒想交检测http://www.docin.com/p-25414966.html
2011年09月23日 19点09分 14
level 7
439702 楼主
2011年09月23日 21点09分 15
level 7
439702 楼主
[射线与平面相交检测]http://www.game798.com/html/2007-03/3160.htm
2011年09月27日 02点09分 16
level 7
2011年10月12日 20点10分 20
level 7
439702 楼主

AABB与射线相交算法
1.根据射线起点与AABB的位置关系,选取出必须进行“线-面”相交的三个面,以前是AABB的6个面都进行了“线-面”相交测试,造成了不必要的浪费。
2.如果射线起点在AABB内,则必相交。
http://blog.sina.com.cn/s/blog_4a657c5a01000eo8.html
2011年10月20日 01点10分 21
level 7
439702 楼主
2011年10月20日 01点10分 22
level 8
Directx3d中如何把世界坐标转成屏幕坐标http://topic.csdn.net/t/20060824/09/4971438.html
2012年01月17日 01点01分 23
1 2 尾页