# matrix multiplication - non-commutativity (solved)

## Recommended Posts

kVandaele    138
thanks to Mushu my ships are now translated (moved) properly, and moving as well. However, either way i multiply the matrices, some ships are moving sideways... Which is not my intention (well, yet anyway - i do know about strafing :)). All ships should simply move forward, and while they do move, it's not forward. It's something i have to look into, but first i need to know if i'm doing matrix multiplication right, but just wanted to give a little background info. As for the order, all i know is to rotate first while the object's on the origin, then translate (move) it to the proper position. An example of matrix multiplication (that i use) follows.
void CFlightShip::GetMatrix(D3DXMATRIX* mat){
// Advanced 3D GAME Programming with DirectX 9.0
// page 166 - 167 'black box'
//... except, NOT!
// Again, not sure what i meant with above comments...

D3DXMATRIX matRot1;
D3DXMATRIX matRot2;
D3DXMATRIX matMove;
D3DXMatrixIdentity(mat);
D3DXMatrixTranslation(&matMove, m_Pos.x, m_Pos.y, m_Pos.z);

D3DXMatrixRotationX(&matRot1, atan2f(m_Dir.y, m_Dir.z));
D3DXMatrixRotationY(&matRot2, atan2f(m_Dir.z, m_Dir.x));

D3DXMatrixMultiply(mat, &matRot1, &matRot2);

D3DXMatrixRotationAxis(&matRot1, &m_Dir, atan2f(m_Dir.y, m_Dir.x));

//	D3DXMatrixMultiply(mat, &matRot1, mat);
//	D3DXMatrixMultiply(mat, &matMove, mat);
D3DXMatrixMultiply(mat, mat, &matRot1);
D3DXMatrixMultiply(mat, mat, &matMove);
}


As you can see in the last 4 lines i'm not sure which i'm supposed to do. First, mat = rotX * rotY. Next i rotate around the direction axis (for rotZ) because the book (in the comments) said something about losing a degree of freedom in some bizarre cases. I admit i don't fully understand it but i did manage to find some examples, as well as find this function which no doubt was made to fix that. So next, i do mat = oldMat * rotZ = rotX * rotY * rotZ. I'm not sure but i don't think order matters in rotations. Finally: mat = oldmat * move = rotX * rotY * rotZ * move. I guess i'm asking, is that the right order? -- Different from above example -- Also, wouldn't D3DXMatrixIdentity(mat); D3DXMatrixMultiply(mat, mat, &matRot1); D3DXMatrixMultiply(mat, mat, &matMove); be the same as D3DXMatrixIdentity(mat); D3DXMatrixMultiply(mat, &matMove, mat); D3DXMatrixMultiply(mat, &matRot1, mat); (except of course the first being more clear - or at least i think so). As a sidenote (as i said above i woulnd't mind looking into it myself first, but) Mushu said my CFlightShip::UpdatePos function was 'borked' :) So, i wouldn't mind having it double-checked... (it looks fine to me but if the problem's not in the matrix multiplications above this would be my next guess).
void CFlightShip::UpdatePos(DWORD dwTimeElapsed){
//	New position = old position + (direction * distance moved)
m_Pos = m_Pos + m_Dir * ((float)dwTimeElapsed/1000.0f * m_fVel);
}


[Edited by - kVandaele on November 6, 2004 5:20:29 PM]

##### Share on other sites
kVandaele    138
it's been 3 weeks... did i perhaps ask the wrong question?

##### Share on other sites
fractoid    703
Umm... in the last two lines, you're storing the result of the multiplication into one of the arguments. The documentation doesn't say explicitly that you can't do this, but it's something I'd be wary of.

Try using another temporary matrix instead of the D3DXMultiply(mat, mat, ***) calls?

##### Share on other sites
kVandaele    138
well i've never seen it done otherwise, but for good measure let me try it out...

