Original post address: http://ogldev.atspace.co.uk/www/tutorial13/tutorial13.html
In the previous tutorial, we used the default camera coordinates at the origin of the 3D coordinates. In this tutorial, we will start to discuss how to place the camera at any position in the 3D space, so that we can conveniently observe objects from different perspectives. There are three factors that determine the coordinate system of a 3D space camera: the camera's position in the 3D space, the camera's lookat direction vector, and the camera's up direction vector, we can determine the position and orientation of the 3D space camera, and then export the conversion matrix from the world coordinate system to the camera coordinate. For more information about the derivation, see another article I transferred: Create a matrix class matrix4f by using to manage all matrix operations. Pipeline. h
struct {
Vector3f Pos;
Vector3f Target;
Vector3f Up;
} m_camera;
Math3d. h
Vector3f Vector3f::Cross(const Vector3f& v) const
{
const float _x = y * v.z - z * v.y;
const float _y = z * v.x - x * v.z;
const float _z = x * v.y - y * v.x;
return Vector3f(_x, _y, _z);
}
Vector vector3f adds two functions of vector cross product. Math3d. h
Vector3f& Vector3f::Normalize()
{
const float Length = sqrtf(x * x + y * y + z * z);
x /= Length;
y /= Length;
z /= Length;
return *this;
}
Note: The right vector is calculated based on the cross product. Math3d. cpp
void Matrix4f::InitCameraTransform(const Vector3f& Target, const Vector3f& Up)
{
Vector3f N = Target;
N.Normalize();
Vector3f U = Up;
U.Normalize();
U = U.Cross(Target);
Vector3f V = N.Cross(U);
m[0][0] = U.x; m[0][1] = U.y; m[0][2] = U.z; m[0][3] = 0.0f;
m[1][0] = V.x; m[1][1] = V.y; m[1][2] = V.z; m[1][3] = 0.0f;
m[2][0] = N.x; m[2][1] = N.y; m[2][2] = N.z; m[2][3] = 0.0f;
m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = 0.0f; m[3][3] = 1.0f;
}
Pipeline. cpp
const Matrix4f* Pipeline::GetTrans()
{
Matrix4f ScaleTrans, RotateTrans, TranslationTrans, CameraTranslationTrans, CameraRotateTrans, PersProjTrans;
ScaleTrans.InitScaleTransform(m_scale.x, m_scale.y, m_scale.z);
RotateTrans.InitRotateTransform(m_rotateInfo.x, m_rotateInfo.y, m_rotateInfo.z);
TranslationTrans.InitTranslationTransform(m_worldPos.x, m_worldPos.y, m_worldPos.z);
CameraTranslationTrans.InitTranslationTransform(-m_camera.Pos.x, -m_camera.Pos.y, -m_camera.Pos.z);
CameraRotateTrans.InitCameraTransform(m_camera.Target, m_camera.Up);
PersProjTrans.InitPersProjTransform(m_persProj.FOV, m_persProj.Width, m_persProj.Height, m_persProj.zNear, m_persProj.zFar);
m_transformation = PersProjTrans * CameraRotateTrans * CameraTranslationTrans * TranslationTrans * RotateTrans * ScaleTrans;
return &m_transformation;
}
The following code moves the camera from the origin to the position (1.0, 1.0,-3.0). The camera is aligned with the position (0.45f, 0.0f, 1.0f), and the camera is in the positive direction of the Y axis. Tutorial13.cpp
Vector3f CameraPos(1.0f, 1.0f, -3.0f);
Vector3f CameraTarget(0.45f, 0.0f, 1.0f);
Vector3f CameraUp(0.0f, 1.0f, 0.0f);
p.SetCamera(CameraPos, CameraTarget, CameraUp);
After running the program, the interface is as follows: