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).