void CFlightShip::GetMatrix(D3DXMATRIX* mat){	// Advanced 3D GAME Programming with DirectX 9.0	// page 166 - 167 'black box'	//... except, NOT!	D3DXMATRIX temp1;	D3DXMATRIX temp2;	D3DXMATRIX matRot1;	D3DXMATRIX matRot2;	D3DXMATRIX matMove;	D3DXMatrixIdentity(mat);	D3DXMatrixTranslation(&matMove, m_Pos.x, m_Pos.y, m_Pos.z);	D3DXMatrixRotationX(&matRot1, atan2f(m_Dir.y, m_Dir.z));	D3DXMatrixRotationY(&matRot2, atan2f(m_Dir.z, m_Dir.x));//	D3DXMatrixMultiply(mat, &matRot1, &matRot2);	D3DXMatrixMultiply(&temp1, &matRot1, &matRot2);	D3DXMatrixRotationAxis(&matRot1, &m_Dir, atan2f(m_Dir.y, m_Dir.x));//	D3DXMatrixMultiply(mat, &matRot1, mat);//	D3DXMatrixMultiply(mat, &matMove, mat);//	D3DXMatrixMultiply(mat, mat, &matRot1);	D3DXMatrixMultiply(&temp2, &temp1, &matRot1);//	D3DXMatrixMultiply(mat, mat, &matMove);	D3DXMatrixMultiply(mat, &temp2, &matMove);}

I can't positively say it's the exact same effect, but it didn't fix the problem... Ships are most certainly still not moving forward...

##### Share on other sites
Staffan E    536
Order _does_ matter in rotation matrix concatenation. Think of the case that you have a ship that you want to rotate pi/4 around Y and also pi/4 around X. If you did it in the order Y then X you would first turn the ship pi/4 and then you would drive a needle through it where the X-axis currently is (which is diagonally through the ship if looking from above) and then rotating around that. The ship would be tilting in a way that probably wasn't the intention.
If you did it the other way around you would first pitch the ship around the X-axis pi/4 so it would be facing slightly downward, then drive a needle from above along with the Y-axis and spin it pi/4 around that one. Think about it and try to visualise it in front of you with your hand. The results are clearly not the same. Maybe none of them are what you intended.

The big problem with complex matrix rotation is that when you make the first rotation you rotate the local coordinate system along with the model. Then when doing the next rotation you still rotate along the global coordinate system.

Most times when using complex rotation, try to use the D3DMatrixRotationAxis() as much as possible, it can even be useful to have a set of three vectors that go along with each model that make up the local coordinate system base. Just remember to rotate them along with the model all the time.

##### Share on other sites
Staffan E    536
Um... have you tried reversing the order of all multiplications alltogether...?
If D3D express vectors as one-row matrices or one-column matrices (dont remember which), it has effect on how all matrices are finally applied to the vector. I dont know, but it might be worth a shot.

##### Share on other sites
kVandaele    138
reversing the multiplications doesn't work... but i do see now that order matters in rotations, and why... I suspect that's where (perhaps only part) of the problem lays...

It took me a while to figure out how exactly to do these rotation with the axis thing so i'll try and figure it out but it will take a while. Any help is much appreciated...

... so basically rather than
D3DXMatrixRotationY(&matRot2, atan2f(m_Dir.z, m_Dir.x));

i need something along the lines of
D3DXMatrixRotationAxis(&matRot1, &XDIR, atan2f(m_Dir.z, m_Dir.x));
where XDIR means the axis created by the xrotation...

##### Share on other sites
Staffan E    536
Hmm... maybe I'm just complicating your problem further...

But there is something fishy about the two rotation matrices you create, though...

D3DXMatrixRotationX(&matRot1, atan2f(m_Dir.y, m_Dir.z));
D3DXMatrixRotationY(&matRot2, atan2f(m_Dir.z, m_Dir.x));

First you rotate the mesh around the X-axis by

angle = atan(m_Dir.y / m_Dir.z)

This can't be right since, if m_Dir viewed from above is perpendicular to the ship (points left or right) then m_Dir.z = 0 and a division by zero will occur. Even if you handle that by an if (m_Dir.z == 0) the calculation will only end up correct if m_Dir.x = 0. Otherwise it will only rotate to match a projection of m_Dir on the Y-Z-plane, not the actual m_Dir vector.

To cover for this you could begin rotate around the Y-axis by the angle:

angle = -atan(m_Dir.x / m_Dir.z)
(minus since D3D is left handed)

and cover explicitly for the case if m_Dir.z = 0.
Then you have got a mesh that, viewed from above, is aligned to m_Dir. Rotating around X now should align it to m_Dir completely. But Just rotating around the X now would be an error since global X doesn't match local X after the Y rotation. To find the local X-axis:

LocalXVector = D3DXVec3Cross(&m_Dir, &D3DXVECTOR(0.0f, 1.0f, 0.0f));

The angle to rotate is:

angle = atan(m_Dir.y / sqrt(m_Dir.x*m_Dir.x + m_Dir.z*m_Dir.z));

Then rotate:

D3DMatrixRotationAxis(&matRot2, &LocalXVector, angle);

(Maybe it's -angle in the last parameter... try it out...)

This should by my knowledge of linear algebra cover for all cases of m_Dir except if it points straight up or down along the global Y-axis... I guess youll have to test for that too... or just keep it in mind.

Dont know if this solves your movement problem still... but...

##### Share on other sites
kVandaele    138
before answering your post, i have attempted (and failed) to fix the problem according to what i think your explanation was:

I have marked the changes with comments
void CFlightShip::GetMatrix(D3DXMATRIX* mat){	// Advanced 3D GAME Programming with DirectX 9.0	// page 166 - 167 'black box'	//... except, NOT!	D3DXMATRIX matRot1;	D3DXMATRIX matRot2;	D3DXMATRIX matMove;	D3DXMatrixIdentity(mat);	D3DXMatrixTranslation(&matMove, m_Pos.x, m_Pos.y, m_Pos.z);	D3DXMatrixRotationX(&matRot1, atan2f(m_Dir.y, m_Dir.z));//	D3DXMatrixRotationY(&matRot2, atan2f(m_Dir.z, m_Dir.x));// above has been removed and the 2lines below replaces that functionality	D3DXVECTOR3 tempVec3 = D3DXVECTOR3(0, m_Dir.y, m_Dir.z);	D3DXMatrixRotationAxis(&matRot2, &tempVec3, atan2f(m_Dir.z, m_Dir.x));// end replacement, below is unchanged	D3DXMatrixMultiply(mat, &matRot1, &matRot2);	D3DXMatrixRotationAxis(&matRot1, &m_Dir, atan2f(m_Dir.y, m_Dir.x));//	D3DXMatrixMultiply(mat, &matRot1, mat);//	D3DXMatrixMultiply(mat, &matMove, mat);	D3DXMatrixMultiply(mat, mat, &matMove);	D3DXMatrixMultiply(mat, mat, &matRot1);}

note that this is probably different, but it does not fix anything.

Now for your reply. Indeed y/x is undefined if x = 0. I am however always cautious about things like these... In the documentation of the atan2f function, under remarks, this is listed:
Quote:
 atan2 calculates the arctangent of y/x. atan2 is well defined for every point other than the origin, even if x equals 0 and y does not equal 0.

The m_Dir vector is normalised... but since it uses only 2 points i suppose it could at some point be 'the origin'?

I think for now i will try out your equations and wonder later how they work.

This is what i came up with:
void CFlightShip::GetMatrix(D3DXMATRIX* mat){	D3DXMATRIX matRot1;	D3DXMATRIX matRot2;	D3DXMATRIX matMove;	D3DXMatrixIdentity(mat);	D3DXMatrixTranslation(&matMove, m_Pos.x, m_Pos.y, m_Pos.z);/*	D3DXMatrixRotationX(&matRot1, atan2f(m_Dir.y, m_Dir.z));//	D3DXMatrixRotationY(&matRot2, atan2f(m_Dir.z, m_Dir.x));				// OPTION ONE RotY	D3DXVECTOR3 tempVec3 = D3DXVECTOR3(0, m_Dir.y, m_Dir.z);				// OPTION TWO RotY	D3DXMatrixRotationAxis(&matRot2, &tempVec3, atan2f(m_Dir.z, m_Dir.x));	// OPTION TWO RotY*/ // Replaced code, with original Y Rotation and my second attempt// Following is your solution	D3DXMatrixRotationY(&matRot1, -atan(m_Dir.x / m_Dir.z));	D3DXVECTOR3 tempVec3;	D3DXVec3Cross(&tempVec3, &m_Dir, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));	D3DXMatrixRotationAxis(&matRot2, &tempVec3, atan(m_Dir.y / sqrt(m_Dir.x*m_Dir.x + m_Dir.z*m_Dir.z)));// code below is unmodified	D3DXMatrixMultiply(mat, &matRot1, &matRot2);	D3DXMatrixRotationAxis(&matRot1, &m_Dir, atan2f(m_Dir.y, m_Dir.x));	D3DXMatrixMultiply(mat, mat, &matRot1);	D3DXMatrixMultiply(mat, mat, &matMove);}

I'll now investigate your code/solution, but it did not work (no matter the signs of both angles).

##### Share on other sites
Staffan E    536
The atan2f() function obvoisly seems superior to atan(). I didn't use it since I'm not familiar with it. I actually looked it up in the Win32SDK and D3DSDK but I didn't find it so I couldn't know.

If you replace all my ugly atan()s with atan2f()s will it generate a better result?

What kind of result do you get. Is it random transformation or does the object show at all?

I've gone through the calcs a few more times and apart from the atan issue it should work. I don't have a project set up to test it myself.

I guess it's a bit hard to follow without the aid of illustrations. I have some at my desk here beside me but I have no means to publish them. Sorry.

If you want I could try to explain it by word in some more detail...

##### Share on other sites
kVandaele    138
i've met with a rather peculiar phenomena due to two things:
1) I'm getting more and more clueless about what's the problem so I've finally thought of simplifying things
2) i was wondering why i used atan2f whilst you suggested atanf.

So, rather than make the direction of all ships random, i set their directions to 0,0,1 in one pass (moving away from viewer) and 0,0,-1 in another (moving towards viewer). They of course only move towards you as long as you don't rotate the view ;)

Before changing anything to the GetMatrix function, in the first pass ships were facing the wrong way (towards viewer) but moving away from the viewer. In essence they were moving correctly but facing the wrong way. In the second pass they were pointing in the correct direction and moving in the right direction, both towards the viewer.

After changing both your functions to atan2f (which -i think- is the correct function), in the first pass the ships were exactly the same as with atanf: moving away from viewer but pointed towards viewer (incorrect). In the second pass the ships were moving towards viewer but pointing away from viewer (also incorrect).

I'll look into this more with 1,0,0 and 0,1,0 as well as a few others that should be obvious.

##### Share on other sites
kVandaele    138
my apologies, here is the info on atan2f. I'm not sure but i think atanf (i'm using floats all around so no need for doubles) has a range of -pi/2 to pi/2, whilst atan2f has a range of -pi to pi (full circle).

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_atan.2c_.atan2.asp

##### Share on other sites
Staffan E    536
I found this in the DX docs at D3DXMatrixMultiply()

Quote:
 The result represents the transformation M2 followed by the transformation M1 (Out = M1 * M2).

If you multiply your matrices in the order
mTrans = mRotY * mRotX * mRotZ * mMove

then the order that the transformations are applied is
mMove, then mRotZ, then mRotX, then mRotY

i.e. the reverse...

##### Share on other sites
kVandaele    138
since i think it's correct, i've left it at atan2f with these tests. The only thing i've changed is the direction of the ships.

Direction:
1,0,0 moving right, pointing right. No complaints there :)
-1,0,0 moving left, pointing left
0,1,0; 0,-1,0 no ships show... i guess this is the error you mentioned
0,1000,1 (when normalised, approaches 0,1,0) ships moving up, pointing down
0,-1000,1 ships moving down, pointing up

