4
votes

I've been trying to figure out what 2 portions of code are doing in this tutorial: Keyboard and Mouse.

Specifically:

// Direction : Spherical coordinates to Cartesian coordinates conversion
glm::vec3 direction(
    cos(verticalAngle) * sin(horizontalAngle),
    sin(verticalAngle),
    cos(verticalAngle) * cos(horizontalAngle)
);

and

// Right vector
glm::vec3 right = glm::vec3(
    sin(horizontalAngle - 3.14f/2.0f),
    0,
    cos(horizontalAngle - 3.14f/2.0f)
);

I don't see how the first one is spherical -> cartesian. When I look it up, I get:

x = r * sin(theta) * cos(phi)
y = r * sin(theta) * sin(phi)
z = r * cos(theta)

I've read on Euler angles, axis-angle and quaternions none of those have shed light on what this is doing or I'm just not able to grasp what I'm reading. ;)

On the 2nd one, shouldn't the right vector just be 90 degrees to the right of the direction vector?

1
Are you passing these values to something like gluLookAt (...) or are they forming the basis of your matrix? One reason the "90 degrees to the right of direction" generalization does not work is because it could be parallel to your up vector and then you have a degenerate 3D space. gluLookAt (...) actually re-orthgonalizes the basis vectors after computing the cross-product, that way the input up and forward vectors do not have to be at 90 degrees to produce a working view matrix.Andon M. Coleman
At the end position, forward and up are passed to glm::lookAt()stewsims

1 Answers

1
votes

This has a lot to do with the tutorial maker, and how he has decided to use spherical coordinates to generate his viewing angles. His approach is interesting, but remember that you can come up with your own!

// Direction : Spherical coordinates to Cartesian coordinates conversion
glm::vec3 direction(
    cos(verticalAngle) * sin(horizontalAngle),
    sin(verticalAngle),
    cos(verticalAngle) * cos(horizontalAngle)
);

The reason that this looks different than the formula that you looked up, is because it's the same idea, but converted into a different space. The author simply wants the camera perspective to be "straight ahead" when verticalAngle == 0 && horizontalAngle == 0

Work it out yourself!

x = cos(0) * sin(0) = 0
y = sin(0)          = 0
z = cos(0) * cos(0) = 1

So, in this instance, the "look" vector of the camera is pointed directly into the z-axis, which in the case of a typical OpenGL application, would generally be considered as straight ahead (ie: Y-Axis is usually up and down).

Try calculating different angles and see how that would make the camera look vector spin around.

In the second instance, the author has taken some liberties with the formula, and defined it in a way which would only be useful in first-person games / applications. There are some 3D situations in which the camera can be oriented in a different way (a flight simulator, for example). Regardless, it's still the same idea. The author is just adjusting spherical coordinates to his own needs.

Personally, I prefer to use euler angles to do camera angles. It's a little bit more work to set up (you'll need to do some matrix math), but it's a different way of solving the same problem. But that might be more useful in a situation that goes beyond the typical FPS-game.