Opengl Model Matrix doesnt rotate around the origin after one rotation - c++

I want to rotate my model Matix in x, y, and z direction, but it rotates in an unexpected way.
I use Qt.
QMatrix4x4 mMatrix;
mMatrix.setToIdentity();
mMatrix.rotate(yAngle, QVector3D(0, 1, 0));
mMatrix.rotate(zAngle, QVector3D(0, 0, 1));
mMatrix.translate(cube->getPosition());
After the first rotation the followed rotations rotate around the base of the new model Matrix, while I want the followed rotations to rotate around the origin.
I drew a little sketch so my problem might be clearer (black shows how it is right now, green is how i want it to be):
The green arrow shows how i want it to be.

I think you will get the desired result if you simply reverse the order of calls you make on the QMatrix4x4 class. To combine the two rotations:
QMatrix4x4 mMatrix;
mMatrix.setToIdentity();
mMatrix.rotate(zAngle, QVector3D(0, 0, 1));
mMatrix.rotate(yAngle, QVector3D(0, 1, 0));
The documentation is kind of lacking, but from looking at the QMatrix4x4 source code, I'm getting the impression that it applies matrix operations the way it's more or less standard with matrix libraries that are used for OpenGL, and the way the OpenGL fixed pipeline used to work.
This means that when you combine matrices, the new matrix is multiplied from the right. As a result, when the combined matrix is applied to vectors, the last specified sub-transformation is applied to the vectors first. Or putting it differently, you specify transformations in the reverse of the order you want them applied.
In your example, it you want to rotate around the y-axis first, then around the z-axis, you need to specify the z-rotation first, then the y-rotation.

I got figured it out by myself, each object needs to have its own rotation Matrix / Quaterunion.
A new rotation around the world origin ist done by creating a rotation matrix with the wanted rotation and right multiply the exiting rotation matrix of the object.

Well, if you want the green arrow thing to happen, then it means that you want a rotation around the x-axis, 90 degrees in the negative direction (or 270 degrees in the positive direction).
To make things simple, think of it like this:
Which of the axes there remains the same? x, right? Since x doesn't change, it looks like you're rotating around the x, and you are.
Now, point your thumb towards the direction that positive x is directed at and casually close the rest of your fingers like a cylinder. The direction that those rest of your fingers curling at is the direction of the rotation.
Since you want a rotation of 90 degrees in the opposite direction that those 4 fingers of yours are curling at, or 270 in the same direction... yeah.
(1, 0, 0) would be the direction vector pointing towards the positive x. While I don't know so much about the functions you're using, my guess is that the second call should be:
mMatrix.rotate(270, QVector3D(1, 0, 0));
Instead, or optionally -90 if it supports negative values.

Related

Rotating object along all 3 axes to map to the player's camera LookAt vector

