Files
stgsharp/源代码/StgSharp/Math/Linear/matrix4x4.cs
T

204 lines
6.5 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace StgSharp.Math
{
public enum TransposeMode
{
New,
Copy
}
public unsafe class Matrix4x4
{
public static readonly Matrix4x4 Unit
= new Matrix4x4(
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
);
internal M128Map map;
internal IntPtr _row0Ptr;
internal IntPtr _row1Ptr;
internal IntPtr _row2Ptr;
internal IntPtr _row3Ptr;
private bool isTransposed=false;
private Matrix4x4 _transpose;
internal Matrix4x4()
{
_row0Ptr = internalIO.load_internal(0,0,0,0);
_row1Ptr = internalIO.load_internal(0,0,0,0);
_row2Ptr = internalIO.load_internal(0,0,0,0);
_row3Ptr = internalIO.load_internal(0,0,0,0);
_transpose = new Matrix4x4(this);
}
//Ctor used for the matixes of transposed matrix
internal Matrix4x4(Matrix4x4 transpose)
{
_row0Ptr = internalIO.load_internal(0, 0, 0, 0);
_row1Ptr = internalIO.load_internal(0, 0, 0, 0);
_row2Ptr = internalIO.load_internal(0, 0, 0, 0);
_row3Ptr = internalIO.load_internal(0, 0, 0, 0);
_transpose = transpose;
this.isTransposed=true;
}
internal unsafe Matrix4x4(
IntPtr row0Ptr,
IntPtr row1Ptr,
IntPtr row2Ptr,
IntPtr row3Ptr
)
{
_row0Ptr = row0Ptr;
_row1Ptr = row1Ptr;
_row2Ptr = row2Ptr;
_row3Ptr = row3Ptr;
_transpose = new Matrix4x4(this);
}
public unsafe 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
)
{
_row0Ptr = internalIO.load_internal(a00,a01,a02,a03);
_row1Ptr = internalIO.load_internal(a10,a11,a12,a13);
_row2Ptr = internalIO.load_internal(a20,a21,a22,a23);
_row3Ptr = internalIO.load_internal(a30,a31,a32,a33);
_transpose = new Matrix4x4(this);
}
internal void internalTranspose()
{
if (!isTransposed)
{
(*(M128*)_transpose._row0Ptr).single_0 = (*(M128*)_row0Ptr).single_0;
(*(M128*)_transpose._row0Ptr).single_1 = (*(M128*)_row1Ptr).single_0;
(*(M128*)_transpose._row0Ptr).single_2 = (*(M128*)_row2Ptr).single_0;
(*(M128*)_transpose._row0Ptr).single_3 = (*(M128*)_row3Ptr).single_0;
(*(M128*)_transpose._row1Ptr).single_0 = (*(M128*)_row0Ptr).single_1;
(*(M128*)_transpose._row1Ptr).single_1 = (*(M128*)_row1Ptr).single_1;
(*(M128*)_transpose._row1Ptr).single_2 = (*(M128*)_row2Ptr).single_1;
(*(M128*)_transpose._row1Ptr).single_3 = (*(M128*)_row3Ptr).single_1;
(*(M128*)_transpose._row2Ptr).single_0 = (*(M128*)_row0Ptr).single_2;
(*(M128*)_transpose._row2Ptr).single_1 = (*(M128*)_row1Ptr).single_2;
(*(M128*)_transpose._row2Ptr).single_2 = (*(M128*)_row2Ptr).single_2;
(*(M128*)_transpose._row2Ptr).single_3 = (*(M128*)_row3Ptr).single_2;
(*(M128*)_transpose._row3Ptr).single_0 = (*(M128*)_row0Ptr).single_3;
(*(M128*)_transpose._row3Ptr).single_1 = (*(M128*)_row1Ptr).single_3;
(*(M128*)_transpose._row3Ptr).single_2 = (*(M128*)_row2Ptr).single_3;
(*(M128*)_transpose._row3Ptr).single_3 = (*(M128*)_row3Ptr).single_3;
isTransposed = true;
}
}
public unsafe Matrix4x4 Transpose(TransposeMode transposeMode)
{
this.internalTranspose();
switch (transposeMode)
{
case TransposeMode.New:
return new Matrix4x4(
_transpose._row0Ptr,
_transpose._row1Ptr,
_transpose._row2Ptr,
_transpose._row3Ptr
);
break;
case TransposeMode.Copy:
return _transpose;
break;
default:
throw new Exception();
break;
}
}
/**/
public static Matrix4x4 operator +(Matrix4x4 matrix1, Matrix4x4 matrix2)
{
return new Matrix4x4(
internalIO.addps_internal(matrix1._row0Ptr, matrix2._row0Ptr),
internalIO.addps_internal(matrix1._row1Ptr, matrix2._row1Ptr),
internalIO.addps_internal(matrix1._row2Ptr, matrix2._row2Ptr),
internalIO.addps_internal(matrix1._row3Ptr, matrix2._row3Ptr)
) ;
}
public static Matrix4x4 operator -(Matrix4x4 matrix1, Matrix4x4 matrix2)
{
return new Matrix4x4(
internalIO.subps_internal(matrix1._row0Ptr, matrix2._row0Ptr),
internalIO.subps_internal(matrix1._row1Ptr, matrix2._row1Ptr),
internalIO.subps_internal(matrix1._row2Ptr, matrix2._row2Ptr),
internalIO.subps_internal(matrix1._row3Ptr, matrix2._row3Ptr)
);
}
/**/
public static Matrix4x4 operator *(Matrix4x4 matrix, float value)
{
return new Matrix4x4(
internalIO.mulps_const_internal(matrix._row0Ptr,value),
internalIO.mulps_const_internal(matrix._row1Ptr,value),
internalIO.mulps_const_internal(matrix._row2Ptr,value),
internalIO.mulps_const_internal(matrix._row3Ptr,value)
);
}
public override string ToString()
{
return $"{*(M128*)_row0Ptr}\n{*(M128*)_row1Ptr}\n{*(M128*)_row2Ptr}\n{*(M128*)_row3Ptr}";
}
/**/
~Matrix4x4()
{
if (map==null)
{
internalIO.deinitM128_internal(_row0Ptr);
internalIO.deinitM128_internal(_row1Ptr);
internalIO.deinitM128_internal(_row2Ptr);
internalIO.deinitM128_internal(_row3Ptr);
}
else
{
//in case the matrix is in a M128 map
}
}
}
}