first commit

This commit is contained in:
2026-06-22 11:49:35 +02:00
commit d805f2ba86
619 changed files with 126873 additions and 0 deletions

View File

@ -0,0 +1,239 @@
/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#ifndef __NMATRIX4__
#define __NMATRIX4__
#include "math/vector.h"
namespace GS {
class Matrix3;
/*!
@short 4x4 Matrix.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
class Matrix4
{
static Matrix4 static_identity;
public:
NPLACEMENT_NEW(Matrix)
/// The matrix values.
float m[4][4];
bool operator == (const Matrix4 &b) const
{
for (uint i = 0; i < 4; i++)
for (uint j = 0; j < 4; j++)
if (!Math::TestEqual(m[i][j], b.m[i][j]))
return false;
return true;
}
bool operator != (const Matrix4 &b) const
{
for (uint i = 0; i < 4; i++)
for (uint j = 0; j < 4; j++)
if (!Math::TestEqual(m[i][j], b.m[i][j]))
return true;
return false;
}
inline Matrix4 operator * (const Matrix4 &b) const
{
#define __M44M44(__I, __J) m[__I][0] * b.m[0][__J] + m[__I][1] * b.m[1][__J] + m[__I][2] * b.m[2][__J] + m[__I][3] * b.m[3][__J]
return Matrix4(
__M44M44(0, 0), __M44M44(1, 0), __M44M44(2, 0), __M44M44(3, 0),
__M44M44(0, 1), __M44M44(1, 1), __M44M44(2, 1), __M44M44(3, 1),
__M44M44(0, 2), __M44M44(1, 2), __M44M44(2, 2), __M44M44(3, 2),
__M44M44(0, 3), __M44M44(1, 3), __M44M44(2, 3), __M44M44(3, 3)
);
}
const Matrix4 operator * (float v) const
{
Matrix4 r;
for (uint j = 0; j < 4; ++j)
for (uint i = 0; i < 4; ++i)
r.m[i][j] = m[i][j] * v;
return r;
}
const Matrix4 operator + (const Matrix4 &b) const
{
Matrix4 r;
for (uint j = 0; j < 4; j++)
for (uint i = 0; i < 4; i++)
r.m[i][j] = m[i][j] + b.m[i][j];
return r;
}
/// Return the nth row.
inline Vector4 GetRow(uint n, bool w_to_one = true) const
{ return Vector4(m[0][n], m[1][n], m[2][n], w_to_one ? 1 : m[3][n]); }
/// Return the nth column.
inline Vector4 GetColumn(uint n, bool w_to_one = true) const
{ return Vector4(m[n][0], m[n][1], m[n][2], w_to_one ? 1 : m[n][3]); }
/// Set the nth row.
inline void SetRow(uint n, const Vector4 &r, bool w_to_one = true)
{ m[0][n] = r.x; m[1][n] = r.y; m[2][n] = r.z; m[3][n] = w_to_one ? 1 : r.w; }
/// Set the nth column.
inline void SetColumn(uint n, const Vector4 &c, bool w_to_one = true)
{ m[n][0] = c.x; m[n][1] = c.y; m[n][2] = c.z; m[n][3] = w_to_one ? 1 : c.w; }
bool Inverse(Matrix4 &out) const;
/*!
@short Return the inverse matrix using a fast approximation.
@warning This function works only for standard 3d transformation
matrices.
*/
Matrix4 InversedFast() const;
/// Transpose matrix.
Matrix4 Transposed() const
{
return Matrix4(
m[0][0], m[0][1], m[0][2], m[0][3],
m[1][0], m[1][1], m[1][2], m[1][3],
m[2][0], m[2][1], m[2][2], m[2][3],
m[3][0], m[3][1], m[3][2], m[3][3]
);
}
/// Normalize matrix.
Matrix4 AsOrthonormalBase() const;
/// Interpolate between two 4x4 transformation matrices.
static Matrix4 LerpAsOrthonormalBase(const Matrix4 &a, const Matrix4 &b, float k, bool fast = false);
/// Decompose a transformation matrix into a position vector, a scale vector and a 3x3 rotation matrix.
void Decompose(Vector4 *position, Vector4 *scale = 0, Matrix3 *rotation = 0) const;
/// Decompose a transformation matrix into a position vector, a scale vector and a rotation vector.
void Decompose(Vector4 *position, Vector4 *scale, Vector4 *rotation, Math::rOrder order = Math::rOrder_Default) const;
/// Apply to vector array.
inline void Apply(Vector4 *o, const Vector4 *i, uint n = 1) const
{
for (uint c = 0; c < n; c++)
{
o[c].x = i[c].x * m[0][0] + i[c].y * m[0][1] + i[c].z * m[0][2] + i[c].w * m[0][3];
o[c].y = i[c].x * m[1][0] + i[c].y * m[1][1] + i[c].z * m[1][2] + i[c].w * m[1][3];
o[c].z = i[c].x * m[2][0] + i[c].y * m[2][1] + i[c].z * m[2][2] + i[c].w * m[2][3];
o[c].w = i[c].x * m[3][0] + i[c].y * m[3][1] + i[c].z * m[3][2] + i[c].w * m[3][3];
}
}
/// Apply upper-left 3x3 sub-matrix to vector array.
inline void ApplyRotation(Vector4 *o, const Vector4 *i, uint n = 1) const
{
for (uint c = 0; c < n; c++)
{
o[c].x = i[c].x * m[0][0] + i[c].y * m[0][1] + i[c].z * m[0][2];
o[c].y = i[c].x * m[1][0] + i[c].y * m[1][1] + i[c].z * m[1][2];
o[c].z = i[c].x * m[2][0] + i[c].y * m[2][1] + i[c].z * m[2][2];
o[c].w = 1.f;
}
}
/// Set values.
void Set (
float m00, float m10, float m20, float m30,
float m01, float m11, float m21, float m31,
float m02, float m12, float m22, float m32,
float m03, float m13, float m23, float m33
)
{
m[0][0] = m00; m[1][0] = m10; m[2][0] = m20; m[3][0] = m30;
m[0][1] = m01; m[1][1] = m11; m[2][1] = m21; m[3][1] = m31;
m[0][2] = m02; m[1][2] = m12; m[2][2] = m22; m[3][2] = m32;
m[0][3] = m03; m[1][3] = m13; m[2][3] = m23; m[3][3] = m33;
}
/// Identity matrix.
static const Matrix4 &IdentityMatrix()
{ return static_identity; }
/// Translation matrix.
static Matrix4 TranslationMatrix(const Vector4 &t);
/// Scale matrix.
static Matrix4 ScaleMatrix(const Vector4 &s);
/// From matrix3.
static Matrix4 FromMatrix3(const Matrix3 &mtx);
/// Position/scale/rotation/offset matrix.
static Matrix4 TransformationMatrix(const Vector4 &p, const Vector4 &r, const Vector4 &s, const Vector4 *o = 0);
/// Position/scale/rotation/offset matrix.
static Matrix4 TransformationMatrix(const Vector4 &p, const Matrix3 &r, const Vector4 &s, const Vector4 *o = 0);
NML::Tag *AsMetaTag(const char *id) const;
bool FromMetaTag(NML::Tag &);
Matrix4(
float m00, float m10, float m20, float m30,
float m01, float m11, float m21, float m31,
float m02, float m12, float m22, float m32,
float m03, float m13, float m23, float m33
)
{
m[0][0] = m00; m[1][0] = m10; m[2][0] = m20; m[3][0] = m30;
m[0][1] = m01; m[1][1] = m11; m[2][1] = m21; m[3][1] = m31;
m[0][2] = m02; m[1][2] = m12; m[2][2] = m22; m[3][2] = m32;
m[0][3] = m03; m[1][3] = m13; m[2][3] = m23; m[3][3] = m33;
}
Matrix4() {}
};
/*
@short 4x4 matrix with inverse.
@author Emmanuel Julien (ejulien@gsworks.fr)
*/
class Matrix4WithInverse
{
protected:
NPLACEMENT_NEW(Matrix)
Matrix4 matrix,
imatrix;
/// Commit a matrix change.
void Commit();
public:
/// Return the matrix inverse.
const Matrix4 &Get() const;
/// Return the matrix inverse.
const Matrix4 &GetInverse() const;
/// Set matrix.
void Set(const Matrix4 &m);
/// Return the nth row.
Vector4 GetRow(uint n, bool w_1 = true) const;
/// Return the nth column.
Vector4 GetColumn(uint n, bool w_1 = true) const;
/// Set the nth row.
void SetRow(uint n, const Vector4 &row, bool w_1 = true);
/// Set the nth column.
void SetColumn(uint n, const Vector4 &col, bool w_1 = true);
bool FromMetaTag(NML::Tag &tag);
NML::Tag *AsMetaTag(const char *id) const;
Matrix4WithInverse()
{
matrix = Matrix4::IdentityMatrix();
imatrix = Matrix4::IdentityMatrix();
}
};
} // GS
#endif // __NMATRIX4__