1
\$\begingroup\$

Can someone help me figure out how to use a Quaternion with the PerspectiveCamera in libGDX or in general? I am trying to rotate my camera around a sphere that is being drawn at (0,0,0). I am not sure how to go about setting up the quaternion correctly, manipulating it, and then applying it to the camera.

Edit: Here is what I have tried to do so far.

// This is how I set it up
Quaternion orientation = new Quaternion();
orientation.setFromAxis(Vector3.Y, 45);

// This is how I am trying to update the rotations
public void rotateX(float amount)
{
    Quaternion temp = new Quaternion();
    temp.set(Vector3.X, amount);

    orientation.mul(temp);
}

public void rotateY(float amount)
{
    Quaternion temp = new Quaternion();
    temp.set(Vector3.Y, amount);

    orientation.mul(temp);
}

public void updateCamera()
{
    // This is where I am unsure how to apply the rotations to the camera
    // I think I should update the view and projection matrices?
    camera.view.mul(orientation);
    ...
}
\$\endgroup\$
  • \$\begingroup\$ Start by looking at the docs of PerspectiveCamera and post here what you tried so far. \$\endgroup\$ – Maik Semder Dec 16 '12 at 20:41
  • \$\begingroup\$ See my edit. I have scoured the docs, and tried many different things but I'm not getting it to do anything! Pretty frustrating... \$\endgroup\$ – Alex_Hyzer_Kenoyer Dec 17 '12 at 1:23
3
\$\begingroup\$

I used 2 Quaternions.
The first rotation quaternion is used to rotate the camera up vector according to the pointer delta movement angle.
The second rotation quaternion is rotating the camera around the new camera up vector.
Note: initialX & initialY are the pointers values in touchDown(), origCameraDirection & origCameraPosition are camera.direction.cpy() & camera.position.cpy()

@Override
public boolean touchDragged(Ray unused, int x, int y, int pointerIndex) {
    super.touchDragged(unused, x, y, pointerIndex);
    float deltaX  = (initialX - x);
    float deltaY  = (initialY - y);
    float rotationAngle = 360.0f * (float)(Math.sqrt(deltaX * deltaX + deltaY * deltaY)/screenDst);
    while (rotationAngle < 0) {
        rotationAngle += 360;
    }
    while (rotationAngle > 360) {
        rotationAngle -= 360;
    }

    float alpha = (float)Math.atan2(deltaY,deltaX) * MathUtils.radiansToDegrees;

    Quaternion q = new Quaternion(origCameraDirection, alpha);
    Vector3 rotatedUp = origCameraUp.cpy();
    q.transform(rotatedUp);

    // rotatedUp is our actual rotation vector
    Quaternion actualQ = new Quaternion(rotatedUp, rotationAngle);

    Vector3 newCameraPosition = origCameraPosition.cpy(); 
    actualQ.transform(newCameraPosition);
    camera.position.set(newCameraPosition);

    Vector3 newCameraDirection = origCameraDirection.cpy(); 
    actualQ.transform(newCameraDirection);
    camera.direction.set(newCameraDirection);

    Vector3 newCameraUp = origCameraUp.cpy(); 
    actualQ.transform(newCameraUp);
    camera.up.set(newCameraUp);
    return true;
}
\$\endgroup\$
0
\$\begingroup\$

Rotate will turn the camera around the axis of the camera! When you rotate the camera around another object, you need to translate the camera, pointing it to the object. To translate the camera around an object, you need use the distance from the object e the angle to rotate. So, you must add sin(angle) in X and cos(angle) in Y.

double distance = DistanceBetween(camera, sphere);
camera.x += distance * sin(angle);
camera.y += distance * cos(angle);
\$\endgroup\$
  • 1
    \$\begingroup\$ If I could get my camera to use the quaternion at all then I will try this, because it may very well be another issues that I will need to fix. I just can't map the quaternion to my camera. \$\endgroup\$ – Alex_Hyzer_Kenoyer Dec 17 '12 at 22:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.