我刚开始学习DirectX。目前我有一个立方体和一个相机,我可以通过球体在立方体周围移动。
但是现在我想要创建一个功能,这样我可以稍微转动相机(左/右/上/下)。我很容易理解如何在2D中制作它:我可以在LookAt函数中更改X和Y并完成它。我怎么能在3D中做同样的事情?有3个尺寸,我的相机可以采取任何角度...
我想我需要找到一个垂直于相机矢量的平面,并像2D一样处理它。 Image
或者我可以更轻松地做到这一点?
答案 0 :(得分:0)
对于相机旋转,请使用D3DXMatrixLookAtLH方法。您的问题是如何计算眼睛所需的“at”或“target”。此Vector3使用2D中使用的相同trig方法计算,但仅使用额外维度。您需要一个Vector3进行旋转,其中每个组件都将围绕该轴旋转。然后使用以下方法将旋转应用于使用前面提到的方法创建的矩阵。
要在您的世界中的对象上执行相同的操作,请根据您的旋转方向使用DirectX方法D3DXMatrixRotation(X,Y,Z)。在正确定向的世界中,左右将围绕Y轴旋转,上下将围绕X轴旋转,并且将围绕Z轴进行倾斜。当然,这是矩阵旋转,而不是四元数。
记住执行旋转(或任何操作操作)以记住操作顺序(ISROT)时:
这样你就不会有看似时髦的东西。另请考虑D3DXMatrixYawPitchRoll方法。
答案 1 :(得分:0)
首先,你should read this question。
基本上,矩阵是一个包含x,y,z向量和系统位置的坐标系(在父系统的坐标内)。因此,您可以拆分矩阵,修改向量,并重新生成矩阵,而无需使用任何“LookAt”例程。但重要的是,如果在此时放置了一个物体而不是相机,则相机矩阵(视图变换)是物体矩阵(世界变换)的反转。但是,由于相机矩阵具有特殊属性(轴是垂直的并且是正常的单位长度),因此您可以简单地转置它并重新计算矩阵的“位置”部分。
我的这个旧功能将从矢量集构建相机矩阵(“视图”变换或D3DTS_VIEW)。 x
点向右,y
向上,z
向前,pos
是相机位置。
typedef D3DXVECTOR3 Vector3;
typedef D3DXMATRIX Matrix;
void vecToCameraMat(Matrix& m, const Vector3& x, const Vector3& y, const Vector3& z, const Vector3& pos){
m._11 = x.x;
m._12 = y.x;
m._13 = z.x;
m._14 = 0;
m._21 = x.y;
m._22 = y.y;
m._23 = z.y;
m._24 = 0;
m._31 = x.z;
m._32 = y.z;
m._33 = z.z;
m._34 = 0;
m._41 = - (pos.x*x.x + pos.y*x.y + pos.z*x.z);//(pos.x*x.x + pos.y*y.x + pos.z*z.x);
m._42 = - (pos.x*y.x + pos.y*y.y + pos.z*y.z);
m._43 = - (pos.x*z.x + pos.y*z.y + pos.z*z.z);
m._44 = 1;
}
将相机矩阵解构为向量:
void cameraMatToVec(Vector3& x, Vector3& y, Vector3& z, Vector3& pos, const Matrix& m){
x.x = m._11;
y.x = m._12;
z.x = m._13;
x.y = m._21;
y.y = m._22;
z.y = m._23;
x.z = m._31;
y.z = m._32;
z.z = m._33;
pos.x = -(m._41*x.x + m._42*y.x + m._43*z.x);
pos.y = -(m._41*x.y + m._42*y.y + m._43*z.y);
pos.z = -(m._41*x.z + m._42*y.z + m._43*z.z);
}
这将使用类似的矢量集构建OBJECT矩阵(即“世界”变换或D3DTS_WORLD)。
void vecToMat(Matrix& m, const Vector3& x, const Vector3& y, const Vector3& z, const Vector3& pos){
m._11 = x.x;
m._12 = x.y;
m._13 = x.z;
m._14 = 0;
m._21 = y.x;
m._22 = y.y;
m._23 = y.z;
m._24 = 0;
m._31 = z.x;
m._32 = z.y;
m._33 = z.z;
m._34 = 0;
m._41 = pos.x;
m._42 = pos.y;
m._43 = pos.z;
m._44 = 1;
}
将“对象”矩阵解构为向量集:
void matToVec(Vector3& x, Vector3& y, Vector3& z, Vector3& vpos, const Matrix& m){
x.x = m._11;
x.y = m._12;
x.z = m._13;
y.x = m._21;
y.y = m._22;
y.z = m._23;
z.x = m._31;
z.y = m._32;
z.z = m._33;
vpos.x = m._41;
vpos.y = m._42;
vpos.z = m._43;
}
对于相机,x
,y
和z
的长度应为1.0
,并且应该相互垂直。
这些例程是DirectX特定的,并假设(视图)矩阵是左撇子。
要将摄像机移动到“右侧”,您需要将矩阵分解为组件,将“x”添加到“pos”并再次构建它。如果你坚持使用“look at”,那么你必须在“view position”和“look at position”中添加“x”。
答案 2 :(得分:0)
视图转换是一个棘手的问题。通常,您有模型转换,例如,移动,旋转或缩放对象(世界变换)。
但是,视图转换是系统转换。我们可以把它想象成一个模型转换,将相机从其位置移动到原点。当然,查看逆视图转换更容易。将相机放在其位置的那个。
这就是我们要做的。假设我们有一个转换M
来定位相机。相应的视图转换是反向的:V = M^(-1)
。如果要旋转相机对象,只需将旋转矩阵乘以模型转换:
M' = R * M
在应用M
后,这会将相机旋转到其位置。相应的视图转换仍然是相反的。将反向应用于M'
会产生
V' = (M')^(-1)
= (R * M)^(-1)
= M^(-1) * R^(-1)
我们看到M^(-1)
是旧视图转换。因此:
V' = V * R^(-1)
因此,如果要旋转相机,请将旋转矩阵(负角度)乘以当前视图矩阵的右侧。
所以工作流程如下:
LookAt
方法设置视图矩阵。LookAt
方法。如果您想要上下翻转,请使用XMMatrixRotationX
。如果要左右转,请使用XMMatrixRotationY
。 XMMatrixRotationZ
会导致滚动。