using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace StgSharp.Math { public enum TransposeMode { New, Copy } public class Matrix4x4 { internal long _row0Ptr; internal long _row1Ptr; internal long _row2Ptr; internal long _row3Ptr; internal M128 _row0; internal M128 _row1; internal M128 _row2; internal M128 _row3; private bool isTransposed=false; private Matrix4x4 _transpose; internal Matrix4x4() { _transpose = new Matrix4x4(); _transpose._transpose = this; _transpose.isTransposed = true; } internal Matrix4x4(M128 row0, M128 row1, M128 row2, M128 row3) { this._row0 = row0; this._row1 = row1; this._row2 = row2; this._row3 = row3; } public Matrix4x4( float a00, float a01, float a02, float a03, float a10, float a11, float a12, float a13, float a20, float a21, float a22, float a23, float a30, float a31, float a32, float a33 ) { _transpose = new Matrix4x4(); _transpose._transpose = this; this._row0 = new M128(a00, a01, a02, a03); this._row1 = new M128(a10, a11, a12, a13); this._row2 = new M128(a20, a21, a22, a23); this._row3 = new M128(a30, a31, a32, a33); } internal void internalTranspose() { if (!isTransposed) { _transpose._row0.single_0 = _row0.single_0; _transpose._row0.single_1 = _row1.single_0; _transpose._row0.single_2 = _row2.single_0; _transpose._row0.single_3 = _row3.single_0; _transpose._row1.single_0 = _row0.single_1; _transpose._row1.single_1 = _row1.single_1; _transpose._row1.single_2 = _row2.single_1; _transpose._row1.single_3 = _row3.single_1; _transpose._row2.single_0 = _row0.single_2; _transpose._row2.single_1 = _row1.single_2; _transpose._row2.single_2 = _row2.single_2; _transpose._row2.single_3 = _row3.single_2; _transpose._row3.single_0 = _row0.single_3; _transpose._row3.single_1 = _row1.single_3; _transpose._row3.single_2 = _row2.single_3; _transpose._row3.single_3 = _row3.single_3; isTransposed = true; } } public unsafe Matrix4x4 Transpose(TransposeMode transposeMode) { this.internalTranspose(); switch (transposeMode) { case TransposeMode.New: return new Matrix4x4( _transpose._row0, _transpose._row1, _transpose._row2, _transpose._row3 ); break; case TransposeMode.Copy: return _transpose; break; default: throw new Exception(); break; } } public static Matrix4x4 operator +(Matrix4x4 matrix1, Matrix4x4 matrix2) { return new Matrix4x4( internalIO.VecAddVec(matrix1._row0, matrix2._row0), internalIO.VecAddVec(matrix1._row1, matrix2._row1), internalIO.VecAddVec(matrix1._row2, matrix2._row2), internalIO.VecAddVec(matrix1._row3, matrix2._row3) ) ; } public static Matrix4x4 operator *(Matrix4x4 matrix, float value) { M128 newRow0 = new M128( matrix._row0.single_0 * value, matrix._row0.single_1 * value, matrix._row0.single_2 * value, matrix._row0.single_3 * value ); M128 newRow1 = new M128( matrix._row1.single_0 * value, matrix._row1.single_1 * value, matrix._row1.single_2 * value, matrix._row1.single_3 * value ); M128 newRow2 = new M128( matrix._row2.single_0 * value, matrix._row2.single_1 * value, matrix._row2.single_2 * value, matrix._row2.single_3 * value ); M128 newRow3 = new M128( matrix._row3.single_0 * value, matrix._row3.single_1 * value, matrix._row3.single_2 * value, matrix._row3.single_3 * value ); return new Matrix4x4( newRow0, newRow1, newRow2, newRow3 ); } } }