1,1,0 moving up-right, pointing up-right
1,-1,0; -1,-1,0; -1,1,0 are all correct

1,0,1 moving far-right, pointing up... huh?
1,0,-1 moving near-right, pointing down
-1,0,-1 moving near-left, pointing down
-1,0,1 moving far-left, pointing down

0,1,1 moving far-up, pointing opposite direction (down-near)
0,1,-1; 0,-1,-1; 0,-1,1 all opposite of expected

As a final note, I seem to have completely ignored my m_Up vector, (perhaps) which has turned out some unexpected rotations. For example, when moving right the model has also been rotated 90degrees to the left around the _local_ Z axis (in other words before any other rotation). Since it's moving right (direction 1,0,0), this could also mean it's been rotated around the X axis 90degrees to the left after it's rotation around the Y axis 90 degrees to the right. ... When the only transformation that should be taking place is the one 90degrees to the right around the Y axis, at least when ignoring the Up vector.

This unexpected rotation occurred in all cases except forthe ones where m_Dir.x = 0.0f. In those 4 particular tests, for direction 0,1,1;0,1,-1; and 0,-1,1 it was correct (save for being pointed in the opposite direction), however in the 4th case where the direction was 0,-1,-1 the model was _locally_ (before any rotation) mirrored across the XZ plane, or -more likely- rotated (locally - before any rotation) around the Z axis 180 degrees.