I have a simple 3D LookAt vector, and I wish to rotate the player model (a simple cube) to show where the player/cube is looking at.
For sideways camera movement I've managed to figure it out and do the following:
glTranslatef(position.x, position.y, position.z);
glRotatef(atan2(lookAt.z, lookAt.x) * 180 / PI, 0, 1, 0);
Now I know that to get up-down camera movement to map to the rendered cube model, I need to rotate the cube around it's x and z axes as well, but I can't seem to figure out what formula to use for those two.
OpenGL will rotate the whole coordinate system (whole space, not only a cube) so after first rotation you just need to rotate only around z axis.
// first rotation
glRotatef(-atan2(lookAt.z, lookAt.x) * 180 / PI, 0, 1, 0);
// second rotation
float d = sqrt(pow(lookAt.x,2) + pow(lookAt.z,2));
float pitch = atan2(lookAt.y, d);
glRotatef(pitch * 180 / PI, 0, 0, 1);
First and second rotation:
I assume your model is looking along x axis (red arrow). I also assume lookAt is given relative to the position of the model.
If you're familiar with matrix math, matrices are an easier way to think about it. If you're not familiar with matrices, this series explains how to use them to solve common game development problems: https://www.youtube.com/playlist?list=PLW3Zl3wyJwWNQjMz941uyOIq3Nw6bcDYC Getting good with matrices is a good idea if you want to be a 3D game programmer.
For your problem, you want to make a translation/rotation matrix which will transform the box to the proper place for you. You can make a translation matrix and a rotation matrix individually, and then at the end take the product of the two. I'll try to break that down.
The translation matrix is simple, if your position is then your matrix will be
To construct a rotation matrix, you need to rotate the standard basis vectors the way you want. Then when you create a matrix from those rotated basis vectors, the matrix will rotate other vectors in the same way. As an example of that, take the standard basis vectors:
Now I'm going to rotate and around by 90 degrees clockwise:
Now put them into a matrix:
and you have R is a matrix that rotates things around by 90 degrees.
In your case you want to rotate stuff such that it faces a vector that you provide. That makes things easy, we can calculate our basis vectors from that vector. If your vector is then and we can solve for the other two basis vectors using cross products. You know that the character won't ever roll their view (right?) so we can use the global up vector as well. I'll call the global up vector . In your case you're using y as the "up" dimension so the global up vector will be
Then:
In the first line you do a cross product between the view vector and the up vector to get a vector orthogonal to both - this will serve as the third basis vector after it is normalized, which is the second line. In the third line another cross product generates the second basis vector. These three vectors represent what happens when the standard basis vectors are rotated the way you want them to be. Use them as the columns in a matrix like so:
Now the last step in the math is to make a final matrix that will do both translation and rotation, and this step is easy:
Then load that matrix into OpenGL with glLoadMatrix:
glLoadMatrixf(&M);
All of this gets explained in the video series I linked as well :)

from glLookAt() to glRotatef() and gltranslatef

I need to replace the gluLookAt() operate by glRotatef() and glTranslatef() operations.
I mange to do that with gluLookAt(1,1,0,0,0,0,0,1,0); but I just guessed some number utill i got the same picture.
what is the math behind that? how can i take some random gluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upZ, upY, upZ) and change it to rotate and translate and get the same picture?
gluLookAt (...) sets up the axes and origin of your view-space.
It is far easier, in my opinion, to consider what each individual column represents than to turn this operation into a series of translations and rotations (even though fundamentally that is what happens).
To setup the orientation of your view-space, gluLookAt (...) basically computes the individual axes. At no point does it ever deal with any Euler angles like glRotatef (...) would require you to do. Given the fact that the view-space gluLookAt (...) produces is orthogonal, computing the third axis from only two is trivial.
The Z-axis (forward) is computed as the direction from eyexyz to centerxyz
The Y-axis (up) is given directly as upxyz
The X-axis (right) is computed as the cross-product between the up and forward vectors
These three axes are then stored in columns 1-3 of the matrix, X, Y, Z.
Last, since the viewing transform has position in addition to rotation, the camera's eye point is stored in the 4th column of your matrix.
Consider the following diagram from Song Ho Ahn (안성호), OpenGL Transformation:
           
Honestly, it is more convenient just to setup the matrix yourself instead of dealing with Euler angles and glRotatef (...).
I agree with Andon that finding the whole matrix is much easier. But if you still need to find the decomposition to glRotate and glTranslate, then you could follow these steps, at least for this specific setting.
We need to find a transformation that would convert the representation of a point in the xyz coordinate system into its representation in the x'y'z' coordinate system (different from transforming a point). This is the same as aligning the orange system with the blue one.
We can say two things about this transformation:
The y'z'=Uz' plane is transformed into the yz plane.
The z' axis is transformed into the z axis.
To make the transformation we do the following:
Translate the origin E to point C.
Rotate around the y' axis 90° clockwise to meet condition (2).
Rotate around the z=z' axis 45° clockwise to meet condition (1).
This can be summed up as:
glRotatef(45, 0, 0, 1);
glRotatef(90, 0, 1, 0);
glTranslatef(-1, -1, 0);

Explanation for 3D rotation about the axis. (Simple coding)

