项目代码中,诡异的摄像机,希望能够将摄像机按照现在的视线水平移动,求解

烧饼兽 2015-12-10 11:22:32
最近项目里面有一个需求,希望能够将摄像机按照当前的视线向左或者向右移动。 若是正常的摄像机设置只需要更改摄像机的眼睛位置即可了,项目中使用的是第三人称摄像机。但是,我们项目中使用的摄像机不是传统的摄像机。它的代码没搞明白,移动达不到预期。
希望有人能够给我讲解一下,这段代码的摄像机是怎么一个形式的。最终呈现出来的摄像机效果是怎样的。如果,能提供保持视线不变移动摄像机的方案的话,自然是极好的。非常感谢。Pos和Target是外部传进来的。
				DXDXVECTOR3 Pos, Target;
float dx = (Pos.x-Target.x);
float dy = (Pos.y-Target.y);
float dz = (Pos.z-Target.z);

float lXZ = fsqr(dx*dx + dz*dz);
float lYZ = fsqr(dy*dy + dz*dz);
float lXY = fsqr(dy*dy + dx*dx);
float XYZ = fsqr(dy*dy + dx*dx + dz*dz);

float sinY = (dx / lXZ);
float cosY = -(dz / lXZ);
float sinX = (dy / XYZ);
float cosX = (lXZ / XYZ);
float sinZ = 0.0f;
float cosZ = 1.0f;

DXDXMATRIX dmRot, dmRotX, dmRotY, dmRotZ,
dmMov, dmView;
dmRotZ._11= cosZ ,dmRotZ._12= -sinZ ,dmRotZ._13= 0.0f ,dmRotZ._14= 0.0f;
dmRotZ._21= sinZ ,dmRotZ._22= cosZ ,dmRotZ._23= 0.0f ,dmRotZ._24= 0.0f;
dmRotZ._31= 0.0f ,dmRotZ._32= 0.0f ,dmRotZ._33= 1.0f ,dmRotZ._34= 0.0f;
dmRotZ._41= 0.0f ,dmRotZ._42= 0.0f ,dmRotZ._43= 0.0f ,dmRotZ._44= 1.0f;

dmRotY._11= cosY ,dmRotY._12= 0.0f ,dmRotY._13= -sinY ,dmRotY._14= 0.0f;
dmRotY._21= 0.0f ,dmRotY._22= 1.0f ,dmRotY._23= 0.0f ,dmRotY._24= 0.0f;
dmRotY._31= sinY ,dmRotY._32= 0.0f ,dmRotY._33= cosY ,dmRotY._34= 0.0f;
dmRotY._41= 0.0f ,dmRotY._42= 0.0f ,dmRotY._43= 0.0f ,dmRotY._44= 1.0f;

dmRotX._11= 1.0f ,dmRotX._12= 0.0f ,dmRotX._13= 0.0f ,dmRotX._14= 0.0f;
dmRotX._21= 0.0f ,dmRotX._22= cosX ,dmRotX._23= -sinX ,dmRotX._24= 0.0f;
dmRotX._31= 0.0f ,dmRotX._32= sinX ,dmRotX._33= cosX ,dmRotX._34= 0.0f;
dmRotX._41= 0.0f ,dmRotX._42= 0.0f ,dmRotX._43= 0.0f ,dmRotX._44= 1.0f;

dmMov._11= 1.0f ,dmMov._12= 0.0f ,dmMov._13= 0.0f ,dmMov._14= 0.0f;
dmMov._21= 0.0f ,dmMov._22= 1.0f ,dmMov._23= 0.0f ,dmMov._24= 0.0f;
dmMov._31= 0.0f ,dmMov._32= 0.0f ,dmMov._33= 1.0f ,dmMov._34= 0.0f;
dmMov._41= -X ,dmMov._42= -Y ,dmMov._43= -Z ,dmMov._44= 1.0f;

dmRotX = dmRotZ * dmRotX;
dmRot = dmRotY * dmRotX;
dmView = dmMov * dmRot;
...全文
242 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
烧饼兽 2015-12-22
  • 打赏
  • 举报
回复
找到解决方案了,使用D3DXMatrixPerspectiveOffCenterLH函数,能够将投影矩阵的中心偏移,然后就可以让摄像机的中心线不在屏幕中央了。不过,由于不在中心了,会导致中心线左右两边的物体看起来不怎么协调。不过,偏移量小的情况下,不明显。
烧饼兽 2015-12-11
  • 打赏
  • 举报