These, to me, seems to indicate a wrong sign (or two), since in most cases the models are improperly rotated by 90 or 180 degrees. There's also a sort of 'stray' rotation that shouldn't be happening, so perhaps one of the three rotations is off by 90degrees (what comes to mind would be using a sine instead of cosine problem).

##### Share on other sites
kVandaele    138
Quote:
 D3DXMATRIX* D3DXMatrixMultiply( D3DXMATRIX* pOut, CONST D3DXMATRIX* pM1, CONST D3DXMATRIX* pM2); The result represents the transformation M2 followed by the transformation M1 (Out = M1 * M2).

that to me says that
D3DXMatrixMultiply(out, M1, M2) is the same as in math out = M1 * M2.

The part "... represents the transformation M2 followed by the transformation M1..." does seem highly suspicious though, so again let me try and reverse everything.

After reversing all the multiply's they're not even moving in the right direction anymore...

I still thought it wrong, but as a test i reversed _only_ the rotation multiply's. Moving left-right they were pointing up, moving up-down they were pointing down, moving near-far they were pointing opposite of expected. When mixing XY, YZ and XZ directions i could not make out a pattern further enforcing my belief that this is the wrong way to multiply.

It was worth the shot though :)

And for good measure, current function:
void CFlightShip::GetMatrix(D3DXMATRIX* mat){	D3DXMATRIX matRot1;	D3DXMATRIX matRot2;	D3DXMATRIX matMove;	D3DXMatrixIdentity(mat);	D3DXMatrixTranslation(&matMove, m_Pos.x, m_Pos.y, m_Pos.z);	D3DXMatrixRotationY(&matRot1, -atan2f(m_Dir.x, m_Dir.z));	D3DXVECTOR3 tempVec3;	D3DXVec3Cross(&tempVec3, &m_Dir, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));	D3DXMatrixRotationAxis(&matRot2, &tempVec3, atan2f(m_Dir.y, sqrt(m_Dir.x*m_Dir.x + m_Dir.z*m_Dir.z)));	D3DXMatrixMultiply(mat, &matRot1, &matRot2);//	D3DXMatrixRotationAxis(&matRot1, &m_Dir, atan2f(m_Dir.y, m_Dir.x));	D3DXMatrixRotationAxis(&matRot1, &m_Dir, atan2f(m_Dir.x, m_Dir.y));	D3DXMatrixMultiply(mat, mat, &matRot1);	D3DXMatrixMultiply(mat, mat, &matMove);}

