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

205 lines
7.1 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
{
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.InternalInitM128(0, 0, 0, 0);
_row1Ptr = internalIO.InternalInitM128(0, 0, 0, 0);
_row2Ptr = internalIO.InternalInitM128(0, 0, 0, 0);
_row3Ptr = internalIO.InternalInitM128(0, 0, 0, 0);
_transpose = new Matrix4x4(this);
}
//Ctor used for the matixes of transposed matrix
internal Matrix4x4(Matrix4x4 transpose)
{
_row0Ptr = internalIO.InternalInitM128(0, 0, 0, 0);
_row1Ptr = internalIO.InternalInitM128(0, 0, 0, 0);
_row2Ptr = internalIO.InternalInitM128(0, 0, 0, 0);
_row3Ptr = internalIO.InternalInitM128(0, 0, 0, 0);
_transpose = transpose;
this.isTransposed=true;
}
internal unsafe Matrix4x4(M128 row0, M128 row1, M128 row2, M128 row3)
{
_row0Ptr = internalIO.InternalInitM128(
row0.single_0, row0.single_1, row0.single_2, row0.single_3);
_row1Ptr = internalIO.InternalInitM128(
row1.single_0, row1.single_1, row1.single_2, row1.single_3);
_row2Ptr = internalIO.InternalInitM128(
row2.single_0, row2.single_1, row2.single_2, row2.single_3);
_row3Ptr = internalIO.InternalInitM128(
row3.single_0, row3.single_1, row3.single_2, row3.single_3);
_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.InternalInitM128(a00,a01,a02,a03);
_row1Ptr = internalIO.InternalInitM128(a10,a11,a12,a13);
_row2Ptr = internalIO.InternalInitM128(a20,a21,a22,a23);
_row3Ptr = internalIO.InternalInitM128(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(
*(M128*)_transpose._row0Ptr,
*(M128*)_transpose._row1Ptr,
*(M128*)_transpose._row2Ptr,
*(M128*)_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.VecAddVec(matrix1._row0Ptr, matrix2._row0Ptr),
internalIO.VecAddVec(matrix1._row1Ptr, matrix2._row1Ptr),
internalIO.VecAddVec(matrix1._row2Ptr, matrix2._row2Ptr),
internalIO.VecAddVec(matrix1._row3Ptr, matrix2._row3Ptr)
) ;
}
public static Matrix4x4 operator *(Matrix4x4 matrix, float value)
{
M128 newRow0 = new M128(
(*(M128*)matrix._row0Ptr).single_0 * value,
(*(M128*)matrix._row0Ptr).single_1 * value,
(*(M128*)matrix._row0Ptr).single_2 * value,
(*(M128*)matrix._row0Ptr).single_3 * value
);
M128 newRow1 = new M128(
(*(M128*)matrix._row1Ptr).single_0 * value,
(*(M128*)matrix._row1Ptr).single_1 * value,
(*(M128*)matrix._row1Ptr).single_2 * value,
(*(M128*)matrix._row1Ptr).single_3 * value
);
M128 newRow2 = new M128(
(*(M128*)matrix._row2Ptr).single_0 * value,
(*(M128*)matrix._row2Ptr).single_1 * value,
(*(M128*)matrix._row2Ptr).single_2 * value,
(*(M128*)matrix._row2Ptr).single_3 * value
);
M128 newRow3 = new M128(
(*(M128*)matrix._row3Ptr).single_0 * value,
(*(M128*)matrix._row3Ptr).single_1 * value,
(*(M128*)matrix._row3Ptr).single_2 * value,
(*(M128*)matrix._row3Ptr).single_3 * value
);
return new Matrix4x4(
newRow0, newRow1, newRow2, newRow3
);
}
public override string ToString()
{
return $"{*(M128*)_row0Ptr}\n{*(M128*)_row1Ptr}\n{*(M128*)_row2Ptr}\n{*(M128*)_row3Ptr}";
}
/**/
~Matrix4x4()
{
if (map==null)
{
Marshal.FreeHGlobal((IntPtr)_row0Ptr);
Marshal.FreeHGlobal((IntPtr)_row1Ptr);
Marshal.FreeHGlobal((IntPtr)_row2Ptr);
Marshal.FreeHGlobal((IntPtr)_row3Ptr);
}
else
{
//in case the matrix is in a M128 map
}
}
}
}