Часть моего старого кода закончилась кучей неприятных хаков, чтобы заставить вещи работать «правильно», с точки зрения перемещения объектов и камеры, например, необходимость принимать «std::sin(-yaw)», а не «std::sin(yaw)» при реализации уравнений, найденных в других местах в Интернете, и тому подобное, и, как правило, во многих случаях просто запутывали все до точки следа и ошибки.
Работая с D3D11 и материалом DirectXMath (то есть левые координаты и основные строки?), что именно представляет собой предполагаемая система координат, например. если предположить, что камера находится в начале координат и смотрит вдоль желтого вектора на изображении без вращения, метки верны?
И затем, учитывая это и камеру, описываемую (x, y, z) и шаг (мышь/управление по оси Y), рыскание (мышь/управление по оси X), и предполагая, что нет другого способа, которым я должен был бы заниматься даже то, что...
Какова правильная функция для получения матрицы вида (в настоящее время я умножаю матрицу перевода и 2 матрицы поворота, умножая на проекцию, затем любые мировые матрицы для рассматриваемого объекта и транспонируя результат для использования в качестве одной константы шейдера).
Каково уравнение для получения вектора, на который смотрит камера (текущее умножение вектора (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 в разных местах? И некоторые из этих функций, которые я в конечном итоге выполнил с трассировкой и ошибкой, чтобы сделать этот бит правильным, онлайн-образцы не использовали отрицательные значения.