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,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__

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__

View 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__

View 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__

View 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__