0

I am trying to stop my 3D character in a game engine I'm working on to be able to rotate their camera more than ~60 degrees (right now, you can clip through the floor and do a 360 degree rotation when turning the camera)

I have been researching on how to do this, and I heard about vector clamping, but the issue is that the code I am using is using "union vec2" which doesn't work with any clamping functions I found.

Is there another way of clamping or "limiting" the possible values of the vector? I want it to be able to go from min -0.60 to 0.60 max.

The original code is:

if (input.mouse.right.down)
    {
        // Fly camera.

        vec3 cameraInputDir = vec3(
            (input.keyboard['D'].down ? 1.f : 0.f) + (input.keyboard['A'].down ? -1.f : 0.f),
            (input.keyboard['E'].down ? 1.f : 0.f) + (input.keyboard['Q'].down ? -1.f : 0.f),
            (input.keyboard['W'].down ? -1.f : 0.f) + (input.keyboard['S'].down ? 1.f : 0.f)
        ) * (input.keyboard[key_shift].down ? 3.f : 1.f) * (input.keyboard[key_ctrl].down ? 0.1f : 1.f) * CAMERA_MOVEMENT_SPEED;

        vec2 turnAngle(0.f, 0.f);   
        turnAngle = vec2(-input.mouse.reldx, -input.mouse.reldy) * CAMERA_SENSITIVITY;

        quat& cameraRotation = camera->rotation;
        cameraRotation = quat(vec3(0.f, 1.f, 0.f), turnAngle.x) * cameraRotation;
        cameraRotation = cameraRotation * quat(vec3(1.f, 0.f, 0.f), turnAngle.y);

        camera->position += cameraRotation * cameraInputDir * dt;

        result = true;
    }

At the top of the code, I also defined:

float MAX_PITCH = 0.65;
float MIN_PITCH = -0.65;
float m_pitch = 0.0f;

What I have realized is that all I would need to change is turnAngle, as changing cameraRotation just changes the variable values, not the actual 3D rotation.

I tried putting a simple logic if statement that would put the value of turnAngle.x to MAX_PITCH or MIN_PITCH if it went over MAX_PITCH or MIN_PITCH;

                turnAngle = vec2(m_pitch, -input.mouse.reldy) * CAMERA_SENSITIVITY;

        if (camera->rotation.x != MAX_PITCH && camera->rotation.x != MIN_PITCH) {
            if (camera->rotation.x > MAX_PITCH) {
                std::printf("\nBigger than 0.60");
                m_pitch = MAX_PITCH;
            }
            else if (camera->rotation.x < MIN_PITCH) {
                std::printf("\nSmaller than -0.60");
                m_pitch = MIN_PITCH;
            }
            else {
                m_pitch = -input.mouse.reldx;
            }
        }

This, however detected when I had my camera over/under 0.65, and tried to set it to MAX_PITCH or MIN_PITCH, but it doesn't do it as smooth as I expected. It cuts really fast, changes direction on its own, and it's just a giant mess.

It also doesn't even keep it at MAX_PITCH or MIN_PITCH, but still lets you rotate over 90 degrees.

I have ran out of all ideas I could have thought of, so I really needed help for this one.

Also, since I am a beginner at this, it would be nice if you have a solution for me to show me how to implement it into my code.

  • 1
    This *DirectX Tool Kit* tutorial implements a simple look camera that limits angle you may want to review: https://github.com/microsoft/DirectXTK/wiki/Mouse-and-keyboard-input – Chuck Walbourn Apr 12 '23 at 18:54

0 Answers0