I'm fairly new to 3D Graphics, so I expect I have done something fundamentally wrong. I have built 4 matrixes to handle my objects in 3D space, a Scaling matrix, Translation Matrix, Perspective Matrix and Rotation matrix.
The rotation and scaling matrix work fine, however my Perspective and Translation Matrixes do not behave as expected, from what I understand the Translation and Perspective Matrixes look like:
Translation Perspective
[1, 0, 0, x] [1, 0, 0 , 0]
[0, 1, 0, y] [0, 1, 0 , 1]
[0, 0, 1, z] [0, 0, 1 , 0]
[0, 0, 0, 1] [0, 0, 1/D, 1]
To understand how everything works behind the scenes I am writing my own Math lib - to create the matrixes defined above I have the following methods:
public static ASMATRIX4 CreatePerspectiveMatrix(double focalLength)
{
// Create matrix as an identity matrix
var m = new ASMATRIX4();
// Set the perspective matrix
m.Matrix[3].Points[2] = 1 / focalLength;
m.Matrix[1].Points[3] = 1;
return m;
}
public static ASMATRIX4 CreateTranslationMatrix(double x, double y, double z)
{
// reset to identity matrix
var m = new ASMATRIX4();
// Set the translation matrix
m.Matrix[0].Points[3] = x;
m.Matrix[1].Points[3] = y;
m.Matrix[2].Points[3] = z;
return m;
}
Nothing too complicated, but when I multiply my matrixes together, nothing happens - I can rotate about any axis, but I cannot translate. Also note above that new ASMATRIX4()
initialises a new 4x4 matrix as an identity matrix.
To multiply my matrixes together I do the following:
m_scaling = ASMATRIX4.CreateScalingMatrix(s, s, s);
m_translation = ASMATRIX4.CreateTranslationMatrix(tX, tY, tZ);
m_perspective = ASMATRIX4.CreatePerspectiveMatrix(f);
m_rotation = ASMATRIX4.RotateByDegrees(rX, rY, rZ);
var transformationMatrix = m_scaling*m_translation*m_perspective*m_rotation;
I also wrote an operator overload to handle multiplying matrixes together:
public static ASMATRIX4 operator *(ASMATRIX4 mA, ASMATRIX4 mB)
{
// Creates a new identity matrix
var m = new ASMATRIX4();
// Multiply the two matrixes together and return the output matrix
for (var i = 0; i < 4; i++)
{
for (var j = 0; j < 4; j++)
{
m.Matrix[i].Points[j] =
(mB.Matrix[i].Points[0]*mA.Matrix[0].Points[j]) +
(mB.Matrix[i].Points[1]*mA.Matrix[1].Points[j]) +
(mB.Matrix[i].Points[2]*mA.Matrix[2].Points[j]) +
(mB.Matrix[i].Points[3]*mA.Matrix[3].Points[j])
}
}
return m;
}
Finally to actually transform my mesh, I have an array of Faces, that I draw to a 2D rendering context, the method below transforms each face by the transformation matrix defined above.
private void TransformMesh()
{
var transformationMatrix = m_scaling*m_translation*m_perspective*m_rotation;
for (var i = 0; i < m_numFaces; i++)
{
m_meshData[i] = m_meshData[i].TransformFace(transformationMatrix);
}
}
The TransformFace
method looks as described below:
public ASFace TransformFace(ASMATRIX4 matrix)
{
var transformedFace = new ASFace();
for (var i = 0; i < 3; i++)
{
transformedFace.m_points[i] = m_points[i].TransformVector(matrix);
transformedFace.m_points[i] = transformedFace.m_points[i].Rescale();
}
return transformedFace;
}
This first method in the loop transforms the homogenous point by the input matrix, and then a rescale method is called to normalise the vector.
I'm confused as to what I have done wrong? I am thinking the order of operations on multiplying the matrixes could be wrong but I am not too sure, any suggestions would be greatly appreciated.
m_scaling*m_translation*m_perspective*m_rotation
– Jeroen van LangenASMATRIX4
is creating an identity matrix and not a zero or (less likely) random matrix. I know it says that in the comments, but you should check to ensure that's the case. – andand