Files
Webcam/include/framework/math/matrix3.h
2026-06-22 11:49:35 +02:00

226 lines
6.0 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NMATRIX3__
#define __NMATRIX3__
#include "math/vector.h"
namespace GS {
struct Quaternion;
class Matrix4;
/*!
@short 3x3 Matrix.
This matrix class is column major.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
class Matrix3
{
static Matrix3 static_identity;
public:
NPLACEMENT_NEW(Matrix)
/// The matrix values.
float m[3][3];
bool operator == (const Matrix3 &b) const
{
for (uint i = 0; i < 3; i++)
for (uint j = 0; j < 3; j++)
if (!Math::TestEqual(m[i][j], b.m[i][j]))
return false;
return true;
}
bool operator != (const Matrix3 &b) const
{
for (uint i = 0; i < 3; i++)
for (uint j = 0; j < 3; j++)
if (!Math::TestEqual(m[i][j], b.m[i][j]))
return true;
return false;
}
Matrix3 operator + (const Matrix3 &b) const
{
Matrix3 r;
for (uint j = 0; j < 3; j++)
for (uint i = 0; i < 3; i++)
r.m[i][j] = m[i][j] + b.m[i][j];
return r;
}
void operator += (const Matrix3 &b)
{ *this = *this + b; }
void operator *= (const float k)
{
for (uint j = 0; j < 3; j++)
for (uint i = 0; i < 3; i++)
m[i][j] *= k;
}
void operator /= (const float k)
{
for (uint j = 0; j < 3; j++)
for (uint i = 0; i < 3; i++)
m[i][j] /= k;
}
Matrix3 operator - (const Matrix3 &b) const
{
Matrix3 r;
for (uint j = 0; j < 3; j++)
for (uint i = 0; i < 3; i++)
r.m[i][j] = m[i][j] - b.m[i][j];
return r;
}
void operator -= (const Matrix3 &b)
{ *this = *this - b; }
Vector4 operator * (const Vector4 &v) const
{
Vector4 o;
o.x = v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2];
o.y = v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2];
o.z = v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2];
o.w = 1;
return o;
}
Matrix3 operator * (const Matrix3 &b) const
{
#define __M33M33(__I, __J) m[__I][0] * b.m[0][__J] + m[__I][1] * b.m[1][__J] + m[__I][2] * b.m[2][__J]
return Matrix3 (
__M33M33(0, 0), __M33M33(1, 0), __M33M33(2, 0),
__M33M33(0, 1), __M33M33(1, 1), __M33M33(2, 1),
__M33M33(0, 2), __M33M33(1, 2), __M33M33(2, 2)
);
}
Matrix3 operator * (const float v) const
{
Matrix3 r;
for (uint j = 0; j < 3; j++)
for (uint i = 0; i < 3; i++)
r.m[i][j] = m[i][j] * v;
return r;
}
void operator *= (const Matrix3 &b)
{ *this = (*this) * b; }
Matrix3 operator / (const float v) const
{
Matrix3 r;
for (uint j = 0; j < 3; j++)
for (uint i = 0; i < 3; i++)
r.m[i][j] = m[i][j] / v;
return r;
}
/// Apply to a set of vector objects.
void Apply(Vector4 *o, const Vector4 *v, uint n = 1) const;
/// Compute the determinant of the matrix.
float Det() const
{
return ((m[1][1] * m[2][2]) - (m[1][2] * m[2][1])) * m[0][0] +
((m[1][2] * m[2][0]) - (m[1][0] * m[2][2])) * m[0][1] +
((m[1][0] * m[2][1]) - (m[1][1] * m[2][0])) * m[0][2];
}
/// Compute inverse matrix.
bool Inverse(Matrix3 &i) const;
/// Return the transposed matrix.
inline Matrix3 Transposed() const
{
return Matrix3
(
m[0][0], m[0][1], m[0][2],
m[1][0], m[1][1], m[1][2],
m[2][0], m[2][1], m[2][2]
);
}
/// Return the nth row.
inline Vector4 GetRow(uint n) const { return Vector4(m[0][n], m[1][n], m[2][n]); }
/// Return the nth column.
inline Vector4 GetColumn(uint n) const { return Vector4(m[n][0], m[n][1], m[n][2]); }
/// Set the nth row.
void SetRow(uint n, const Vector4 &row);
/// Set the nth column.
void SetColumn(uint n, const Vector4 &col);
/// Set matrix values.
void Set (
float m00, float m10, float m20,
float m01, float m11, float m21,
float m02, float m12, float m22
);
/// Set matrix values.
void Set(const Vector4 &u, const Vector4 &v, const Vector4 &w);
/// Return this matrix after normalization.
Matrix3 Normalized() const;
/// Normalize as orthonormal base.
Matrix3 AsOrthonormalBase() const;
/// Return an Euler orientation equivalent to this matrix.
Vector4 AsEuler(Math::rOrder rorder = Math::rOrder_Default) const;
/// Vector matrix.
static Matrix3 VectorMatrix(const Vector4 &v);
/// Identity matrix.
static Matrix3 &IdentityMatrix() { return static_identity; }
/// Translation matrix.
static Matrix3 TranslationMatrix(const Vector2 &t);
static Matrix3 TranslationMatrix(const Vector4 &t);
/// Scale matrix.
static Matrix3 ScaleMatrix(const Vector2 &s);
static Matrix3 ScaleMatrix(const Vector4 &s);
/// Cross product matrix.
static Matrix3 CrossProductMatrix(const Vector4 &v);
/// Rotation matrix around X axis.
static Matrix3 RotationMatrixXAxis(float a);
/// Rotation matrix around Y axis.
static Matrix3 RotationMatrixYAxis(float a);
/// Rotation matrix around Z axis.
static Matrix3 RotationMatrixZAxis(float a);
/*!
@short From Orthonormal basis.
Transform an orthogonal basis formed by one or two vectors to a
rotation matrix.
@note Left-handed base, eg: u = {1,0,0}, v = {0,1,0}, w = {0,0,1}.
*/
static Matrix3 FromOrthonormalBasis(const Vector4 &w, const Vector4 *v = 0);
/// From Euler triplet.
static Matrix3 FromEuler(float x = 0, float y = 0, float z = 0, Math::rOrder rorder = Math::rOrder_Default);
/// From Euler vector.
static Matrix3 FromEuler(const Vector4 &euler, Math::rOrder rorder = Math::rOrder_Default);
/// From matrix4.
static Matrix3 FromMatrix4(const Matrix4 &mtx);
NML::Tag *AsMetaTag(const char *) const;
bool FromMetaTag(NML::Tag &);
Matrix3(
float m00 = 1, float m10 = 0, float m20 = 0,
float m01 = 0, float m11 = 1, float m21 = 0,
float m02 = 0, float m12 = 0, float m22 = 1
)
{ Set(m00, m10, m20, m01, m11, m21, m02, m12, m22); }
Matrix3(const Vector4 &u, const Vector4 &v, const Vector4 &w)
{ Set(u, v, w); }
};
} // GS
#endif // __NMATRIX3__