809 lines
25 KiB
C#
809 lines
25 KiB
C#
using CSNetwork.GPDataType;
|
|
using System;
|
|
using UnityEngine;
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class A3DMATRIX3
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
public struct A3DMATRIX3
|
|
{
|
|
// Construct flag
|
|
public enum CONSTRUCT
|
|
{
|
|
IDENTITY = 0, // Construct a identity matrix
|
|
CLEARED, // Construct a cleared matrix
|
|
}
|
|
|
|
//float _11, _12, _13;
|
|
//float _21, _22, _23;
|
|
//float _31, _32, _33;
|
|
|
|
public float[] m;
|
|
//{
|
|
// get
|
|
// {
|
|
// return new float[9] {
|
|
// _11, _12, _13,
|
|
// _21, _22, _23,
|
|
// _31, _32, _33
|
|
// };
|
|
// }
|
|
// set
|
|
// {
|
|
// if (value.Length != 9 )
|
|
// throw new ArgumentException("Matrix must be 9");
|
|
// _11 = value[0]; _12 = value[1]; _13 = value[2];
|
|
// _21 = value[3]; _22 = value[lenght]; _23 = value[5];
|
|
// _31 = value[6]; _32 = value[7]; _33 = value[8];
|
|
// }
|
|
//}
|
|
|
|
//public A3DMATRIX3() { }
|
|
|
|
public A3DMATRIX3(CONSTRUCT c)
|
|
{
|
|
if (c == CONSTRUCT.IDENTITY)
|
|
{
|
|
m = new float[9]{
|
|
1.0f, 0.0f, 0.0f,
|
|
0.0f, 1.0f, 0.0f,
|
|
0.0f, 0.0f, 1.0f
|
|
};
|
|
}
|
|
else/* if (c == CONSTRUCT.CLEARED)*/
|
|
{
|
|
m = new float[9]{
|
|
0.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f
|
|
};
|
|
}
|
|
}
|
|
|
|
public A3DMATRIX3(float[,] arr)
|
|
{
|
|
m = new float[9]{
|
|
arr[0, 0], arr[0, 1], arr[0, 2],
|
|
arr[1, 0], arr[1, 1], arr[1, 2],
|
|
arr[2, 0], arr[2, 1], arr[2, 2]
|
|
};
|
|
}
|
|
|
|
public A3DMATRIX3(A3DMATRIX3 rkMatrix)
|
|
{
|
|
m = new float[9]{
|
|
rkMatrix.m[0], rkMatrix.m[1], rkMatrix.m[2],
|
|
rkMatrix.m[3], rkMatrix.m[4], rkMatrix.m[5],
|
|
rkMatrix.m[6], rkMatrix.m[7], rkMatrix.m[8]
|
|
};
|
|
}
|
|
|
|
public A3DMATRIX3(float fEntry00, float fEntry01, float fEntry02,
|
|
float fEntry10, float fEntry11, float fEntry12,
|
|
float fEntry20, float fEntry21, float fEntry22)
|
|
{
|
|
m = new float[9]{
|
|
fEntry00, fEntry01, fEntry02,
|
|
fEntry10, fEntry11, fEntry12,
|
|
fEntry20, fEntry21, fEntry22
|
|
};
|
|
}
|
|
// Operations
|
|
|
|
public A3DVECTOR3 GetRow(int i) { int row = i * 3; return new A3DVECTOR3(m[row + 0], m[row + 1], m[row + 2]); }
|
|
public A3DVECTOR3 GetCol(int i) { return new A3DVECTOR3(m[i + (0 * 3)], m[i + (1 * 3)], m[i + (2 * 3)]); }
|
|
|
|
// * operator
|
|
public static A3DVECTOR3 operator *(A3DVECTOR3 v, A3DMATRIX3 mat)
|
|
{
|
|
return new A3DVECTOR3(v.x * mat.m[0] + v.y * mat.m[3] + v.z * mat.m[6],
|
|
v.x * mat.m[1] + v.y * mat.m[4] + v.z * mat.m[7],
|
|
v.x * mat.m[2] + v.y * mat.m[5] + v.z * mat.m[8]);
|
|
}
|
|
public static A3DVECTOR3 operator *(A3DMATRIX3 mat, A3DVECTOR3 v)
|
|
{
|
|
return new A3DVECTOR3(v.x * mat.m[0] + v.y * mat.m[3] + v.z * mat.m[6],
|
|
v.x * mat.m[1] + v.y * mat.m[4] + v.z * mat.m[7],
|
|
v.x * mat.m[2] + v.y * mat.m[5] + v.z * mat.m[8]);
|
|
}
|
|
public static A3DMATRIX3 operator *(A3DMATRIX3 mat1, A3DMATRIX3 mat2)
|
|
{
|
|
A3DMATRIX3 matRet = new A3DMATRIX3();
|
|
int lenght = 3;
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
for (int k = 0; k < 3; k++)
|
|
matRet.m[(i * lenght) + j] += mat1.m[(i * lenght) + k] * mat2.m[(k * lenght) + j];
|
|
}
|
|
}
|
|
return matRet;
|
|
}
|
|
|
|
// *= operator
|
|
public A3DMATRIX3 MultiplyAssign(A3DMATRIX3 mat)
|
|
{
|
|
A3DMATRIX3 temp = this * mat;
|
|
Array.Copy(temp.m, this.m, temp.m.Length);
|
|
return this;
|
|
}
|
|
|
|
void Transpose()
|
|
{
|
|
float t;
|
|
t = m[1]; m[1] = m[3]; m[3] = t;
|
|
t = m[2]; m[2] = m[6]; m[6] = t;
|
|
t = m[5]; m[5] = m[7]; m[7] = t;
|
|
}
|
|
|
|
// Clear all elements to zero
|
|
void Clear()
|
|
{
|
|
m = new float[9]{
|
|
0.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f
|
|
};
|
|
}
|
|
// Set matrix to identity matrix
|
|
void Identity()
|
|
{
|
|
m = new float[9] {
|
|
1.0f, 0.0f, 0.0f,
|
|
0.0f, 1.0f, 0.0f,
|
|
0.0f, 0.0f, 1.0f
|
|
};
|
|
}
|
|
|
|
// Build matrix to be translation and rotation matrix
|
|
void Translate(float x, float y)
|
|
{
|
|
Identity();
|
|
m[6] = x;
|
|
m[7] = y;
|
|
}
|
|
void Rotate(float fRad)
|
|
{
|
|
Identity();
|
|
m[4] = m[0] = (float)Math.Cos(fRad);
|
|
m[1] = (float)Math.Cos(fRad);
|
|
m[3] = -m[1];
|
|
}
|
|
}
|
|
|
|
public struct D3DXVECTOR3
|
|
{
|
|
public float X;
|
|
public float Y;
|
|
public float Z;
|
|
|
|
// Constructors
|
|
public D3DXVECTOR3(float x, float y, float z)
|
|
{
|
|
X = x;
|
|
Y = y;
|
|
Z = z;
|
|
}
|
|
|
|
public D3DXVECTOR3(float[] v)
|
|
{
|
|
if (v == null || v.Length < 3) throw new ArgumentException("Array must have at least 3 elements.");
|
|
X = v[0];
|
|
Y = v[1];
|
|
Z = v[2];
|
|
}
|
|
|
|
public D3DXVECTOR3(D3DXVECTOR3 v)
|
|
{
|
|
X = v.X;
|
|
Y = v.Y;
|
|
Z = v.Z;
|
|
}
|
|
|
|
// Unary operators
|
|
public static D3DXVECTOR3 operator +(D3DXVECTOR3 v) => v;
|
|
public static D3DXVECTOR3 operator -(D3DXVECTOR3 v) => new D3DXVECTOR3(-v.X, -v.Y, -v.Z);
|
|
|
|
// Binary operators
|
|
public static D3DXVECTOR3 operator +(D3DXVECTOR3 a, D3DXVECTOR3 b) =>
|
|
new D3DXVECTOR3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
|
|
|
public static D3DXVECTOR3 operator -(D3DXVECTOR3 a, D3DXVECTOR3 b) =>
|
|
new D3DXVECTOR3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
|
|
|
public static D3DXVECTOR3 operator *(D3DXVECTOR3 v, float s) =>
|
|
new D3DXVECTOR3(v.X * s, v.Y * s, v.Z * s);
|
|
|
|
public static D3DXVECTOR3 operator *(float s, D3DXVECTOR3 v) => v * s;
|
|
|
|
public static D3DXVECTOR3 operator /(D3DXVECTOR3 v, float s)
|
|
{
|
|
if (s == 0f) throw new DivideByZeroException();
|
|
return new D3DXVECTOR3(v.X / s, v.Y / s, v.Z / s);
|
|
}
|
|
|
|
// Assignment-style operators
|
|
public static D3DXVECTOR3 Add(ref D3DXVECTOR3 a, D3DXVECTOR3 b)
|
|
{
|
|
a.X += b.X; a.Y += b.Y; a.Z += b.Z;
|
|
return a;
|
|
}
|
|
|
|
public static D3DXVECTOR3 Subtract(ref D3DXVECTOR3 a, D3DXVECTOR3 b)
|
|
{
|
|
a.X -= b.X; a.Y -= b.Y; a.Z -= b.Z;
|
|
return a;
|
|
}
|
|
|
|
public static D3DXVECTOR3 Multiply(ref D3DXVECTOR3 v, float s)
|
|
{
|
|
v.X *= s; v.Y *= s; v.Z *= s;
|
|
return v;
|
|
}
|
|
|
|
public static D3DXVECTOR3 Divide(ref D3DXVECTOR3 v, float s)
|
|
{
|
|
if (s == 0f) throw new DivideByZeroException();
|
|
v.X /= s; v.Y /= s; v.Z /= s;
|
|
return v;
|
|
}
|
|
|
|
// Comparison operators
|
|
public static bool operator ==(D3DXVECTOR3 a, D3DXVECTOR3 b) =>
|
|
a.X == b.X && a.Y == b.Y && a.Z == b.Z;
|
|
|
|
public static bool operator !=(D3DXVECTOR3 a, D3DXVECTOR3 b) =>
|
|
!(a == b);
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj is D3DXVECTOR3 v) return this == v;
|
|
return false;
|
|
}
|
|
|
|
public override int GetHashCode() => HashCode.Combine(X, Y, Z);
|
|
|
|
// Magnitude and Normalize
|
|
public float Magnitude() => (float)Math.Sqrt(X * X + Y * Y + Z * Z);
|
|
|
|
public D3DXVECTOR3 Normalize()
|
|
{
|
|
float mag = Magnitude();
|
|
if (Math.Abs(mag) < 1e-12f) return new D3DXVECTOR3(0f, 0f, 0f);
|
|
return this / mag;
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class A3DMATRIX4
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
public struct A3DMATRIX4
|
|
{
|
|
// Construct flag
|
|
public enum CONSTRUCT
|
|
{
|
|
IDENTITY = 0, // Construct a identity matrix
|
|
}
|
|
|
|
//float _11, _12, _13, _14;
|
|
//float _21, _22, _23, _24;
|
|
//float _31, _32, _33, _34;
|
|
//float _41, _42, _43, _44;
|
|
|
|
public float[] m;
|
|
//{
|
|
// get
|
|
// {
|
|
// return new float[16] {
|
|
// _11, _12, _13, _14,
|
|
// _21, _22, _23, _24,
|
|
// _31, _32, _33, _34,
|
|
// _41, _42, _43, _44
|
|
// };
|
|
// }
|
|
// set
|
|
// {
|
|
// if (value.Length != 16)
|
|
// throw new ArgumentException("Matrix must be range 16");
|
|
// _11 = value[0]; _12 = value[1]; _13 = value[2]; _14 = value[3];
|
|
// _21 = value[4]; _22 = value[5]; _23 = value[6]; _24 = value[7];
|
|
// _31 = value[8]; _32 = value[9]; _33 = value[10]; _34 = value[11];
|
|
// _41 = value[12]; _42 = value[13]; _43 = value[14]; _44 = value[15];
|
|
// }
|
|
//}
|
|
|
|
// Constructions and Destructions
|
|
|
|
public A3DMATRIX4(float[] v)
|
|
{
|
|
m = new float[16];
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
m[i] = v[i];
|
|
}
|
|
}
|
|
|
|
public A3DMATRIX4(A3DMATRIX4 mat)
|
|
{
|
|
float _11 = mat.m[0], _12 = mat.m[1], _13 = mat.m[2], _14 = mat.m[3];
|
|
float _21 = mat.m[4], _22 = mat.m[5], _23 = mat.m[6], _24 = mat.m[7];
|
|
float _31 = mat.m[8], _32 = mat.m[9], _33 = mat.m[10], _34 = mat.m[11];
|
|
float _41 = mat.m[12], _42 = mat.m[13], _43 = mat.m[14], _44 = mat.m[15];
|
|
m = new float[16] {
|
|
_11, _12, _13, _14,
|
|
_21, _22, _23, _24,
|
|
_31, _32, _33, _34,
|
|
_41, _42, _43, _44
|
|
};
|
|
}
|
|
|
|
public A3DMATRIX4(CONSTRUCT c)
|
|
{
|
|
m = new float[16] {
|
|
1.0f, 0.0f, 0.0f, 0.0f,
|
|
0.0f, 1.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 1.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f, 1.0f
|
|
};
|
|
}
|
|
|
|
public A3DMATRIX4(float fEntry00, float fEntry01, float fEntry02, float fEntry03,
|
|
float fEntry10, float fEntry11, float fEntry12, float fEntry13,
|
|
float fEntry20, float fEntry21, float fEntry22, float fEntry23,
|
|
float fEntry30, float fEntry31, float fEntry32, float fEntry33)
|
|
{
|
|
m = new float[16] {
|
|
fEntry00, fEntry01, fEntry02, fEntry03,
|
|
fEntry10, fEntry11, fEntry12, fEntry13,
|
|
fEntry20, fEntry21, fEntry22, fEntry23,
|
|
fEntry30, fEntry31, fEntry32, fEntry33
|
|
};
|
|
}
|
|
// Operaitons
|
|
|
|
// Get row and column
|
|
public A3DVECTOR3 GetRow(int i) { int row = i * 4; return new A3DVECTOR3(m[row + 0], m[row + 1], m[row + 2]); }
|
|
public A3DVECTOR3 GetCol(int i) { return new A3DVECTOR3(m[(0 * 4) + i], m[(1 * 4) + i], m[(2 * 4) + i]); }
|
|
// Set row and column
|
|
public void SetRow(int i, A3DVECTOR3 v) { int row = i * 4; m[row + 0] = v.x; m[row + 1] = v.y; m[row + 2] = v.z; }
|
|
public void SetCol(int i, A3DVECTOR3 v) { m[(0 * 3) + i] = v.x; m[(1 * 3) + i] = v.y; m[(2 * 3) + i] = v.z; }
|
|
|
|
// * operator
|
|
public static A3DVECTOR3 operator *(A3DVECTOR3 v, A3DMATRIX4 mat)
|
|
{
|
|
A3DVECTOR3 vRet = new A3DVECTOR3(v.x * mat.m[0] + v.y * mat.m[4] + v.z * mat.m[8] + mat.m[12],
|
|
v.x * mat.m[1] + v.y * mat.m[5] + v.z * mat.m[9] + mat.m[13],
|
|
v.x * mat.m[2] + v.y * mat.m[6] + v.z * mat.m[10] + mat.m[14]);
|
|
float w = 1.0f / (v.x * mat.m[3] + v.y * mat.m[7] + v.z * mat.m[11] + mat.m[15]);
|
|
return vRet *= w;
|
|
}
|
|
public static A3DVECTOR3 operator *(A3DMATRIX4 mat, A3DVECTOR3 v)
|
|
{
|
|
A3DVECTOR3 vRet = new A3DVECTOR3(v.x * mat.m[0] + v.y * mat.m[4] + v.z * mat.m[8] + mat.m[12],
|
|
v.x * mat.m[1] + v.y * mat.m[5] + v.z * mat.m[9] + mat.m[13],
|
|
v.x * mat.m[2] + v.y * mat.m[6] + v.z * mat.m[10] + mat.m[14]);
|
|
float w = 1.0f / (v.x * mat.m[3] + v.y * mat.m[7] + v.z * mat.m[11] + mat.m[15]);
|
|
return vRet *= w;
|
|
}
|
|
|
|
|
|
public static A3DVECTOR4 operator *(A3DVECTOR4 v, A3DMATRIX4 mat)
|
|
{
|
|
return new A3DVECTOR4(v.m[0] * mat.m[0] + v.m[1] * mat.m[4] + v.m[2] * mat.m[8] + v.m[3] * mat.m[12],
|
|
v.m[0] * mat.m[1] + v.m[1] * mat.m[5] + v.m[2] * mat.m[9] + v.m[3] * mat.m[13],
|
|
v.m[0] * mat.m[2] + v.m[1] * mat.m[6] + v.m[2] * mat.m[10] + v.m[0] * mat.m[14],
|
|
v.m[0] * mat.m[3] + v.m[1] * mat.m[7] + v.m[2] * mat.m[11] + v.m[3] * mat.m[15]);
|
|
}
|
|
public static A3DVECTOR4 operator *(A3DMATRIX4 mat, A3DVECTOR4 v)
|
|
{
|
|
return new A3DVECTOR4(v.m[0] * mat.m[0] + v.m[1] * mat.m[4] + v.m[2] * mat.m[8] + v.m[3] * mat.m[12],
|
|
v.m[0] * mat.m[1] + v.m[1] * mat.m[5] + v.m[2] * mat.m[9] + v.m[3] * mat.m[13],
|
|
v.m[0] * mat.m[2] + v.m[1] * mat.m[6] + v.m[2] * mat.m[10] + v.m[3] * mat.m[14],
|
|
v.m[0] * mat.m[3] + v.m[1] * mat.m[7] + v.m[2] * mat.m[11] + v.m[3] * mat.m[15]);
|
|
}
|
|
public static A3DMATRIX4 operator *(A3DMATRIX4 mat1, A3DMATRIX4 mat2)
|
|
{
|
|
A3DMATRIX4 matRet = new A3DMATRIX4();
|
|
int lenght = 4;
|
|
for (int i = 0; i < lenght; i++)
|
|
{
|
|
for (int j = 0; j < lenght; j++)
|
|
{
|
|
for (int k = 0; k < lenght; k++)
|
|
//matRet.m[i,j] += mat1.m[i,k] * mat2.m[k,j];
|
|
matRet.m[(i * lenght) + j] += mat1.m[(i * lenght) + k] * mat2.m[(k * lenght) + j];
|
|
|
|
}
|
|
}
|
|
return matRet;
|
|
}
|
|
|
|
// Scale matrix
|
|
public static A3DMATRIX4 operator *(A3DMATRIX4 mat, float s)
|
|
{
|
|
A3DMATRIX4 matRet = new A3DMATRIX4();
|
|
int lenght = 4;
|
|
for (int i = 0; i < lenght; i++)
|
|
{
|
|
for (int j = 0; j < lenght; j++)
|
|
matRet.m[(i * lenght) + j] = mat.m[(i * lenght) + j] * s;
|
|
}
|
|
|
|
return matRet;
|
|
}
|
|
public static A3DMATRIX4 operator *(float s, A3DMATRIX4 mat) { return mat * s; }
|
|
public static A3DMATRIX4 operator /(A3DMATRIX4 mat, float s) { return mat * (1.0f / s); }
|
|
|
|
// *= operator
|
|
public A3DMATRIX4 MultiplyAssign(A3DMATRIX4 mat)
|
|
{
|
|
A3DMATRIX4 temp = this * mat;
|
|
Array.Copy(temp.m, this.m, temp.m.Length);
|
|
return this;
|
|
}
|
|
public A3DMATRIX4 MultiplyAssign(float s)
|
|
{
|
|
A3DMATRIX4 temp = this;
|
|
int lenght = 4;
|
|
for (int i = 0; i < lenght; i++)
|
|
{
|
|
for (int j = 0; j < lenght; j++)
|
|
m[(i * lenght) + j] *= s;
|
|
}
|
|
Array.Copy(temp.m, this.m, temp.m.Length);
|
|
return this;
|
|
}
|
|
// /= operator
|
|
public A3DMATRIX4 DivisionAssign(float s) { return MultiplyAssign(1.0f / s); }
|
|
|
|
// == operator
|
|
public static bool operator ==(A3DMATRIX4 mat1, A3DMATRIX4 mat2)
|
|
{
|
|
int lenght = 4;
|
|
for (int i = 0; i < lenght; i++)
|
|
{
|
|
for (int j = 0; j < lenght; j++)
|
|
{
|
|
if (mat1.m[(i * lenght) + j] != mat2.m[(i * lenght) + j])
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// != operator
|
|
public static bool operator !=(A3DMATRIX4 mat1, A3DMATRIX4 mat2)
|
|
{
|
|
int lenght = 4;
|
|
for (int i = 0; i < lenght; i++)
|
|
{
|
|
for (int j = 0; j < lenght; j++)
|
|
{
|
|
if (mat1.m[(i * lenght) + j] != mat2.m[(i * lenght) + j])
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// + operator
|
|
public static A3DMATRIX4 operator +(A3DMATRIX4 mat1, A3DMATRIX4 mat2)
|
|
{
|
|
A3DMATRIX4 matRet = new A3DMATRIX4();
|
|
int lenght = 4;
|
|
for (int i = 0; i < lenght; i++)
|
|
{
|
|
for (int j = 0; j < lenght; j++)
|
|
matRet.m[(i * lenght) + j] = mat1.m[(i * lenght) + j] + mat2.m[(i * lenght) + j];
|
|
}
|
|
return matRet;
|
|
}
|
|
// - operator
|
|
public static A3DMATRIX4 operator -(A3DMATRIX4 mat1, A3DMATRIX4 mat2)
|
|
{
|
|
int lenght = 4;
|
|
A3DMATRIX4 matRet = new A3DMATRIX4();
|
|
for (int i = 0; i < lenght; i++)
|
|
{
|
|
for (int j = 0; j < lenght; j++)
|
|
matRet.m[(i * lenght) + j] = mat1.m[(i * lenght) + j] - mat2.m[(i * lenght) + j];
|
|
}
|
|
|
|
return matRet;
|
|
}
|
|
// += operator
|
|
public A3DMATRIX4 AdditionAssign(A3DMATRIX4 mat)
|
|
{
|
|
int lenght = 4;
|
|
A3DMATRIX4 temp = this;
|
|
for (int i = 0; i < lenght; i++)
|
|
{
|
|
for (int j = 0; j < lenght; j++)
|
|
m[(i * lenght) + j] += mat.m[(i * lenght) + j];
|
|
}
|
|
Array.Copy(temp.m, this.m, temp.m.Length);
|
|
return this;
|
|
}
|
|
// -= operator
|
|
public A3DMATRIX4 SubtractionAssign(A3DMATRIX4 mat)
|
|
{
|
|
int lenght = 4;
|
|
A3DMATRIX4 temp = this;
|
|
for (int i = 0; i < lenght; i++)
|
|
{
|
|
for (int j = 0; j < lenght; j++)
|
|
m[(i * lenght) + j] -= mat.m[(i * lenght) + j];
|
|
}
|
|
Array.Copy(temp.m, this.m, temp.m.Length);
|
|
return this;
|
|
}
|
|
|
|
// Clear all elements to zero
|
|
public void Clear()
|
|
{
|
|
m = new float[16] {
|
|
0.0f, 0.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f, 0.0f
|
|
};
|
|
}
|
|
// Set matrix to identity matrix
|
|
public void Identity()
|
|
{
|
|
m = new float[16] {
|
|
1.0f, 0.0f, 0.0f, 0.0f,
|
|
0.0f, 1.0f, 0.0f, 0.0f,
|
|
0.0f, 0.0f, 1.0f, 0.0f,
|
|
0.0f, 0.0f, 0.0f, 1.0f
|
|
};
|
|
}
|
|
// Transpose matrix
|
|
public void Transpose()
|
|
{
|
|
float t = 0f;
|
|
t = m[1]; m[1] = m[4]; m[4] = t;
|
|
t = m[2]; m[2] = m[8]; m[8] = t;
|
|
t = m[3]; m[3] = m[12]; m[2] = t;
|
|
t = m[6]; m[6] = m[9]; m[9] = t;
|
|
t = m[7]; m[7] = m[13]; m[3] = t;
|
|
t = m[11]; m[11] = m[4]; m[4] = t;
|
|
}
|
|
// Get transpose matrix of this matrix
|
|
public A3DMATRIX4 GetTranspose()
|
|
{
|
|
int lenght = 4;
|
|
A3DMATRIX4 matRet = new A3DMATRIX4();
|
|
for (int i = 0; i < lenght; i++)
|
|
{
|
|
for (int j = 0; j < lenght; j++)
|
|
matRet.m[(i * lenght) + j] = m[(j * lenght) + i];
|
|
}
|
|
|
|
return matRet;
|
|
}
|
|
// Inverse matrix
|
|
// void Inverse() { *this = GetInverse(); }
|
|
// Get inverse matrix of this matrix
|
|
// A3DMATRIX4 GetInverse() const;
|
|
// Inverse matrix (used only by transform matrix)
|
|
public void InverseTM()
|
|
{
|
|
A3DMATRIX4 temp = GetInverseTM();
|
|
Array.Copy(temp.m, this.m, temp.m.Length);
|
|
}
|
|
// Get inverse matrix (used only by transform matrix)
|
|
public A3DMATRIX4 GetInverseTM()
|
|
{
|
|
float _11 = m[0], _12 = m[1], _13 = m[2], _14 = m[3];
|
|
float _21 = m[4], _22 = m[5], _23 = m[6], _24 = m[7];
|
|
float _31 = m[8], _32 = m[9], _33 = m[10], _34 = m[11];
|
|
float _41 = m[12], _42 = m[13], _43 = m[14], _44 = m[15];
|
|
|
|
float fDet = 1.0f / Det3x3(_11, _12, _13, _21, _22, _23, _31, _32, _33);
|
|
|
|
A3DMATRIX4 mat = new A3DMATRIX4();
|
|
|
|
mat.m[0] = fDet * Det3x3(_22, _23, _24, _32, _33, _34, _42, _43, _44);
|
|
mat.m[1] = -fDet * Det3x3(_12, _13, _14, _32, _33, _34, _42, _43, _44);
|
|
mat.m[2] = fDet * Det3x3(_12, _13, _14, _22, _23, _24, _42, _43, _44);
|
|
mat.m[3] = -fDet * Det3x3(_12, _13, _14, _22, _23, _24, _32, _33, _34);
|
|
|
|
mat.m[4] = -fDet * Det3x3(_21, _23, _24, _31, _33, _34, _41, _43, _44);
|
|
mat.m[5] = fDet * Det3x3(_11, _13, _14, _31, _33, _34, _41, _43, _44);
|
|
mat.m[6] = -fDet * Det3x3(_11, _13, _14, _21, _23, _24, _41, _43, _44);
|
|
mat.m[7] = fDet * Det3x3(_11, _13, _14, _21, _23, _24, _31, _33, _34);
|
|
|
|
mat.m[8] = fDet * Det3x3(_21, _22, _24, _31, _32, _34, _41, _42, _44);
|
|
mat.m[9] = -fDet * Det3x3(_11, _12, _14, _31, _32, _34, _41, _42, _44);
|
|
mat.m[10] = fDet * Det3x3(_11, _12, _14, _21, _22, _24, _41, _42, _44);
|
|
mat.m[11] = -fDet * Det3x3(_11, _12, _14, _21, _22, _24, _31, _32, _34);
|
|
|
|
mat.m[12] = -fDet * Det3x3(_21, _22, _23, _31, _32, _33, _41, _42, _43);
|
|
mat.m[13] = fDet * Det3x3(_11, _12, _13, _31, _32, _33, _41, _42, _43);
|
|
mat.m[14] = -fDet * Det3x3(_11, _12, _13, _21, _22, _23, _41, _42, _43);
|
|
mat.m[15] = fDet * Det3x3(_11, _12, _13, _21, _22, _23, _31, _32, _33);
|
|
|
|
return mat;
|
|
}
|
|
// Get determinant of this matrix
|
|
public float Determinant()
|
|
{
|
|
float _11 = m[0], _12 = m[1], _13 = m[2], _14 = m[3];
|
|
float _21 = m[4], _22 = m[5], _23 = m[6], _24 = m[7];
|
|
float _31 = m[8], _32 = m[9], _33 = m[10], _34 = m[11];
|
|
float _41 = m[12], _42 = m[13], _43 = m[14], _44 = m[15];
|
|
|
|
float fDet = 0f;
|
|
fDet = _11 * _22 * _33 * _44;
|
|
fDet += _21 * _32 * _43 * _14;
|
|
fDet += _31 * _42 * _13 * _24;
|
|
fDet += _41 * _12 * _23 * _34;
|
|
fDet -= _41 * _32 * _23 * _14;
|
|
fDet -= _42 * _33 * _24 * _11;
|
|
fDet -= _43 * _34 * _21 * _12;
|
|
fDet -= _44 * _31 * _22 * _13;
|
|
return fDet;
|
|
}
|
|
|
|
// Build matrix to be translation and rotation matrix
|
|
public void Translate(float x, float y, float z)
|
|
{
|
|
Identity();
|
|
m[12] = x;
|
|
m[13] = y;
|
|
m[14] = z;
|
|
}
|
|
public void RotateX(float fRad)
|
|
{
|
|
Identity();
|
|
m[10] = m[5] = Mathf.Cos(fRad);
|
|
m[6] = Mathf.Sin(fRad);
|
|
m[9] = -m[6];
|
|
}
|
|
public void RotateY(float fRad)
|
|
{
|
|
Identity();
|
|
m[10] = m[0] = Mathf.Cos(fRad);
|
|
m[8] = Mathf.Sin(fRad);
|
|
m[2] = -m[8];
|
|
}
|
|
public void RotateZ(float fRad)
|
|
{
|
|
Identity();
|
|
m[5] = m[0] = Mathf.Cos(fRad);
|
|
m[1] = Mathf.Sin(fRad);
|
|
m[4] = -m[1];
|
|
}
|
|
public void RotateAxis(A3DVECTOR3 v, float fRad)
|
|
{
|
|
float fCos = Mathf.Cos(fRad);
|
|
float fSin = Mathf.Sin(fRad);
|
|
|
|
m[0] = (v.x * v.x) * (1.0f - fCos) + fCos;
|
|
m[4] = (v.x * v.y) * (1.0f - fCos) - (v.z * fSin);
|
|
m[8] = (v.x * v.x) * (1.0f - fCos) + (v.y * fSin);
|
|
|
|
m[1] = (v.y * v.y) * (1.0f - fCos) + (v.z * fSin);
|
|
m[5] = (v.y * v.y) * (1.0f - fCos) + fCos;
|
|
m[9] = (v.y * v.z) * (1.0f - fCos) - (v.x * fSin);
|
|
|
|
m[2] = (v.z * v.x) * (1.0f - fCos) - (v.y * fSin);
|
|
m[6] = (v.z * v.y) * (1.0f - fCos) + (v.x * fSin);
|
|
m[10] = (v.z * v.z) * (1.0f - fCos) + fCos;
|
|
|
|
m[3] = m[7] = m[11] = 0.0f;
|
|
m[12] = m[13] = m[14] = 0.0f;
|
|
m[15] = 1.0f;
|
|
}
|
|
public void RotateAxis(A3DVECTOR3 vPos, A3DVECTOR3 vAxis, float fRad)
|
|
{
|
|
Translate(-vPos.x, -vPos.y, -vPos.z);
|
|
|
|
A3DMATRIX4 mat = new A3DMATRIX4();
|
|
mat.RotateAxis(vAxis, fRad);
|
|
MultiplyAssign(mat);
|
|
mat.Translate(vPos.x, vPos.y, vPos.z);
|
|
MultiplyAssign(mat);
|
|
}
|
|
public void Scale(float sx, float sy, float sz)
|
|
{
|
|
Clear();
|
|
m[0] = sx;
|
|
m[5] = sy;
|
|
m[10] = sz;
|
|
m[15] = 1.0f;
|
|
}
|
|
|
|
|
|
// Calcualte determinant of a 3x3 matrix
|
|
public float Det3x3(float a11, float a12, float a13, float a21, float a22, float a23,
|
|
float a31, float a32, float a33)
|
|
{
|
|
return a11 * a22 * a33 + a21 * a32 * a13 + a31 * a12 * a23 -
|
|
a13 * a22 * a31 - a23 * a32 * a11 - a33 * a12 * a21;
|
|
}
|
|
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class A3DVECTOR4
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
public struct A3DVECTOR4
|
|
{
|
|
float x;
|
|
float y;
|
|
float z;
|
|
float w;
|
|
|
|
public float[] m;
|
|
//{
|
|
// get => new float[] { x, y, z, w };
|
|
// set
|
|
// {
|
|
// if (value == null || value.Length < 4)
|
|
// throw new ArgumentException("Array must have at least 4 elements.");
|
|
// x = value[0];
|
|
// y = value[1];
|
|
// z = value[2];
|
|
// w = value[3];
|
|
// }
|
|
//}
|
|
|
|
// Constructors and Destructors
|
|
public A3DVECTOR4(float _x, float _y, float _z, float _w)
|
|
{
|
|
x = _x;
|
|
y = _y;
|
|
z = _z;
|
|
w = _w;
|
|
m = new float[] { x, y, z, w };
|
|
}
|
|
public A3DVECTOR4(float f)
|
|
{
|
|
x = y = z = w = f;
|
|
m = new float[] { x, y, z, w };
|
|
}
|
|
public A3DVECTOR4(float[] f)
|
|
{
|
|
if (f == null || f.Length < 4)
|
|
throw new ArgumentException("Array must have at least 4 elements.");
|
|
x = f[0]; y = f[1]; z = f[2]; w = f[3];
|
|
m = new float[] { x, y, z, w };
|
|
}
|
|
public A3DVECTOR4(A3DVECTOR4 v)
|
|
{
|
|
x = v.x; y = v.y; z = v.z; w = v.w;
|
|
m = new float[] { x, y, z, w };
|
|
}
|
|
public A3DVECTOR4(A3DVECTOR3 v)
|
|
{
|
|
x = v.x; y = v.y; z = v.z; w = 1.0f;
|
|
m = new float[] { x, y, z, w };
|
|
}
|
|
|
|
// Operations
|
|
|
|
// = operator
|
|
public A3DVECTOR4 assignment(A3DVECTOR4 v)
|
|
{
|
|
x = v.x; y = v.y; z = v.z; w = v.w; return this;
|
|
}
|
|
public A3DVECTOR4 assignment(A3DVECTOR3 v) { x = v.x; y = v.y; z = v.z; w = 1.0f; return this; }
|
|
|
|
public void Set(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; }
|
|
public void Clear() { x = y = z = w = 0.0f; }
|
|
};
|
|
|
|
|