I was preparing for my test but I need help understanding rotation about the axis. In one question I am to assume a function drawHouse() which draws a wire frame house in the xy-plane as shown in this image:
We are given multiple choices of segments of code and asked which one would result in this transformed house:
The right answer is as follows: but I am not sure if the commands are executed from back to front or front to back:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(2, 1, 1);
glRotatef(90, 0, 0, 1);
glRotatef(180, 1, 0, 0);
drawHouse();
The problem is that I do not know WHICH way to rotate on WHICH axis so if anyone can give me a brief summary on that, I will be obliged.
Original question is 22 on here, PDF
Presumably you have documentation for the gl functions and the order in which the transformations get applied. If you look at the transformations in terms of the axes being fixed, then the solution only makes sense if the transformations happen in reverse order, i.e. starting with glRotatef(180, 1, 0, 0);. So the transformations would be
rotate by 180 degrees about the X axis, leavung the house pointing downwards
rotate by 90 degrees about the Z axis, leaving the house lying on the X axis as in the final image, without stretching
scale *2 along the X axis, stretching the house out
EDIT this text is completely different to the (incorrect) answer that was accepted, but I couldn't delete my answer after it was accepted.
The transformations are applied in reverse order.
The first rotation (last in the function) flips the house upside down by rotating around the x axis.
The second rotates it around the z axis so that it points right.
The final scaling function stretches it along the x axis.

Rotating a spaceship model for a space simulator/game

