Jump to content
  • Advertisement
Sign in to follow this  
Suen

Camera matrix

This topic is 2401 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to "create" a camera in OpenGL by multiplying all vertices in my world with a camera matrix. As far as I've understood, to simply calculate a static camera it is enough to provide a position for the camera, its target point and its up-direction. From these three the rest can be derived. Assuming the up-direction is parallel to the world's y-axis and the direction of the camera is parallel to the z-axis I've written the following code:


glm::vec3 cameraPos(0.0f, 0.0f, -2.0f); //Camera position
glm::vec3 cameraTarget(0.0f, 0.0f, -3.0f); //Camera target

glm::vec3 lookDir = glm::normalize(cameraTarget - cameraPos); // Direction the camera is looking at
glm::vec3 upDir = glm::normalize(glm::vec3(0.0f, 1.0f, 0.0f)); //Up-direction of the camera
glm::vec3 rightDir = glm::normalize(glm::cross(lookDir, upDir)); //Calculate the third axis
glm::vec3 perpUpDir = glm::normalize(glm::cross(rightDir, lookDir)); //Recalculate the up-direction of the camera

glm::mat4 rotMat(1.0f); //4x4 identity matrix (to be rotation matrix)
rotMat[0] = glm::vec4(rightDir, 0.0f); //Add calculated vector
rotMat[1] = glm::vec4(perpUpDir, 0.0f); //Add calculated vector
rotMat[2] = glm::vec4(-lookDir, 0.0f); //Add calculated vector ********

rotMat = glm::transpose(rotMat); //Transpose the matrix
glm::mat4 transMat(1.0f); //4x4 identity matrix (to be translation matrix)
transMat[3] = glm::vec4(-cameraPos, 1.0f); //Inverse of the world position of the camera

glm::mat4 finalMatrix = rotMat*transMat; //Multiply rotation and translation matrices together to get the view matrix.


Now the code is not what is important here but I displayed it to show the steps I do, it should be pretty self-explanatory with the comments. I understand everything except one thing; why do I have to use the negative result of my camera direction (the line of code commented with *******)? If I just use lookDir then I can't see my objects but if I use -lookDir I see my objects as expected. -lookDir was used in a tutorial which most of this code was taken from but there is never an explanation for that choice.

I've seen countless of tutorials where they explain the theory of how a camera matrix is created and I've not seen one where they use -someCameraDirection instead of someCameraDirection.

So...I'm wondering if I am missing something out in the math involved here or if it's related to something else.

Share this post


Link to post
Share on other sites
Advertisement
I'm not an expert, but I think the OpenGL convention is that we look into the negative z axis. I don't think it's any deeper than that.

Share this post


Link to post
Share on other sites

I'm not an expert, but I think the OpenGL convention is that we look into the negative z axis. I don't think it's any deeper than that.


That is how I understand it as well. But assuming we start at the origin and we calculate the direction we look at by cameraTarget - cameraPos and then use the negative result of that as above we will always have (0, 0, z) instead of (0, 0, -z) which means that we are looking in the positive z-axis...or am I thinking wrong here?

Share this post


Link to post
Share on other sites
Well I managed to find an answer to this, instead I ended up with a new question which is kind of unrelated to the above however I thought I might as well ask it here to start with instead of starting a new thread.

Anyhow here's the thing. I was looking at how to transform a point in spherical coordinates to cartesian coordinates and came up with:

Inline44.gif Inline45.gif Inline46.gif
Inline47.gif Inline45.gif Inline49.gif
Inline50.gif Inline45.gif Inline52.gif

where theta is between 0..360 and phi is 0..180 degrees. I was then taking a look at the following tutorial here and when they transform from spherical to cartesian coordinates (look in the Orientation section just above the unit circle image) they do the conversion in an entirely different way compared to the description above. It's probably something simple but regardless I'm having a hard time understanding what they exactly did let alone how to visualize it. Any explanation to this would be nice.

Share this post


Link to post
Share on other sites
They don't do it in a entirely different way, they just swap cos and sin - which is just rotating theta and phi by 90 degrees - and fiddle the order of their axes. Basically they're doing the same calculation, but choosing different conventions for where measurements are made from.

