first commit
This commit is contained in:
225
include/framework/math/matrix3.h
Normal file
225
include/framework/math/matrix3.h
Normal file
@ -0,0 +1,225 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
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__
|
||||
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__
|
||||
|
||||
107
include/framework/math/quaternion.h
Normal file
107
include/framework/math/quaternion.h
Normal file
@ -0,0 +1,107 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NQUATERNION__
|
||||
#define __NQUATERNION__
|
||||
|
||||
|
||||
#include "math/nmath.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
struct Vector4;
|
||||
class Matrix3;
|
||||
|
||||
namespace NML {
|
||||
class File;
|
||||
class Tag;
|
||||
}
|
||||
|
||||
/*!
|
||||
@short Quaternion.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct Quaternion
|
||||
{
|
||||
float x, y, z, w;
|
||||
|
||||
void operator += (const Quaternion &b) { x += b.x; y += b.y; z += b.z; w += b.w; };
|
||||
void operator += (float k) { x += k; y += k; z += k; w += k; };
|
||||
void operator -= (const Quaternion &b) { x -= b.x; y -= b.y; z -= b.z; w -= b.w; };
|
||||
void operator -= (float k) { x -= k; y -= k; z -= k; w -= k; };
|
||||
void operator *= (const Quaternion &b)
|
||||
{
|
||||
Quaternion t = *this;
|
||||
w = t.w * b.w - (t.x * b.x + t.y * b.y + t.z * b.z);
|
||||
x = t.w * b.x + b.w * t.x + t.y * b.z - t.z * b.y;
|
||||
y = t.w * b.y + b.w * t.y + t.z * b.x - t.x * b.z;
|
||||
z = t.w * b.z + b.w * t.z + t.x * b.y - t.y * b.x;
|
||||
};
|
||||
void operator *= (float k) { x *= k; y *= k; z *= k; w *= k; };
|
||||
void operator /= (float k) { k = 1.f / k; x *= k; y *= k; z *= k; w *= k; };
|
||||
|
||||
Quaternion operator + (const Quaternion &b) const
|
||||
{ return Quaternion(x + b.x, y + b.y, z + b.z, w + b.w); }
|
||||
Quaternion operator + (float v) const
|
||||
{ return Quaternion(x + v, y + v, z + v, w + v); }
|
||||
Quaternion operator - (const Quaternion &b) const
|
||||
{ return Quaternion(x - b.x, y - b.y, z - b.z, w - b.w); }
|
||||
Quaternion operator - (float v) const
|
||||
{ return Quaternion(x - v, y - v, z - v, w - v); }
|
||||
Quaternion operator * (const Quaternion &b) const
|
||||
{
|
||||
return Quaternion (
|
||||
w * b.x + b.w * x + y * b.z - z * b.y,
|
||||
w * b.y + b.w * y + z * b.x - x * b.z,
|
||||
w * b.z + b.w * z + x * b.y - y * b.x,
|
||||
w * b.w - (x * b.x + y * b.y + z * b.z)
|
||||
);
|
||||
}
|
||||
Quaternion operator * (float v) const
|
||||
{ return Quaternion(x * v, y * v, z * v, w * v); }
|
||||
Quaternion operator / (float v) const
|
||||
{ v = 1.f / v; return Quaternion(x * v, y * v, z * v, w * v); }
|
||||
|
||||
/// Dot product.
|
||||
float Dot(const Quaternion &b) const
|
||||
{ return x * b.x + y * b.y + z * b.z + w * b.w; }
|
||||
|
||||
/// Normalize quaternion.
|
||||
Quaternion Normalize() const;
|
||||
/// Inverse quaternion.
|
||||
Quaternion Inverse() const;
|
||||
/// To rotation matrix.
|
||||
Matrix3 AsMatrix3() const;
|
||||
|
||||
/// Distance to quaternion.
|
||||
static float Distance(const Quaternion &a, const Quaternion &b);
|
||||
/// Slerp.
|
||||
static Quaternion Slerp(float t, const Quaternion &a, const Quaternion &b);
|
||||
|
||||
/// From Euler angle.
|
||||
static Quaternion FromEuler(float x, float y, float z, Math::rOrder rorder = Math::rOrder_Default);
|
||||
/// Get an orientation from a 'look at' vector (look_at = to - from).
|
||||
static Quaternion LookAt(const Vector4 &at);
|
||||
/// From matrix3.
|
||||
static Quaternion FromMatrix3(const Matrix3 &m);
|
||||
/// From axis-angle.
|
||||
static Quaternion FromAxisAngle(float angle, float x, float y, float z);
|
||||
|
||||
/// Set quaternion values.
|
||||
void Set(float _x = 0, float _y = 0, float _z = 0, float _w = 1.f)
|
||||
{ x = _x; y = _y; z = _z; w = _w; }
|
||||
|
||||
NML::Tag *AsMetaTag(const char *id) const;
|
||||
bool FromMetaTag(NML::Tag &tag);
|
||||
|
||||
Quaternion(float _x = 0, float _y = 0, float _z = 0, float _w = 1.f)
|
||||
{ Set(_x, _y, _z, _w); }
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NQUATERNION__
|
||||
301
include/framework/math/vector.h
Normal file
301
include/framework/math/vector.h
Normal file
@ -0,0 +1,301 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NVECTOR__
|
||||
#define __NVECTOR__
|
||||
|
||||
|
||||
#include "math/nmath.h"
|
||||
#include "alloc/ialloc.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
class Matrix3;
|
||||
class Matrix4;
|
||||
|
||||
namespace NML {
|
||||
class File;
|
||||
class Tag;
|
||||
}
|
||||
|
||||
/*!
|
||||
@short Vector 2d template class.
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
template <class T> struct tVector2
|
||||
{
|
||||
NPLACEMENT_NEW(Vector)
|
||||
|
||||
T x, y;
|
||||
|
||||
inline bool operator == (const tVector2 <T> &b) const { return (x == b.x) && (y == b.y); }
|
||||
inline bool operator != (const tVector2 <T> &b) const { return (x != b.x) || (y != b.y); }
|
||||
|
||||
inline void operator += (const tVector2 <T> &b) { x += b.x; y += b.y; }
|
||||
inline void operator += (const float k) { x += k; y += k; }
|
||||
inline void operator -= (const tVector2 <T> &b) { x -= b.x; y -= b.y; }
|
||||
inline void operator -= (const float k) { x -= k; y -= k; }
|
||||
inline void operator *= (const tVector2 <T> &b) { x *= b.x; y *= b.y; }
|
||||
inline void operator *= (const float k) { x *= k; y *= k; }
|
||||
inline void operator /= (const tVector2 <T> &b) { x /= b.x; y /= b.y; }
|
||||
inline void operator /= (const float k) { x /= k; y /= k; }
|
||||
|
||||
inline tVector2 <T> operator + (const tVector2 <T> &b) const { return tVector2 <T> (x + b.x, y + b.y); }
|
||||
inline tVector2 <T> operator + (const T v) const { return tVector2 <T> (x + v, y + v); }
|
||||
inline tVector2 <T> operator - (const tVector2 <T> &b) const { return tVector2 <T> (x - b.x, y - b.y); }
|
||||
inline tVector2 <T> operator - (const T v) const { return tVector2 <T> (x - v, y - v); }
|
||||
inline tVector2 <T> operator * (const tVector2 <T> &b) const { return tVector2 <T> (x * b.x, y * b.y); }
|
||||
inline tVector2 <T> operator * (const T v) const { return tVector2 <T> (x * v, y * v); }
|
||||
inline tVector2 <T> operator / (const tVector2 <T> &b) const { return tVector2 <T> (x / b.x, y / b.y); }
|
||||
inline tVector2 <T> operator / (const T v) const { return tVector2 <T> (x / v, y / v); }
|
||||
|
||||
tVector2 <T> operator * (const Matrix3 &m) const;
|
||||
|
||||
/// Squared vector length.
|
||||
inline float Len2() const { return (float)(x * x + y * y); }
|
||||
/// Vector length.
|
||||
inline float Len() const { return Math::Sqrt((float)(x * x + y * y)); }
|
||||
|
||||
/// Normalize this vector.
|
||||
inline void Normalize() { float l = Len(); if (l) { float k = 1.f / l; x *= k; y *= k; } }
|
||||
/// Normalize vector.
|
||||
inline tVector2 <T> Normalized() const
|
||||
{
|
||||
float k = 1.f / Len();
|
||||
return tVector2 <T>(x * k, y * k);
|
||||
}
|
||||
|
||||
/// Reversed vector.
|
||||
inline tVector2 <T> Reversed() const
|
||||
{ return tVector2 <T> (-x, -y); }
|
||||
|
||||
/// Vector squared distance.
|
||||
static float Dist2(const tVector2 &a, const tVector2 &b)
|
||||
{ return ((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y)); }
|
||||
/// Vector distance.
|
||||
static float Dist(const tVector2 &a, const tVector2 &b)
|
||||
{ return Math::Sqrt((float)((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y))); }
|
||||
|
||||
/// Set vector 2D components.
|
||||
inline void Set(const T a, const T b) { x = a; y = b; }
|
||||
|
||||
tVector2 <T> (T a, T b) { Set(a, b); }
|
||||
tVector2 <T> () { Set(0, 0); }
|
||||
};
|
||||
|
||||
typedef tVector2 <float> Vector2;
|
||||
|
||||
/*!
|
||||
@short 4-Component vector
|
||||
@author Emmanuel Julien (ejulien@gsworks.fr)
|
||||
*/
|
||||
struct Vector4
|
||||
{
|
||||
NPLACEMENT_NEW(Vector)
|
||||
|
||||
float x, y, z, w;
|
||||
|
||||
inline bool operator == (const Vector4 &b) const { return Math::TestEqual(x, b.x) && Math::TestEqual(y, b.y) && Math::TestEqual(z, b.z); }
|
||||
inline bool operator != (const Vector4 &b) const { return !Math::TestEqual(x, b.x) || !Math::TestEqual(y, b.y) || !Math::TestEqual(z, b.z); }
|
||||
|
||||
inline void operator += (const Vector4 &b) { x += b.x; y += b.y; z += b.z; };
|
||||
inline void operator += (const float k) { x += k; y += k; z += k; };
|
||||
inline void operator -= (const Vector4 &b) { x -= b.x; y -= b.y; z -= b.z; };
|
||||
inline void operator -= (const float k) { x -= k; y -= k; z -= k; };
|
||||
inline void operator *= (const Vector4 &b) { x *= b.x; y *= b.y; z *= b.z; };
|
||||
inline void operator *= (const float k) { x *= k; y *= k; z *= k; };
|
||||
inline void operator /= (const Vector4 &b) { x /= b.x; y /= b.y; z /= b.z; };
|
||||
inline void operator /= (const float k) { float k_ = k ? 1 / k : 0; x *= k_; y *= k_; z *= k_; };
|
||||
|
||||
inline Vector4 operator + (const Vector4 &b) const { return Vector4(x + b.x, y + b.y, z + b.z); }
|
||||
inline Vector4 operator + (const float v) const { return Vector4(x + v, y + v, z + v); }
|
||||
inline Vector4 operator - (const Vector4 &b) const { return Vector4(x - b.x, y - b.y, z - b.z); }
|
||||
inline Vector4 operator - (const float v) const { return Vector4(x - v, y - v, z - v); }
|
||||
inline Vector4 operator * (const Vector4 &b) const { return Vector4(x * b.x, y * b.y, z * b.z); }
|
||||
inline Vector4 operator * (const float v) const { return Vector4(x * v, y * v, z * v); }
|
||||
inline Vector4 operator / (const Vector4 &b) const { return Vector4(x / b.x, y / b.y, z / b.z); }
|
||||
inline Vector4 operator / (const float v) const { float i = v ? 1 / v : 0; return Vector4(x * i, y * i, z * i); }
|
||||
|
||||
inline float operator [] (size_t n) const { return (&x)[n]; }
|
||||
inline float &operator [] (size_t n) { return (&x)[n]; }
|
||||
|
||||
inline Vector4 SafeDivided(const Vector4 &b) const
|
||||
{ return Vector4(b.x ? x / b.x : 0, b.y ? y / b.y : 0, b.z ? z / b.z : 0); }
|
||||
|
||||
/// Set vector components.
|
||||
inline void Set(float x_, float y_, float z_, float w_)
|
||||
{ x = x_; y = y_; z = z_; w = w_; }
|
||||
inline void Set(float x_ = 0.f, float y_ = 0.f, float z_ = 0.f) // Used to provide script overload.
|
||||
{ x = x_; y = y_; z = z_; w = 1.0f; }
|
||||
inline void Set(Vector4 &v)
|
||||
{ x = v.x; y = v.y; z = v.z; w = v.w; }
|
||||
|
||||
/// Dot product.
|
||||
inline float Dot(const Vector4 &b) const
|
||||
{ return x * b.x + y * b.y + z * b.z; }
|
||||
/// Cross product.
|
||||
inline Vector4 Cross(const Vector4 &b) const
|
||||
{ return Vector4(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); }
|
||||
|
||||
void operator *= (const Matrix4 &);
|
||||
Vector4 operator * (const Matrix4 &) const;
|
||||
void operator *= (const Matrix3 &);
|
||||
Vector4 operator * (const Matrix3 &) const;
|
||||
|
||||
/// Reverse this vector.
|
||||
inline void Reverse() { x = -x; y = -y; z = -z; }
|
||||
/// Inverse vector.
|
||||
inline void Inverse() { x = x ? 1.f / x : 0; y = y ? 1.f / y : 0; z = z ? 1.f / z : 0; }
|
||||
|
||||
/// Normalize this vector.
|
||||
inline void Normalize() { float l = Len(); if (l) { float k = 1.f / l; x *= k; y *= k; z *= k; } }
|
||||
/// Normalize vector.
|
||||
inline Vector4 Normalized() const
|
||||
{
|
||||
float l = Len();
|
||||
float k = l ? 1.f / l : 1.f;
|
||||
return Vector4(x * k, y * k, z * k);
|
||||
}
|
||||
|
||||
/// Clamp vector components to [min;max].
|
||||
Vector4 Clamped(float min, float max) const;
|
||||
/// Clamp vector components to [min;max].
|
||||
Vector4 Clamped(const Vector4 &min, const Vector4 &max) const;
|
||||
/// Clamp vector magnitude to [min;max].
|
||||
Vector4 ClampedMagnitude(float min, float max) const;
|
||||
|
||||
/// Return the opposite vector to this vector.
|
||||
inline Vector4 Reversed() const
|
||||
{ return Vector4(-x, -y, -z); }
|
||||
/// Return the inverse vector to this vector.
|
||||
inline Vector4 Inversed() const
|
||||
{ return Vector4(1.f / x, 1.f / y, 1.f / z); }
|
||||
/// Absolute vector.
|
||||
Vector4 Abs() const;
|
||||
/// Sign vector.
|
||||
inline Vector4 Sign() const
|
||||
{ return Vector4(x < 0.f ? -1.f : 1.f, y < 0.f ? -1.f : 1.f, z < 0.f ? -1.f : 1.f); }
|
||||
|
||||
/// Maximum of two vectors.
|
||||
static Vector4 Maximum(const Vector4 &a, const Vector4 &b)
|
||||
{ return Vector4(a.x > b.x ? a.x : b.x, a.y > b.y ? a.y : b.y, a.z > b.z ? a.z : b.z); }
|
||||
/// Minimum of two vectors.
|
||||
static Vector4 Minimum(const Vector4 &a, const Vector4 &b)
|
||||
{ return Vector4(a.x < b.x ? a.x : b.x, a.y < b.y ? a.y : b.y, a.z < b.z ? a.z : b.z); }
|
||||
|
||||
/*!
|
||||
@short Reflect vector.
|
||||
@note Vector must be normalized.
|
||||
*/
|
||||
inline Vector4 Reflected(const Vector4 &n) const
|
||||
{
|
||||
Vector4 rv = Reversed();
|
||||
return n * (2.f * rv.Dot(n)) - rv;
|
||||
}
|
||||
/*!
|
||||
@short Refract vector.
|
||||
@note Vector must be normalized.
|
||||
*/
|
||||
inline Vector4 Refracted(const Vector4 &n, float kin = 1, float kout = 1) const
|
||||
{
|
||||
const float k = kin / kout;
|
||||
return (*this) * k + n * (k - 1.f);
|
||||
}
|
||||
|
||||
/// Squared vector length.
|
||||
inline float Len2() const { return (float)(x * x + y * y + z * z); }
|
||||
/// Vector length.
|
||||
inline float Len() const { return Math::Sqrt((float)(x * x + y * y + z * z)); }
|
||||
/// Hash vector.
|
||||
int Hash() const;
|
||||
|
||||
Vector4 Floor() const;
|
||||
Vector4 Ceil() const;
|
||||
|
||||
/*!
|
||||
@short Return a random vector.
|
||||
@note w component is not randomized but set to 1.
|
||||
*/
|
||||
static Vector4 Random(float min = -1, float max = 1);
|
||||
/// Vector squared distance.
|
||||
static float Dist2(const Vector4 &a, const Vector4 &b)
|
||||
{ return ((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y) + (b.z - a.z) * (b.z - a.z)); }
|
||||
/// Vector distance.
|
||||
static float Dist(const Vector4 &a, const Vector4 &b)
|
||||
{ return Math::Sqrt((float)((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y) + (b.z - a.z) * (b.z - a.z))); }
|
||||
/*!
|
||||
@short Vector base to Euler.
|
||||
@note base convention u = {0,0,1}, v = {1,0,0}, second axis is optional.
|
||||
*/
|
||||
static void BaseToEuler(Vector4 &euler, Vector4 &u, Vector4 *v = NULL);
|
||||
|
||||
/*!
|
||||
@short Return a vector which is facing a given direction.
|
||||
|
||||
Returns a copy of this vector if it is already facing the given
|
||||
direction or the opposite of this vector otherwise.
|
||||
*/
|
||||
Vector4 FaceForward(Vector4 &dir);
|
||||
|
||||
NML::Tag *AsMetaTag(const char *id, bool full_dump = false) const;
|
||||
bool FromMetaTag(NML::Tag &tag);
|
||||
|
||||
Vector4(float a, float b, float c, float d = 1) : x(a), y(b), z(c), w(d) {}
|
||||
Vector4(const tVector2 <float> &v2) : x(v2.x), y(v2.y), z(1), w(1) {}
|
||||
Vector4(const tVector2 <int> &v2) : x(float(v2.x)), y(float(v2.y)), z(1), w(1) {}
|
||||
Vector4() {}
|
||||
};
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#define Vec3Set(v, a, b, c) { (v).x = a; (v).y = b; (v).z = c; }
|
||||
|
||||
#define Vec3Len2(v) ((v).x * (v).x + (v).y * (v).y + (v).z * (v).z)
|
||||
#define Vec3Len(v) Math::Sqrt((float)Vec3Len2(v))
|
||||
|
||||
#define Vec3Add(r, a, b) { (r).x = (a).x + (b).x; (r).y = (a).y + (b).y; (r).z = (a).z + (b).z; }
|
||||
#define Vec3AddConst(r, a, k) { (r).x = (a).x + k; (r).y = (a).y + k; (r).z = (a).z + k; }
|
||||
#define Vec3Sub(r, a, b) { (r).x = (a).x - (b).x; (r).y = (a).y - (b).y; (r).z = (a).z - (b).z; }
|
||||
#define Vec3SubConst(r, a, k) { (r).x = (a).x - k; (r).y = (a).y - k; (r).z = (a).z - k; }
|
||||
#define Vec3Mul(r, a, b) { (r).x = (a).x * (b).x; (r).y = (a).y * (b).y; (r).z = (a).z * (b).z; }
|
||||
#define Vec3MulConst(r, a, k) { float _k = k; (r).x = (a).x * _k; (r).y = (a).y * _k; (r).z = (a).z * _k; }
|
||||
#define Vec3Div(r, a, b) { (r).x = (a).x / (b).x; (r).y = (a).y / (b).y; (r).z = (a).z / (b).z; }
|
||||
#define Vec3DivConst(r, a, k) { float ik = 1.f / k; (r).x = (a).x * ik; (r).y = (a).y * ik; (r).z = (a).z * ik; }
|
||||
|
||||
#define Vec3Inc(r, a) { (r).x += (a).x; (r).y += (a).y; (r).z += (a).z; }
|
||||
#define Vec3IncConst(r, k) { (r).x += k; (r).y += k; (r).z += k; }
|
||||
#define Vec3Dec(r, a) { (r).x -= (a).x; (r).y -= (a).y; (r).z -= (a).z; }
|
||||
#define Vec3DecConst(r, k) { (r).x -= k; (r).y -= k; (r).z -= k; }
|
||||
#define Vec3Scale(r, a) { (r).x *= (a).x; (r).y *= (a).y; (r).z *= (a).z; }
|
||||
#define Vec3ScaleConst(r, k) { float _k = k; (r).x *= _k; (r).y *= _k; (r).z *= _k; }
|
||||
#define Vec3Shrink(r, a) { (r).x /= (a).x; (r).y /= (a).y; (r).z /= (a).z; }
|
||||
#define Vec3ShrinkConst(r, k) { float ik = 1.f / k; (r).x *= ik; (r).y *= ik; (r).z *= ik; }
|
||||
|
||||
#define Vec3Dot(a, b) ((a).x * (b).x + (a).y * (b).y + (a).z * (b).z)
|
||||
#define Vec3Cross(r, a, b) {\
|
||||
(r).x = (a).y * (b).z - (a).z * (b).y;\
|
||||
(r).y = (a).z * (b).x - (a).x * (b).z;\
|
||||
(r).z = (a).x * (b).y - (a).y * (b).x;\
|
||||
}
|
||||
|
||||
#define Vec3Clamp(v, a, b) {\
|
||||
if ((v).x < a) (v).x = a; else if ((v).x > b) (v).x = b;\
|
||||
if ((v).x < a) (v).x = a; else if ((v).x > b) (v).x = b;\
|
||||
if ((v).x < a) (v).x = a; else if ((v).x > b) (v).x = b;\
|
||||
}
|
||||
#define Vec3ClampMag(v, m) {\
|
||||
const float m2 = (m) * (m);\
|
||||
const float l2 = Vec3Len2(v);\
|
||||
if (l2 > m2)\
|
||||
{\
|
||||
const float k = Math::Sqrt((float)(m2 / l2));\
|
||||
Vec3ScaleConst(v, k);\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
#endif // __NVECTOR__
|
||||
50
include/framework/math/vector_nml.h
Normal file
50
include/framework/math/vector_nml.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
GSFramework
|
||||
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
||||
----------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#ifndef __NVECTORNML__
|
||||
#define __NVECTORNML__
|
||||
|
||||
|
||||
#include "metafile/nml.h"
|
||||
#include "math/vector.h"
|
||||
|
||||
|
||||
namespace GS {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class T> NML::Tag *tVectorAsMetaTag(const tVector2 <T> &v, const char *id)
|
||||
{
|
||||
NML::Tag *root = id ? new NML::Tag(id) : new NML::Tag("Vector2");
|
||||
|
||||
if (root)
|
||||
{
|
||||
root->AddChild("X", v.x);
|
||||
root->AddChild("Y", v.y);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
template <class T> bool tVectorFromMetaTag(tVector2 <T> &v, NML::Tag &tag)
|
||||
{
|
||||
NML::Tag *t;
|
||||
List <NML::Tag *> ::Iterator i(tag.GetTags().GetRoot());
|
||||
|
||||
if ((t = i.ObjectPtr()) == NULL)
|
||||
return false;
|
||||
v.x = t->GetReal();
|
||||
++i;
|
||||
|
||||
if ((t = i.ObjectPtr()) == NULL)
|
||||
return false;
|
||||
v.y = t->GetReal();
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
} // GS
|
||||
|
||||
|
||||
#endif // __NVECTORNML__
|
||||
Reference in New Issue
Block a user