c++ – Arcball camera panning – how to apply mouse coordinates to position regardless of orientation


I have an Arcball camera with panning and rotation working properly; however, panning does not work as intended after rotation is happening. Here are my panning and rotation functions:

void EditorCamera::pan() {
  constexpr float panSpeed = 0.03f;

  glm::vec2 mousePos = window->getCurrentMousePosition();

  glm::vec2 mousePosDiff(mousePos - prevMousePos) * panSpeed);

  eye += glm::vec3{mousePosDiff, 0.0};
  center += glm::vec3{mousePosDiff, 0.0};
  prevMousePos = mousePos;
}

void EditorCamera::rotate() {
  glm::vec2 mousePos = window->getCurrentMousePosition();

  glm::vec2 screenToSphere{
      // horizontal = 2pi
      (2.0f * glm::pi<float>() / window->getFramebufferSize().width),
      // vertical = pi
      (glm::pi<float>() / window->getFramebufferSize().height)};

  // Convert mouse position difference to angle
  // difference for arcball
  glm::vec2 angleDiff = (mousePos - prevMousePos) * screenToSphere;

  glm::vec4 focus4 = glm::vec4(center, 1.0f);
  glm::vec4 direction4 = glm::vec4(eye, 1.0f) - focus4;

  glm::vec3 right = glm::cross(glm::vec3(eye - center), up);

  glm::mat4 rotationX = glm::rotate(glm::mat4{1.0f}, -angleDiff.x, up);
  glm::mat4 rotationY = glm::rotate(glm::mat4{1.0f}, angleDiff.y, right);

  eye = glm::vec3(rotationY * (rotationX * direction4)) + center;

  prevMousePos = mousePos;
}

void EditorCamera::update() {
  lookAt(eye, center, up);
}

Here is the output:

enter image description here

As you can see, the initial panning and rotation works as expected; however, after the rotation, the panning is happening in the wrong direction. I am trying to make it so that the panning is always based on screen’s XY axis, not scene’s XY axis. How can I calculate the vectors to match what screen space coordinates, regardless of applied orientation.



Source link

More To Explore

Share on facebook
Share on twitter
Share on linkedin
Share on email