Ich habe einen Eingabe-3D-Vektor, zusammen mit der Neigung und dem Gieren der Kamera. Kann jemand einen Link zu einer Ressource beschreiben oder bereitstellen, der mir hilft, die erforderliche Transformation und Matrixzuordnung zu verstehen und zu implementieren?Wie konvertiert man Weltkoordinaten in Kamerakoordinaten?
Antwort
Die Welt-zu-Kamera-Transformationsmatrix ist die Umkehrung der Kamera-zu-Welt-Matrix. Die Kamera-zu-Welt-Matrix ist die Kombination einer Übersetzung mit der Kameraposition und einer Drehung zur Kameraausrichtung. Wenn also M die zur Ausrichtung der Kamera entsprechende 3x3 Rotationsmatrix ist und t die Position der Kamera ist, dann ist die 4x4-Kamera-zu-Welt-Matrix ist:
M00 M01 M02 tx M10 M11 M12 ty M20 M21 M22 tz 0 0 0 1
Bitte beachte, dass ich angenommen habe, dass Vektoren sind Spaltenvektoren, die rechts multipliziert werden, um Transformationen durchzuführen. Wenn Sie die umgekehrte Konvention verwenden, stellen Sie sicher, dass Sie die Matrix transponieren.
Um M zu finden, können Sie eine der auf Wikipedia aufgelisteten Formeln verwenden, abhängig von Ihrer speziellen Konvention für Roll, Pitch und Gier. Beachten Sie, dass diese Formeln die Konvention verwenden, dass Vektoren Zeilenvektoren sind, die auf der linken Seite multipliziert werden.
Anstatt die Kamera-zu-Welt-Matrix zu berechnen und sie zu invertieren, ist eine effizientere (und numerisch stabile) Alternative, die Welt-zu-Kamera-Matrix direkt zu berechnen. Um dies zu tun, invertieren Sie einfach die Position der Kamera (durch Negieren aller 3 Koordinaten) und ihre Ausrichtung (indem Sie die Roll-, Nick- und Gierwinkel negieren und sie so einstellen, dass sie in ihren richtigen Bereichen sind) und berechnen Sie dann die Matrix Algorithmus.
Was Sie beschreiben, heißt "Perspektive Projektion" und es gibt viele Ressourcen im Internet, die die Matrix-Mathematik erklären und den dafür notwendigen Code liefern. Mit dem wikipedia page
beginnen könnten, wenn wir eine Struktur wie diese haben, um eine 4x4-Matrix zu beschreiben:
class Matrix4x4
{
public:
union
{
struct
{
Type Xx, Xy, Xz, Xw;
Type Yx, Yy, Yz, Yw;
Type Zx, Zy, Zz, Zw;
Type Wx, Wy, Wz, Ww;
};
struct
{
Vector3<Type> Right;
Type XW;
Vector3<Type> Up;
Type YW;
Vector3<Type> Look;
Type ZW;
Vector3<Type> Pos;
Type WW;
};
Type asDoubleArray[4][4];
Type asArray[16];
};
};
Wenn alles, was Sie haben Euler-Winkel ist, dh ein Winkel, die die Gier-, Nick- und Roll und einen Punkt im 3D-Raum für die Position, können Sie die Vektoren Right, Up und Look berechnen. Beachten Sie, dass Right, Up und Look nur die X-, Y-, Z-Vektoren sind, aber da dies eine Kamera ist, finde ich es einfacher, sie so zu benennen. Der einfachste Weg, um Ihre Koordinaten auf die Kameramatrix anzuwenden, besteht darin, eine Reihe von Rotationsmatrizen zu erstellen und unsere Kameramatrix mit jeder Rotationsmatrix zu multiplizieren.
Eine gute Referenz für das heißt hier: http://www.euclideanspace.com
Sobald Sie alle benötigten Drehungen angewendet haben, können Sie den Vektor-Pos auf die Position der Kamera in der Welt Raum einstellen.
Zuletzt, bevor Sie die Transformation der Kamera anwenden, müssen Sie die Kamera inverse ihrer Matrix nehmen. Dies ist, was Sie Ihre Modelview-Matrix multiplizieren werden, bevor Sie beginnen, Polygone zu zeichnen. Für die Matrix-Klasse oben wird die inverse wie folgt berechnet:
template <typename Type>
Matrix4x4<Type> Matrix4x4<Type>::OrthoNormalInverse(void)
{
Matrix4x4<Type> OrthInv;
OrthInv = Transpose();
OrthInv.Xw = 0;
OrthInv.Yw = 0;
OrthInv.Zw = 0;
OrthInv.Wx = -(Right*Pos);
OrthInv.Wy = -(Up*Pos);
OrthInv.Wz = -(Look*Pos);
return OrthInv;
}
So schließlich mit all unseren Matrix constuction aus dem Weg, würden Sie so etwas wie dies tun:
Matrix4x4<float> cameraMatrix, rollRotation, pitchRotation, yawRotation;
Vector4<float> cameraPosition;
cameraMatrix = cameraMatrix * rollRotation * pitchRotation * yawRotation;
Matrix4x4<float> invCameraMat;
invCameraMat = cameraMatrix.OrthoNormalInverse();
glMultMatrixf(invCameraMat.asArray);
Hope Diese hilft.