Я просмотрел массу примеров кватернионов на нескольких сайтах, включая этот, но не нашел ни одного ответа на этот вопрос, так что поехали ...
Я хочу, чтобы моя камера вращалась вокруг большой сферы, и чтобы камера всегда была направлена в центр сферы. Чтобы упростить задачу, сфера расположена в точке {0,0,0} в мире. Я использую кватернион для ориентации камеры и вектор для положения камеры. Проблема в том, что положение камеры идеально вращается вокруг сферы, как и должно, но всегда смотрит в одном постоянном направлении прямо вперед, вместо того, чтобы настраиваться так, чтобы указывать на центр, когда она вращается.
Это должно быть что-то простое, но я новичок в кватернионах ... что мне не хватает?
Я использую C ++, DirectX9. Вот мой код:
// Note: g_camRotAngleYawDir and g_camRotAnglePitchDir are set to either 1.0f, -1.0f according to keypresses, otherwise equal 0.0f
// Also, g_camOrientationQuat is just an identity quat to begin with.
float theta = 0.05f;
D3DXQUATERNION g_deltaQuat( 0.0f, 0.0f, 0.0f, 1.0f );
D3DXQuaternionRotationYawPitchRoll(&g_deltaQuat, g_camRotAngleYawDir * theta, g_camRotAnglePitchDir * theta, g_camRotAngleRollDir * theta);
D3DXQUATERNION tempQuat = g_camOrientationQuat;
D3DXQuaternionMultiply(&g_camOrientationQuat, &tempQuat, &g_deltaQuat);
D3DXMatrixRotationQuaternion(&g_viewMatrix, &g_camOrientationQuat);
g_viewMatrix._41 = g_camPosition.x;
g_viewMatrix._42 = g_camPosition.y;
g_viewMatrix._43 = g_camPosition.z;
g_direct3DDevice9->SetTransform( D3DTS_VIEW, &g_viewMatrix );
[РЕДАКТИРОВАТЬ - 13 февраля 2012 г.]
Хорошо, вот мое понимание:
перемещайте камеру, используя угловую дельту для каждого кадра. Получите вектор от центра к положению камеры. Вызовите quaternionRotationBetweenVectors с единичным вектором, направленным по оси z, и целевым вектором. Затем используйте результат этой функции для ориентации матрицы обзора, и положение камеры войдет в часть трансляции матрицы обзора.
Вот новый код (вызываемый каждым кадром) ...
// This part orbits the position around the sphere according to deltas for yaw, pitch, roll
D3DXQuaternionRotationYawPitchRoll(&deltaQuat, yawDelta, pitchDelta, rollDelta);
D3DXMatrixRotationQuaternion(&mat1, &deltaQuat);
D3DXVec3Transform(&g_camPosition, &g_camPosition, &mat1);
// Эта часть регулирует ориентацию камеры так, чтобы она указывала на центр сферы
dir1 = normalize(vec3(0.0f, 0.0f, 0.0f) - g_camPosition);
QuaternionRotationBetweenVectors(&g_camOrientationQuat, vec3(0.0f, 0.0f, 1.0f), &dir1);
D3DXMatrixRotationQuaternion(&g_viewMatrix, &g_camOrientationQuat);
g_viewMatrix._41 = g_camPosition.x;
g_viewMatrix._42 = g_camPosition.y;
g_viewMatrix._43 = g_camPosition.z;
g_direct3DDevice9->SetTransform( D3DTS_VIEW, &g_viewMatrix );
... Я попробовал это решение, но безуспешно. Что я делаю неправильно?
D3DXMatrixInverse(&g_viewMatrix, NULL, &g_viewMatrix);
передSetTransform
. - person kloffy   schedule 14.02.2012