Disfigurement When Rotating Objects

To start off, I'm not using glRotate() nor do I want to. With that said, I'm trying to make the gun in my game move along with the player and have been moderately successful as of now. I have the gun moving around and staying 'stuck' to the lower right side of the screen but it does not rotate with the camera, i.e. it won' always point towards the crosshair. I have a function that rotates vectors (of which my vertices are) and so I tried using that. It works to some extent. It rotates along with it, but tends to shrink the object on the Y axis until it becomes a plane. If I rotate faster, I can even get some weird results. Is this a result of my code being bad, inefficient, both, or neither?

Here are the functions in use (Mesh::Rotate(), Vector::Rotate(), and Mesh::Update()). The way I track the mesh is VERY messy and that could be it as well. I'm trying to store vectors and distances and the center and create the vertices but that's not helping keep them from shrinking in.

I've also posted the "broken" program up on my site as SimEngine Problem if you'd like to see what I mean.

Code:

Mesh crate[6];
....
//this code is called to rotate the mesh (not the gun, but has the same problem and simpler code)
crate[5].RotateAround(crate[5].GetCenter(),-5*FrameInterval,0,1,0)

It looks like your code is directly modying the mesh's vertex positions- due to numerical inaccuracy, your object will eventually lose its shape if you do this, which is why each vertex is typically tranformed each frame by some sort of matrix while keeping its original object space position. You need to do this both for your physics and graphics engine (OpenGL makes the graphics part easier with its matrix operations, but your physics engine will need to do this too.)

phydeaux Wrote:It looks like your code is directly modying the mesh's vertex positions- due to numerical inaccuracy, your object will eventually lose its shape if you do this, which is why each vertex is typically tranformed each frame by some sort of matrix while keeping its original object space position. You need to do this both for your physics and graphics engine (OpenGL makes the graphics part easier with its matrix operations, but your physics engine will need to do this too.)

I know this is off topic but:
Why would you perform the exact same operations twice? If you have to know where your mesh is going to be for physics purposes, why not just pass that information to openGL?

There was a long silence...
'I claim them all,' said the Savage at last.

hangt5 Wrote:I know this is off topic but:
Why would you perform the exact same operations twice? If you have to know where your mesh is going to be for physics purposes, why not just pass that information to openGL?

Sure, if the information is not changing, you might as well only compute it once. But if you transform the vertices in-place every frame, the overall shape of the object will eventually collapse due to numerical inaccuracy.

Also, for a given object, it's more expensive to send every vertex position to the graphics card each frame rather than keep that information on the graphics card and simply supply a different matrix transformation every frame.

Ok so if im cumulatively transforming the object it will deform. But why cant i just keep track of what transformations i do, and start from scratch every frame?...Its just cheaper to just let openGL do it after i do it?

There was a long silence...
'I claim them all,' said the Savage at last.

hangt5 Wrote:Ok so if im cumulatively transforming the object it will deform. But why cant i just keep track of what transformations i do, and start from scratch every frame?...Its just cheaper to just let openGL do it after i do it?

I'm not sure what you mean by this. You still can cumulatively keep track of what transformation is being performed, but you keep that information in a matrix instead of in the vertex positions of your model. The model keeps the same (object space) positions for all time, but then you have a transformation matrix (This will usually be the same as the modelview matrix in OpenGL) that you can apply to object space positions every physics step to get their world space positions (after which you can perform collision detection.) So with this collision detection step, the cpu and graphics card will be performing redundant work, but it's faster than sending each vertex to the graphics card since that redundant work is essentially free (the graphics card will transform each vertex by a matrix anyway each frame.)

Nick Wrote:How could I use a matrix to represent the transformation?

If you don't feel like writing a complete matrix transformation class, you can actually have OpenGL do quite a bit of the work for you. If you have created a modelview matrix that moves your objects to where you want, you can then use glGetParameterd(MODELVIEW_MATRIX) (or something like that) you can get the OpenGL matrix, which you can then multiply by each of your vertices to get their world space positions. Again, you need to do this each physics step, and leave the original positions intact, or else they will eventually lose shape due to numerical inaccuracy.

I guess I phrased the question poorly. If I have, say, a cube sitting with the center at (0,0,0) and each vertex being a +1 or -1 in the directions (so I'd have (1,1,1), (-1,1,1), (1,1,-1), (-1,1,-1), (1,0,1), (-1,0,1), (1,0,-1), and (-1,0,-1)). I have the center and each vertex stored as a vector containing the X,Y, and Z for each, what would the matrix look like that...
1) Moved the cube along an axis?
2) Rotated the cube?
3) Scaled the cube?

This is an example of how to pass the orientation matrix of the camera to OpenGL. The matrix is a 4 x 4 array, but bear in mind that C++ uses row major matrices, and OpenGL uses column major matrices, so you need to store you array items in the proper order, or transpose the matrix before you pass it to OpenGL. OpenGL sees the array as a linear array with 16 items. The camera orientation matrix must be inverted before you pass it to OpenGL. If you are working with quaternions, get the conjugate of the camera quaternion (w, -x, -y, -z) to calculate the orientation matrix that you will pass to OpenGL.

I think I understand all of that. Let me ask one more question before I go ripping into my code to convert a whole bunch of stuff from absolute coordinates to relative coordinates:

Say I have this crate which has the same points as above. Let's say the vertices are simply stored as an array of vectors V[8] within the mesh. If the mesh needs to be rotated 45 degress on the y axis and moved along the x axis at the same time, how do I find a combined matrix? Or do I simply use two?