I'm having a hard time trying to implement my "matrix system" into my engine. Which basically gives all renderable objects their own matrix, even the camera. And it's with the camera where the trouble starts. I'm not really sure of how to implement the matrix into the camera to make it work right.
Right now I only have one matrix in it's class, which transforms it like any other object in the engine.
However this matrix only takes care of the camera's own location and rotation and not the objects which might or might not be in it's view. So the other objects are not transformed correctly, if I multiply their matrices with this camera matrix. So I guess I need another matrix?
So does anyone of you guys know what/how I can solve this? I can't really get a hang of it...
Camera Matrix
Started by pago, Sep 21 2005 08:51 AM
9 replies to this topic
#1
Posted 21 September 2005 - 08:51 AM
#2
Posted 21 September 2005 - 11:56 AM
I think I know what's going wrong here.
You need to realize what matrix transformations really do. An object in your game has a transformation matrix that represents the mathematical operations involved to transform the vertices from the object's local space to world space. Let's ignore rotations and scaling for the moment as they only confuse things, and only concentrate on translations. Say your object's position is located at (10, 20, 30). Obviously, rendering the object without any transformation puts the object right in the center of the world, but since it needs to be at (10, 20, 30) you need to translate the vertices of the objects by (10, 20, 30).
Now suppose your camera is at the world's origin, so (0, 0, 0). All is fine and your object shows at location (10, 20, 30). Now if you move the camera 20 units to the right, your camera object matrix should have a translation of (20, 0, 0) (assuming 'to the right' corresponds with the positive x axis). Now, before doing any calculations, imagine where the object should be positioned relative to the camera. That means, the placement of the object in camera space, where the camera is always at (0, 0, 0). Since the object was at (10, 20, 30), and you moved the camera 20 units to the right, the object should now show at (-10, 20, 30), as if the object moved 20 units to the left. But if you multiply the object's matrix with the camera's matrix, you'll get (30, 20, 30), as if it seems either the camera moved to the left or the object to the right.
Therefore, what you need to realize is that the view matrix is the transformation from world to camera space, and not from camera space to world (like with any other object). Because what it really is is the transformation of the world with respect to the camera, not the other way around. If you move the camera to the left, the world moves to the right. If you turn the camera upwards (looking up), the world really rotates downward so the ceiling is positioned in front of you.
So if you have a camera-to-world matrix that puts the camera in the right location of the world, what you need to do is multiply the object matrices with the inverted camera matrix.
You need to realize what matrix transformations really do. An object in your game has a transformation matrix that represents the mathematical operations involved to transform the vertices from the object's local space to world space. Let's ignore rotations and scaling for the moment as they only confuse things, and only concentrate on translations. Say your object's position is located at (10, 20, 30). Obviously, rendering the object without any transformation puts the object right in the center of the world, but since it needs to be at (10, 20, 30) you need to translate the vertices of the objects by (10, 20, 30).
Now suppose your camera is at the world's origin, so (0, 0, 0). All is fine and your object shows at location (10, 20, 30). Now if you move the camera 20 units to the right, your camera object matrix should have a translation of (20, 0, 0) (assuming 'to the right' corresponds with the positive x axis). Now, before doing any calculations, imagine where the object should be positioned relative to the camera. That means, the placement of the object in camera space, where the camera is always at (0, 0, 0). Since the object was at (10, 20, 30), and you moved the camera 20 units to the right, the object should now show at (-10, 20, 30), as if the object moved 20 units to the left. But if you multiply the object's matrix with the camera's matrix, you'll get (30, 20, 30), as if it seems either the camera moved to the left or the object to the right.
Therefore, what you need to realize is that the view matrix is the transformation from world to camera space, and not from camera space to world (like with any other object). Because what it really is is the transformation of the world with respect to the camera, not the other way around. If you move the camera to the left, the world moves to the right. If you turn the camera upwards (looking up), the world really rotates downward so the ceiling is positioned in front of you.
So if you have a camera-to-world matrix that puts the camera in the right location of the world, what you need to do is multiply the object matrices with the inverted camera matrix.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.
-
Currently working on: the 3D engine for Tomb Raider.
#3
Posted 21 September 2005 - 12:47 PM
Hmm.. maybe I should explain more about what the results I get. What I basically do is this:
And this gives me the result that I can rotate my camera and look around the world just fine, but as soon as I hit that forward button on my keyboard, it moves the camera in the direction towards the box and not the direction it's facing. While if I would put the same transformation on the box instead, it would move the direction it's facing. I define the direction it's facing as it's positive Z axis.
Your answer about multiplying with the inverse of the camera matrix gave me the result that the box rotates around it's own origin rather than around the cameras origin. And when I move forward or backward it still moves towards or away from the box.
// entering render method cam.rotate(crx, cry, crz); cam.translate(cpx, cpy, cpz); glLoadMatrixf(cam.matrix); drawBox(1.0f, 1.0f, 1.0f);
And this gives me the result that I can rotate my camera and look around the world just fine, but as soon as I hit that forward button on my keyboard, it moves the camera in the direction towards the box and not the direction it's facing. While if I would put the same transformation on the box instead, it would move the direction it's facing. I define the direction it's facing as it's positive Z axis.
Your answer about multiplying with the inverse of the camera matrix gave me the result that the box rotates around it's own origin rather than around the cameras origin. And when I move forward or backward it still moves towards or away from the box.
#4
Posted 21 September 2005 - 01:14 PM
Quote
Your answer about multiplying with the inverse of the camera matrix gave me the result that the box rotates around it's own origin rather than around the cameras origin
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.
-
Currently working on: the 3D engine for Tomb Raider.
#5
Posted 21 September 2005 - 04:10 PM
No I don't think so :/
This is so strange, been looking all over the internet for tutorials and source on this subject, but none mentions the way I want it to be done. Weird...
So if it's not to much work, can someone provide an example source showing the stuff I want to do? You don't need to go over board with the math, just try to keep it in psuedo code/math or whatever making it easy to understand.
Also I think I should provide with some more of my source just to make it really clear of how I try to do it:
And none of this make the camera move towards it's camera space positive z-axis. Instead it seems to move towards the world space positive z-axis.
This is so strange, been looking all over the internet for tutorials and source on this subject, but none mentions the way I want it to be done. Weird...
So if it's not to much work, can someone provide an example source showing the stuff I want to do? You don't need to go over board with the math, just try to keep it in psuedo code/math or whatever making it easy to understand.
Also I think I should provide with some more of my source just to make it really clear of how I try to do it:
void render()
{
static float xpos = 0.0f;
static float zpos = 5.0f;
static float yrot = 0.0f;
static float xrot = 0.0f;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Transform cam;
cam.rotate(xrot, yrot, 0.0f);
cam.translate(-xpos, 0.0f, -zpos);
// i've tried this...
glLoadMatrixf(cam);
// and this...
glLoadMatrixf(cam.inverse());
drawWireBox(1.0f, 1.0f, 1.0f);
if( GetKeyState(VK_LEFT)&0x80 ){
yrot += 1.0f;
}
if( GetKeyState(VK_RIGHT)&0x80 ){
yrot -= 1.0f;
}
if( GetKeyState(VK_UP)&0x80 ){
xrot += 1.0f;
}
if( GetKeyState(VK_DOWN)&0x80 ){
xrot -= 1.0f;
}
if( GetKeyState('W')&0x80 ){
zpos += 1.0f;
}
if( GetKeyState('S')&0x80 ){
zpos -= 1.0f;
}
SwapBuffers(hDC);
}
And none of this make the camera move towards it's camera space positive z-axis. Instead it seems to move towards the world space positive z-axis.
#6
Posted 21 September 2005 - 04:19 PM
Of course it makes the camera move along the world space z-axis. Consider what's happening. You're drawing the box at world space coordinates (1, 1, 1). The first transformation that occurs is the translation, which moves the world origin so that it coincides with the camera location (xpos, 0, zpos) - i.e. this point is the camera's location in world space. Then the rotation occurs, which lines up the camera's view direction with the negative z-axis, thus completing the transformation into eye space.
In order to move the camera along its view direction, you need to explicitly calculate this direction (it is simply the negative of the third row of the camera's rotation matrix) and translate along it. I would advise against attempting to keep track of the camera's location in terms of eye space - it's easier by far to keep track of it in world space, as you are doing.
Also remember that OpenGL expects matrices in column-major order. Be sure you're not accidentally transposing a matrix someplace where it shouldn't be. I keep my matrix class in standard, row-major order throughout and then transpose every time I send it to an OpenGL function.
In order to move the camera along its view direction, you need to explicitly calculate this direction (it is simply the negative of the third row of the camera's rotation matrix) and translate along it. I would advise against attempting to keep track of the camera's location in terms of eye space - it's easier by far to keep track of it in world space, as you are doing.
Also remember that OpenGL expects matrices in column-major order. Be sure you're not accidentally transposing a matrix someplace where it shouldn't be. I keep my matrix class in standard, row-major order throughout and then transpose every time I send it to an OpenGL function.
reedbeta.com - developer blog, OpenGL demos, and other projects
#7
Posted 21 September 2005 - 04:33 PM
Ok, the problem as reedbeta showed is that you're not moving the camera along the viewing vector but along _UNKNOWN_ direction, which occurs, because of the camera rotation. The solution is simple. Just find the viewing direction that the camera matrix defines and normalize it. Then use it to calculate the new position of the camera propertly.
#8
Posted 21 September 2005 - 05:00 PM
Hmmm... I don't understand why I need to calculate the view vector of the camera, since I wouldn't need to do this if it wasn't a camera but a model, such as a box.
However it would make more sense to me if you guys mean that I need two matrices, one for the orientation and location of the "camera model" and one for it's "viewing", which you use to transform all objects(the world) around, since the camera when "active" is not an ordinary object in space, but rather the origin of space which space itself revolves around, ehh..
gahhh... I guess if nothing of what I just said made any sense that I will take the first best camera source I can find out there and use it instead.
However it would make more sense to me if you guys mean that I need two matrices, one for the orientation and location of the "camera model" and one for it's "viewing", which you use to transform all objects(the world) around, since the camera when "active" is not an ordinary object in space, but rather the origin of space which space itself revolves around, ehh..
gahhh... I guess if nothing of what I just said made any sense that I will take the first best camera source I can find out there and use it instead.
#9
Posted 21 September 2005 - 06:06 PM
If you wanted to move a box (or, let's say a spaceship) along its forward direction you would indeed have to calculate which direction it was facing. You have to keep track of its position in a different space than local coordinate space - think about it, the object's location is always (0, 0, 0) in its local space, so you can't use the local space to position it in world space. The usual local-to-world transform consists of a rotation to orient the object in the world, followed by a translation to locate the object in the world. If you do these in the opposite order, your rotation ends up orbiting the object around the world origin rather than orienting it about its own pivot point.
Note that this transformation paradigm (rotation, followed by translation) is OPPOSITE that used for the camera. Therefore, you can use an "ordinary" local-to-world matrix for the camera, allowing you to think of the camera as an object the same as all others - you then have to invert this matrix to get the world-to-camera transformation.
Note that this transformation paradigm (rotation, followed by translation) is OPPOSITE that used for the camera. Therefore, you can use an "ordinary" local-to-world matrix for the camera, allowing you to think of the camera as an object the same as all others - you then have to invert this matrix to get the world-to-camera transformation.
reedbeta.com - developer blog, OpenGL demos, and other projects
#10
Posted 21 September 2005 - 10:46 PM
Great, I think I'm finally starting to make sense of this. Thanks Reedbeta for your last post, it really turned on a light in my head which have seemed to be long forgotten.
So I finally started listening to you guys instead of thinking that there was some kind of conspiracy against me, and used the 3rd row of matrix and multiplied my translation with it and got it working nicely =) Even the inverse stuff works now =)
So big thanks to all of you guys, but don't breathe out just yet, I'm pretty sure I will come back in a day or two with another impossible question =D =P
So I finally started listening to you guys instead of thinking that there was some kind of conspiracy against me, and used the 3rd row of matrix and multiplied my translation with it and got it working nicely =) Even the inverse stuff works now =)
So big thanks to all of you guys, but don't breathe out just yet, I'm pretty sure I will come back in a day or two with another impossible question =D =P
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users











