FPS 相机上不需要的滚动
Unwanted Roll on FPS Camera
所以最近我一直在学习使用四元数,我有一个 fps 相机,但是当从本地 up 旋转时我得到了一些 "unwanted" 滚动和正确 向量,但是我很确定这是正常的,但是如何防止它这样做呢?我尝试了 here and here 中的一些方法,但都没有用,并且在旋转相机时给出了奇怪的结果。如有任何帮助,我们将不胜感激!
void Transform::Update()
{
transform = position * glm::toMat4(quatRot) * scale;
}
void Transform::ApplyRotation(glm::vec3 rot, bool isDegr = true)
{
if (isDegr)
quatRot = glm::quat(GetRads(rot)) * quatRot;
else
quatRot = glm::quat(rot) * quatRot;
}
glm::vec3 Transform::Forward() const
{
return glm::normalize(glm::vec3(transform[2][0], transform[2][1], transform[2][2]));
}
glm::vec3 Transform::Right() const
{
return glm::normalize(glm::vec3(transform[0][0], transform[0][1], transform[0][2]));
}
glm::vec3 Transform::Up() const
{
return glm::normalize(glm::vec3(transform[1][0], transform[1][1], transform[1][2]));
}
void FPCamera::Update()
{
Transform *trans = GetOwner()->GetTransform();
Vec2_i difference = GetWindow()->GetDifference();
glm::vec3 tmpDiff(-(static_cast<float>(difference[1]) * 0.5f), -(static_cast<float>(difference[0]) * 0.5f), 0.0f);
trans->ApplyRotation(trans->Right() * tmpDiff[0]);
trans->ApplyRotation(trans->Up() * tmpDiff[1]);
view = glm::inverse(trans->GetMatrix());
}
当我使用 this solution, I didn't know I needed to use world vectors instead of local vectors for the axis angles as I found from 解决方案时,我找到了答案。
void Transform::ApplyRotation(glm::quat yaw, glm::quat pitch)
{
quatRot = pitch * quatRot * yaw;
}
void FPCamera::Update()
{
Transform *trans = GetOwner()->GetTransform();
Vec2_i difference = GetWindow()->GetDifference();
glm::vec3 tmpDiff(-(static_cast<float>(difference[1]) * 0.5f), -(static_cast<float>(difference[0]) * 0.5f), 0.0f);
trans->ApplyRotation(glm::quat(GetRads(glm::vec3(tmpDiff[0], 0.0f, 0.0f))), glm::quat(GetRads(glm::vec3(0.0f, tmpDiff[1], 0.0f))));
view = glm::inverse(trans->GetMatrix());
}
所以最近我一直在学习使用四元数,我有一个 fps 相机,但是当从本地 up 旋转时我得到了一些 "unwanted" 滚动和正确 向量,但是我很确定这是正常的,但是如何防止它这样做呢?我尝试了 here and here 中的一些方法,但都没有用,并且在旋转相机时给出了奇怪的结果。如有任何帮助,我们将不胜感激!
void Transform::Update()
{
transform = position * glm::toMat4(quatRot) * scale;
}
void Transform::ApplyRotation(glm::vec3 rot, bool isDegr = true)
{
if (isDegr)
quatRot = glm::quat(GetRads(rot)) * quatRot;
else
quatRot = glm::quat(rot) * quatRot;
}
glm::vec3 Transform::Forward() const
{
return glm::normalize(glm::vec3(transform[2][0], transform[2][1], transform[2][2]));
}
glm::vec3 Transform::Right() const
{
return glm::normalize(glm::vec3(transform[0][0], transform[0][1], transform[0][2]));
}
glm::vec3 Transform::Up() const
{
return glm::normalize(glm::vec3(transform[1][0], transform[1][1], transform[1][2]));
}
void FPCamera::Update()
{
Transform *trans = GetOwner()->GetTransform();
Vec2_i difference = GetWindow()->GetDifference();
glm::vec3 tmpDiff(-(static_cast<float>(difference[1]) * 0.5f), -(static_cast<float>(difference[0]) * 0.5f), 0.0f);
trans->ApplyRotation(trans->Right() * tmpDiff[0]);
trans->ApplyRotation(trans->Up() * tmpDiff[1]);
view = glm::inverse(trans->GetMatrix());
}
当我使用 this solution, I didn't know I needed to use world vectors instead of local vectors for the axis angles as I found from
void Transform::ApplyRotation(glm::quat yaw, glm::quat pitch)
{
quatRot = pitch * quatRot * yaw;
}
void FPCamera::Update()
{
Transform *trans = GetOwner()->GetTransform();
Vec2_i difference = GetWindow()->GetDifference();
glm::vec3 tmpDiff(-(static_cast<float>(difference[1]) * 0.5f), -(static_cast<float>(difference[0]) * 0.5f), 0.0f);
trans->ApplyRotation(glm::quat(GetRads(glm::vec3(tmpDiff[0], 0.0f, 0.0f))), glm::quat(GetRads(glm::vec3(0.0f, tmpDiff[1], 0.0f))));
view = glm::inverse(trans->GetMatrix());
}