Files
test/Assets/PerfectWorld/Scripts/Managers/A3DMatrix.cs
T
2025-10-07 14:11:28 +07:00

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; }
};