Search code examples
3dcameragame-physicsgame-development

3D camera movement and rotation


i have a 3D scene with three equally spaced boxes, i want the camera to be able to rotate around the camera target and move in any direction, typically like the camera in a 3D modeling application, however my setup works only when my camera target is positioned at the origin, whenever i move the camera at any direction my camera position and camera target translates to the new position correctly, however my camera still rotates around the origin of the scene

the image below shows my camera target and rotation at the origin of coordinate system enter image description here

the image below shows my camera target shifted left however the camera rotates with respect to the origin of the coordinate system enter image description here

the following is my code for camera rotation and movement on x/y plane:

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);


    }

Solution

  • Accumulate the horizontal and vertical angles (yaw and pitch); every time these change:

    • Create and cache the rotation matrix cameraRot using the yawPitchRoll function.
    • Calculate and cache the camera's front and up directions using this matrix:

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

      Save for floating point precision issues, these will already be normalized.

    • The camera's position can then be calculated from the target using:

      cameraPos = cameraTarget - cameraDistance * cameraDirection;
      

      Where cameraDistance is the distance from the target to the camera.