mirror of
https://github.com/leozide/leocad.git
synced 2026-07-28 04:07:11 +00:00
Added the Quaternion class, faster float functions, and a ProjectPoint() function.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// Math and Linear Algebra stuff.
|
||||
//
|
||||
|
||||
#include "defines.h"
|
||||
#include "algebra.h"
|
||||
|
||||
// ============================================================================
|
||||
@@ -30,3 +31,49 @@ void Matrix44::CreateLookAt(const Point3& Eye, const Point3& Target, const Vecto
|
||||
m_Rows[2] = Float4(x.GetZ(), y.GetZ(), z.GetZ(), 0.0f);
|
||||
m_Rows[3] = m_Rows[0]*-Eye.GetX() + m_Rows[1]*-Eye.GetY() + m_Rows[2]*-Eye.GetZ();
|
||||
}
|
||||
|
||||
void Matrix44::CreatePerspective(float FoVy, float Aspect, float Near, float Far)
|
||||
{
|
||||
float Left, Right, Bottom, Top;
|
||||
|
||||
Top = Near * (float)tan(FoVy * LC_PI / 360.0f);
|
||||
Bottom = -Top;
|
||||
|
||||
Left = Bottom * Aspect;
|
||||
Right = Top * Aspect;
|
||||
|
||||
if ((Near <= 0.0f) || (Far <= 0.0f) || (Near == Far) || (Left == Right) || (Top == Bottom))
|
||||
return;
|
||||
|
||||
float x, y, a, b, c, d;
|
||||
|
||||
x = (2.0f * Near) / (Right - Left);
|
||||
y = (2.0f * Near) / (Top - Bottom);
|
||||
a = (Right + Left) / (Right - Left);
|
||||
b = (Top + Bottom) / (Top - Bottom);
|
||||
c = -(Far + Near) / (Far - Near);
|
||||
d = -(2.0f * Far * Near) / (Far - Near);
|
||||
|
||||
m_Rows[0] = Float4(x, 0, a, 0);
|
||||
m_Rows[1] = Float4(0, y, b, 0);
|
||||
m_Rows[2] = Float4(0, 0, c, d);
|
||||
m_Rows[3] = Float4(0, 0, -1, 0);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Other Functions.
|
||||
|
||||
// Convert object coordinates to screen coordinates.
|
||||
Point3 ProjectPoint(const Point3& Pt, const Matrix44& ModelView, const Matrix44& Projection, const int Viewport[4])
|
||||
{
|
||||
Point3 Tmp;
|
||||
|
||||
Tmp = Pt * ModelView;
|
||||
Tmp = Tmp * Projection;
|
||||
|
||||
// Normalize.
|
||||
Tmp /= Tmp[3];
|
||||
|
||||
// Screen coordinates.
|
||||
return Point3(Viewport[0]+(1+Tmp[0])*Viewport[2]/2, Viewport[1]+(1+Tmp[1])*Viewport[3]/2, (1+Tmp[2])/2);
|
||||
}
|
||||
|
||||
+248
-109
@@ -9,6 +9,9 @@
|
||||
// Everything is based on the Float4 class, so changing that class should be enough
|
||||
// to add support for compiler specific math intrinsics.
|
||||
//
|
||||
// Functions that end with 34 mean that they don't care what happens to the 4th
|
||||
// component, it can either be affected or not.
|
||||
//
|
||||
|
||||
// TODO: Move this define to config.h
|
||||
#define LC_MATH_FLOAT
|
||||
@@ -18,6 +21,7 @@
|
||||
class Float4;
|
||||
class Point3;
|
||||
class Vector3;
|
||||
class Quaternion;
|
||||
class Matrix33;
|
||||
class Matrix44;
|
||||
|
||||
@@ -30,65 +34,84 @@ class Float4
|
||||
{
|
||||
public:
|
||||
// Constructors.
|
||||
inline Float4() { };
|
||||
inline Float4() { }
|
||||
inline explicit Float4(const float _x, const float _y, const float _z)
|
||||
: x(_x), y(_y), z(_z) { };
|
||||
: x(_x), y(_y), z(_z) { }
|
||||
inline explicit Float4(const float _x, const float _y, const float _z, const float _w)
|
||||
: x(_x), y(_y), z(_z), w(_w) { };
|
||||
: x(_x), y(_y), z(_z), w(_w) { }
|
||||
|
||||
// Get/Set functions.
|
||||
inline float GetX() const { return x; };
|
||||
inline float GetY() const { return y; };
|
||||
inline float GetZ() const { return z; };
|
||||
inline float GetW() const { return w; };
|
||||
inline void SetX(const float _x) { x = _x; };
|
||||
inline void SetY(const float _y) { y = _y; };
|
||||
inline void SetZ(const float _z) { z = _z; };
|
||||
inline void SetW(const float _w) { w = _w; };
|
||||
inline float GetX() const { return x; }
|
||||
inline float GetY() const { return y; }
|
||||
inline float GetZ() const { return z; }
|
||||
inline float GetW() const { return w; }
|
||||
inline void SetX(const float _x) { x = _x; }
|
||||
inline void SetY(const float _y) { y = _y; }
|
||||
inline void SetZ(const float _z) { z = _z; }
|
||||
inline void SetW(const float _w) { w = _w; }
|
||||
|
||||
template<typename T>
|
||||
inline const float operator[](T i) const { return ((const float*)this)[i]; };
|
||||
inline const float operator[](T i) const { return ((const float*)this)[i]; }
|
||||
|
||||
// Comparison.
|
||||
friend inline bool operator==(const Float4& a, const Float4& b)
|
||||
{ return (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w); };
|
||||
{ return (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w); }
|
||||
|
||||
friend inline bool Compare3(const Float4& a, const Float4& b)
|
||||
{ return (a.x == b.x) && (a.y == b.y) && (a.z == b.z); };
|
||||
{ return (a.x == b.x) && (a.y == b.y) && (a.z == b.z); }
|
||||
|
||||
// Math operations.
|
||||
// Math operations for 4 components.
|
||||
friend inline Float4 operator+(const Float4& a, const Float4& b)
|
||||
{ return Float4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w); };
|
||||
{ return Float4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w); }
|
||||
|
||||
friend inline Float4 operator-(const Float4& a, const Float4& b)
|
||||
{ return Float4(a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w); };
|
||||
{ return Float4(a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w); }
|
||||
|
||||
friend inline Float4 operator*(const Float4& a, float f)
|
||||
{ return Float4(a.x*f, a.y*f, a.z*f, a.w*f); };
|
||||
{ return Float4(a.x*f, a.y*f, a.z*f, a.w*f); }
|
||||
|
||||
friend inline Float4 operator*(const Float4& a, const Float4& b)
|
||||
{ return Float4(a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w); };
|
||||
{ return Float4(a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w); }
|
||||
|
||||
friend inline Float4 operator/(const Float4& a, float f)
|
||||
{ return Float4(a.x/f, a.y/f, a.z/f, a.w/f); };
|
||||
{ return Float4(a.x/f, a.y/f, a.z/f, a.w/f); }
|
||||
|
||||
friend inline Float4 operator-(const Float4& a)
|
||||
{ return Float4(-a.x, -a.y, -a.z, -a.w); };
|
||||
{ return Float4(-a.x, -a.y, -a.z, -a.w); }
|
||||
|
||||
// Math operations ignoring the 4th component.
|
||||
friend inline Float4 Add34(const Float4& a, const Float4& b)
|
||||
{ return Float4(a.x+b.x, a.y+b.y, a.z+b.z); }
|
||||
|
||||
friend inline Float4 Subtract34(const Float4& a, const Float4& b)
|
||||
{ return Float4(a.x-b.x, a.y-b.y, a.z-b.z); }
|
||||
|
||||
friend inline Float4 Multiply34(const Float4& a, float f)
|
||||
{ return Float4(a.x*f, a.y*f, a.z*f); }
|
||||
|
||||
friend inline Float4 Multiply34(const Float4& a, const Float4& b)
|
||||
{ return Float4(a.x*b.x, a.y*b.y, a.z*b.z); }
|
||||
|
||||
friend inline Float4 Divide34(const Float4& a, float f)
|
||||
{ return Float4(a.x/f, a.y/f, a.z/f); }
|
||||
|
||||
friend inline Float4 Negate34(const Float4& a)
|
||||
{ return Float4(-a.x, -a.y, -a.z, -a.w); }
|
||||
|
||||
// Dot product.
|
||||
friend inline float Dot3(const Float4& a, const Float4& b)
|
||||
{ return a.x*b.x + a.y*b.y + a.z*b.z; };
|
||||
{ return a.x*b.x + a.y*b.y + a.z*b.z; }
|
||||
|
||||
// Cross product.
|
||||
friend inline Float4 Cross3(const Float4& a, const Float4& b)
|
||||
{ return Float4(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); };
|
||||
{ return Float4(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); }
|
||||
|
||||
// Other functions.
|
||||
inline float Length3() const
|
||||
{ return sqrtf(Dot3(*this, *this)); };
|
||||
{ return sqrtf(Dot3(*this, *this)); }
|
||||
|
||||
inline void Normalize3()
|
||||
{ *this = *this / Length3(); };
|
||||
{ *this = *this / Length3(); }
|
||||
|
||||
inline void Abs()
|
||||
{
|
||||
@@ -96,7 +119,7 @@ public:
|
||||
if (y < 0.0f) y = -y;
|
||||
if (z < 0.0f) z = -z;
|
||||
if (w < 0.0f) w = -w;
|
||||
};
|
||||
}
|
||||
|
||||
protected:
|
||||
float x, y, z, w;
|
||||
@@ -116,71 +139,90 @@ class __declspec(align(16)) Float4
|
||||
{
|
||||
public:
|
||||
// Constructors.
|
||||
inline Float4() { };
|
||||
inline Float4() { }
|
||||
inline explicit Float4(const __m128& _xyzw)
|
||||
: xyzw(_xyzw) { };
|
||||
: xyzw(_xyzw) { }
|
||||
inline explicit Float4(const float _x, const float _y, const float _z)
|
||||
: xyzw(_mm_setr_ps(_x, _y, _z, _z)) { };
|
||||
: xyzw(_mm_setr_ps(_x, _y, _z, _z)) { }
|
||||
inline explicit Float4(const float _x, const float _y, const float _z, const float _w)
|
||||
: xyzw(_mm_setr_ps(_x, _y, _z, _w)) { };
|
||||
: xyzw(_mm_setr_ps(_x, _y, _z, _w)) { }
|
||||
|
||||
// Get/Set functions.
|
||||
inline float GetX() const { return ((const float*)this)[0]; };
|
||||
inline float GetY() const { return ((const float*)this)[1]; };
|
||||
inline float GetZ() const { return ((const float*)this)[2]; };
|
||||
inline float GetW() const { return ((const float*)this)[3]; };
|
||||
inline float GetX() const { return ((const float*)this)[0]; }
|
||||
inline float GetY() const { return ((const float*)this)[1]; }
|
||||
inline float GetZ() const { return ((const float*)this)[2]; }
|
||||
inline float GetW() const { return ((const float*)this)[3]; }
|
||||
inline void SetX(const float _x)
|
||||
{
|
||||
__m128 xxyy = _mm_shuffle_ps(_mm_load_ps1(&_x), xyzw, _MM_SHUFFLE(1, 1, 0, 0));
|
||||
xyzw = _mm_shuffle_ps(xxyy, xyzw, _MM_SHUFFLE(3, 2, 2, 0));
|
||||
};
|
||||
}
|
||||
inline void SetY(const float _y)
|
||||
{
|
||||
__m128 xxyy = _mm_shuffle_ps(xyzw, _mm_load_ps1(&_y), _MM_SHUFFLE(1, 1, 0, 0));
|
||||
xyzw = _mm_shuffle_ps(xxyy, xyzw, _MM_SHUFFLE(3, 2, 2, 0));
|
||||
};
|
||||
}
|
||||
inline void SetZ(const float _z)
|
||||
{
|
||||
__m128 zzww = _mm_shuffle_ps(_mm_load_ps1(&_z), xyzw, _MM_SHUFFLE(3, 3, 2, 2));
|
||||
xyzw = _mm_shuffle_ps(xyzw, zzww, _MM_SHUFFLE(2, 0, 1, 0));
|
||||
};
|
||||
}
|
||||
inline void SetW(const float _w)
|
||||
{
|
||||
__m128 zzww = _mm_shuffle_ps(xyzw, _mm_load_ps1(&_w), _MM_SHUFFLE(3, 3, 2, 2));
|
||||
xyzw = _mm_shuffle_ps(xyzw, zzww, _MM_SHUFFLE(2, 0, 1, 0));
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline const float operator[](T i) const { return ((const float*)this)[i]; };
|
||||
inline const float operator[](T i) const { return ((const float*)this)[i]; }
|
||||
|
||||
// Comparison.
|
||||
friend inline bool operator==(const Float4& a, const Float4& b)
|
||||
{ return !_mm_movemask_ps(_mm_cmpneq_ps(a.xyzw, b.xyzw)); };
|
||||
{ return !_mm_movemask_ps(_mm_cmpneq_ps(a.xyzw, b.xyzw)); }
|
||||
|
||||
friend inline bool Compare3(const Float4& a, const Float4& b)
|
||||
{ return (_mm_movemask_ps(_mm_cmpeq_ps(a.xyzw, b.xyzw)) & 0x7) == 0x7; };
|
||||
{ return (_mm_movemask_ps(_mm_cmpeq_ps(a.xyzw, b.xyzw)) & 0x7) == 0x7; }
|
||||
|
||||
// Math operations.
|
||||
// Math operations for 4 components.
|
||||
friend inline Float4 operator+(const Float4& a, const Float4& b)
|
||||
{ return Float4(_mm_add_ps(a.xyzw, b.xyzw)); };
|
||||
{ return Float4(_mm_add_ps(a.xyzw, b.xyzw)); }
|
||||
|
||||
friend inline Float4 operator-(const Float4& a, const Float4& b)
|
||||
{ return Float4(_mm_sub_ps(a.xyzw, b.xyzw)); };
|
||||
{ return Float4(_mm_sub_ps(a.xyzw, b.xyzw)); }
|
||||
|
||||
friend inline Float4 operator*(const Float4& a, float f)
|
||||
{ return Float4(_mm_mul_ps(a.xyzw, _mm_load_ps1(&f))); };
|
||||
{ return Float4(_mm_mul_ps(a.xyzw, _mm_load_ps1(&f))); }
|
||||
|
||||
friend inline Float4 operator*(const Float4& a, const Float4& b)
|
||||
{ return Float4(_mm_mul_ps(a.xyzw, b.xyzw)); };
|
||||
{ return Float4(_mm_mul_ps(a.xyzw, b.xyzw)); }
|
||||
|
||||
friend inline Float4 operator/(const Float4& a, float f)
|
||||
{ return Float4(_mm_div_ps(a.xyzw, _mm_load_ps1(&f))); };
|
||||
{ return Float4(_mm_div_ps(a.xyzw, _mm_load_ps1(&f))); }
|
||||
|
||||
friend inline Float4 operator-(const Float4& a)
|
||||
{
|
||||
static const __declspec(align(16)) unsigned int Mask[4] = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 };
|
||||
static const __declspec(align(16)) unsigned int Mask[4] = { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }
|
||||
return Float4(_mm_xor_ps(xyzw, *(__m128*)&Mask));
|
||||
};
|
||||
}
|
||||
|
||||
// Math operations ignoring the 4th component.
|
||||
friend inline Float4 Add34(const Float4& a, const Float4& b)
|
||||
{ return a*b }
|
||||
|
||||
friend inline Float4 Subtract34(const Float4& a, const Float4& b)
|
||||
{ return a-b; }
|
||||
|
||||
friend inline Float4 Multiply34(const Float4& a, float f)
|
||||
{ return a*f; }
|
||||
|
||||
friend inline Float4 Multiply34(const Float4& a, const Float4& b)
|
||||
{ return a*b; }
|
||||
|
||||
friend inline Float4 Divide34(const Float4& a, float f)
|
||||
{ return a/f; }
|
||||
|
||||
friend inline Float4 Negate34(const Float4& a)
|
||||
{ return -a; }
|
||||
|
||||
// Dot product.
|
||||
friend inline float Dot3(const Float4& a, const Float4& b)
|
||||
@@ -190,7 +232,7 @@ public:
|
||||
tmp = _mm_add_ss(tmp, yz);
|
||||
|
||||
return *(const float*)&tmp;
|
||||
};
|
||||
}
|
||||
|
||||
// Cross product.
|
||||
friend inline Float4 Cross3(const Float4& a, const Float4& b)
|
||||
@@ -200,7 +242,7 @@ public:
|
||||
__m128 r2 = _mm_mul_ps(_mm_shuffle_ps(a.xyzw, a.xyzw, _MM_SHUFFLE(0, 1, 0, 2)), _mm_shuffle_ps(b.xyzw, b.xyzw, _MM_SHUFFLE(0, 0, 2, 1)));
|
||||
|
||||
return Float4(_mm_sub_ps(r1, r2));
|
||||
};
|
||||
}
|
||||
|
||||
// Other functions.
|
||||
inline float Length3() const
|
||||
@@ -211,7 +253,7 @@ public:
|
||||
tmp = _mm_sqrt_ss(tmp);
|
||||
|
||||
return *(const float*)&tmp;
|
||||
};
|
||||
}
|
||||
|
||||
inline void Normalize3()
|
||||
{
|
||||
@@ -221,13 +263,13 @@ public:
|
||||
tmp = _mm_rsqrt_ss(tmp);
|
||||
tmp = _mm_shuffle_ps(tmp, tmp, _MM_SHUFFLE(0, 0, 0, 0));
|
||||
xyzw = _mm_mul_ps(xyzw, tmp);
|
||||
};
|
||||
}
|
||||
|
||||
inline void Abs()
|
||||
{
|
||||
static const __declspec(align(16)) unsigned int Mask[4] = { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff };
|
||||
static const __declspec(align(16)) unsigned int Mask[4] = { 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff }
|
||||
xyzw = _mm_and_ps(xyzw, *(__m128*)&Mask);
|
||||
};
|
||||
}
|
||||
|
||||
protected:
|
||||
__m128 xyzw;
|
||||
@@ -242,23 +284,23 @@ class Point3
|
||||
{
|
||||
public:
|
||||
// Constructors.
|
||||
inline Point3() { };
|
||||
inline Point3() { }
|
||||
inline explicit Point3(const Float4& _v)
|
||||
: m_Value(_v) { };
|
||||
: m_Value(_v) { }
|
||||
inline explicit Point3(const float _x, const float _y, const float _z)
|
||||
: m_Value(_x, _y, _z) { };
|
||||
: m_Value(_x, _y, _z) { }
|
||||
|
||||
// Get/Set functions.
|
||||
inline const Float4& GetValue() const { return m_Value; };
|
||||
inline float GetX() const { return m_Value.GetX(); };
|
||||
inline float GetY() const { return m_Value.GetY(); };
|
||||
inline float GetZ() const { return m_Value.GetZ(); };
|
||||
inline void SetX(const float _x) { m_Value.SetX(_x); };
|
||||
inline void SetY(const float _y) { m_Value.SetY(_y); };
|
||||
inline void SetZ(const float _z) { m_Value.SetZ(_z); };
|
||||
inline const Float4& GetValue() const { return m_Value; }
|
||||
inline float GetX() const { return m_Value.GetX(); }
|
||||
inline float GetY() const { return m_Value.GetY(); }
|
||||
inline float GetZ() const { return m_Value.GetZ(); }
|
||||
inline void SetX(const float _x) { m_Value.SetX(_x); }
|
||||
inline void SetY(const float _y) { m_Value.SetY(_y); }
|
||||
inline void SetZ(const float _z) { m_Value.SetZ(_z); }
|
||||
|
||||
template<typename T>
|
||||
inline const float operator[](T i) const { return m_Value[i]; };
|
||||
inline const float operator[](T i) const { return m_Value[i]; }
|
||||
|
||||
// Math operations.
|
||||
template<typename T> inline Point3& operator+=(const T& a) { return *this = *this + a; }
|
||||
@@ -277,24 +319,25 @@ protected:
|
||||
class Vector3
|
||||
{
|
||||
public:
|
||||
// Constructors.
|
||||
inline Vector3()
|
||||
{ };
|
||||
{ }
|
||||
inline explicit Vector3(const Float4& _v)
|
||||
: m_Value(_v) { };
|
||||
: m_Value(_v) { }
|
||||
inline explicit Vector3(const float _x, const float _y, const float _z)
|
||||
: m_Value(_x, _y, _z) { };
|
||||
: m_Value(_x, _y, _z) { }
|
||||
|
||||
// Get/Set functions.
|
||||
inline const Float4& GetValue() const { return m_Value; };
|
||||
inline float GetX() const { return m_Value.GetX(); };
|
||||
inline float GetY() const { return m_Value.GetY(); };
|
||||
inline float GetZ() const { return m_Value.GetZ(); };
|
||||
inline void SetX(const float _x) { m_Value.SetX(_x); };
|
||||
inline void SetY(const float _y) { m_Value.SetY(_y); };
|
||||
inline void SetZ(const float _z) { m_Value.SetZ(_z); };
|
||||
inline const Float4& GetValue() const { return m_Value; }
|
||||
inline float GetX() const { return m_Value.GetX(); }
|
||||
inline float GetY() const { return m_Value.GetY(); }
|
||||
inline float GetZ() const { return m_Value.GetZ(); }
|
||||
inline void SetX(const float _x) { m_Value.SetX(_x); }
|
||||
inline void SetY(const float _y) { m_Value.SetY(_y); }
|
||||
inline void SetZ(const float _z) { m_Value.SetZ(_z); }
|
||||
|
||||
template<typename T>
|
||||
inline const float operator[](T i) const { return m_Value[i]; };
|
||||
inline const float operator[](T i) const { return m_Value[i]; }
|
||||
|
||||
// Math operations.
|
||||
template<typename T> inline Vector3& operator+=(const T& a) { return *this = *this + a; }
|
||||
@@ -304,16 +347,105 @@ public:
|
||||
|
||||
// Other functions.
|
||||
inline float Length() const
|
||||
{ return m_Value.Length3(); };
|
||||
{ return m_Value.Length3(); }
|
||||
|
||||
inline float LengthSquared() const
|
||||
{ return Dot3(m_Value, m_Value); };
|
||||
{ return Dot3(m_Value, m_Value); }
|
||||
|
||||
inline void Normalize()
|
||||
{ m_Value.Normalize3(); };
|
||||
{ m_Value.Normalize3(); }
|
||||
|
||||
inline void Abs()
|
||||
{ m_Value.Abs(); };
|
||||
{ m_Value.Abs(); }
|
||||
|
||||
protected:
|
||||
Float4 m_Value;
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Quaternion class.
|
||||
|
||||
class Quaternion
|
||||
{
|
||||
public:
|
||||
// Constructors.
|
||||
inline Quaternion()
|
||||
{ }
|
||||
inline explicit Quaternion(const Float4& _v)
|
||||
: m_Value(_v) { }
|
||||
inline explicit Quaternion(const float _x, const float _y, const float _z, const float _w)
|
||||
: m_Value(_x, _y, _z, _w) { }
|
||||
|
||||
// Get/Set functions.
|
||||
inline float GetX() const { return m_Value.GetX(); }
|
||||
inline float GetY() const { return m_Value.GetY(); }
|
||||
inline float GetZ() const { return m_Value.GetZ(); }
|
||||
inline float GetW() const { return m_Value.GetW(); }
|
||||
inline void SetX(const float _x) { m_Value.SetX(_x); }
|
||||
inline void SetY(const float _y) { m_Value.SetY(_y); }
|
||||
inline void SetZ(const float _z) { m_Value.SetZ(_z); }
|
||||
inline void SetW(const float _w) { m_Value.SetW(_w); }
|
||||
|
||||
template<typename T>
|
||||
inline const float operator[](T i) const { return m_Value[i]; }
|
||||
|
||||
// Conversions.
|
||||
inline void FromAxisAngle(const Float4& AxisAngle)
|
||||
{
|
||||
float s = sinf(AxisAngle[3] / 2.0f);
|
||||
m_Value = Float4(AxisAngle[0] * s, AxisAngle[1] * s, AxisAngle[2] * s, cosf(AxisAngle[3] / 2.0f));
|
||||
}
|
||||
|
||||
inline void ToAxisAngle(Float4& AxisAngle) const
|
||||
{
|
||||
float Len = m_Value[0]*m_Value[0] + m_Value[1]*m_Value[1] + m_Value[2]*m_Value[2];
|
||||
|
||||
if (Len > 0.001f)
|
||||
{
|
||||
float f = 1.0f / sqrtf(Len);
|
||||
AxisAngle = Float4(m_Value[0] * f, m_Value[1] * f, m_Value[2] * f, acosf(m_Value[3]) * 2.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
AxisAngle = Float4(0, 0, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Operators.
|
||||
friend inline Quaternion operator*(const Quaternion& a, const Quaternion& b)
|
||||
{
|
||||
float x = a.m_Value[0] * b.m_Value[3] + a.m_Value[1] * b.m_Value[2] - a.m_Value[2] * b.m_Value[1] + a.m_Value[3] * b.m_Value[0];
|
||||
float y = -a.m_Value[0] * b.m_Value[2] + a.m_Value[1] * b.m_Value[3] + a.m_Value[2] * b.m_Value[0] + a.m_Value[3] * b.m_Value[1];
|
||||
float z = a.m_Value[0] * b.m_Value[1] - a.m_Value[1] * b.m_Value[0] + a.m_Value[2] * b.m_Value[3] + a.m_Value[3] * b.m_Value[2];
|
||||
float w = -a.m_Value[0] * b.m_Value[0] - a.m_Value[1] * b.m_Value[1] - a.m_Value[2] * b.m_Value[2] + a.m_Value[3] * b.m_Value[3];
|
||||
|
||||
return Quaternion(x, y, z, w);
|
||||
}
|
||||
|
||||
friend inline Vector3 operator*(const Vector3& a, const Quaternion& b)
|
||||
{
|
||||
// Faster to transform to a matrix and multiply.
|
||||
float Tx = 2.0f*b[0];
|
||||
float Ty = 2.0f*b[1];
|
||||
float Tz = 2.0f*b[2];
|
||||
float Twx = Tx*b[3];
|
||||
float Twy = Ty*b[3];
|
||||
float Twz = Tz*b[3];
|
||||
float Txx = Tx*b[0];
|
||||
float Txy = Ty*b[0];
|
||||
float Txz = Tz*b[0];
|
||||
float Tyy = Ty*b[1];
|
||||
float Tyz = Tz*b[1];
|
||||
float Tzz = Tz*b[2];
|
||||
|
||||
Vector3 Rows[3];
|
||||
Rows[0] = Vector3(1.0f-(Tyy+Tzz), Txy+Twz, Txz-Twy);
|
||||
Rows[1] = Vector3(Txy-Twz, 1.0f-(Txx+Tzz), Tyz+Twx);
|
||||
Rows[2] = Vector3(Txz+Twy, Tyz-Twx, 1.0f-(Txx+Tyy));
|
||||
|
||||
return Vector3(Rows[0].GetValue()*a.GetX() + Rows[1].GetValue()*a.GetY() + Rows[2].GetValue()*a.GetZ());
|
||||
}
|
||||
|
||||
protected:
|
||||
Float4 m_Value;
|
||||
@@ -326,10 +458,11 @@ protected:
|
||||
class Matrix33
|
||||
{
|
||||
public:
|
||||
// Constructors.
|
||||
inline Matrix33()
|
||||
{ };
|
||||
{ }
|
||||
inline Matrix33(const Vector3& Row0, const Vector3& Row1, const Vector3& Row2)
|
||||
{ m_Rows[0] = Row0; m_Rows[1] = Row1; m_Rows[2] = Row2; };
|
||||
{ m_Rows[0] = Row0; m_Rows[1] = Row1; m_Rows[2] = Row2; }
|
||||
|
||||
protected:
|
||||
Vector3 m_Rows[3];
|
||||
@@ -343,9 +476,9 @@ class Matrix44
|
||||
{
|
||||
public:
|
||||
inline Matrix44()
|
||||
{ };
|
||||
{ }
|
||||
inline Matrix44(const Float4& Row0, const Float4& Row1, const Float4& Row2, const Float4& Row3)
|
||||
{ m_Rows[0] = Row0; m_Rows[1] = Row1; m_Rows[2] = Row2; m_Rows[3] = Row3; };
|
||||
{ m_Rows[0] = Row0; m_Rows[1] = Row1; m_Rows[2] = Row2; m_Rows[3] = Row3; }
|
||||
|
||||
inline void Transpose3()
|
||||
{
|
||||
@@ -356,12 +489,13 @@ public:
|
||||
}
|
||||
|
||||
inline void SetTranslation(const Point3& a)
|
||||
{ m_Rows[3] = Float4(a.GetX(), a.GetY(), a.GetZ(), 0.0f); };
|
||||
{ m_Rows[3] = Float4(a.GetX(), a.GetY(), a.GetZ(), 0.0f); }
|
||||
|
||||
void CreateLookAt(const Point3& Eye, const Point3& Target, const Vector3& Up);
|
||||
void CreatePerspective(float FoVy, float Aspect, float Near, float Far);
|
||||
|
||||
friend inline Point3 operator*(const Point3& a, const Matrix44& b)
|
||||
{ return Point3(b.m_Rows[0]*a.GetX() + b.m_Rows[1]*a.GetY() + b.m_Rows[2]*a.GetZ() + b.m_Rows[3]); };
|
||||
{ return Point3(b.m_Rows[0]*a.GetX() + b.m_Rows[1]*a.GetY() + b.m_Rows[2]*a.GetZ() + b.m_Rows[3]); }
|
||||
|
||||
protected:
|
||||
Float4 m_Rows[4];
|
||||
@@ -373,76 +507,81 @@ protected:
|
||||
|
||||
// Comparison.
|
||||
inline bool operator==(const Point3& a, const Point3& b)
|
||||
{ return Compare3(a.GetValue(), b.GetValue()); };
|
||||
{ return Compare3(a.GetValue(), b.GetValue()); }
|
||||
|
||||
inline bool operator==(const Vector3& a, const Vector3& b)
|
||||
{ return Compare3(a.GetValue(), b.GetValue()); };
|
||||
{ return Compare3(a.GetValue(), b.GetValue()); }
|
||||
|
||||
// Multiply by a scalar.
|
||||
inline Vector3 operator*(const Vector3& a, float f)
|
||||
{ return Vector3(a.GetValue()*f); };
|
||||
{ return Vector3(Multiply34(a.GetValue(), f)); }
|
||||
|
||||
inline Vector3 operator*(float f, const Vector3& a)
|
||||
{ return Vector3(a.GetValue()*f); };
|
||||
{ return Vector3(Multiply34(a.GetValue(), f)); }
|
||||
|
||||
inline Point3 operator*(const Point3& a, float f)
|
||||
{ return Point3(a.GetValue()*f); };
|
||||
{ return Point3(Multiply34(a.GetValue(), f)); }
|
||||
|
||||
inline Point3 operator*(float f, const Point3& a)
|
||||
{ return Point3(a.GetValue()*f); };
|
||||
{ return Point3(Multiply34(a.GetValue(), f)); }
|
||||
|
||||
// Divide by a scalar.
|
||||
inline Vector3 operator/(const Vector3& a, float f)
|
||||
{ return Vector3(a.GetValue()/f); };
|
||||
{ return Vector3(Divide34(a.GetValue(), f)); }
|
||||
|
||||
inline Vector3 operator/(float f, const Vector3& a)
|
||||
{ return Vector3(a.GetValue()/f); };
|
||||
{ return Vector3(Divide34(a.GetValue(), f)); }
|
||||
|
||||
inline Point3 operator/(const Point3& a, float f)
|
||||
{ return Point3(a.GetValue()/f); };
|
||||
{ return Point3(Divide34(a.GetValue(), f)); }
|
||||
|
||||
inline Point3 operator/(float f, const Point3& a)
|
||||
{ return Point3(a.GetValue()/f); };
|
||||
{ return Point3(Divide34(a.GetValue(), f)); }
|
||||
|
||||
// Add vectors/points (return a point if either is a point).
|
||||
inline Point3 operator+(const Point3& a, const Point3& b)
|
||||
{ return Point3(a.GetValue()+b.GetValue()); };
|
||||
{ return Point3(Add34(a.GetValue(), b.GetValue())); }
|
||||
|
||||
inline Point3 operator+(const Point3& a, const Vector3& b)
|
||||
{ return Point3(a.GetValue()+b.GetValue()); };
|
||||
{ return Point3(Add34(a.GetValue(), b.GetValue())); }
|
||||
|
||||
inline Point3 operator+(const Vector3& a, const Point3& b)
|
||||
{ return Point3(a.GetValue()+b.GetValue()); };
|
||||
{ return Point3(Add34(a.GetValue(), b.GetValue())); }
|
||||
|
||||
inline Vector3 operator+(const Vector3& a, const Vector3& b)
|
||||
{ return Vector3(a.GetValue()+b.GetValue()); };
|
||||
{ return Vector3(Add34(a.GetValue(), b.GetValue())); }
|
||||
|
||||
// Subtract vectors/points (return a vector if both arguments are the same type).
|
||||
inline Vector3 operator-(const Point3& a, const Point3& b)
|
||||
{ return Vector3(a.GetValue()-b.GetValue()); };
|
||||
{ return Vector3(Subtract34(a.GetValue(), b.GetValue())); }
|
||||
|
||||
inline Point3 operator-(const Point3& a, const Vector3& b)
|
||||
{ return Point3(a.GetValue()-b.GetValue()); };
|
||||
{ return Point3(Subtract34(a.GetValue(), b.GetValue())); }
|
||||
|
||||
inline Point3 operator-(const Vector3& a, const Point3& b)
|
||||
{ return Point3(a.GetValue()-b.GetValue()); };
|
||||
{ return Point3(Subtract34(a.GetValue(), b.GetValue())); }
|
||||
|
||||
inline Vector3 operator-(const Vector3& a, const Vector3& b)
|
||||
{ return Vector3(a.GetValue()-b.GetValue()); };
|
||||
{ return Vector3(Subtract34(a.GetValue(), b.GetValue())); }
|
||||
|
||||
// Negate.
|
||||
inline Vector3 operator-(const Vector3& a)
|
||||
{ return Vector3(-a.GetValue()); }
|
||||
{ return Vector3(Negate34(a.GetValue())); }
|
||||
|
||||
inline Point3 operator-(const Point3& a)
|
||||
{ return Point3(-a.GetValue()); }
|
||||
{ return Point3(Negate34(a.GetValue())); }
|
||||
|
||||
// Dot product.
|
||||
inline float Dot3(const Vector3& a, const Vector3& b)
|
||||
{ return Dot3(a.GetValue(), b.GetValue()); };
|
||||
{ return Dot3(a.GetValue(), b.GetValue()); }
|
||||
|
||||
// Cross product.
|
||||
inline Vector3 Cross3(const Vector3& a, const Vector3& b)
|
||||
{ return Vector3(Cross3(a.GetValue(), b.GetValue())); };
|
||||
{ return Vector3(Cross3(a.GetValue(), b.GetValue())); }
|
||||
|
||||
// ============================================================================
|
||||
// Other Functions.
|
||||
|
||||
Point3 ProjectPoint(const Point3& Pt, const Matrix44& ModelView, const Matrix44& Projection, const int Viewport[4]);
|
||||
|
||||
#endif
|
||||
|
||||
+7
-1
@@ -57,7 +57,13 @@ char* strlwr(char* string);
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// LeoCAD constants
|
||||
|
||||
// Math numbers
|
||||
// Math numbers.
|
||||
#define LC_DTOR 0.017453f
|
||||
#define LC_RTOD 57.29578f
|
||||
#define LC_PI 3.141592f
|
||||
#define LC_2PI 6.283185f
|
||||
|
||||
|
||||
#define DTOR 0.017453f
|
||||
#define RTOD 57.29578f
|
||||
#define PI 3.14159265
|
||||
|
||||
Reference in New Issue
Block a user