253 lines
8.7 KiB
C#
253 lines
8.7 KiB
C#
namespace SourceFormatParser.Common
|
|
{
|
|
/// <summary>
|
|
/// Matrix 3x4 (float)
|
|
/// Size: 48 bytes (4 bytes per val)
|
|
/// </summary>
|
|
public class SourceMatrix3x4
|
|
{
|
|
public SourceMatrix3x4() { }
|
|
public SourceMatrix3x4(float m00, float m01, float m02, float m03,
|
|
float m10, float m11, float m12, float m13,
|
|
float m20, float m21, float m22, float m23)
|
|
{
|
|
m_flMatVal[0][0] = m00; m_flMatVal[0][1] = m01; m_flMatVal[0][2] = m02; m_flMatVal[0][3] = m03;
|
|
m_flMatVal[1][0] = m10; m_flMatVal[1][1] = m11; m_flMatVal[1][2] = m12; m_flMatVal[1][3] = m13;
|
|
m_flMatVal[2][0] = m20; m_flMatVal[2][1] = m21; m_flMatVal[2][2] = m22; m_flMatVal[2][3] = m23;
|
|
}
|
|
|
|
/// Creates a matrix where the X axis = forward the Y axis = left, and the Z axis = up
|
|
void InitXYZ(SourceVector xAxis, SourceVector yAxis, SourceVector zAxis, SourceVector vecOrigin)
|
|
{
|
|
m_flMatVal[0][0] = xAxis.x; m_flMatVal[0][1] = yAxis.x; m_flMatVal[0][2] = zAxis.x; m_flMatVal[0][3] = vecOrigin.x;
|
|
m_flMatVal[1][0] = xAxis.y; m_flMatVal[1][1] = yAxis.y; m_flMatVal[1][2] = zAxis.y; m_flMatVal[1][3] = vecOrigin.y;
|
|
m_flMatVal[2][0] = xAxis.z; m_flMatVal[2][1] = yAxis.z; m_flMatVal[2][2] = zAxis.z; m_flMatVal[2][3] = vecOrigin.z;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Creates a matrix where the X axis = forward
|
|
// the Y axis = left, and the Z axis = up
|
|
//-----------------------------------------------------------------------------
|
|
void Init(SourceVector xAxis, SourceVector yAxis, SourceVector zAxis, SourceVector vecOrigin)
|
|
{
|
|
m_flMatVal[0][0] = xAxis.x; m_flMatVal[0][1] = yAxis.x; m_flMatVal[0][2] = zAxis.x; m_flMatVal[0][3] = vecOrigin.x;
|
|
m_flMatVal[1][0] = xAxis.y; m_flMatVal[1][1] = yAxis.y; m_flMatVal[1][2] = zAxis.y; m_flMatVal[1][3] = vecOrigin.y;
|
|
m_flMatVal[2][0] = xAxis.z; m_flMatVal[2][1] = yAxis.z; m_flMatVal[2][2] = zAxis.z; m_flMatVal[2][3] = vecOrigin.z;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Creates a matrix where the X axis = forward
|
|
// the Y axis = left, and the Z axis = up
|
|
//-----------------------------------------------------------------------------
|
|
public SourceMatrix3x4(SourceVector xAxis, SourceVector yAxis, SourceVector zAxis, SourceVector vecOrigin)
|
|
{
|
|
Init(xAxis, yAxis, zAxis, vecOrigin);
|
|
}
|
|
|
|
public void InitFromQAngles(SourceQAngle angles, SourceVector vPosition)
|
|
{
|
|
var t = this;
|
|
MathUtils.AngleMatrix(angles, vPosition, ref t);
|
|
this.m_flMatVal = t.m_flMatVal;
|
|
}
|
|
public void InitFromQAngles(SourceQAngle angles) { InitFromQAngles(angles, SourceVector.Empty); }
|
|
public void InitFromRadianEuler(SourceRadianEuler angles, SourceVector vPosition)
|
|
{
|
|
var t = this;
|
|
MathUtils.AngleMatrix(angles, vPosition, ref t);
|
|
this.m_flMatVal = t.m_flMatVal;
|
|
}
|
|
public void InitFromRadianEuler(SourceRadianEuler angles) { InitFromRadianEuler(angles, SourceVector.Empty); }
|
|
public void InitFromCTransform(SourceCTransform transform)
|
|
{
|
|
var t = this;
|
|
MathUtils.TransformMatrix(transform, ref t);
|
|
this.m_flMatVal = t.m_flMatVal;
|
|
}
|
|
public void InitFromQuaternion(SourceQuaternion orientation, SourceVector vPosition)
|
|
{
|
|
var t = this;
|
|
MathUtils.QuaternionMatrix(orientation, vPosition, ref t);
|
|
this.m_flMatVal = t.m_flMatVal;
|
|
}
|
|
public void InitFromQuaternion(SourceQuaternion orientation) { InitFromQuaternion(orientation, SourceVector.Empty); }
|
|
public void InitFromDiagonal(SourceVector vDiagonal)
|
|
{
|
|
SetToIdentity();
|
|
m_flMatVal[0][0] = vDiagonal.x;
|
|
m_flMatVal[1][1] = vDiagonal.y;
|
|
m_flMatVal[2][2] = vDiagonal.z;
|
|
}
|
|
|
|
public SourceQuaternion ToQuaternion() => MathUtils.MatrixQuaternion(this);
|
|
public SourceQAngle ToQAngle()
|
|
{
|
|
SourceQAngle tmp = new SourceQAngle();
|
|
MathUtils.MatrixAngles(this, ref tmp);
|
|
return tmp;
|
|
}
|
|
public SourceCTransform ToCTransform() => MathUtils.MatrixTransform(this);
|
|
|
|
public void SetToIdentity()
|
|
{
|
|
for (int i1 = 0; i1 < m_flMatVal.Length; i1++)
|
|
for (int i2 = 0; i2 < m_flMatVal[i1].Length; i2++)
|
|
m_flMatVal[i1][i2] = 0.0f;
|
|
m_flMatVal[0][0] = 1.0f;
|
|
m_flMatVal[1][1] = 1.0f;
|
|
m_flMatVal[2][2] = 1.0f;
|
|
}
|
|
|
|
/// multiply the scale/rot part of the matrix by a constant. This doesn't init the matrix ,
|
|
/// just scale in place. So if you want to construct a scaling matrix, init to identity and
|
|
/// then call this.
|
|
public void ScaleUpper3x3Matrix(float flScale)
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
for (int j = 0; j < 3; j++)
|
|
{
|
|
m_flMatVal[i][j] *= flScale;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// modify the origin
|
|
public void SetOrigin(SourceVector p)
|
|
{
|
|
m_flMatVal[0][3] = p.x;
|
|
m_flMatVal[1][3] = p.y;
|
|
m_flMatVal[2][3] = p.z;
|
|
}
|
|
|
|
/// return the origin
|
|
public SourceVector GetOrigin()
|
|
{
|
|
return new SourceVector(m_flMatVal[0][3], m_flMatVal[1][3], m_flMatVal[2][3]);
|
|
}
|
|
|
|
void Invalidate()
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
for (int j = 0; j < 4; j++)
|
|
{
|
|
m_flMatVal[i][j] = float.NaN;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// check all components for invalid floating point values
|
|
bool IsValid()
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
for (int j = 0; j < 4; j++)
|
|
{
|
|
if (m_flMatVal[i][j] == float.NaN)
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static bool operator ==(SourceMatrix3x4 m1, SourceMatrix3x4 m2)
|
|
{
|
|
bool equals = true;
|
|
for (int i1 = 0; i1 < 3; i1++)
|
|
{
|
|
if (!equals) break;
|
|
for (int i2 = 0; i2 < 4; i2++)
|
|
{
|
|
if (m1[i1][i2] != m2[i1][i2])
|
|
{
|
|
equals = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return equals;
|
|
}
|
|
public static bool operator !=(SourceMatrix3x4 m1, SourceMatrix3x4 m2) => !(m1 == m2);
|
|
|
|
public override bool Equals(object obj) => this == (SourceMatrix3x4)obj;
|
|
public override int GetHashCode() => base.GetHashCode();
|
|
|
|
// bool IsEqualTo( const SourceMatrix3x4 &other, float flTolerance = 1e-5f) const;
|
|
|
|
//void GetBasisVectorsFLU(Vector* pForward, Vector* pLeft, Vector* pUp) const;
|
|
//SourceVector TransformVector( const Vector &v0 ) const;
|
|
//SourceVector RotateVector( const Vector &v0 ) const;
|
|
//SourceVector TransformVectorByInverse( const Vector &v0 ) const;
|
|
//SourceVector RotateVectorByInverse( const Vector &v0 ) const;
|
|
//SourceVector RotateExtents( const Vector &vBoxExtents ) const; // these are extents and must remain positive/symmetric after rotation
|
|
public void TransformAABB(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
|
|
{
|
|
MathUtils.TransformAABB(this, vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
|
|
}
|
|
public void TransformAABBByInverse(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
|
|
{
|
|
MathUtils.ITransformAABB(this, vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
|
|
}
|
|
public void RotateAABB(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
|
|
{
|
|
MathUtils.RotateAABB(this, vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
|
|
}
|
|
public void RotateAABBByInverse(SourceVector vecMinsIn, SourceVector vecMaxsIn, ref SourceVector vecMinsOut, ref SourceVector vecMaxsOut)
|
|
{
|
|
MathUtils.IRotateAABB(this, vecMinsIn, vecMaxsIn, ref vecMinsOut, ref vecMaxsOut);
|
|
}
|
|
//void TransformPlane( const cplane_t &inPlane, cplane_t &outPlane ) const;
|
|
//void TransformPlaneByInverse( const cplane_t &inPlane, cplane_t &outPlane ) const;
|
|
//float GetOrthogonalityError() const;
|
|
//float GetDeterminant()const;
|
|
//float GetSylvestersCriterion()const; // for symmetrical matrices only: should be >0 iff it's a positive definite matrix
|
|
|
|
//SourceVector GetColumn(MatrixAxisType_t nColumn) const;
|
|
//void SetColumn( const Vector &vColumn, MatrixAxisType_t nColumn);
|
|
//SourceVector GetForward() const { return GetColumn(FORWARD_AXIS ); }
|
|
// SourceVector GetLeft() const { return GetColumn(LEFT_AXIS ); }
|
|
// SourceVector GetUp() const { return GetColumn(UP_AXIS ); }
|
|
// SourceVector GetRow(int nRow) const { return * (Vector*) (m_flMatVal[nRow]); }
|
|
// void SetRow(int nRow, const Vector &vRow ) { m_flMatVal[nRow][0] = vRow.x; m_flMatVal[nRow][1] = vRow.y; m_flMatVal[nRow][2] = vRow.z; }
|
|
|
|
public void InverseTR(ref SourceMatrix3x4 _out)
|
|
{
|
|
MathUtils.MatrixInvert(this, ref _out);
|
|
}
|
|
public SourceMatrix3x4 InverseTR()
|
|
{
|
|
SourceMatrix3x4 _out = new SourceMatrix3x4();
|
|
InverseTR(ref _out);
|
|
return _out;
|
|
}
|
|
|
|
public float[] this[int i]
|
|
{
|
|
get => m_flMatVal[i];
|
|
set => m_flMatVal[i] = value;
|
|
}
|
|
|
|
public float Base() { return m_flMatVal[0][0]; }
|
|
|
|
float[][] _m_flMatVal;
|
|
public float[][] m_flMatVal//[3][4];
|
|
{
|
|
get
|
|
{
|
|
if (_m_flMatVal == null)
|
|
{
|
|
_m_flMatVal = new float[3][];
|
|
for (int v = 0; v < 3; v++)
|
|
_m_flMatVal[v] = new float[4];
|
|
}
|
|
return _m_flMatVal;
|
|
}
|
|
set
|
|
{
|
|
_m_flMatVal = value;
|
|
}
|
|
}
|
|
}
|
|
}
|