rotate around own axis
I definitely have to stop using Euler angles as ive spotted more problems; specifically with moving in the direction your pointing. Eg, if you rotate 180 around y and then rotate 180 around x, so essentially your pointing the same way you started; but it will mess up the move ability as it still acts as though you are facing the opposite direction.
On a side note, I think there is a typo in the Matrices tutorial:
struct Matrix {
float m[16];
}
typedef struct Matrix Matrix;
should be:
struct Matrix {
float m[16];
};
typedef struct Matrix Matrix;
it took me a while to spot it. Mainly cos Im still new to C
On a side note, I think there is a typo in the Matrices tutorial:
struct Matrix {
float m[16];
}
typedef struct Matrix Matrix;
should be:
struct Matrix {
float m[16];
};
typedef struct Matrix Matrix;
it took me a while to spot it. Mainly cos Im still new to C
Ooh, good catch. Thanks! Will fix...
ok, I think Ive got the rotation code figured out. Fairly simple when it came to it
Im still maintaining my eular angles but here's what im doing:
quat = quaternion_from_euler(viewAngle.x/RAD_TO_DEG, viewAngle.y/RAD_TO_DEG, viewAngle.z/RAD_TO_DEG);
Quaternion_toAxisAngle(quat, &newV, &myangle);
Matrix matrix;
matrix = Quaternion_toMatrix(quat);
glMultMatrixf(matrix.m);
But like I said earlier, Im still having problems moving forward in the direction you are pointing. Im currently doing:
viewSpeed.x =cos((viewAngle.y+270)/RAD_TO_DEG);
viewSpeed.y =cos((viewAngle.x+90)/RAD_TO_DEG);
viewSpeed.z =((cos((viewAngle.y+180)/RAD_TO_DEG)/2) + (cos((viewAngle.x+90)/RAD_TO_DEG))/2);
viewPosition.x+=viewSpeed.x;
viewPosition.y+=viewSpeed.y;
viewPosition.z+=viewSpeed.z;
But, as i mentioned earlier this really messes up and rotating x around 180 and then y around 180, as it moves me further away instead of closer to. Is there a better a way of doing this?
Thanks again!
Im still maintaining my eular angles but here's what im doing:
quat = quaternion_from_euler(viewAngle.x/RAD_TO_DEG, viewAngle.y/RAD_TO_DEG, viewAngle.z/RAD_TO_DEG);
Quaternion_toAxisAngle(quat, &newV, &myangle);
Matrix matrix;
matrix = Quaternion_toMatrix(quat);
glMultMatrixf(matrix.m);
But like I said earlier, Im still having problems moving forward in the direction you are pointing. Im currently doing:
viewSpeed.x =cos((viewAngle.y+270)/RAD_TO_DEG);
viewSpeed.y =cos((viewAngle.x+90)/RAD_TO_DEG);
viewSpeed.z =((cos((viewAngle.y+180)/RAD_TO_DEG)/2) + (cos((viewAngle.x+90)/RAD_TO_DEG))/2);
viewPosition.x+=viewSpeed.x;
viewPosition.y+=viewSpeed.y;
viewPosition.z+=viewSpeed.z;
But, as i mentioned earlier this really messes up and rotating x around 180 and then y around 180, as it moves me further away instead of closer to. Is there a better a way of doing this?
Thanks again!
wonza Wrote:Im still maintaining my eular angles
...
But, as i mentioned earlier this really messes up and rotating x around 180 and then y around 180, as it moves me further away instead of closer to. Is there a better a way of doing this?
As I said before, Euler angles really don't work at all. Don't use them. Use a quaternion to store the cumulative state of each rotation. If you're keeping Euler angles around and recalculating your rotation every time based on them, you will keep running into the sort of problems you're seeing here.
The quaternion solution is reasonably simple; just start with the identity, apply rotations to it when you want to rotate, and allow those rotations to accumulate over the lifetime of your object (as in, don't restart with the identity quaternion every frame). So, when you want to turn left, simply do this:
Code:
Vector axis = {0.0f, 1.0f, 0.0f};
Quaternion_rotate(&orientation, axis, some_positive_value_in_radians);
Rotations will be on the quaternion's local axes; if you want to rotate on a world axis, multiply your axis vector by the inverse of the quaternion before rotating, like so:
Code:
Vector axis = {0.0f, 1.0f, 0.0f};
axis = Quaternion_multiplyVector(Quaternion_inverted(orientation), axis);
Quaternion_rotate(&orientation, axis, some_positive_value_in_radians);
Also, as AnotherJake mentioned, you may need to normalize your quaternion occasionally, but you probably won't have to worry about that unless you see your object getting mysteriously larger or smaller after having been rotated a lot. (For the record, I've never seen it happen in practice, but it certainly could if your quaternion has a long lifetime is rotated a lot.)
To move forward relative to a quaternion orientation, you can simply do this:
Code:
// IDENTITY_DIRECTION is the forward vector in the identity orientation
Vector direction = IDENTITY_DIRECTION;
direction = Quaternion_multiplyVector(orientation, direction);
position.x += SPEED * direction.x;
position.y += SPEED * direction.y;
position.z += SPEED * direction.z;
ThemsAllTook Wrote:(For the record, I've never seen it happen in practice, but it certainly could if your quaternion has a long lifetime is rotated a lot.)
[Slightly OffTopic  doesn't directly help the OP ATM] I've seen it happen with relatively large quaternion deltas. It only *appeared* to happen when the quaternion was possibly near some mathematical singularity (i.e. near one of its own internal axes), so even at that, it didn't happen very often. I don't know how the math worked out like that, but it looked almost like a weird little gimbal lock of some kind at certain points during the rotation, with the object speeding up and rotating around that point temporarily  hard to describe. Normalizing after every few of those "large" deltas fixed it. I've since decided to just normalize every update for simplicity (three quat delta adds (x, y, z)). Doesn't seem to affect performance much. Seems like the rendering code still winds up at the top of the list in Shark, and quaternion code often showing up a distant second. I suppose if it did start to affect performance, one could use something like that fast InvSqrt, but even then, it seems like hardware nowadays handles sqrtf pretty quick (and floating point calcs in general).
thats exactly what i was looking for, thanks!
I seem to have a problem with the direction movement though. Im doing this:
Vector direction = {0.0f, 0.0f, 1.0f};
direction = Quaternion_multiplyVector(orientation, direction);
This works for the most part, but for particular angles and positions it will suddenly start moving me away from the object instead of close to similar to the old method. Do I need to be altering the direction vector based on its current direct?
I seem to have a problem with the direction movement though. Im doing this:
Vector direction = {0.0f, 0.0f, 1.0f};
direction = Quaternion_multiplyVector(orientation, direction);
This works for the most part, but for particular angles and positions it will suddenly start moving me away from the object instead of close to similar to the old method. Do I need to be altering the direction vector based on its current direct?
No, that should work... Any specific examples you can give of it misbehaving? (Which angle, etc.)
here is some of my debug:
positions: vx: 3.705867, vy: 26.964016, vz: 5.705433
angles: vax: 25.000000, vay: 220.000000,
so I moved forward, up and to the right of the center, then turned towards the centre and tried to go forwards, but it sent me back instead. very strange.
positions: vx: 3.705867, vy: 26.964016, vz: 5.705433
angles: vax: 25.000000, vay: 220.000000,
so I moved forward, up and to the right of the center, then turned towards the centre and tried to go forwards, but it sent me back instead. very strange.
Looks OK. The only suspicious thing I see is that you say you moved up, but your y coordinate is negative. Unless you meant to say down, there may be a math error somewhere in your code.
It looks like there was an error in the code I posted earlier for my quaternionbased gluLookAt substitute. I don't know if you're actually using that, but if you are, you'll want to invert the quaternion before multiplying the current matrix by it. So, invert if the thing that's rotating is the camera; don't invert if the thing that's rotating is the object being viewed from another perspective.
If that doesn't help, could you post the multiplybyorientationandmoveforward code you're using, as well as your drawing transformation code?
It looks like there was an error in the code I posted earlier for my quaternionbased gluLookAt substitute. I don't know if you're actually using that, but if you are, you'll want to invert the quaternion before multiplying the current matrix by it. So, invert if the thing that's rotating is the camera; don't invert if the thing that's rotating is the object being viewed from another perspective.
If that doesn't help, could you post the multiplybyorientationandmoveforward code you're using, as well as your drawing transformation code?
I decided to use the multiplybyorientationandmoveforward code you helped me with:
//rotate on button pressed (there are 3 others of these for look up,down,left,right)
Vector axis = {0.0f, 1.0f, 0.0f};
axis = Quaternion_multiplyVector(Quaternion_inverted(orientation), axis);
Quaternion_rotate(&orientation, axis, inc);
//thrust applied/ move forward
Vector direction = {0.0f, 0.0f, 1.0f};
direction = Quaternion_multiplyVector(orientation, direction);
viewSpeed.x+=direction.x;
viewSpeed.y+=direction.y;
viewSpeed.z+=direction.z;
//update view
viewPosition.x+=viewSpeed.x;
viewPosition.y+=viewSpeed.y;
viewPosition.z+=viewSpeed.z;
glTranslatef(viewPosition.x, viewPosition.y, viewPosition.z);
//rotate on quat
Matrix matrix;
matrix = Quaternion_toMatrix(orientation);
glMultMatrixf(matrix.m);
hope this helps, thanks!
//rotate on button pressed (there are 3 others of these for look up,down,left,right)
Vector axis = {0.0f, 1.0f, 0.0f};
axis = Quaternion_multiplyVector(Quaternion_inverted(orientation), axis);
Quaternion_rotate(&orientation, axis, inc);
//thrust applied/ move forward
Vector direction = {0.0f, 0.0f, 1.0f};
direction = Quaternion_multiplyVector(orientation, direction);
viewSpeed.x+=direction.x;
viewSpeed.y+=direction.y;
viewSpeed.z+=direction.z;
//update view
viewPosition.x+=viewSpeed.x;
viewPosition.y+=viewSpeed.y;
viewPosition.z+=viewSpeed.z;
glTranslatef(viewPosition.x, viewPosition.y, viewPosition.z);
//rotate on quat
Matrix matrix;
matrix = Quaternion_toMatrix(orientation);
glMultMatrixf(matrix.m);
hope this helps, thanks!
This might just be the way you're doing the view transformation. See if it helps to do things in this order and invert the orientation:
Code:
matrix = Quaternion_toMatrix(Quaternion_inverted(orientation));
glMultMatrixf(matrix.m);
glTranslatef(viewPosition.x, viewPosition.y, viewPosition.z);
I just tried unfortunately it didnt seem to work. It didnt move towards the objects at, and then when i rotated they dissappeared. I also tried keeping that order but removing the inverted part.. and i tried keeping the original order but leaving in the inverted function; but neither worked.
I think I may have it!
I just inverted the quat then multiplied it before passing it into the direction vector:
Vector direction = {0.0f, 0.0f, 1.0f};
direction = Quaternion_multiplyVector(Quaternion_inverted(orientation), direction);
Its made me realise I am going to have to add buttons for rotating around z though
Again, thanks for all your help!!
I just inverted the quat then multiplied it before passing it into the direction vector:
Vector direction = {0.0f, 0.0f, 1.0f};
direction = Quaternion_multiplyVector(Quaternion_inverted(orientation), direction);
Its made me realise I am going to have to add buttons for rotating around z though
Again, thanks for all your help!!
Cool, glad to hear it's working for you!
As its very related I thought Id post here. I've now got my camera properly working, and ships too; as they move around randomly in the direct they are point, and ive also got some at random to point towards the camera and move towards it. Now again, Im having problems but with getting missiles working.
When i press another button Ive got a missile to become active and ive moved it to the position of the camera and then firing away from the camera. My problem is that I've setting the missiles orientation to that of the camera, which I think should make it move in the direction you are looking, but it just does not want to seem to work. Here is some of the relevant code:
Thanks for any help!
When i press another button Ive got a missile to become active and ive moved it to the position of the camera and then firing away from the camera. My problem is that I've setting the missiles orientation to that of the camera, which I think should make it move in the direction you are looking, but it just does not want to seem to work. Here is some of the relevant code:
Code:
glPushMatrix();
glTranslatef(AllMissiles[m].Position.x, AllMissiles[m].Position.y, AllMissiles[m].Position.z);
moveMissile(&AllMissiles[m]);
Matrix matrix;
matrix = Quaternion_toMatrix((AllMissiles[m].missileOrientation));
glMultMatrixf(matrix.m);
showMissile();
glPopMatrix();
//create new missile
AllMissiles[m].active = TRUE;
AllMissiles[m].Position = viewPosition;
AllMissiles[m].missileOrientation = orientation;
Thanks for any help!
Possibly Related Threads...
Thread:  Author  Replies:  Views:  Last Post  
Seperating Axis Theorem Code  mikey  5  7,996 
Oct 9, 2010 03:25 PM Last Post: Oddity007 

Separating Axis Collision Detection  Joseph Duchesne  4  5,842 
Dec 22, 2005 10:18 AM Last Post: Leisure Suit Lurie 

Separation axis collision detection  SOURMonkey  5  8,628 
Mar 24, 2005 01:23 AM Last Post: DoG 