描述:
本帖最后由 wuanshi5 于 2015-12-10 11:42:34 编辑
Directx游戏开发PCC++
最近项目里面有一个需求,希望能够将摄像机按照当前的视线向左或者向右移动。 若是正常的摄像机设置只需要更改摄像机的眼睛位置即可了,项目中使用的是第三人称摄像机。但是,我们项目中使用的摄像机不是传统的摄像机。它的代码没搞明白,移动达不到预期。希望有人能够给我讲解一下,这段代码的摄像机是怎么一个形式的。最终呈现出来的摄像机效果是怎样的。如果,能提供保持视线不变移动摄像机的方案的话,自然是极好的。非常感谢。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;
解决方案1:
补充一下,上面第一步计算出来的look,然后在世界空间计算它的旋转
解决方案2: 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 =&