回复
引用 2 楼 kvls 的回复:
补充一下,上面第一步计算出来的look,然后在世界空间计算它的旋转
谢谢你的答案,不过,我发现问题所在了,原来,其实摄像机已经平移了。但是,因为3D世界的近大远小的关系。同样距离的物体,在远处的话看起来更近一些。所以,导致看起来摄像机像是没有移动一样。 不过,现在又产生了新的问题。 能不能通过某种手段,让球在不处于屏幕中间时的飞行方向是垂直于屏幕的那? 现在的情况是,实际上摄像机的视线方向和球的飞行方向是平行的,但是,在屏幕上看起来不是平行的。 我要如何做才能让球看起来是垂直于屏幕的那?
kvls 2015-12-10
  • 打赏
  • 举报
回复
补充一下,上面第一步计算出来的look,然后在世界空间计算它的旋转
kvls 2015-12-10
  • 打赏
  • 举报
回复
DXDXVECTOR3 Pos, Target; // Pos为摄像机位置,Target为摄像机看的位置 float dx = (Pos.x-Target.x); // dx dy dz 组成了Target到Pos的向量,即非Normalize的Look向量的反方向 float dy = (Pos.y-Target.y); float dz = (Pos.z-Target.z); float lXZ = fsqr(dx*dx + dz*dz); // 从这儿开始计算上面那个类Look向量分别绕X/Y/Z轴旋转的角度 float lYZ = fsqr(dy*dy + dz*dz); float lXY = fsqr(dy*dy + dx*dx); float XYZ = fsqr(dy*dy + dx*dx + dz*dz); float sinY = (dx / lXZ); float cosY = -(dz / lXZ); float sinX = (dy / XYZ); float cosX = (lXZ / XYZ); float sinZ = 0.0f; // 设定摄像机没有翻滚,即不绕Z轴旋转 float cosZ = 1.0f; // 这下面开始填充旋转矩阵 DXDXMATRIX dmRot, dmRotX, dmRotY, dmRotZ, dmMov, dmView; dmRotZ._11= cosZ ,dmRotZ._12= -sinZ ,dmRotZ._13= 0.0f ,dmRotZ._14= 0.0f; dmRotZ._21= sinZ ,dmRotZ._22= cosZ ,dmRotZ._23= 0.0f ,dmRotZ._24= 0.0f; dmRotZ._31= 0.0f ,dmRotZ._32= 0.0f ,dmRotZ._33= 1.0f ,dmRotZ._34= 0.0f; dmRotZ._41= 0.0f ,dmRotZ._42= 0.0f ,dmRotZ._43= 0.0f ,dmRotZ._44= 1.0f; dmRotY._11= cosY ,dmRotY._12= 0.0f ,dmRotY._13= -sinY ,dmRotY._14= 0.0f; dmRotY._21= 0.0f ,dmRotY._22= 1.0f ,dmRotY._23= 0.0f ,dmRotY._24= 0.0f; dmRotY._31= sinY ,dmRotY._32= 0.0f ,dmRotY._33= cosY ,dmRotY._34= 0.0f; dmRotY._41= 0.0f ,dmRotY._42= 0.0f ,dmRotY._43= 0.0f ,dmRotY._44= 1.0f; dmRotX._11= 1.0f ,dmRotX._12= 0.0f ,dmRotX._13= 0.0f ,dmRotX._14= 0.0f; dmRotX._21= 0.0f ,dmRotX._22= cosX ,dmRotX._23= -sinX ,dmRotX._24= 0.0f; dmRotX._31= 0.0f ,dmRotX._32= sinX ,dmRotX._33= cosX ,dmRotX._34= 0.0f; dmRotX._41= 0.0f ,dmRotX._42= 0.0f ,dmRotX._43= 0.0f ,dmRotX._44= 1.0f; // 这里填充平移矩阵 dmMov._11= 1.0f ,dmMov._12= 0.0f ,dmMov._13= 0.0f ,dmMov._14= 0.0f; dmMov._21= 0.0f ,dmMov._22= 1.0f ,dmMov._23= 0.0f ,dmMov._24= 0.0f; dmMov._31= 0.0f ,dmMov._32= 0.0f ,dmMov._33= 1.0f ,dmMov._34= 0.0f; dmMov._41= -X ,dmMov._42= -Y ,dmMov._43= -Z ,dmMov._44= 1.0f; // 推测上面的X/Y/Z应该等于Pos的xyz dmRotX = dmRotZ * dmRotX; // 将分别绕XYZ轴旋转的矩阵合成一个矩阵 dmRot = dmRotY * dmRotX; dmView = dmMov * dmRot; // 将旋转矩阵和位移矩阵合成视图矩阵,即最后的摄像机矩阵 那么将摄像机按照当前的视线向左或者向右移动: 1、计算right的方向,很多方法,比如可以将view空间的X向量乘View旋转的逆矩阵,或者根据你的需求来假设一些方向是不变的然后通过差乘来计算,也可以修改它上面的算法保存摄像机的几个方向向量 2、沿right方向移动摄像机位置

456

社区成员

发帖
与我相关
我的任务
社区描述
其它游戏引擎
社区管理员
  • 其它游戏引擎社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