For the last week or so, I've been trying to write my own rotation matrix. I do mean day in, day out staring at the same 30 or so lines of code. At first I tried to use an algorithm that would rotate a point around an arbitrary axis by combining three rotation matrices, one for each of the X, Y and Z axes into one matrix calculation but I couldn't get this to work. I then had a look at some of the pixel shader examples in RenderMonkey 1.62 and tried to port across an algorithm using Euler angles from GLSL to C++, and this had pretty much the same result. I then had another look at the problem and broke it down into the elements so that I was creating the X, Y and Z rotation matrices seperately.

I've emailed my lecturers with code and so far I've had two responses, one saying "can't see anything obvious" and to the second suggesting a few alterations to the code. I've performed these alterations but I'm getting the same effect. For now I'm using a simple sphere object extended from a base graphic object class where the vertices are stored in a vertex array (*)(3). Using each matrix individually yields different results. Using the Y axis rotation matrix, the sphere rotates around the Y axis (it spins) and shrinks in size gradually over time. Using the X axis rotation matrix, the sphere rotates around the X axis but the sphere coordinates are flattened on the Z axis. Again over time it scales. Using the Z axis rotation matrix, a similar thing happens but rotation takes place around the Z axis and flattening occurs to the X coordinate.

I wasnt sure if it was a good idea to post a lot of C++ on my first go. It's not so much about the code as the underlying algorithm that's causing problems. I feel I'm so close to the code I can't see the problem and I have tried working out the algorithm seperately. Does anyone have any suggestions?

Quote:

/***********************************************************************

Update the player - This is performed before GraphicObject::Rotate() so that the value to rotate by is set

***********************************************************************/

void Player::Update(void)

{

// Update dt value

dt = (float)timer.GetDT();

float rotationInDegrees = 30.0f;

float rotationInRadians = rotationInDegrees*dt*(PI/180.0f);

rotation.xyzw[0] = rotationInRadians;

rotation.xyzw[1] = rotationInRadians;

rotation.xyzw[2] = rotationInRadians;

SetRotation(rotation);

}

/*******************************************************************************

Rotate this graphicobject's vertices

*******************************************************************************/

void GraphicObject::Rotate(const float rotateX, const float rotateY, const float rotateZ)

{

// Rotation about an arbitrary axis

Matrix33f rotationMatrixX;

Matrix33f rotationMatrixY;

Matrix33f rotationMatrixAll;

rotationMatrixX.MakeRotationMatrixX(rotation.xyzw[0]);

rotationMatrixY.MakeRotationMatrixY(rotation.xyzw[1]);

rotationMatrixAll.MakeRotationMatrixZ(rotation.xyzw[2]);

rotationMatrixAll.MultiplyThis(rotationMatrixX);

rotationMatrixAll.MultiplyThis(rotationMatrixY);

// Update vertices

Vector3f temp;

for (int i = 0; i < numberOfVertices; i++)

{

temp.Set3f(vertexArray[i][0], vertexArray[i][1], vertexArray[i][2]);

temp.MultiplyThis33f(rotationMatrixAll);

vertexArray[i][0] = temp.xyz[0];

vertexArray[i][1] = temp.xyz[1];

vertexArray[i][2] = temp.xyz[2];

}

// TODO: update normals!

}

/*******************************************************************************

Creates a rotation matrix which vector3fs can be multiplied to rotate around the

X axis

*******************************************************************************/

void Matrix33f::MakeRotationMatrixX(float angle)

{

float fCos = cosf(angle);

float fSin = sinf(angle);

m[0][0] = 1.0f; m[1][0] = 0.0f; m[2][0] = 0.0f;

m[0][1] = 0.0f; m[1][1] = fCos; m[2][1] = fSin;

m[0][2] = 0.0f; m[1][2] = -fSin; m[2][2] = fCos;

}

/*******************************************************************************

Creates a rotation matrix which vector3fs can be multiplied to rotate around the

Y axis

*******************************************************************************/

void Matrix33f::MakeRotationMatrixY(float angle)

{

float fCos = cosf(angle);

float fSin = sinf(angle);

m[0][0] = fCos; m[1][0] = 0.0f; m[2][0] = -fSin;

m[0][1] = 0.0f; m[1][1] = 1.0f; m[2][1] = 0.0f;

m[0][2] = fSin; m[1][2] = 0.0f; m[2][2] = fCos;

}

/*******************************************************************************

Creates a rotation matrix which vector3fs can be multiplied to rotate around the

Z axis

*******************************************************************************/

void Matrix33f::MakeRotationMatrixZ(float angle)

{

float fCos = cosf(angle);

float fSin = sinf(angle);

m[0][0] = fCos; m[1][0] = fSin; m[2][0] = 0.0f;

m[0][1] = -fSin; m[1][1] = fCos; m[2][1] = 0.0f;

m[0][2] = 0.0f; m[1][2] = 0.0f; m[2][2] = 1.0f;

}

/*******************************************************************************

Multiply this Matrix33f by another Matrix33f

*******************************************************************************/

void Matrix33f::MultiplyThis(Matrix33f& a)

{

// Calculate the dot products

m[0][0] = m[0][0]*a.m[0][0] + m[0][1]*a.m[1][0] + m[0][2]*a.m[2][0];

m[1][0] = m[0][0]*a.m[0][1] + m[0][1]*a.m[1][1] + m[0][2]*a.m[2][1];

m[2][0] = m[0][0]*a.m[0][2] + m[0][1]*a.m[1][2] + m[0][2]*a.m[2][2];

m[0][1] = m[1][0]*a.m[0][0] + m[1][1]*a.m[1][0] + m[1][2]*a.m[2][0];

m[1][1] = m[1][0]*a.m[0][1] + m[1][1]*a.m[1][1] + m[1][2]*a.m[2][1];

m[2][1] = m[1][0]*a.m[0][2] + m[1][1]*a.m[1][2] + m[1][2]*a.m[2][2];

m[0][2] = m[2][0]*a.m[0][0] + m[2][1]*a.m[1][0] + m[2][2]*a.m[2][0];

m[1][2] = m[2][0]*a.m[0][1] + m[2][1]*a.m[1][1] + m[2][2]*a.m[2][1];

m[2][2] = m[2][0]*a.m[0][2] + m[2][1]*a.m[1][2] + m[2][2]*a.m[2][2];

}

/*******************************************************************************

Multiply this vector by a matrix33f

*******************************************************************************/

void Vector3f::MultiplyThis33f(Matrix33f& mat)

{

xyz[0] = mat.m[0][0]*xyz[0] + mat.m[0][1]*xyz[1] + mat.m[0][2]*xyz[2];

xyz[1] = mat.m[1][0]*xyz[0] + mat.m[1][1]*xyz[1] + mat.m[1][2]*xyz[2];

xyz[2] = mat.m[2][0]*xyz[0] + mat.m[2][1]*xyz[1] + mat.m[2][2]*xyz[2];

}