Matrix to Matrix4 to Matrix conversions

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
thzero

Matrix to Matrix4 to Matrix conversions

Post by thzero »

Its really late, and after hunting around and looking at the API and just doing some comparisons via good old printf (er Console.WriteLine in C#), I ended up having a conversion method from Matrix to Matrix4 as follows:

Code: Select all

        public static Matrix4 convert(Matrix m)
        {
            Matrix4 m4 = new Matrix4();
            m4.set_M(0, 0, m.M11);
            m4.set_M(0, 1, m.M12);
            m4.set_M(0, 2, m.M13);
            m4.set_M(0, 3, m.M41);
            m4.set_M(1, 0, m.M21);
            m4.set_M(1, 1, m.M22);
            m4.set_M(1, 2, m.M23);
            m4.set_M(1, 3, m.M42);
            m4.set_M(2, 0, m.M32);
            m4.set_M(2, 1, m.M31);
            m4.set_M(2, 2, m.M33);
            m4.set_M(2, 3, m.M43);
            m4.set_M(3, 0, 0);
            m4.set_M(3, 1, 0);
            m4.set_M(3, 2, 0);
            m4.set_M(3, 3, 1);

            return m4;
        }
It seems that the DirectX.Matrix holds the translations in row 41, 42, 43, whereas Matrix4 holds them in the 14, 24, and 34 positions of the matrix.

Is this correct and legit? It seems to work correctly.

Thanks.
IRRer

Post by IRRer »

Well, if it works -> it seems to be correct -> use it :P
hybrid

Post by hybrid »

matrix4 should be an exact copy of the D3D matrix such that rows and columsn should be the same.
thzero

Post by thzero »

hybrid wrote:matrix4 should be an exact copy of the D3D matrix such that rows and columsn should be the same.
It's not a direct copy. You can prove it to yourself quite simply by doing the following:

Code: Select all

Matrix m = Matrix.Translation(5.0f, 10.0f, 15.0f);
Matrix4 m4 = new Matrix4();
m4.SetTranslation(new Vector3D(5.0f, 10.0f, 15.0f));

Console.WriteLine();
Console.WriteLine("DirectX.Matrix translated from vector (5f, 10f, 15f):");
Console.WriteLine();

Console.WriteLine("{0} {1} {2} {3}", m.M11, m.M12, m.M13, m.M14);
Console.WriteLine("{0} {1} {2} {3}", m.M21, m.M22, m.M23, m.M24);
Console.WriteLine("{0} {1} {2} {3}", m.M31, m.M32, m.M33, m.M34);
Console.WriteLine("{0} {1} {2} {3}", m.M41, m.M42, m.M43, m.M44);

Console.WriteLine();
Console.WriteLine("Irrlicht.Matrix4 translated from vector (5f, 10f, 15f):");
Console.WriteLine();

Console.WriteLine("{0} {1} {2} {3}", m4.get_M(0, 0), m4.get_M(0, 1), m4.get_M(0, 2), m4.get_M(0, 3));
Console.WriteLine("{0} {1} {2} {3}", m4.get_M(1, 0), m4.get_M(1, 1), m4.get_M(1, 2), m4.get_M(1, 3));
Console.WriteLine("{0} {1} {2} {3}", m4.get_M(2, 0), m4.get_M(2, 1), m4.get_M(2, 2), m4.get_M(2, 3));
Console.WriteLine("{0} {1} {2} {3}", m4.get_M(3, 0), m4.get_M(3, 1), m4.get_M(3, 2), m4.get_M(3, 3));

Console.WriteLine();

Code: Select all

DirectX.Matrix translated from vector (5f, 10f, 15f):

1 0 0 0
0 1 0 0
0 0 1 0
5 10 15 1

Irrlicht.Matrix4 translated from vector (5f, 10f, 15f):

1 0 0 5
0 1 0 10
0 0 1 15
0 0 0 1
If I'm doing something wrong, or have something screwed up please let me know. But my imperical evidence, Matrix and Matrix4 are NOT the same thing.
hybrid

Post by hybrid »

quote from matrix4.h (shoudl be accessible from the API documentation as well):
The matrix is a D3D style matrix, row major with translations in the 4th row.

Don't know about your results, but maybe that's different in C#?
thzero
Posts: 6
Joined: Fri Apr 14, 2006 1:29 pm

Post by thzero »

hybrid wrote:quote from matrix4.h (shoudl be accessible from the API documentation as well):
The matrix is a D3D style matrix, row major with translations in the 4th row.

Don't know about your results, but maybe that's different in C#?
I don't know, all it says in the online API (not the .NET API mind you) is

"4x4 matrix. Mostly used as transformation matrix for 3d calculations."

Again, according to the online API help (http://irrlicht.sourceforge.net/docu/ma ... tml#l00260) the SetTranslation method looks like:

Code: Select all

inline void matrix4::setTranslation( const vector3df& translation )
00261         {
00262                 M[12] = translation.X;
00263                 M[13] = translation.Y;
00264                 M[14] = translation.Z;
00265         }
Which seems to make sense if the translations are in the 4th row.

If we look at the get_M method from the Irrlicht.NET API we see...

Code: Select all

public unsafe float get_M(int row, int col)
{
      if (((row < 0) || (row >= 4)) || ((col < 0) || (col >= 4)))
      {
            throw new Exception("Invalid index for accessing matrix members");
      }
      return (((col * 4) + row) * 4)[(int) &this.Members];
}
...so if we do a get_M(3, 0) which should give us our X component of the translation we see that if we get the following:

Code: Select all

((col * 4) + row) = (3 * 4) + 0  = 12

which is exactly what we'd expect!

But here is some more of my debugging/test code and the results!  There's something not quite right somewhere and I'm not seeing it! :(

[code]
#if DEBUG
Matrix m = Matrix.Translation(5.0f, 10.0f, 15.0f);
Matrix4 m4 = new Matrix4();
m4.SetTranslation(new Vector3D(5.0f, 10.0f, 15.0f));

Console.WriteLine();
Console.WriteLine("DirectX.Matrix translated from vector (5f, 10f, 15f):");
Console.WriteLine();

Console.WriteLine("{0} {1} {2} {3}", m.M11, m.M12, m.M13, m.M14);
Console.WriteLine("{0} {1} {2} {3}", m.M21, m.M22, m.M23, m.M24);
Console.WriteLine("{0} {1} {2} {3}", m.M31, m.M32, m.M33, m.M34);
Console.WriteLine("{0} {1} {2} {3}", m.M41, m.M42, m.M43, m.M44);

Console.WriteLine();
Console.WriteLine("Irrlicht.Matrix4 translated from vector (5f, 10f, 15f):");
Console.WriteLine();

Console.WriteLine("{0} {1} {2} {3}", m4.get_M(0, 0), m4.get_M(0, 1), m4.get_M(0, 2), m4.get_M(0, 3));
Console.WriteLine("{0} {1} {2} {3}", m4.get_M(1, 0), m4.get_M(1, 1), m4.get_M(1, 2), m4.get_M(1, 3));
Console.WriteLine("{0} {1} {2} {3}", m4.get_M(2, 0), m4.get_M(2, 1), m4.get_M(2, 2), m4.get_M(2, 3));
Console.WriteLine("{0} {1} {2} {3}", m4.get_M(3, 0), m4.get_M(3, 1), m4.get_M(3, 2), m4.get_M(3, 3));

m4 = Utility.ToMatrix4(m);

Console.WriteLine();
Console.WriteLine("DirectX.Matrix convert to Irrlicht.Matrix4:");
Console.WriteLine();

Console.WriteLine("{0} {1} {2} {3}", m4.get_M(0, 0), m4.get_M(0, 1), m4.get_M(0, 2), m4.get_M(0, 3));
Console.WriteLine("{0} {1} {2} {3}", m4.get_M(1, 0), m4.get_M(1, 1), m4.get_M(1, 2), m4.get_M(1, 3));
Console.WriteLine("{0} {1} {2} {3}", m4.get_M(2, 0), m4.get_M(2, 1), m4.get_M(2, 2), m4.get_M(2, 3));
Console.WriteLine("{0} {1} {2} {3}", m4.get_M(3, 0), m4.get_M(3, 1), m4.get_M(3, 2), m4.get_M(3, 3));

Console.WriteLine();

m = Utility.ToMatrix(m4);

Console.WriteLine();
Console.WriteLine("Irrlicht.Matrix4 convert to DirectX.Matrix:");
Console.WriteLine();

Console.WriteLine("{0} {1} {2} {3}", m.M11, m.M12, m.M13, m.M14);
Console.WriteLine("{0} {1} {2} {3}", m.M21, m.M22, m.M23, m.M24);
Console.WriteLine("{0} {1} {2} {3}", m.M31, m.M32, m.M33, m.M34);
Console.WriteLine("{0} {1} {2} {3}", m.M41, m.M42, m.M43, m.M44);

Console.WriteLine();
#endif
gives you

Code: Select all

DirectX.Matrix translated from vector (5f, 10f, 15f):

1 0 0 0
0 1 0 0
0 0 1 0
5 10 15 1

Irrlicht.Matrix4 translated from vector (5f, 10f, 15f):

1 0 0 5
0 1 0 10
0 0 1 15
0 0 0 1

DirectX.Matrix convert to Irrlicht.Matrix4:

1 0 0 5
0 1 0 10
0 0 1 15
0 0 0 1


Irrlicht.Matrix4 convert to DirectX.Matrix:

1 0 0 0
0 1 0 0
0 0 1 0
5 10 15 1
I found the comments (http://irrlicht.sourceforge.net/docu/ma ... tml#l00260)

/* Matrix4 is mainly used by the Irrlicht engine for doing transformations.
00022 The matrix is a D3D style matrix, row major with translations in the 4th row.
00023 */

But frankly imperical evidence says that it is a D3D style matrix, row major with translations in the 4th COLUMN.

If you set an Irrlicht node to 0, 0, 0 then set up a Matrix4 with 15, 15, 15 in the 4th ROW, nothing happens at all. If you set the 15, 15, 15 in the 4th column, then your node is translated.
hybrid

Post by hybrid »

According to Wikipedia this access function is column major! So there is really quite some confusion in this Irrlicht class. If someone with both good knowledge on 3d graphics and Irrlicht background could have a look at this? Spintz, EK maybe?
Post Reply