##### Share on other sites
Staffan E    536
0,1,0 and 0,-1,0 won't show since you can't make a cross product from two parallel vectors.

D3DXVec3Cross(&tempVec3, &m_Dir, &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
try to create a local x-vector in this way:

D3DXVec3TransformCoord(&tempVec3, &D3DXVECTOR3(1.0f, 0.0f, 0.0f), &matRot1);

That is, you apply the Y rotation on a vector parallel to the X-axis. This should, at least, solve the issue with m_Dir pointing up and down.

##### Share on other sites
kVandaele    138
that fixed the x = 0, z = 0, y = 1 or y = -1 problem marvelously. In fact, it's perfect with y = -1, but with y = 1 the model is mirrored across the XY plane (the top of the ship is facing away from the viewer whilst if the ship was rotated 90 degrees across the x axis it would be facing towards the viewer).

Likewise, when x = 1 or -1, the ship is facing away from the viewer whilst it should be facing up.
Their top is facing up correctly with z = 1 or -1; but with z (and only Z now) they are facing backwards, leading me to believe this is where the problem is at, and perhaps the only problem (let us hope). There remains the fact that the up vector isn't used but that's for later (and frankly seems extremely easy to implement).

##### Share on other sites
kVandaele    138
First off, when direction was Z only the ships were flying in opposite direction. That's fixed now (apparently the models were made to point towards you... oops), but now the same problem has arisen for X direction only. So basically nothing's been fixed really, it's just the error was misperceived. To quickfix the 'model points towards you' error i first rotate around the Y axis by PI (half a circle), before doing anything else.

void CFlightShip::GetMatrix(D3DXMATRIX* mat){	D3DXMATRIX matRot1;	D3DXMATRIX matRot2;	D3DXMATRIX matMove;	D3DXMatrixIdentity(mat);	D3DXMatrixTranslation(&matMove, m_Pos.x, m_Pos.y, m_Pos.z);	D3DXMatrixRotationY(&matRot1, -atan2f(m_Dir.x, m_Dir.z));	D3DXMatrixRotationY(&matRot2, D3DX_PI);				// a little cheat	D3DXMatrixMultiply(&matRot1, &matRot1, &matRot2);	// until you mirror all ship models across x axis	D3DXVECTOR3 tempVec3;	D3DXVec3TransformCoord(&tempVec3, &D3DXVECTOR3(1.0f, 0.0f, 0.0f), &matRot1);	D3DXMatrixRotationAxis(&matRot2, &tempVec3, atan2f(m_Dir.y, sqrt(m_Dir.x*m_Dir.x + m_Dir.z*m_Dir.z)));	D3DXMatrixMultiply(mat, &matRot1, &matRot2);	D3DXMatrixRotationAxis(&matRot1, &m_Dir, atan2f(m_Dir.y, m_Dir.x));	D3DXMatrixMultiply(mat, mat, &matRot1);	D3DXMatrixMultiply(mat, mat, &matMove);}

Now i figured since 'only Y direction' and 'only Z direction' were working perfectly, the fault had to lay with 'only X direction', and how X direction was put into rotation. So i decided to 'nullify' each z, y, and x m_Dir value and see if it has any effect. Sure enough, if x is 0.0f all rotations are done perfectly. Errors happen when x is a random value but y or z are 0.0f...

Unfortunately m_Dir.x is used in all 3 rotations...
D3DXMatrixRotationY(&matRot1, -atan2f(m_Dir.x, m_Dir.z));
D3DXMatrixRotationAxis(&matRot2, &tempVec3, atan2f(m_Dir.y, sqrt(m_Dir.x*m_Dir.x + m_Dir.z*m_Dir.z)));
D3DXMatrixRotationAxis(&matRot1, &m_Dir, atan2f(m_Dir.y, m_Dir.x));

back to the definition of atan2f:
float atan2f(float a, float b);
- If both parameters of atan2 are 0, the function returns 0.
- atan2 calculates the arctangent of a/b. atan2 is well defined for every point other than the origin, even if b equals 0 and a does not equal 0.

-atan2f(0, m_Dir.z) = arctangent(0/anything) = arctangent(0) = 0.
having X as 0 cancels the Y rotation, so this is where the fault may lay. The only thing wrong could be the angle however...
atan2f(m_Dir.y, sqrt(m_Dir.x*m_Dir.x + m_Dir.z*m_Dir.z)). Having x be 0 here has the same effect as Z being zero. Since z being zero acts normally, having X be zero can't affect the rotation.
atan2f(m_Dir.y, 0) = 'well defined', presumably 0. This is where the fault may lay, since having X be 0 (presumably) cancels the rotation.

##### Share on other sites
Staffan E    536
I did some checking on the atan2f(), feeding it with different values.

atan2f( 1.0f, 1.0f) -> 0.785398 (pi/4)
atan2f( 1.0f, 0.0f) -> 1.5708 (pi/2)
atan2f(-1.0f, 0.0f) -> -1.5708 (-pi/2)
atan2f( 0.0f, 1.0f) -> 0
atan2f( 0.0f,-1.0f) -> 3.14159 (pi)

According to this the atan2f() never gives any false angles. If in the Y rotation x = 0 and z is positive the angle is 0 and if x = 0 and z is negative the angle is PI. Those angles are correct.

In the X roation, atan2f(m_Dir.y, 0) occurs when both x and z is 0. If so the angle returned is 1.5708 (pi/2) with the same sign as y. This is also the correct angle.

##### Share on other sites
kVandaele    138
if all the angles are correct, is it perhaps a mistake to rotate around the m_Dir vector for the Z rotation?

but why is it that then that with (and only with) m_Dir.x = 0.0f everything works perfectly?

##### Share on other sites
Staffan E    536
Actually I don't make any sense out of the line
D3DXMatrixRotationAxis(&matRot1, &m_Dir, atan2f(m_Dir.y, m_Dir.x));
It seems to have no connection to the current algoritm.

Have you tried removing the minus sign at
D3DXMatrixRotationY(&matRot1, -atan2f(m_Dir.x, m_Dir.z));
I cannot guarantee it's correct and it could be a an error since, if x = 0.0f the Y rotation will be 0/-0 or pi/-pi depending on the sign of z.
0 = -0 and pi = -pi in this implementation, so no error would be visible there...

##### Share on other sites
kVandaele    138
D3DXMatrixRotationAxis(&matRot1, &m_Dir, atan2f(m_Dir.y, m_Dir.x));

that line's there for the Z rotation. I don't remember why i picked the m_Dir vector for the axis but at the time it made sense. It was there before...

yep, it was the minus sign. It looks great now :)

##### Share on other sites
Staffan E    536
No prob!
My pleasure really... ;D

See you around kVandaele