using System; using System.Runtime.InteropServices; namespace XCEngine { [StructLayout(LayoutKind.Sequential)] public struct Matrix4x4 { public float M00; public float M01; public float M02; public float M03; public float M10; public float M11; public float M12; public float M13; public float M20; public float M21; public float M22; public float M23; public float M30; public float M31; public float M32; public float M33; public static Matrix4x4 Identity => new Matrix4x4 { M00 = 1.0f, M11 = 1.0f, M22 = 1.0f, M33 = 1.0f }; public float this[int row, int column] { get { switch (row) { case 0: switch (column) { case 0: return M00; case 1: return M01; case 2: return M02; case 3: return M03; default: throw new ArgumentOutOfRangeException( nameof(column)); } case 1: switch (column) { case 0: return M10; case 1: return M11; case 2: return M12; case 3: return M13; default: throw new ArgumentOutOfRangeException( nameof(column)); } case 2: switch (column) { case 0: return M20; case 1: return M21; case 2: return M22; case 3: return M23; default: throw new ArgumentOutOfRangeException( nameof(column)); } case 3: switch (column) { case 0: return M30; case 1: return M31; case 2: return M32; case 3: return M33; default: throw new ArgumentOutOfRangeException( nameof(column)); } default: throw new ArgumentOutOfRangeException(nameof(row)); } } set { switch (row) { case 0: switch (column) { case 0: M00 = value; return; case 1: M01 = value; return; case 2: M02 = value; return; case 3: M03 = value; return; } break; case 1: switch (column) { case 0: M10 = value; return; case 1: M11 = value; return; case 2: M12 = value; return; case 3: M13 = value; return; } break; case 2: switch (column) { case 0: M20 = value; return; case 1: M21 = value; return; case 2: M22 = value; return; case 3: M23 = value; return; } break; case 3: switch (column) { case 0: M30 = value; return; case 1: M31 = value; return; case 2: M32 = value; return; case 3: M33 = value; return; } break; } throw new ArgumentOutOfRangeException( row < 0 || row > 3 ? nameof(row) : nameof(column)); } } public Vector4 GetRow(int row) { switch (row) { case 0: return new Vector4(M00, M01, M02, M03); case 1: return new Vector4(M10, M11, M12, M13); case 2: return new Vector4(M20, M21, M22, M23); case 3: return new Vector4(M30, M31, M32, M33); default: throw new ArgumentOutOfRangeException(nameof(row)); } } public Vector4 GetColumn(int column) { switch (column) { case 0: return new Vector4(M00, M10, M20, M30); case 1: return new Vector4(M01, M11, M21, M31); case 2: return new Vector4(M02, M12, M22, M32); case 3: return new Vector4(M03, M13, M23, M33); default: throw new ArgumentOutOfRangeException( nameof(column)); } } } }