I been working on a space sim for sometime now.
At first I was using my own 3d engine with software rasterizer.
But I gave up when the time for implementing textures was due.
Now I started again after sometime and now I'm using Opengl (with SDL) instead to render the 3d models.
But now I hit another brick wall.
I can't figure out how to make proper rotations.
Being a space-simulator I want similar controls to a flighsim
using
glRotatef(angleX, 1.0f, 0.0f, 0.0f);
glRotatef(angleY, 0.0f, 1.0f, 0.0f);
glRotatef(angleZ, 0.0f, 0.0f, 1.0f);
or similar,
does not work properly if I rotate the model(spaceship) first 90 degrees to the left and then rotate it "up".
Instead it rolls.
Here's a image that illustrate my problem.
Image Link
I tried several tricks to try and counter this but somehow I feel I missing something.
It doesn't help either that simulator style rotation examples are almost impossible to find.
So I'm searching for examples, links and the theory of rotating a 3d model (like a spaceship, airplane).
Should I be using 3 vectors (left, up, forward) for orientation as I'm also going to have to calculate things like acceleration from thrusters and stuff that will change with the rotation (orientation?) and from the models perspective points in a direction like rocket-engines.
I'm not very good with math and trying to visualize a solution just give a headache
I'm not sure I entirely understand the situation, but it sounds like you might be describing gimbal lock. You might want to look at using quaternions to represent your rotations.
Getting this right certainly can be challenging. The problem I think you are facing is that you are using the same transformation matrices for rotations regardless of how the 'ship' is already oriented. But you don't want to rotate your ship based on how it would turn when it's facing forward, you want to rotate based on how it's facing now. To do that, you should transform your controlled turn matrices the same way you transform your ship.
For instance, say we've got three matrices, each representing the kinds of turns we want to do.
float theta = 10.0*(pi/180.0)
matrix<float> roll = [[ cos(theta), sin(theta), 0]
[ -sin(theta), cos(theta), 0]
[ 0, 0, 1]
matrix<float> pitch = [[ cos(theta), 0, sin(theta)]
[ 0, 1, 0]
[ -sin(theta), 0, cos(theta)]
matrix<float> yaw = [[1, 0, 0]
[0, cos(theta), sin(theta)]
[0, -sin(theta), cos(theta)]]
matrix<float> orientation = [[1, 0, 0]
[0, 1, 0]
[0, 0, 1]]
each which represent 10 degrees of rotation across each of the three flight attitude axes. Also we have a matrix for your ship's orientation, initially just strait forward. You will transform your ship's vertices by that orientation matrix to display it.
Then to get your orientation after a turn, you need to do just a bit of cleverness, first transform the attitude control matrices into the player's coordinates, and then apply that to the orientation to get a new orientation: something like
function do_roll(float amount):
matrix<float> local_roll = amount * (roll * orientation)
orientation = orientation * local_roll
function do_pitch(float amount):
matrix<float> local_pitch = amount * (pitch * orientation)
orientation = orientation * pitch_roll
function do_yaw(float amount):
matrix<float> local_yaw = amount * (yaw * orientation)
orientation = orientation * local_yaw
so that each time you want to rotate in one way or another, you just call one of those functions.
What you're going to want to use here is quaternions. They eliminate the strange behaviors you are experiencing. Thinking of them as a matrix on steroids with similar functionality. You CAN use matrices better than you are (in your code above) by using whatever OpenGL functionality that allows you to create a rotational matrix upon a particular rotational axis vector, but quaternions will store your rotations for future modification. For example, You start with an identity quaternion and rotate it upon a particular axis vector. The quaternion then gets translated into a world matrix for your object, but you keep the quaternion stored within your object. Next time you need to perform a rotation, then just further modify that quaternion instead of having to try and keep track of X, Y, and Z axis rotation degrees, etc.
My experience is within directx (sorry, no OpenGL experience here), though I did once run into your problem when I was attempting to rotate beachballs that were bouncing around a room & rotating as they encountered floors, walls, and each other.
Google has a bunch of options on "OpenGL Quaternion", but this, in particular, appears to be a good source:
http://gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation
As you may have guessed by now, Quaternions are great for handling cameras within your environment. Here's a great tutorial:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=Quaternion_Camera_Class
You should study 3D mathematics so that you can gain a deeper understanding of how to control rotations. If you don't know the theory it can be hard to even copy and paste correctly. Specifically texts such as 3D Math Primer(Amazon), and relevant sites like http://gamemath.com will greatly aid you in your project (and all future ones).
I understand you may not like math now, but learning the relevant arithmetic will be the best solution to your issue.
Quaternions may help, but a simpler solution may be to observe a strict order of rotations. It sounds like you're rotating around y, and then rotating around x. You must always rotate x first, then y, then z. Not that there's anything particularly special about that order, just that if you do it that way, rotations tend to work a little bit closer to how you expect them to work.
Edit: to clarify a little bit, you also shouldn't cumulatively rotate across time in the game. Each frame you should start your model out in identity position, and then rotate, x, y, then z, to that frame's new position.
General rotations are difficult. Physicist tend to use some set of so-called Euler angles to describe them. In this method a general rotation is described by three angles taken about three axis in fixed succession. But the three axis are not the X-, Y- and Z- axis of the original frame. They are often the Z-, Y- and Z- axis of the original frame (yes, it really is completely general), or two axis from the original frame followed by an axis in the intermediate frame. Many choices are available, and making sure that you are following the same convention all the way through can be a real hassle.

Making an object orbit a fixed point in directx?

I am trying to make a very simple object rotate around a fixed point in 3dspace.
Basically my object is created from a single D3DXVECTOR3, which indicates the current position of the object, relative to a single constant point. Lets just say 0,0,0.
I already calculate my angle based on the current in game time of the day.
But how can i apply that angle to the position, so it will rotate?
:(?
Sorry im pretty new to Directx.
So are you trying to plot the sun or the moon?
If so then one assumes your celestial object is something like a sphere that has (0,0,0) as its center point.
Probably the easiest way to rotate it into position is to do something like the following
D3DXMATRIX matRot;
D3DXMATRIX matTrans;
D3DXMatrixRotationX( &matRot, angle );
D3DXMatrixTranslation( &matTrans, 0.0f, 0.0f, orbitRadius );
D3DXMATRIX matFinal = matTrans * matRot;
Then Set that matrix as your world matrix.
What it does is it creates a rotation matrix to rotate the object by "angle" around the XAxis (ie in the Y-Z plane); It then creates a matrix that pushes it out to the appropriate place at the 0 angle (orbitRadius may be better off as the 3rd parameter in the translation call, depending on where your zero point is). The final line multiplies these 2 matrices together. Matrix multiplications are non commutative (ie M1 * M2 != M2 * M1). What the above does is move the object orbitRadius units along the Z-axis and then it rotates that around the point (0, 0, 0). You can think of rotating an object that is held in your hand. If orbitRadius is the distance from your elbow to your hand then any rotation around your elbow (at 0,0,0) is going to form an arc through the air.
I hope that helps, but I would really recommend doing some serious reading up on Linear Algebra. The more you know the easier questions like this will be to solve yourself :)