first commit
This commit is contained in:
239
include/framework/math/matrix4.h
Normal file
239
include/framework/math/matrix4.h
Normal 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__
|
||||
|
||||
Reference in New Issue
Block a user