0
votes

I initialize the camera class from the eye, target and up vectors with glm::lookAt function, then I get Yaw, Pitch and Roll values from glm::yaw and so on. I made a rotate method that takes xoffset and yoffset to rotate the camera around its target point.

void ThirdPersonCamera::Rotate(float _yaw, float _pitch) {
    view.yaw += _yaw;
    view.pitch += _pitch;
    float radius = glm::length(view.GetEye() - view.GetTarget());
    view.GetEye().x = glm::cos(glm::radians(view.yaw)) * glm::cos(glm::radians(view.pitch)) * radius;
    view.GetEye().y = glm::sin(glm::radians(view.pitch)) * radius;
    view.GetEye().z = glm::sin(glm::radians(view.yaw)) * glm::cos(glm::radians(view.pitch)) * radius;
    view.init();
}

where view.init() creates the view matrix from lookAt. the problem is that for the first rotation the eye X and Z values are exchanged so the camera jumps from its place to another one for example if the camera initialized at (0,10,10) then after first movement the eye became at (10,10,0) then it works fine.

1
Yes I know, so what is the wrong in calculations? I tried get the Yaw and Pitch from the inverse of the view matrix after initializing but I got the Y in negative . - Mohamed Moussa

1 Answers

1
votes

Obviously, glm::yaw() and so on do not do what you need. You need the inverse of your calculations for the eye. That is:

auto d = eye - target;
yaw = std::atan2(d.z, d.x);
pitch = std::asin(d.y / glm::length(d));

For the last line, make sure that the argument to asin stays within [-1, 1]. Floating-point inaccuracies might produce an argument outside of this range.