Share this post


Link to post
Share on other sites
I still find it a bit hard to understand. Basically the formula above gives us the (x, y, z) coordinates in one way. If it is done as in the tutorial what exactly would differ from the above? How do they come to that conclusion? Also from what I know and that you mentioned if is that if I swap (x, y) to (-y, x) it would give a 90 degree rotation CCW. In this case you say the cos and sin are swapped...do you mean that instead of sin(theta) * sin(phi) we have cos(theta)*cos(phi)? I'm really lost in this, I feel it shouldn't be hard to understand but I still have a hard time to think of what is going on when they choose the different conventions.

I realize phi is the zenith angle and theta is the azimuth angle while r describes the distance to a point. Furthermore r*sin(phi) and r*cos(phi) in the equation are , from what I understood, from the triangle formed with the z-axis while the ones involving theta are with the triangle formed on the xy-plane if you were to project the point there. But that is about as far as I go in understanding what's going on here.

Share this post


Link to post
Share on other sites
Here's how I think of spherical coordinates. Think of the Earth and let's try to find the Cartesian coordinates of a point given latitude and longitude. We'll think of the Earth as being completely spherical and with radius 1 (which is fine because I didn't say in which units we are working).

The coordinate system I am thinking of has the North pole at (0,1,0) and the South pole at (0,-1,0). Since parallels are contained in horizontal planes, the y coordinate of a point only depends on its latitude. You can convince yourself that it's actually

y = sin(latitude)

If this is not clear, make a plot that contains a section of the Earth through a plane that contains both poles, draw the latitude as an angle with respect to the horizontal axis and see that the height of the point on the surface is sin(latitude). In that same plot, we see that the distance from that point to the North-South axis is cos(latitude). If we now ignore the y coordinate and make a plot on the x-z plane, we'll see that the parallel is a circle centered on the origin with radius cos(latitude). The points in this circle are parametrized by longitude, and the formula for a point will then be something like

x = cos(latitude)*sin(longitude)
z = cos(latitude)*cos(longitude)

You'll get slightly different formulas if you use different conventions for the coordinates.

EDIT: One more thing. You can verify that the points obtained through this formula are indeed on the sphere, by computing

y^2 + x^2 + z^2 = sin(a)^2 + cos(a)^2 * sin(b)^2 + cos(a)^2 * cos(b)^2 = sin(a)^2 + cos(a)^2 * (sin(b)^2 + cos(b)^2) = sin(a)^2 + cos(a)^2 = 1

(I used `a' and `b' instead of `latitude' and `longitude' for clarity)

Share this post


Link to post
Share on other sites
Thanks for the great explanation. I do understand it a bit better now. So basically the difference between the two coordinate conventions above is that the spherical coordinates represents changes in different directions in the world? More specifically; if you want for example the coordinate phi to represent a change in y-axis then that's one convention, if you want it to represent a change in z-axis then that's another convention? Did I understand this right when you wrote about having different conventions? Is that what TheUnbeliever meant by fiddling around with the axes?

The way I visualized it (which can be entirely wrong) was by comparing the two conventions above (the one in the tutorial and the one written in the post) but I kind of got stuck at the end of the comparison biggrin.png Assuming the vertical angle is phi and horizontal angle is theta:

In the tutorial above keeping both angles zero while changing r would affect the z-coordinate only. Changing the vertical angle (while keeping the horizontal angle zero) say..from 1..90 degrees would affect the y-coordinate while the x-coordinate stays fixed in the world. If we change the horizontal angle from 1..90 degrees (while keeping the vertical angle zero) it would affect the x-coordinate while the y-coordinate stays fixed.

In the formula in my post above keeping both angles zero gives us a change in z-axis which is the same as the convention used in the tutorial. Changing the vertical angle (while keeping the horizontal angle zero) would give us a change in x-axis(!) as opposed to in the y-axis in the other convention. However when I checked what happens if I keep the vertical angle zero (while changing the horizontal angle) I noticed that I would only be getting a change in z-axis again...and that's where I got stuck thinking this way.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!