c++ - 用 glm::Quat(ernions) 模拟 gluLookAt

标签 c++ opengl quaternions glm-math glulookat

我一直在尝试模拟 gluLookAt 功能,但使用的是四元数。我的每个游戏对象都有一个 TranslationComponent。此组件存储对象的位置 (glm::vec3)、旋转 (glm::quat) 和 < strong>scale (glm::vec3)。相机计算其每个刻度的位置,执行以下操作:

// UP = glm::vec3(0,1,0); 
//FORWARD = glm::vec3(0,0,1);
cameraPosition = playerPosition - (UP * distanceUP) - (FORWARD * distanceAway);

此位置代码如预期的那样工作,摄像机位于玩家身后 3 米处和上方 1 米处。现在,相机的四元数设置如下:

//Looking at the player's feet  
cameraRotation = quatFromToRotation(FORWARD, playerPosition); 

渲染引擎现在采用这些值并生成 ViewMatrix(相机)和 ModelMatrix(播放器),然后渲染场景。代码如下所示:

 glm::mat4 viewTranslationMatrix = 
         glm::translate(glm::mat4(1.0f), cameraTransform->getPosition());
 glm::mat4 viewScaleMatrix = 
         glm::scale(glm::mat4(1.0f), cameraTransform->getScale());
 glm::mat4 viewRotationMatrix = 
         glm::mat4_cast(cameraTransform->getRotation());

 viewMatrix = viewTranslationMatrix * viewRotationMatrix * viewScaleMatrix;

quatFromToRotation(glm::vec3 from, glm::vec3 to) 定义如下:

glm::quat quatFromToRotation(glm::vec3 from, glm::vec3 to)
{
    from = glm::normalize(from); to = glm::normalize(to);

    float cosTheta = glm::dot(from, to);
    glm::vec3 rotationAxis;

    if (cosTheta < -1 + 0.001f)
    {
        rotationAxis = glm::cross(glm::vec3(0.0f, 0.0f, 1.0f), from);
        if (glm::length2(rotationAxis) < 0.01f)
            rotationAxis = glm::cross(glm::vec3(1.0f, 0.0f, 0.0f), from);

        rotationAxis = glm::normalize(rotationAxis);
        return glm::angleAxis(180.0f, rotationAxis);
    }

    rotationAxis = glm::cross(from, to);

    float s = sqrt((1.0f + cosTheta) * 2.0f);
    float invis = 1.0f / s;

    return glm::quat(
            s * 0.5f,
            rotationAxis.x * invis,
            rotationAxis.y * invis,
            rotationAxis.z * invis
        );
}

我遇到的问题是 cameraRotation 设置不正确。无论玩家身在何处,相机的前向始终为(0,0,-1)

最佳答案

你的问题在线

//Looking at the player's feet  
cameraRotation = quatToFromRotation(FORWARD, playerPosition);

您需要从摄像机位置看向玩家的脚 - 而不是从“玩家上方一米”(假设您最初执行此操作时玩家位于 (0,0,0) ).将 FORWARD 替换为 cameraPosition:

cameraRotation = quatToFromRotation(cameraPosition, playerPosition);

编辑 我相信您的 quatToFromRotation 函数也有错误。参见 https://stackoverflow.com/a/11741520/1967396对于四元数旋转的一个非常好的解释(和一些伪代码)。

关于c++ - 用 glm::Quat(ernions) 模拟 gluLookAt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21177545/

相关文章:

c++ - 光线追踪 GLSL - 位置移动时球体拉伸(stretch)

c++ - 完全透明的OpenGL模型

c++ - 行进立方体和八叉树有什么区别?

c# - 需要带罗盘帮助的陀螺仪

javascript - Three.js 四元数 slerp 在极点附近给出了糟糕的结果

latitude-longitude - 经度/纬度到四元数

c++ - 在 OSX 10.10 上打开菜单时 Qt 系统托盘图标消失

c++ - 通过开放空间检查两个物体的连通性

c++ - 内存泄漏 C++

c++ - C/C++ 宏,用于在不使用三元运算符的情况下查找两个数的最大值