Я пытаюсь реализовать модель камеры в Delphi/OpenGL после описания, приведенного в OpenGL SuperBible. Камера имеет положение, вектор вперед и вектор вверх. Перевод камеры, кажется, работает нормально, но когда я пытаюсь повернуть камеру в соответствии с передним вектором, я теряю вид моего объекта.OpenGL: Помощь с преобразованием камеры
function TCamera.GetCameraOrientation: TMatrix4f;
var
x, z: T3DVector;
begin
z := T3DVector.Create(-FForward.X, -FForward.y, -FForward.z);
x := T3DVector.Cross(z, FUp);
result[0, 0] := x.X;
result[1, 0] := x.Y;
result[2, 0] := x.Z;
result[3, 0] := 0;
result[0, 1] := FUp.X;
result[1, 1] := FUp.Y;
result[2, 1] := FUp.Z;
result[3, 1] := 0;
result[0, 2] := z.x;
result[1, 2] := z.y;
result[2, 2] := z.z;
result[3, 2] := 0;
result[0, 3] := 0;
result[1, 3] := 0;
result[2, 3] := 0;
result[3, 3] := 1;
end;
procedure TCamera.ApplyTransformation;
var
cameraOrient: TMatrix4f;
a, b, c: TMatrix4f;
begin
cameraOrient := getcameraOrientation;
glMultMatrixf(@cameraOrient);
glTranslatef(-FPosition.x, -FPosition.y, -FPosition.z);
end;
Учитывая положение (0, 0, -15), вперед, вектор (0 0 1) и до вектора (0 1 0), я ожидал, чтобы получить идентификационную матрицу из getCameraOrientation-метода, но вместо этого я получаю
(1, 0, 0, 0)
(0, 1, 0, 0)
(0, 0, -1, 0)
(0, 0, 0, 1)
Если я изменяю вперед вектора (0 0 -1) я получаю следующую матрицу:
(-1, 0, 0, 0)
(0, 1, 0, 0)
(0, 0, 1, 0)
(0, 0, 0, 1)
После вызова glMultMatrix() и glTranslate(), glGet () дает мне следующее GL_MODELVIEW_MATRIX:
(1, 0, 0, 0)
(0, 1, 0, 0)
(0, 0, -1, 0)
(0, 0, 15, 1)
Я бы ожидал, что 15 будет в колонке 4, строка 3, столбец не 3, строка 4.
Может кто-нибудь увидеть, где я получаю это неправильно?
EDIT: Исходный код с OpenGL SuperBible:
inline void GetCameraOrientation(M3DMatrix44f m)
{
M3DVector3f x, z;
// Make rotation matrix
// Z vector is reversed
z[0] = -vForward[0];
z[1] = -vForward[1];
z[2] = -vForward[2];
// X vector = Y cross Z
m3dCrossProduct(x, vUp, z);
// Matrix has no translation information and is
// transposed.... (rows instead of columns)
#define M(row,col) m[col*4+row]
M(0, 0) = x[0];
M(0, 1) = x[1];
M(0, 2) = x[2];
M(0, 3) = 0.0;
M(1, 0) = vUp[0];
M(1, 1) = vUp[1];
M(1, 2) = vUp[2];
M(1, 3) = 0.0;
M(2, 0) = z[0];
M(2, 1) = z[1];
M(2, 2) = z[2];
M(2, 3) = 0.0;
M(3, 0) = 0.0;
M(3, 1) = 0.0;
M(3, 2) = 0.0;
M(3, 3) = 1.0;
#undef M
}
inline void ApplyCameraTransform(bool bRotOnly = false)
{
M3DMatrix44f m;
GetCameraOrientation(m);
// Camera Transform
glMultMatrixf(m);
// If Rotation only, then do not do the translation
if(!bRotOnly)
glTranslatef(-vOrigin[0], -vOrigin[1], -vOrigin[2]);
}
Он должен быть способен вращаться вокруг переднего вектора, не теряя из виду свой объект. – Nosredna
Я не вращаюсь вокруг прямого вектора, я вращаюсь в соответствии с передним вектором. В моем случае, где up прямо вверх по оси y, это будет таким же, как вращение вокруг оси y. так как вперед прямо вниз по оси z, не должно быть никакого вращения вообще. Но есть, поэтому я теряю отслеживание своего объекта .... – Vegar
Ну результирующая матрица в вашем первом случае возвращает ось z. Поскольку вы «смотрите на» положительную ось z, возврат ее будет просто «оглянуться». Итак, почему z рассчитывается из отрицательного вектора вперед вместо того, чтобы просто быть копией, если это? –