3D 相机移动和旋转

3D camera movement and rotation

我有一个包含三个等距框的 3D 场景,我希望相机能够围绕相机目标旋转并沿任何方向移动,通常就像 3D 建模应用程序中的相机,但我的设置仅适用当我的相机目标位于原点时,每当我在任何方向移动相机时,我的相机位置和相机目标都会正确转换到新位置,但是我的相机仍然围绕场景的原点旋转

下图显示了我的相机目标和坐标系原点的旋转

下图显示我的相机目标向左移动,但相机相对于坐标系的原点旋转

以下是我在 x/y 平面上进行相机旋转和移动的代码:

if (event.type == SDL_MOUSEMOTION && leftMouseButtonPressed == true)
{

    New.x = event.button.x;
    New.y = event.button.y;

    delta = New - prev;


    if (delta.x != 0) {

        angleX = delta.x / 2.0f;

        rotMat = glm::mat4(1);
        rotMat =   glm::rotate(rotMat, glm::radians(angleX), up);
        cameraUp = glm::normalize(glm::vec4(up, 1) * rotMat);
        cameraRight = glm::normalize(glm::cross(cameraUp, cameraDirection));
        cameraPos = rotMat * glm::vec4(cameraPos, 1) ;
        cameraDirection = glm::normalize(cameraPos - cameraTarget);

        camera = glm::lookAt(cameraPos, cameraTarget, up);


    }





if (event.type == SDL_MOUSEMOTION && rightMouseButtonPressed == true)
{

    New.x = event.button.x;
    New.y = event.button.y;

    delta = New - prev;


    if (delta.x != 0) {

        delta.x /= 10.0f;

        translateMat = glm::mat4(1);
        translateMat = glm::translate(translateMat, cameraRight * delta.x);
        cameraPos = translateMat * glm::vec4(cameraPos, 1);
        cameraTarget = translateMat * glm::vec4(cameraTarget, 1) ;


        camera = glm::lookAt(cameraPos, cameraTarget , cameraUp);


    }

累加水平和垂直角度(偏航角和俯仰角);每次这些变化:

  • 使用 yawPitchRoll 函数创建并缓存旋转矩阵 cameraRot
  • 使用此矩阵计算并缓存相机的正面和向上方向:

    cameraDirection = cameraRot * glm::vec3(-1.0f, 0.0f, 0.0f);
    cameraUp = cameraRot * glm::vec3(0.0f, 1.0f, 0.0f);
    

    除了浮点精度问题,这些都已经标准化。

  • 然后可以使用以下方法根据目标计算相机的位置:

    cameraPos = cameraTarget - cameraDistance * cameraDirection;
    

    其中cameraDistance是目标到相机的距离。