我的一些旧代码最终出现了一堆令人讨厌的黑客行为,以使事情“正确”工作,在移动物体和相机方面,例如必须采用“std::sin(-yaw)”而不是“std::sin(yaw)”在实现在线其他地方找到的方程时,通常会让一切变得混乱,在许多情况下都达到了追踪和错误的程度。
-
使用 D3D11 和 DirectXMath 的东西(所以左手坐标和行专业?),预期的坐标系到底是什么,例如假设相机位于原点并沿着图像中的黄色矢量看而不旋转,标签是否正确?
然后考虑到这一点,以及由(x,y,z)和俯仰(y轴鼠标/控件),偏航(x轴鼠标/控件)描述的相机,并假设我没有其他方法应该做即使...
获取视图矩阵的正确函数是什么(当前我乘以一个平移矩阵和两个旋转矩阵,乘以投影,然后乘以相关对象的任何世界矩阵,并将结果转置以用作单个着色器常量)。
获取相机所观察的向量的方程是什么(当前将 (0,0,1) 向量乘以 2 中的矩阵)。
- ...以及“向上”和“向右”向量(因为即使不使用观察矩阵视图函数,似乎视锥体剔除也需要知道这些)。当前再次与 2 中的矩阵相乘。
- 根据方向矢量计算正确的俯仰和偏航标量/分量(例如,对于具有单独的俯仰/偏航关节的炮塔)。
编辑:代码示例:
//Moving a floating object with only yaw forwards (moveX,moveY,moveZ).
//Negative yaw seems wrong?
auto c = std::cosf(-yaw);
auto s = std::sinf(-yaw);
pos.x += moveX * c - moveZ * s;
pos.y += moveY;
pos.z += moveX * s + moveZ * c;
//Gets the vector the camera is looking along
//This time yaw is positive, but pitch is negative?
float c = std::cos(-pitch);
Vector3F facing(
c * std::sinf(yaw),
std::sinf(-pitch),
c * std::cosf(yaw));
//Creating the view transform matrix, everything is negative
XMMATRIX xmviewrot;
xmviewrot = XMMatrixRotationY(-yaw);
xmviewrot*= XMMatrixRotationX(-pitch);
XMMATRIX xmview;
xmview = XMMatrixTranslation(-x, -y, -z);
xmview *= xmviewrot;
XMStoreFloat4x4A(&view, xmview);
//Other vectors needed for frustum culling
XMVECTOR xmup = XMVector3Transform(XMLoadFloat4A(&UP), xmview);
XMVECTOR xmright = XMVector3Transform(XMLoadFloat4A(&RIGHT), xmview);
//Matrix for stuff that is already in world space (e.g. terrain)
XMMATRIX xmviewProj = xmview * xmproj;
//Apparently needs transposing before use on the GPU...
XMStoreFloat4x4A(&constants.transform, XMMatrixTranspose(xmviewProj));
//In the shaders
output.pos = mul(input.pos, transform);
//vertex positions for an upwards facing square with triangle strip
v0 = (x1, y, z1);
v1 = (x1, y, z2);
v2 = (x2, y, z2);
v3 = (x2, y, z1);
所以在我看来,我在这里做了一些根本性的错误,需要在不同的地方使用 -yaw 和 +yaw、-pitch 和 +pitch?其中一些功能我最终通过反复试验来完成,以获得正确的结果,在线样本没有使用负数。