使用世界变换矩阵让相机注视点?
Make Camera Look at point using a world transformation matrix?
这个问题的变体可能已在此站点上被问到,但我找到的 none 个答案对我的情况有效。
我正在尝试让相机注视一个点。 camera有一个world transformation matrix,用于计算front vector,最后做view matrix时眼睛的位置。我的相机像场景中的任何其他对象一样处理,因此具有世界变换。我希望能够修改这个世界变换,这应该会自动影响相机。我想实际修改此相机的世界变换,使其 "LookAt" 成为一个点。
为此,我修改了世界变换的旋转项(R in T * S * R) 这样:
void WorldTransform::SetLookAt( float x, float y, float z ) {
vec3 lookPoint = vec3 ( x, y, z );
vec3 lookDir = normalize( lookPoint - m_position );
float lookLengthOnXZ = sqrtf( lookDir.z*lookDir.z + lookDir.x*lookDir.x );
m_rotationX = degrees(atan2f( lookDir.y, lookLengthOnXZ ));
m_rotationY = degrees(atan2f( lookDir.x, lookDir.z ));
RotateAbs( m_rotationX, m_rotationY, m_rotationZ );
UpdateMatLocal( );
}
基本上,我已经有一个可以设置旋转的函数(RotateAbs()
),所以我计算俯仰角、偏航角和横滚角并传递给那里。
在计算视图矩阵时,我只是做了:
void Camera::Update( ) {
if (m_pTransform.m_pointer == nullptr) return;
vec3& position = m_pTransform->GetPosition( );
m_look = m_pTransform->GetForward( );
m_lookAt = position + m_look;
//Calculate the new matrix
m_view = glm::lookAt( position, m_lookAt, glm::vec3( 0.0f, 1.f, 0.0f ));
}
这样的作品,一段时间后相机开始偏离它应该看的地方。我做错了什么?
在 "eye" 点为相机创建一个视图 "look at" 矩阵,寻找 "at",即我的看起来像这样:
Matrix4x4<T> & LookAt(Vec3<T> const & eye, Vec3<T> const & at, Vec3<T> const & up)
{
auto d = Vec3<T>();
auto u = Vec3<T>();
auto r = Vec3<T>();
d = Unit(at - eye);
u = Unit(up);
r = Unit(Cross(d, u));
u = Cross(r, d);
v[0] = r[0]; v[1] = u[0]; v[2] = -d[0]; v[3] = 0;
v[4] = r[1]; v[5] = u[1]; v[6] = -d[1]; v[7] = 0;
v[8] = r[2]; v[9] = u[2]; v[10] = -d[2]; v[11] = 0;
v[12] = 0; v[13] = 0; v[14] = 0; v[15] = 1;
return operator *= (Math::Translate<T>(-eye[0], -eye[1], -eye[2]));
}
。有了这个,您将不需要世界矩阵来移动到 eye
。还是我误解了你的问题?
这个问题的变体可能已在此站点上被问到,但我找到的 none 个答案对我的情况有效。
我正在尝试让相机注视一个点。 camera有一个world transformation matrix,用于计算front vector,最后做view matrix时眼睛的位置。我的相机像场景中的任何其他对象一样处理,因此具有世界变换。我希望能够修改这个世界变换,这应该会自动影响相机。我想实际修改此相机的世界变换,使其 "LookAt" 成为一个点。
为此,我修改了世界变换的旋转项(R in T * S * R) 这样:
void WorldTransform::SetLookAt( float x, float y, float z ) {
vec3 lookPoint = vec3 ( x, y, z );
vec3 lookDir = normalize( lookPoint - m_position );
float lookLengthOnXZ = sqrtf( lookDir.z*lookDir.z + lookDir.x*lookDir.x );
m_rotationX = degrees(atan2f( lookDir.y, lookLengthOnXZ ));
m_rotationY = degrees(atan2f( lookDir.x, lookDir.z ));
RotateAbs( m_rotationX, m_rotationY, m_rotationZ );
UpdateMatLocal( );
}
基本上,我已经有一个可以设置旋转的函数(RotateAbs()
),所以我计算俯仰角、偏航角和横滚角并传递给那里。
在计算视图矩阵时,我只是做了:
void Camera::Update( ) {
if (m_pTransform.m_pointer == nullptr) return;
vec3& position = m_pTransform->GetPosition( );
m_look = m_pTransform->GetForward( );
m_lookAt = position + m_look;
//Calculate the new matrix
m_view = glm::lookAt( position, m_lookAt, glm::vec3( 0.0f, 1.f, 0.0f ));
}
这样的作品,一段时间后相机开始偏离它应该看的地方。我做错了什么?
在 "eye" 点为相机创建一个视图 "look at" 矩阵,寻找 "at",即我的看起来像这样:
Matrix4x4<T> & LookAt(Vec3<T> const & eye, Vec3<T> const & at, Vec3<T> const & up)
{
auto d = Vec3<T>();
auto u = Vec3<T>();
auto r = Vec3<T>();
d = Unit(at - eye);
u = Unit(up);
r = Unit(Cross(d, u));
u = Cross(r, d);
v[0] = r[0]; v[1] = u[0]; v[2] = -d[0]; v[3] = 0;
v[4] = r[1]; v[5] = u[1]; v[6] = -d[1]; v[7] = 0;
v[8] = r[2]; v[9] = u[2]; v[10] = -d[2]; v[11] = 0;
v[12] = 0; v[13] = 0; v[14] = 0; v[15] = 1;
return operator *= (Math::Translate<T>(-eye[0], -eye[1], -eye[2]));
}
。有了这个,您将不需要世界矩阵来移动到 eye
。还是我误解了你的问题?