summaryrefslogtreecommitdiffstats
path: root/src/math
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-06-26 22:23:05 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-06-26 22:23:05 +0200
commitebed57aa22b772211387a5561f995eee8f5faed1 (patch)
tree9a0b08371df54c125957e63c7ecff81c001d4eaf /src/math
parentfc5389d18816799ba2698914384cd099ba8a7a6c (diff)
downloadcolobot-ebed57aa22b772211387a5561f995eee8f5faed1.tar.gz
colobot-ebed57aa22b772211387a5561f995eee8f5faed1.tar.bz2
colobot-ebed57aa22b772211387a5561f995eee8f5faed1.zip
Whitespace and language change
- changed tabs to spaces and DOS line endings to Unix (except in CBot and metafile) - changed language to English - fixed #include <d3d.h> in d3dengine.h
Diffstat (limited to 'src/math')
-rw-r--r--src/math/const.h32
-rw-r--r--src/math/conv.h26
-rw-r--r--src/math/func.h156
-rw-r--r--src/math/geometry.h496
-rw-r--r--src/math/intpoint.h10
-rw-r--r--src/math/matrix.h630
-rw-r--r--src/math/point.h216
-rw-r--r--src/math/test/geometry_test.cpp472
-rw-r--r--src/math/test/matrix_test.cpp612
-rw-r--r--src/math/test/vector_test.cpp132
-rw-r--r--src/math/vector.h332
11 files changed, 1557 insertions, 1557 deletions
diff --git a/src/math/const.h b/src/math/const.h
index 6721284..dd7ab0f 100644
--- a/src/math/const.h
+++ b/src/math/const.h
@@ -24,27 +24,27 @@
// Math module namespace
namespace Math
{
- /* @{ */ // start of group
+/* @{ */ // start of group
- //! Tolerance level -- minimum accepted float value
- const float TOLERANCE = 1e-6f;
+//! Tolerance level -- minimum accepted float value
+const float TOLERANCE = 1e-6f;
- //! Very small number (used in testing/returning some values)
- const float VERY_SMALL = 1e-6f;
- //! Very big number (used in testing/returning some values)
- const float VERY_BIG = 1e6f;
+//! Very small number (used in testing/returning some values)
+const float VERY_SMALL = 1e-6f;
+//! Very big number (used in testing/returning some values)
+const float VERY_BIG = 1e6f;
- //! Huge number
- const float HUGE = 1.0e+38f;
+//! Huge number
+const float HUGE = 1.0e+38f;
- //! PI
- const float PI = 3.14159265358979323846f;
+//! PI
+const float PI = 3.14159265358979323846f;
- //! Degrees to radians multiplier
- const float DEG_TO_RAD = 0.01745329251994329547f;
- //! Radians to degrees multiplier
- const float RAD_TO_DEG = 57.29577951308232286465f;
+//! Degrees to radians multiplier
+const float DEG_TO_RAD = 0.01745329251994329547f;
+//! Radians to degrees multiplier
+const float RAD_TO_DEG = 57.29577951308232286465f;
- /* @} */ // end of group
+/* @} */ // end of group
}; // namespace Math
diff --git a/src/math/conv.h b/src/math/conv.h
index bb6700b..43e6fbd 100644
--- a/src/math/conv.h
+++ b/src/math/conv.h
@@ -11,29 +11,29 @@
inline D3DVECTOR VEC_TO_D3DVEC(Math::Vector vec)
{
- return D3DVECTOR(vec.x, vec.y, vec.z);
+ return D3DVECTOR(vec.x, vec.y, vec.z);
}
inline Math::Vector D3DVEC_TO_VEC(D3DVECTOR vec)
{
- return Math::Vector(vec.x, vec.y, vec.z);
+ return Math::Vector(vec.x, vec.y, vec.z);
}
inline D3DMATRIX MAT_TO_D3DMAT(Math::Matrix mat)
{
- D3DMATRIX result;
- mat.Transpose();
- for (int r = 0; r < 4; ++r)
- {
- for (int c = 0; c < 16; ++c)
- result.m[r][c] = mat.m[4*c+r];
- }
- return result;
+ D3DMATRIX result;
+ mat.Transpose();
+ for (int r = 0; r < 4; ++r)
+ {
+ for (int c = 0; c < 16; ++c)
+ result.m[r][c] = mat.m[4*c+r];
+ }
+ return result;
}
inline Math::Matrix D3DMAT_TO_MAT(D3DMATRIX mat)
{
- Math::Matrix result(mat.m);
- result.Transpose();
- return result;
+ Math::Matrix result(mat.m);
+ result.Transpose();
+ return result;
}
diff --git a/src/math/func.h b/src/math/func.h
index 212f7c1..8f0e4ab 100644
--- a/src/math/func.h
+++ b/src/math/func.h
@@ -16,7 +16,7 @@
// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathFuncModule math/func.h
- Contains common math functions.
+ Contains common math functions.
*/
#pragma once
@@ -36,146 +36,146 @@ namespace Math
//! Compares \a a and \a b within \a tolerance
inline bool IsEqual(float a, float b, float tolerance = TOLERANCE)
{
- return fabs(a - b) < tolerance;
+ return fabs(a - b) < tolerance;
}
//! Compares \a a to zero within \a tolerance
inline bool IsZero(float a, float tolerance = TOLERANCE)
{
- return IsEqual(a, 0.0f, tolerance);
+ return IsEqual(a, 0.0f, tolerance);
}
//! Minimum
inline float Min(float a, float b)
{
- if ( a <= b ) return a;
- else return b;
+ if ( a <= b ) return a;
+ else return b;
}
inline float Min(float a, float b, float c)
{
- return Min( Min(a, b), c );
+ return Min( Min(a, b), c );
}
inline float Min(float a, float b, float c, float d)
{
- return Min( Min(a, b), Min(c, d) );
+ return Min( Min(a, b), Min(c, d) );
}
inline float Min(float a, float b, float c, float d, float e)
{
- return Min( Min(a, b), Min(c, d), e );
+ return Min( Min(a, b), Min(c, d), e );
}
//! Maximum
inline float Max(float a, float b)
{
- if ( a >= b ) return a;
- else return b;
+ if ( a >= b ) return a;
+ else return b;
}
inline float Max(float a, float b, float c)
{
- return Max( Max(a, b), c );
+ return Max( Max(a, b), c );
}
inline float Max(float a, float b, float c, float d)
{
- return Max( Max(a, b), Max(c, d) );
+ return Max( Max(a, b), Max(c, d) );
}
inline float Max(float a, float b, float c, float d, float e)
{
- return Max( Max(a, b), Max(c, d), e );
+ return Max( Max(a, b), Max(c, d), e );
}
//! Returns the normalized value (0 .. 1)
inline float Norm(float a)
{
- if ( a < 0.0f ) return 0.0f;
- if ( a > 1.0f ) return 1.0f;
- return a;
+ if ( a < 0.0f ) return 0.0f;
+ if ( a > 1.0f ) return 1.0f;
+ return a;
}
//! Swaps two integers
inline void Swap(int &a, int &b)
{
- int c = a;
- a = b;
- b = c;
+ int c = a;
+ a = b;
+ b = c;
}
//! Swaps two real numbers
inline void Swap(float &a, float &b)
{
- float c = a;
- a = b;
- b = c;
+ float c = a;
+ a = b;
+ b = c;
}
//! Returns the modulo of a floating point number
/** Mod(8.1, 4) = 0.1
- Mod(n, 1) = fractional part of n */
+ Mod(n, 1) = fractional part of n */
inline float Mod(float a, float m)
{
- return a - ((int)(a/m))*m;
+ return a - ((int)(a/m))*m;
}
//! Returns a random value between 0 and 1.
inline float Rand()
{
- return (float)rand()/RAND_MAX;
+ return (float)rand()/RAND_MAX;
}
//! Returns a normalized angle, that is in other words between 0 and 2 * PI
inline float NormAngle(float angle)
{
- angle = Mod(angle, PI*2.0f);
- if ( angle < 0.0f )
- return PI*2.0f + angle;
+ angle = Mod(angle, PI*2.0f);
+ if ( angle < 0.0f )
+ return PI*2.0f + angle;
- return angle;
+ return angle;
}
//! Test if a angle is between two terminals
inline bool TestAngle(float angle, float min, float max)
{
- angle = NormAngle(angle);
- min = NormAngle(min);
- max = NormAngle(max);
+ angle = NormAngle(angle);
+ min = NormAngle(min);
+ max = NormAngle(max);
- if ( min > max )
- return ( angle <= max || angle >= min );
+ if ( min > max )
+ return ( angle <= max || angle >= min );
- return ( angle >= min && angle <= max );
+ return ( angle >= min && angle <= max );
}
//! Calculates a value (radians) proportional between a and b (degrees)
inline float PropAngle(int a, int b, float p)
{
- float aa = (float)a * DEG_TO_RAD;
- float bb = (float)b * DEG_TO_RAD;
+ float aa = (float)a * DEG_TO_RAD;
+ float bb = (float)b * DEG_TO_RAD;
- return aa+p*(bb-aa);
+ return aa+p*(bb-aa);
}
//! Calculates the angle to rotate the angle \a a to the angle \a g
/** A positive angle is counterclockwise (CCW). */
inline float Direction(float a, float g)
{
- a = NormAngle(a);
- g = NormAngle(g);
+ a = NormAngle(a);
+ g = NormAngle(g);
- if ( a < g )
- {
- if ( a+PI*2.0f-g < g-a ) a += PI*2.0f;
- }
- else
- {
- if ( g+PI*2.0f-a < a-g ) g += PI*2.0f;
- }
+ if ( a < g )
+ {
+ if ( a+PI*2.0f-g < g-a ) a += PI*2.0f;
+ }
+ else
+ {
+ if ( g+PI*2.0f-a < a-g ) g += PI*2.0f;
+ }
- return g-a;
+ return g-a;
}
//! Managing the dead zone of a joystick.
@@ -187,33 +187,33 @@ inline float Direction(float a, float g)
out: -1 0 0 1\endverbatim */
inline float Neutral(float value, float dead)
{
- if ( fabs(value) <= dead )
- {
- return 0.0f;
- }
- else
- {
- if ( value > 0.0f ) return (value-dead)/(1.0f-dead);
- else return (value+dead)/(1.0f-dead);
- }
+ if ( fabs(value) <= dead )
+ {
+ return 0.0f;
+ }
+ else
+ {
+ if ( value > 0.0f ) return (value-dead)/(1.0f-dead);
+ else return (value+dead)/(1.0f-dead);
+ }
}
//! Gently advances a desired value from its current value
/** Over time, the progression is more rapid. */
inline float Smooth(float actual, float hope, float time)
{
- float future = actual + (hope-actual)*time;
+ float future = actual + (hope-actual)*time;
- if ( hope > actual )
- {
- if ( future > hope ) future = hope;
- }
- if ( hope < actual )
- {
- if ( future < hope ) future = hope;
- }
+ if ( hope > actual )
+ {
+ if ( future > hope ) future = hope;
+ }
+ if ( hope < actual )
+ {
+ if ( future < hope ) future = hope;
+ }
- return future;
+ return future;
}
//! Bounces any movement
@@ -230,16 +230,16 @@ inline float Smooth(float actual, float hope, float time)
|<---->|middle\endverbatim */
inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f)
{
- if ( progress < middle )
- {
- progress = progress/middle; // 0..1
- return 0.5f+sinf(progress*PI-PI/2.0f)/2.0f;
- }
- else
- {
- progress = (progress-middle)/(1.0f-middle); // 0..1
- return (1.0f-bounce/2.0f)+sinf((0.5f+progress*2.0f)*PI)*(bounce/2.0f);
- }
+ if ( progress < middle )
+ {
+ progress = progress/middle; // 0..1
+ return 0.5f+sinf(progress*PI-PI/2.0f)/2.0f;
+ }
+ else
+ {
+ progress = (progress-middle)/(1.0f-middle); // 0..1
+ return (1.0f-bounce/2.0f)+sinf((0.5f+progress*2.0f)*PI)*(bounce/2.0f);
+ }
}
/* @} */ // end of group
diff --git a/src/math/geometry.h b/src/math/geometry.h
index 5654dad..2f937e5 100644
--- a/src/math/geometry.h
+++ b/src/math/geometry.h
@@ -42,40 +42,40 @@ namespace Math
//! Returns py up on the line \a a - \a b
inline float MidPoint(const Point &a, const Point &b, float px)
{
- if (IsEqual(a.x, b.x))
- {
- if (a.y < b.y)
- return HUGE;
- else
- return -HUGE;
- }
- return (b.y-a.y) * (px-a.x) / (b.x-a.x) + a.y;
+ if (IsEqual(a.x, b.x))
+ {
+ if (a.y < b.y)
+ return HUGE;
+ else
+ return -HUGE;
+ }
+ return (b.y-a.y) * (px-a.x) / (b.x-a.x) + a.y;
}
//! Tests whether the point \a p is inside the triangle (\a a,\a b,\a c)
inline bool IsInsideTriangle(Point a, Point b, Point c, Point p)
{
- float n, m;
+ float n, m;
- if ( p.x < a.x && p.x < b.x && p.x < c.x ) return false;
- if ( p.x > a.x && p.x > b.x && p.x > c.x ) return false;
- if ( p.y < a.y && p.y < b.y && p.y < c.y ) return false;
- if ( p.y > a.y && p.y > b.y && p.y > c.y ) return false;
+ if ( p.x < a.x && p.x < b.x && p.x < c.x ) return false;
+ if ( p.x > a.x && p.x > b.x && p.x > c.x ) return false;
+ if ( p.y < a.y && p.y < b.y && p.y < c.y ) return false;
+ if ( p.y > a.y && p.y > b.y && p.y > c.y ) return false;
- if ( a.x > b.x ) Swap(a,b);
- if ( a.x > c.x ) Swap(a,c);
- if ( c.x < a.x ) Swap(c,a);
- if ( c.x < b.x ) Swap(c,b);
+ if ( a.x > b.x ) Swap(a,b);
+ if ( a.x > c.x ) Swap(a,c);
+ if ( c.x < a.x ) Swap(c,a);
+ if ( c.x < b.x ) Swap(c,b);
- n = MidPoint(a, b, p.x);
- m = MidPoint(a, c, p.x);
- if ( (n>p.y||p.y>m) && (n<p.y||p.y<m) ) return false;
+ n = MidPoint(a, b, p.x);
+ m = MidPoint(a, c, p.x);
+ if ( (n>p.y||p.y>m) && (n<p.y||p.y<m) ) return false;
- n = MidPoint(c, b, p.x);
- m = MidPoint(c, a, p.x);
- if ( (n>p.y||p.y>m) && (n<p.y||p.y<m) ) return false;
+ n = MidPoint(c, b, p.x);
+ m = MidPoint(c, a, p.x);
+ if ( (n>p.y||p.y>m) && (n<p.y||p.y<m) ) return false;
- return true;
+ return true;
}
//! Rotates a point around a center
@@ -84,18 +84,18 @@ inline bool IsInsideTriangle(Point a, Point b, Point c, Point p)
\a p the point */
inline Point RotatePoint(const Point &center, float angle, const Point &p)
{
- Point a;
- a.x = p.x-center.x;
- a.y = p.y-center.y;
+ Point a;
+ a.x = p.x-center.x;
+ a.y = p.y-center.y;
- Point b;
- b.x = a.x*cosf(angle) - a.y*sinf(angle);
- b.y = a.x*sinf(angle) + a.y*cosf(angle);
+ Point b;
+ b.x = a.x*cosf(angle) - a.y*sinf(angle);
+ b.y = a.x*sinf(angle) + a.y*cosf(angle);
- b.x += center.x;
- b.y += center.y;
+ b.x += center.x;
+ b.y += center.y;
- return b;
+ return b;
}
//! Rotates a point around the origin (0,0)
@@ -103,10 +103,10 @@ inline Point RotatePoint(const Point &center, float angle, const Point &p)
\a p the point */
inline Point RotatePoint(float angle, const Point &p)
{
- float x = p.x*cosf(angle) - p.y*sinf(angle);
- float y = p.x*sinf(angle) + p.y*cosf(angle);
+ float x = p.x*cosf(angle) - p.y*sinf(angle);
+ float y = p.x*sinf(angle) + p.y*cosf(angle);
- return Point(x, y);
+ return Point(x, y);
}
//! Rotates a vector (dist, 0).
@@ -114,25 +114,25 @@ inline Point RotatePoint(float angle, const Point &p)
\a dist distance to origin */
inline Point RotatePoint(float angle, float dist)
{
- float x = dist*cosf(angle);
- float y = dist*sinf(angle);
+ float x = dist*cosf(angle);
+ float y = dist*sinf(angle);
- return Point(x, y);
+ return Point(x, y);
}
//! TODO documentation
inline void RotatePoint(float cx, float cy, float angle, float &px, float &py)
{
- float ax, ay;
+ float ax, ay;
- px -= cx;
- py -= cy;
+ px -= cx;
+ py -= cy;
- ax = px*cosf(angle) - py*sinf(angle);
- ay = px*sinf(angle) + py*cosf(angle);
+ ax = px*cosf(angle) - py*sinf(angle);
+ ay = px*sinf(angle) + py*cosf(angle);
- px = cx+ax;
- py = cy+ay;
+ px = cx+ax;
+ py = cy+ay;
}
//! Rotates a point around a center in space.
@@ -142,16 +142,16 @@ inline void RotatePoint(float cx, float cy, float angle, float &px, float &py)
\returns the rotated point */
inline void RotatePoint(const Vector &center, float angleH, float angleV, Vector &p)
{
- p.x -= center.x;
- p.y -= center.y;
- p.z -= center.z;
+ p.x -= center.x;
+ p.y -= center.y;
+ p.z -= center.z;
- Vector b;
- b.x = p.x*cosf(angleH) - p.z*sinf(angleH);
- b.y = p.z*sinf(angleV) + p.y*cosf(angleV);
- b.z = p.x*sinf(angleH) + p.z*cosf(angleH);
+ Vector b;
+ b.x = p.x*cosf(angleH) - p.z*sinf(angleH);
+ b.y = p.z*sinf(angleV) + p.y*cosf(angleV);
+ b.z = p.x*sinf(angleH) + p.z*cosf(angleH);
- p = center + b;
+ p = center + b;
}
//! Rotates a point around a center in space.
@@ -161,60 +161,60 @@ inline void RotatePoint(const Vector &center, float angleH, float angleV, Vector
\returns the rotated point */
inline void RotatePoint2(const Vector center, float angleH, float angleV, Vector &p)
{
- p.x -= center.x;
- p.y -= center.y;
- p.z -= center.z;
+ p.x -= center.x;
+ p.y -= center.y;
+ p.z -= center.z;
- Vector a;
- a.x = p.x*cosf(angleH) - p.z*sinf(angleH);
- a.y = p.y;
- a.z = p.x*sinf(angleH) + p.z*cosf(angleH);
+ Vector a;
+ a.x = p.x*cosf(angleH) - p.z*sinf(angleH);
+ a.y = p.y;
+ a.z = p.x*sinf(angleH) + p.z*cosf(angleH);
- Vector b;
- b.x = a.x;
- b.y = a.z*sinf(angleV) + a.y*cosf(angleV);
- b.z = a.z*cosf(angleV) - a.y*sinf(angleV);
+ Vector b;
+ b.x = a.x;
+ b.y = a.z*sinf(angleV) + a.y*cosf(angleV);
+ b.z = a.z*cosf(angleV) - a.y*sinf(angleV);
- p = center + b;
+ p = center + b;
}
//! Returns the angle between point (x,y) and (0,0)
inline float RotateAngle(float x, float y)
{
- if ( (x == 0.0f) && (y == 0.0f) )
- return 0.0f;
+ if ( (x == 0.0f) && (y == 0.0f) )
+ return 0.0f;
- float atan = atan2(x, y);
+ float atan = atan2(x, y);
- if ((y < 0.0f) && (x >= 0.0f))
- return -atan + 2.5f*PI;
- else
- return -atan + 0.5f*PI;
+ if ((y < 0.0f) && (x >= 0.0f))
+ return -atan + 2.5f*PI;
+ else
+ return -atan + 0.5f*PI;
}
//! Calculates the angle between two points and one center
/** \a center the center point
\a p1,p2 the two points
- \returns The angle in radians (positive is counterclockwise (CCW) ) */
+ \returns The angle in radians (positive is counterclockwise (CCW) ) */
inline float RotateAngle(const Point &center, const Point &p1, const Point &p2)
{
- if (PointsEqual(p1, center))
- return 0;
+ if (PointsEqual(p1, center))
+ return 0;
- if (PointsEqual(p2, center))
- return 0;
+ if (PointsEqual(p2, center))
+ return 0;
- float a1 = asinf((p1.y - center.y) / Distance(p1, center));
- float a2 = asinf((p2.y - center.y) / Distance(p2, center));
+ float a1 = asinf((p1.y - center.y) / Distance(p1, center));
+ float a2 = asinf((p2.y - center.y) / Distance(p2, center));
- if (p1.x < center.x) a1 = PI - a1;
- if (p2.x < center.x) a2 = PI - a2;
+ if (p1.x < center.x) a1 = PI - a1;
+ if (p2.x < center.x) a2 = PI - a2;
- float a = a2 - a1;
- if (a < 0)
- a += 2.0f*PI;
+ float a = a2 - a1;
+ if (a < 0)
+ a += 2.0f*PI;
- return a;
+ return a;
}
//! Loads view matrix from the given vectors
@@ -223,62 +223,62 @@ inline float RotateAngle(const Point &center, const Point &p1, const Point &p2)
\a worldUp up vector */
inline void LoadViewMatrix(Matrix &mat, const Vector &from, const Vector &at, const Vector &worldUp)
{
- // Get the z basis vector, which points straight ahead. This is the
- // difference from the eyepoint to the lookat point.
- Vector view = at - from;
+ // Get the z basis vector, which points straight ahead. This is the
+ // difference from the eyepoint to the lookat point.
+ Vector view = at - from;
- float length = view.Length();
- assert(! IsZero(length) );
+ float length = view.Length();
+ assert(! IsZero(length) );
- // Normalize the z basis vector
- view /= length;
+ // Normalize the z basis vector
+ view /= length;
- // Get the dot product, and calculate the projection of the z basis
- // vector onto the up vector. The projection is the y basis vector.
- float dotProduct = DotProduct(worldUp, view);
+ // Get the dot product, and calculate the projection of the z basis
+ // vector onto the up vector. The projection is the y basis vector.
+ float dotProduct = DotProduct(worldUp, view);
- Vector up = worldUp - dotProduct * view;
+ Vector up = worldUp - dotProduct * view;
- // If this vector has near-zero length because the input specified a
- // bogus up vector, let's try a default up vector
- if ( IsZero(length = up.Length()) )
- {
- up = Vector(0.0f, 1.0f, 0.0f) - view.y * view;
-
- // If we still have near-zero length, resort to a different axis.
+ // If this vector has near-zero length because the input specified a
+ // bogus up vector, let's try a default up vector
if ( IsZero(length = up.Length()) )
{
- up = Vector(0.0f, 0.0f, 1.0f) - view.z * view;
+ up = Vector(0.0f, 1.0f, 0.0f) - view.y * view;
+
+ // If we still have near-zero length, resort to a different axis.
+ if ( IsZero(length = up.Length()) )
+ {
+ up = Vector(0.0f, 0.0f, 1.0f) - view.z * view;
- assert(! IsZero(up.Length()) );
+ assert(! IsZero(up.Length()) );
+ }
}
- }
-
- // Normalize the y basis vector
- up /= length;
-
- // The x basis vector is found simply with the cross product of the y
- // and z basis vectors
- Vector right = CrossProduct(up, view);
-
- // Start building the matrix. The first three rows contains the basis
- // vectors used to rotate the view to point at the lookat point
- mat.LoadIdentity();
-
- /* (1,1) */ mat.m[0 ] = right.x;
- /* (2,1) */ mat.m[1 ] = up.x;
- /* (3,1) */ mat.m[2 ] = view.x;
- /* (1,2) */ mat.m[4 ] = right.y;
- /* (2,2) */ mat.m[5 ] = up.y;
- /* (3,2) */ mat.m[6 ] = view.y;
- /* (1,3) */ mat.m[8 ] = right.z;
- /* (2,3) */ mat.m[9 ] = up.z;
- /* (3,3) */ mat.m[10] = view.z;
-
- // Do the translation values (rotations are still about the eyepoint)
- /* (1,4) */ mat.m[12] = -DotProduct(from, right);
- /* (2,4) */ mat.m[13] = -DotProduct(from, up);
- /* (3,4) */ mat.m[14] = -DotProduct(from, view);
+
+ // Normalize the y basis vector
+ up /= length;
+
+ // The x basis vector is found simply with the cross product of the y
+ // and z basis vectors
+ Vector right = CrossProduct(up, view);
+
+ // Start building the matrix. The first three rows contains the basis
+ // vectors used to rotate the view to point at the lookat point
+ mat.LoadIdentity();
+
+ /* (1,1) */ mat.m[0 ] = right.x;
+ /* (2,1) */ mat.m[1 ] = up.x;
+ /* (3,1) */ mat.m[2 ] = view.x;
+ /* (1,2) */ mat.m[4 ] = right.y;
+ /* (2,2) */ mat.m[5 ] = up.y;
+ /* (3,2) */ mat.m[6 ] = view.y;
+ /* (1,3) */ mat.m[8 ] = right.z;
+ /* (2,3) */ mat.m[9 ] = up.z;
+ /* (3,3) */ mat.m[10] = view.z;
+
+ // Do the translation values (rotations are still about the eyepoint)
+ /* (1,4) */ mat.m[12] = -DotProduct(from, right);
+ /* (2,4) */ mat.m[13] = -DotProduct(from, up);
+ /* (3,4) */ mat.m[14] = -DotProduct(from, view);
}
//! Loads a perspective projection matrix
@@ -289,73 +289,73 @@ inline void LoadViewMatrix(Matrix &mat, const Vector &from, const Vector &at, co
inline void LoadProjectionMatrix(Matrix &mat, float fov = 1.570795f, float aspect = 1.0f,
float nearPlane = 1.0f, float farPlane = 1000.0f)
{
- assert(fabs(farPlane - nearPlane) >= 0.01f);
- assert(fabs(sin(fov / 2)) >= 0.01f);
+ assert(fabs(farPlane - nearPlane) >= 0.01f);
+ assert(fabs(sin(fov / 2)) >= 0.01f);
- float w = aspect * (cosf(fov / 2) / sinf(fov / 2));
- float h = 1.0f * (cosf(fov / 2) / sinf(fov / 2));
- float q = farPlane / (farPlane - nearPlane);
+ float w = aspect * (cosf(fov / 2) / sinf(fov / 2));
+ float h = 1.0f * (cosf(fov / 2) / sinf(fov / 2));
+ float q = farPlane / (farPlane - nearPlane);
- mat.LoadZero();
+ mat.LoadZero();
- /* (1,1) */ mat.m[0 ] = w;
- /* (2,2) */ mat.m[5 ] = h;
- /* (3,3) */ mat.m[10] = q;
- /* (4,3) */ mat.m[11] = 1.0f;
- /* (3,4) */ mat.m[14] = -q * nearPlane;
+ /* (1,1) */ mat.m[0 ] = w;
+ /* (2,2) */ mat.m[5 ] = h;
+ /* (3,3) */ mat.m[10] = q;
+ /* (4,3) */ mat.m[11] = 1.0f;
+ /* (3,4) */ mat.m[14] = -q * nearPlane;
}
//! Loads a translation matrix from given vector
/** \a trans vector of translation*/
inline void LoadTranslationMatrix(Matrix &mat, const Vector &trans)
{
- mat.LoadIdentity();
- /* (1,4) */ mat.m[12] = trans.x;
- /* (2,4) */ mat.m[13] = trans.y;
- /* (3,4) */ mat.m[14] = trans.z;
+ mat.LoadIdentity();
+ /* (1,4) */ mat.m[12] = trans.x;
+ /* (2,4) */ mat.m[13] = trans.y;
+ /* (3,4) */ mat.m[14] = trans.z;
}
//! Loads a scaling matrix fom given vector
/** \a scale vector with scaling factors for X, Y, Z */
inline void LoadScaleMatrix(Matrix &mat, const Vector &scale)
{
- mat.LoadIdentity();
- /* (1,1) */ mat.m[0 ] = scale.x;
- /* (2,2) */ mat.m[5 ] = scale.y;
- /* (3,3) */ mat.m[10] = scale.z;
+ mat.LoadIdentity();
+ /* (1,1) */ mat.m[0 ] = scale.x;
+ /* (2,2) */ mat.m[5 ] = scale.y;
+ /* (3,3) */ mat.m[10] = scale.z;
}
//! Loads a rotation matrix along the X axis
/** \a angle angle in radians */
inline void LoadRotationXMatrix(Matrix &mat, float angle)
{
- mat.LoadIdentity();
- /* (2,2) */ mat.m[5 ] = cosf(angle);
- /* (3,2) */ mat.m[6 ] = sinf(angle);
- /* (2,3) */ mat.m[9 ] = -sinf(angle);
- /* (3,3) */ mat.m[10] = cosf(angle);
+ mat.LoadIdentity();
+ /* (2,2) */ mat.m[5 ] = cosf(angle);
+ /* (3,2) */ mat.m[6 ] = sinf(angle);
+ /* (2,3) */ mat.m[9 ] = -sinf(angle);
+ /* (3,3) */ mat.m[10] = cosf(angle);
}
//! Loads a rotation matrix along the Y axis
/** \a angle angle in radians */
inline void LoadRotationYMatrix(Matrix &mat, float angle)
{
- mat.LoadIdentity();
- /* (1,1) */ mat.m[0 ] = cosf(angle);
- /* (3,1) */ mat.m[2 ] = -sinf(angle);
- /* (1,3) */ mat.m[8 ] = sinf(angle);
- /* (3,3) */ mat.m[10] = cosf(angle);
+ mat.LoadIdentity();
+ /* (1,1) */ mat.m[0 ] = cosf(angle);
+ /* (3,1) */ mat.m[2 ] = -sinf(angle);
+ /* (1,3) */ mat.m[8 ] = sinf(angle);
+ /* (3,3) */ mat.m[10] = cosf(angle);
}
//! Loads a rotation matrix along the Z axis
/** \a angle angle in radians */
inline void LoadRotationZMatrix(Matrix &mat, float angle)
{
- mat.LoadIdentity();
- /* (1,1) */ mat.m[0 ] = cosf(angle);
- /* (2,1) */ mat.m[1 ] = sinf(angle);
- /* (1,2) */ mat.m[4 ] = -sinf(angle);
- /* (2,2) */ mat.m[5 ] = cosf(angle);
+ mat.LoadIdentity();
+ /* (1,1) */ mat.m[0 ] = cosf(angle);
+ /* (2,1) */ mat.m[1 ] = sinf(angle);
+ /* (1,2) */ mat.m[4 ] = -sinf(angle);
+ /* (2,2) */ mat.m[5 ] = cosf(angle);
}
//! Loads a rotation matrix along the given axis
@@ -363,66 +363,66 @@ inline void LoadRotationZMatrix(Matrix &mat, float angle)
\a angle angle in radians */
inline void LoadRotationMatrix(Matrix &mat, const Vector &dir, float angle)
{
- float cos = cosf(angle);
- float sin = sinf(angle);
- Vector v = Normalize(dir);
+ float cos = cosf(angle);
+ float sin = sinf(angle);
+ Vector v = Normalize(dir);
- mat.LoadIdentity();
+ mat.LoadIdentity();
- /* (1,1) */ mat.m[0 ] = (v.x * v.x) * (1.0f - cos) + cos;
- /* (2,1) */ mat.m[1 ] = (v.x * v.y) * (1.0f - cos) - (v.z * sin);
- /* (3,1) */ mat.m[2 ] = (v.x * v.z) * (1.0f - cos) + (v.y * sin);
+ /* (1,1) */ mat.m[0 ] = (v.x * v.x) * (1.0f - cos) + cos;
+ /* (2,1) */ mat.m[1 ] = (v.x * v.y) * (1.0f - cos) - (v.z * sin);
+ /* (3,1) */ mat.m[2 ] = (v.x * v.z) * (1.0f - cos) + (v.y * sin);
- /* (1,2) */ mat.m[4 ] = (v.y * v.x) * (1.0f - cos) + (v.z * sin);
- /* (2,2) */ mat.m[5 ] = (v.y * v.y) * (1.0f - cos) + cos ;
- /* (3,2) */ mat.m[6 ] = (v.y * v.z) * (1.0f - cos) - (v.x * sin);
+ /* (1,2) */ mat.m[4 ] = (v.y * v.x) * (1.0f - cos) + (v.z * sin);
+ /* (2,2) */ mat.m[5 ] = (v.y * v.y) * (1.0f - cos) + cos ;
+ /* (3,2) */ mat.m[6 ] = (v.y * v.z) * (1.0f - cos) - (v.x * sin);
- /* (1,3) */ mat.m[8 ] = (v.z * v.x) * (1.0f - cos) - (v.y * sin);
- /* (2,3) */ mat.m[9 ] = (v.z * v.y) * (1.0f - cos) + (v.x * sin);
- /* (3,3) */ mat.m[10] = (v.z * v.z) * (1.0f - cos) + cos;
+ /* (1,3) */ mat.m[8 ] = (v.z * v.x) * (1.0f - cos) - (v.y * sin);
+ /* (2,3) */ mat.m[9 ] = (v.z * v.y) * (1.0f - cos) + (v.x * sin);
+ /* (3,3) */ mat.m[10] = (v.z * v.z) * (1.0f - cos) + cos;
}
//! Calculates the matrix to make three rotations in the order X, Z and Y
inline void LoadRotationXZYMatrix(Matrix &mat, const Vector &angle)
{
- Matrix temp;
- LoadRotationXMatrix(temp, angle.x);
+ Matrix temp;
+ LoadRotationXMatrix(temp, angle.x);
- LoadRotationZMatrix(mat, angle.z);
- mat = Math::MultiplyMatrices(temp, mat);
+ LoadRotationZMatrix(mat, angle.z);
+ mat = Math::MultiplyMatrices(temp, mat);
- LoadRotationYMatrix(temp, angle.y);
- mat = Math::MultiplyMatrices(temp, mat);
+ LoadRotationYMatrix(temp, angle.y);
+ mat = Math::MultiplyMatrices(temp, mat);
}
//! Calculates the matrix to make three rotations in the order Z, X and Y
inline void LoadRotationZXYMatrix(Matrix &mat, const Vector &angle)
{
- Matrix temp;
- LoadRotationZMatrix(temp, angle.z);
+ Matrix temp;
+ LoadRotationZMatrix(temp, angle.z);
- LoadRotationXMatrix(mat, angle.x);
- mat = Math::MultiplyMatrices(temp, mat);
+ LoadRotationXMatrix(mat, angle.x);
+ mat = Math::MultiplyMatrices(temp, mat);
- LoadRotationYMatrix(temp, angle.y);
- mat = Math::MultiplyMatrices(temp, mat);
+ LoadRotationYMatrix(temp, angle.y);
+ mat = Math::MultiplyMatrices(temp, mat);
}
//! Returns the distance between projections on XZ plane of two vectors
inline float DistanceProjected(const Vector &a, const Vector &b)
{
- return sqrtf( (a.x-b.x)*(a.x-b.x) +
- (a.z-b.z)*(a.z-b.z) );
+ return sqrtf( (a.x-b.x)*(a.x-b.x) +
+ (a.z-b.z)*(a.z-b.z) );
}
//! Returns the normal vector to a plane
/** \param p1,p2,p3 points defining the plane */
inline Vector NormalToPlane(const Vector &p1, const Vector &p2, const Vector &p3)
{
- Vector u = p3 - p1;
- Vector v = p2 - p1;
+ Vector u = p3 - p1;
+ Vector v = p2 - p1;
- return Normalize(CrossProduct(u, v));
+ return Normalize(CrossProduct(u, v));
}
//! Returns a point on the line \a p1 - \a p2, in \a dist distance from \a p1
@@ -430,7 +430,7 @@ inline Vector NormalToPlane(const Vector &p1, const Vector &p2, const Vector &p3
\a dist scaling factor from \a p1, relative to distance between \a p1 and \a p2 */
inline Vector SegmentPoint(const Vector &p1, const Vector &p2, float dist)
{
- return p1 + (p2 - p1) * dist;
+ return p1 + (p2 - p1) * dist;
}
//! Returns the distance between given point and a plane
@@ -438,10 +438,10 @@ inline Vector SegmentPoint(const Vector &p1, const Vector &p2, float dist)
\param a,b,c points defining the plane */
inline float DistanceToPlane(const Vector &a, const Vector &b, const Vector &c, const Vector &p)
{
- Vector n = NormalToPlane(a, b, c);
- float d = -(n.x*a.x + n.y*a.y + n.z*a.z);
+ Vector n = NormalToPlane(a, b, c);
+ float d = -(n.x*a.x + n.y*a.y + n.z*a.z);
- return fabs(n.x*p.x + n.y*p.y + n.z*p.z + d);
+ return fabs(n.x*p.x + n.y*p.y + n.z*p.z + d);
}
//! Checks if two planes defined by three points are the same
@@ -449,73 +449,73 @@ inline float DistanceToPlane(const Vector &a, const Vector &b, const Vector &c,
\a plane2 array of three vectors defining the second plane */
inline bool IsSamePlane(const Vector (&plane1)[3], const Vector (&plane2)[3])
{
- Vector n1 = NormalToPlane(plane1[0], plane1[1], plane1[2]);
- Vector n2 = NormalToPlane(plane2[0], plane2[1], plane2[2]);
+ Vector n1 = NormalToPlane(plane1[0], plane1[1], plane1[2]);
+ Vector n2 = NormalToPlane(plane2[0], plane2[1], plane2[2]);
- if ( fabs(n1.x-n2.x) > 0.1f ||
- fabs(n1.y-n2.y) > 0.1f ||
- fabs(n1.z-n2.z) > 0.1f )
- return false;
+ if ( fabs(n1.x-n2.x) > 0.1f ||
+ fabs(n1.y-n2.y) > 0.1f ||
+ fabs(n1.z-n2.z) > 0.1f )
+ return false;
- float dist = DistanceToPlane(plane1[0], plane1[1], plane1[2], plane2[0]);
- if ( dist > 0.1f )
- return false;
+ float dist = DistanceToPlane(plane1[0], plane1[1], plane1[2], plane2[0]);
+ if ( dist > 0.1f )
+ return false;
- return true;
+ return true;
}
//! Calculates the intersection "i" right "of" the plane "abc".
inline bool Intersect(const Vector &a, const Vector &b, const Vector &c, const Vector &d, const Vector &e, Vector &i)
{
- float d1 = (d.x-a.x)*((b.y-a.y)*(c.z-a.z)-(c.y-a.y)*(b.z-a.z)) -
- (d.y-a.y)*((b.x-a.x)*(c.z-a.z)-(c.x-a.x)*(b.z-a.z)) +
- (d.z-a.z)*((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
+ float d1 = (d.x-a.x)*((b.y-a.y)*(c.z-a.z)-(c.y-a.y)*(b.z-a.z)) -
+ (d.y-a.y)*((b.x-a.x)*(c.z-a.z)-(c.x-a.x)*(b.z-a.z)) +
+ (d.z-a.z)*((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
- float d2 = (d.x-e.x)*((b.y-a.y)*(c.z-a.z)-(c.y-a.y)*(b.z-a.z)) -
- (d.y-e.y)*((b.x-a.x)*(c.z-a.z)-(c.x-a.x)*(b.z-a.z)) +
- (d.z-e.z)*((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
+ float d2 = (d.x-e.x)*((b.y-a.y)*(c.z-a.z)-(c.y-a.y)*(b.z-a.z)) -
+ (d.y-e.y)*((b.x-a.x)*(c.z-a.z)-(c.x-a.x)*(b.z-a.z)) +
+ (d.z-e.z)*((b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y));
- if (d2 == 0)
- return false;
+ if (d2 == 0)
+ return false;
- i.x = d.x + d1/d2*(e.x-d.x);
- i.y = d.y + d1/d2*(e.y-d.y);
- i.z = d.z + d1/d2*(e.z-d.z);
+ i.x = d.x + d1/d2*(e.x-d.x);
+ i.y = d.y + d1/d2*(e.y-d.y);
+ i.z = d.z + d1/d2*(e.z-d.z);
- return true;
+ return true;
}
//! Calculates the intersection of the straight line passing through p (x, z)
/** Line is parallel to the y axis, with the plane abc. Returns p.y. */
inline bool IntersectY(const Vector &a, const Vector &b, const Vector &c, Vector &p)
{
- float d = (b.x-a.x)*(c.z-a.z) - (c.x-a.x)*(b.z-a.z);
- float d1 = (p.x-a.x)*(c.z-a.z) - (c.x-a.x)*(p.z-a.z);
- float d2 = (b.x-a.x)*(p.z-a.z) - (p.x-a.x)*(b.z-a.z);
+ float d = (b.x-a.x)*(c.z-a.z) - (c.x-a.x)*(b.z-a.z);
+ float d1 = (p.x-a.x)*(c.z-a.z) - (c.x-a.x)*(p.z-a.z);
+ float d2 = (b.x-a.x)*(p.z-a.z) - (p.x-a.x)*(b.z-a.z);
- if (d == 0.0f)
- return false;
+ if (d == 0.0f)
+ return false;
- p.y = a.y + d1/d*(b.y-a.y) + d2/d*(c.y-a.y);
+ p.y = a.y + d1/d*(b.y-a.y) + d2/d*(c.y-a.y);
- return true;
+ return true;
}
//! Calculates the end point
inline Vector LookatPoint(const Vector &eye, float angleH, float angleV, float length)
{
- Vector lookat = eye;
- lookat.z += length;
+ Vector lookat = eye;
+ lookat.z += length;
- RotatePoint(eye, angleH, angleV, lookat);
+ RotatePoint(eye, angleH, angleV, lookat);
- return lookat;
+ return lookat;
}
//! TODO documentation
inline Vector Transform(const Matrix &m, const Vector &p)
{
- return MatrixVectorMultiply(m, p);
+ return MatrixVectorMultiply(m, p);
}
//! Calculates the projection of the point \a p on a straight line \a a to \a b.
@@ -523,28 +523,28 @@ inline Vector Transform(const Matrix &m, const Vector &p)
\a a,b two ends of the line */
inline Vector Projection(const Vector &a, const Vector &b, const Vector &p)
{
- float k = DotProduct(b - a, p - a);
- k /= DotProduct(b - a, b - a);
+ float k = DotProduct(b - a, p - a);
+ k /= DotProduct(b - a, b - a);
- return a + k*(b-a);
+ return a + k*(b-a);
}
//! Calculates point of view to look at a center two angles and a distance
inline Vector RotateView(Vector center, float angleH, float angleV, float dist)
{
- Matrix mat1, mat2;
- LoadRotationZMatrix(mat1, -angleV);
- LoadRotationYMatrix(mat2, -angleH);
+ Matrix mat1, mat2;
+ LoadRotationZMatrix(mat1, -angleV);
+ LoadRotationYMatrix(mat2, -angleH);
- Matrix mat = MultiplyMatrices(mat2, mat1);
+ Matrix mat = MultiplyMatrices(mat2, mat1);
- Vector eye;
- eye.x = 0.0f+dist;
- eye.y = 0.0f;
- eye.z = 0.0f;
- eye = Transform(mat, eye);
+ Vector eye;
+ eye.x = 0.0f+dist;
+ eye.y = 0.0f;
+ eye.z = 0.0f;
+ eye = Transform(mat, eye);
- return eye+center;
+ return eye+center;
}
/* @} */ // end of group
diff --git a/src/math/intpoint.h b/src/math/intpoint.h
index cbfee2d..a760bc2 100644
--- a/src/math/intpoint.h
+++ b/src/math/intpoint.h
@@ -31,12 +31,12 @@ namespace Math {
*/
struct IntPoint
{
- //! X coord
- long x;
- //! Y coord
- long y;
+ //! X coord
+ long x;
+ //! Y coord
+ long y;
- IntPoint(long aX = 0, long aY = 0) : x(aX), y(aY) {}
+ IntPoint(long aX = 0, long aY = 0) : x(aX), y(aY) {}
};
/* @} */ // end of group
diff --git a/src/math/matrix.h b/src/math/matrix.h
index 35871cf..9b29f46 100644
--- a/src/math/matrix.h
+++ b/src/math/matrix.h
@@ -37,356 +37,356 @@ namespace Math
/** \struct Matrix math/matrix.h
\brief 4x4 matrix
- Represents an universal 4x4 matrix that can be used in OpenGL and DirectX engines.
- Contains the required methods for operating on matrices (inverting, multiplying, etc.).
+ Represents an universal 4x4 matrix that can be used in OpenGL and DirectX engines.
+ Contains the required methods for operating on matrices (inverting, multiplying, etc.).
- The internal representation is a 16-value table in column-major order, thus:
+ The internal representation is a 16-value table in column-major order, thus:
- \verbatim
+ \verbatim
m[0 ] m[4 ] m[8 ] m[12]
m[1 ] m[5 ] m[9 ] m[13]
m[2 ] m[6 ] m[10] m[14]
m[3 ] m[7 ] m[11] m[15] \endverbatim
- This representation is native to OpenGL; DirectX requires transposing the matrix.
+ This representation is native to OpenGL; DirectX requires transposing the matrix.
- The order of multiplication of matrix and vector is also OpenGL-native
- (see the function MatrixVectorMultiply).
+ The order of multiplication of matrix and vector is also OpenGL-native
+ (see the function MatrixVectorMultiply).
- All methods are made inline to maximize optimization.
+ All methods are made inline to maximize optimization.
- Unit tests for the structure and related functions are in module: math/test/matrix_test.cpp.
+ Unit tests for the structure and related functions are in module: math/test/matrix_test.cpp.
**/
struct Matrix
{
- //! Matrix values in column-major order
- float m[16];
-
- //! Creates the indentity matrix
- inline Matrix()
- {
- LoadIdentity();
- }
-
- //! Creates the matrix from 1D array
- /** \a m matrix values in column-major order */
- inline explicit Matrix(const float (&m)[16])
- {
- for (int i = 0; i < 16; ++i)
- this->m[i] = m[i];
- }
-
- //! Creates the matrix from 2D array
- /** The array's first index is row, second is column.
- \a m array with values */
- inline explicit Matrix(const float (&m)[4][4])
- {
- for (int c = 0; c < 4; ++c)
+ //! Matrix values in column-major order
+ float m[16];
+
+ //! Creates the indentity matrix
+ inline Matrix()
{
- for (int r = 0; r < 4; ++r)
- {
- this->m[4*c+r] = m[r][c];
- }
+ LoadIdentity();
}
- }
- inline void Set(int row, int col, float value)
- {
- m[(col-1)*4+(row-1)] = value;
- }
+ //! Creates the matrix from 1D array
+ /** \a m matrix values in column-major order */
+ inline explicit Matrix(const float (&m)[16])
+ {
+ for (int i = 0; i < 16; ++i)
+ this->m[i] = m[i];
+ }
- inline float Get(int row, int col)
- {
- return m[(col-1)*4+(row-1)];
- }
+ //! Creates the matrix from 2D array
+ /** The array's first index is row, second is column.
+ \a m array with values */
+ inline explicit Matrix(const float (&m)[4][4])
+ {
+ for (int c = 0; c < 4; ++c)
+ {
+ for (int r = 0; r < 4; ++r)
+ {
+ this->m[4*c+r] = m[r][c];
+ }
+ }
+ }
- //! Loads the zero matrix
- inline void LoadZero()
- {
- for (int i = 0; i < 16; ++i)
- m[i] = 0.0f;
- }
-
- //! Loads the identity matrix
- inline void LoadIdentity()
- {
- LoadZero();
- /* (1,1) */ m[0 ] = 1.0f;
- /* (2,2) */ m[5 ] = 1.0f;
- /* (3,3) */ m[10] = 1.0f;
- /* (4,4) */ m[15] = 1.0f;
- }
-
- //! Transposes the matrix
- inline void Transpose()
- {
- /* (2,1) <-> (1,2) */ Swap(m[1 ], m[4 ]);
- /* (3,1) <-> (1,3) */ Swap(m[2 ], m[8 ]);
- /* (4,1) <-> (1,4) */ Swap(m[3 ], m[12]);
- /* (3,2) <-> (2,3) */ Swap(m[6 ], m[9 ]);
- /* (4,2) <-> (2,4) */ Swap(m[7 ], m[13]);
- /* (4,3) <-> (3,4) */ Swap(m[11], m[14]);
- }
-
- //! Calculates the determinant of the matrix
- /** \returns the determinant */
- inline float Det() const
- {
- float result = 0.0f;
- for (int i = 0; i < 4; ++i)
+ inline void Set(int row, int col, float value)
{
- result += m[i] * Cofactor(i, 0);
+ m[(col-1)*4+(row-1)] = value;
}
- return result;
- }
- //! Calculates the cofactor of the matrix
- /** \a r row (0 to 3)
- \a c column (0 to 3)
- \returns the cofactor */
- inline float Cofactor(int r, int c) const
- {
- assert(r >= 0 && r <= 3);
- assert(c >= 0 && c <= 3);
+ inline float Get(int row, int col)
+ {
+ return m[(col-1)*4+(row-1)];
+ }
- float result = 0.0f;
+ //! Loads the zero matrix
+ inline void LoadZero()
+ {
+ for (int i = 0; i < 16; ++i)
+ m[i] = 0.0f;
+ }
- /* That looks horrible, I know. But it's fast :) */
+ //! Loads the identity matrix
+ inline void LoadIdentity()
+ {
+ LoadZero();
+ /* (1,1) */ m[0 ] = 1.0f;
+ /* (2,2) */ m[5 ] = 1.0f;
+ /* (3,3) */ m[10] = 1.0f;
+ /* (4,4) */ m[15] = 1.0f;
+ }
- switch (4*r + c)
+ //! Transposes the matrix
+ inline void Transpose()
{
- // r=0, c=0
- /* 05 09 13
- 06 10 14
- 07 11 15 */
- case 0:
- result = + m[5 ] * (m[10] * m[15] - m[14] * m[11])
- - m[9 ] * (m[6 ] * m[15] - m[14] * m[7 ])
- + m[13] * (m[6 ] * m[11] - m[10] * m[7 ]);
- break;
-
- // r=0, c=1
- /* 01 09 13
- 02 10 14
- 03 11 15 */
- case 1:
- result = - m[1 ] * (m[10] * m[15] - m[14] * m[11])
- + m[9 ] * (m[2 ] * m[15] - m[14] * m[3 ])
- - m[13] * (m[2 ] * m[11] - m[10] * m[3 ]);
- break;
-
- // r=0, c=2
- /* 01 05 13
- 02 06 14
- 03 07 15 */
- case 2:
- result = + m[1 ] * (m[6 ] * m[15] - m[14] * m[7 ])
- - m[5 ] * (m[2 ] * m[15] - m[14] * m[3 ])
- + m[13] * (m[2 ] * m[7 ] - m[6 ] * m[3 ]);
- break;
-
- // r=0, c=3
- /* 01 05 09
- 02 06 10
- 03 07 11 */
- case 3:
- result = - m[1 ] * (m[6 ] * m[11] - m[10] * m[7 ])
- + m[5 ] * (m[2 ] * m[11] - m[10] * m[3 ])
- - m[9 ] * (m[2 ] * m[7 ] - m[6 ] * m[3 ]);
- break;
-
- // r=1, c=0
- /* 04 08 12
- 06 10 14
- 07 11 15 */
- case 4:
- result = - m[4 ] * (m[10] * m[15] - m[14] * m[11])
- + m[8 ] * (m[6 ] * m[15] - m[14] * m[7 ])
- - m[12] * (m[6 ] * m[11] - m[10] * m[7 ]);
- break;
-
- // r=1, c=1
- /* 00 08 12
- 02 10 14
- 03 11 15 */
- case 5:
- result = + m[0 ] * (m[10] * m[15] - m[14] * m[11])
- - m[8 ] * (m[2 ] * m[15] - m[14] * m[3 ])
- + m[12] * (m[2 ] * m[11] - m[10] * m[3 ]);
- break;
-
- // r=1, c=2
- /* 00 04 12
- 02 06 14
- 03 07 15 */
- case 6:
- result = - m[0 ] * (m[6 ] * m[15] - m[14] * m[7 ])
- + m[4 ] * (m[2 ] * m[15] - m[14] * m[3 ])
- - m[12] * (m[2 ] * m[7 ] - m[6 ] * m[3 ]);
- break;
-
- // r=1, c=3
- /* 00 04 08
- 02 06 10
- 03 07 11 */
- case 7:
- result = + m[0 ] * (m[6 ] * m[11] - m[10] * m[7 ])
- - m[4 ] * (m[2 ] * m[11] - m[10] * m[3 ])
- + m[8 ] * (m[2 ] * m[7 ] - m[6 ] * m[3 ]);
- break;
-
- // r=2, c=0
- /* 04 08 12
- 05 09 13
- 07 11 15 */
- case 8:
- result = + m[4 ] * (m[9 ] * m[15] - m[13] * m[11])
- - m[8 ] * (m[5 ] * m[15] - m[13] * m[7 ])
- + m[12] * (m[5 ] * m[11] - m[9 ] * m[7 ]);
- break;
-
- // r=2, c=1
- /* 00 08 12
- 01 09 13
- 03 11 15 */
- case 9:
- result = - m[0 ] * (m[9 ] * m[15] - m[13] * m[11])
- + m[8 ] * (m[1 ] * m[15] - m[13] * m[3 ])
- - m[12] * (m[1 ] * m[11] - m[9 ] * m[3 ]);
- break;
-
- // r=2, c=2
- /* 00 04 12
- 01 05 13
- 03 07 15 */
- case 10:
- result = + m[0 ] * (m[5 ] * m[15] - m[13] * m[7 ])
- - m[4 ] * (m[1 ] * m[15] - m[13] * m[3 ])
- + m[12] * (m[1 ] * m[7 ] - m[5 ] * m[3 ]);
- break;
-
- // r=2, c=3
- /* 00 04 08
- 01 05 09
- 03 07 11 */
- case 11:
- result = - m[0 ] * (m[5 ] * m[11] - m[9 ] * m[7 ])
- + m[4 ] * (m[1 ] * m[11] - m[9 ] * m[3 ])
- - m[8 ] * (m[1 ] * m[7 ] - m[5 ] * m[3 ]);
- break;
-
- // r=3, c=0
- /* 04 08 12
- 05 09 13
- 06 10 14 */
- case 12:
- result = - m[4 ] * (m[9 ] * m[14] - m[13] * m[10])
- + m[8 ] * (m[5 ] * m[14] - m[13] * m[6 ])
- - m[12] * (m[5 ] * m[10] - m[9 ] * m[6 ]);
- break;
-
- // r=3, c=1
- /* 00 08 12
- 01 09 13
- 02 10 14 */
- case 13:
- result = + m[0 ] * (m[9 ] * m[14] - m[13] * m[10])
- - m[8 ] * (m[1 ] * m[14] - m[13] * m[2 ])
- + m[12] * (m[1 ] * m[10] - m[9 ] * m[2 ]);
- break;
-
- // r=3, c=2
- /* 00 04 12
- 01 05 13
- 02 06 14 */
- case 14:
- result = - m[0 ] * (m[5 ] * m[14] - m[13] * m[6 ])
- + m[4 ] * (m[1 ] * m[14] - m[13] * m[2 ])
- - m[12] * (m[1 ] * m[6 ] - m[5 ] * m[2 ]);
- break;
-
- // r=3, c=3
- /* 00 04 08
- 01 05 09
- 02 06 10 */
- case 15:
- result = + m[0 ] * (m[5 ] * m[10] - m[9 ] * m[6 ])
- - m[4 ] * (m[1 ] * m[10] - m[9 ] * m[2 ])
- + m[8 ] * (m[1 ] * m[6 ] - m[5 ] * m[2 ]);
- break;
-
- default:
- break;
+ /* (2,1) <-> (1,2) */ Swap(m[1 ], m[4 ]);
+ /* (3,1) <-> (1,3) */ Swap(m[2 ], m[8 ]);
+ /* (4,1) <-> (1,4) */ Swap(m[3 ], m[12]);
+ /* (3,2) <-> (2,3) */ Swap(m[6 ], m[9 ]);
+ /* (4,2) <-> (2,4) */ Swap(m[7 ], m[13]);
+ /* (4,3) <-> (3,4) */ Swap(m[11], m[14]);
}
- return result;
- }
+ //! Calculates the determinant of the matrix
+ /** \returns the determinant */
+ inline float Det() const
+ {
+ float result = 0.0f;
+ for (int i = 0; i < 4; ++i)
+ {
+ result += m[i] * Cofactor(i, 0);
+ }
+ return result;
+ }
- //! Calculates the inverse matrix
- /** The determinant of the matrix must not be zero.
- \returns the inverted matrix */
- inline Matrix Inverse() const
- {
- float d = Det();
- assert(! IsZero(d));
+ //! Calculates the cofactor of the matrix
+ /** \a r row (0 to 3)
+ \a c column (0 to 3)
+ \returns the cofactor */
+ inline float Cofactor(int r, int c) const
+ {
+ assert(r >= 0 && r <= 3);
+ assert(c >= 0 && c <= 3);
- float result[16] = { 0.0f };
+ float result = 0.0f;
- for (int r = 0; r < 4; ++r)
- {
- for (int c = 0; c < 4; ++c)
- {
- // Already transposed!
- result[4*r+c] = (1.0f / d) * Cofactor(r, c);
- }
- }
+ /* That looks horrible, I know. But it's fast :) */
- return Matrix(result);
- }
+ switch (4*r + c)
+ {
+ // r=0, c=0
+ /* 05 09 13
+ 06 10 14
+ 07 11 15 */
+ case 0:
+ result = + m[5 ] * (m[10] * m[15] - m[14] * m[11])
+ - m[9 ] * (m[6 ] * m[15] - m[14] * m[7 ])
+ + m[13] * (m[6 ] * m[11] - m[10] * m[7 ]);
+ break;
+
+ // r=0, c=1
+ /* 01 09 13
+ 02 10 14
+ 03 11 15 */
+ case 1:
+ result = - m[1 ] * (m[10] * m[15] - m[14] * m[11])
+ + m[9 ] * (m[2 ] * m[15] - m[14] * m[3 ])
+ - m[13] * (m[2 ] * m[11] - m[10] * m[3 ]);
+ break;
+
+ // r=0, c=2
+ /* 01 05 13
+ 02 06 14
+ 03 07 15 */
+ case 2:
+ result = + m[1 ] * (m[6 ] * m[15] - m[14] * m[7 ])
+ - m[5 ] * (m[2 ] * m[15] - m[14] * m[3 ])
+ + m[13] * (m[2 ] * m[7 ] - m[6 ] * m[3 ]);
+ break;
+
+ // r=0, c=3
+ /* 01 05 09
+ 02 06 10
+ 03 07 11 */
+ case 3:
+ result = - m[1 ] * (m[6 ] * m[11] - m[10] * m[7 ])
+ + m[5 ] * (m[2 ] * m[11] - m[10] * m[3 ])
+ - m[9 ] * (m[2 ] * m[7 ] - m[6 ] * m[3 ]);
+ break;
+
+ // r=1, c=0
+ /* 04 08 12
+ 06 10 14
+ 07 11 15 */
+ case 4:
+ result = - m[4 ] * (m[10] * m[15] - m[14] * m[11])
+ + m[8 ] * (m[6 ] * m[15] - m[14] * m[7 ])
+ - m[12] * (m[6 ] * m[11] - m[10] * m[7 ]);
+ break;
+
+ // r=1, c=1
+ /* 00 08 12
+ 02 10 14
+ 03 11 15 */
+ case 5:
+ result = + m[0 ] * (m[10] * m[15] - m[14] * m[11])
+ - m[8 ] * (m[2 ] * m[15] - m[14] * m[3 ])
+ + m[12] * (m[2 ] * m[11] - m[10] * m[3 ]);
+ break;
+
+ // r=1, c=2
+ /* 00 04 12
+ 02 06 14
+ 03 07 15 */
+ case 6:
+ result = - m[0 ] * (m[6 ] * m[15] - m[14] * m[7 ])
+ + m[4 ] * (m[2 ] * m[15] - m[14] * m[3 ])
+ - m[12] * (m[2 ] * m[7 ] - m[6 ] * m[3 ]);
+ break;
+
+ // r=1, c=3
+ /* 00 04 08
+ 02 06 10
+ 03 07 11 */
+ case 7:
+ result = + m[0 ] * (m[6 ] * m[11] - m[10] * m[7 ])
+ - m[4 ] * (m[2 ] * m[11] - m[10] * m[3 ])
+ + m[8 ] * (m[2 ] * m[7 ] - m[6 ] * m[3 ]);
+ break;
+
+ // r=2, c=0
+ /* 04 08 12
+ 05 09 13
+ 07 11 15 */
+ case 8:
+ result = + m[4 ] * (m[9 ] * m[15] - m[13] * m[11])
+ - m[8 ] * (m[5 ] * m[15] - m[13] * m[7 ])
+ + m[12] * (m[5 ] * m[11] - m[9 ] * m[7 ]);
+ break;
+
+ // r=2, c=1
+ /* 00 08 12
+ 01 09 13
+ 03 11 15 */
+ case 9:
+ result = - m[0 ] * (m[9 ] * m[15] - m[13] * m[11])
+ + m[8 ] * (m[1 ] * m[15] - m[13] * m[3 ])
+ - m[12] * (m[1 ] * m[11] - m[9 ] * m[3 ]);
+ break;
+
+ // r=2, c=2
+ /* 00 04 12
+ 01 05 13
+ 03 07 15 */
+ case 10:
+ result = + m[0 ] * (m[5 ] * m[15] - m[13] * m[7 ])
+ - m[4 ] * (m[1 ] * m[15] - m[13] * m[3 ])
+ + m[12] * (m[1 ] * m[7 ] - m[5 ] * m[3 ]);
+ break;
+
+ // r=2, c=3
+ /* 00 04 08
+ 01 05 09
+ 03 07 11 */
+ case 11:
+ result = - m[0 ] * (m[5 ] * m[11] - m[9 ] * m[7 ])
+ + m[4 ] * (m[1 ] * m[11] - m[9 ] * m[3 ])
+ - m[8 ] * (m[1 ] * m[7 ] - m[5 ] * m[3 ]);
+ break;
+
+ // r=3, c=0
+ /* 04 08 12
+ 05 09 13
+ 06 10 14 */
+ case 12:
+ result = - m[4 ] * (m[9 ] * m[14] - m[13] * m[10])
+ + m[8 ] * (m[5 ] * m[14] - m[13] * m[6 ])
+ - m[12] * (m[5 ] * m[10] - m[9 ] * m[6 ]);
+ break;
+
+ // r=3, c=1
+ /* 00 08 12
+ 01 09 13
+ 02 10 14 */
+ case 13:
+ result = + m[0 ] * (m[9 ] * m[14] - m[13] * m[10])
+ - m[8 ] * (m[1 ] * m[14] - m[13] * m[2 ])
+ + m[12] * (m[1 ] * m[10] - m[9 ] * m[2 ]);
+ break;
+
+ // r=3, c=2
+ /* 00 04 12
+ 01 05 13
+ 02 06 14 */
+ case 14:
+ result = - m[0 ] * (m[5 ] * m[14] - m[13] * m[6 ])
+ + m[4 ] * (m[1 ] * m[14] - m[13] * m[2 ])
+ - m[12] * (m[1 ] * m[6 ] - m[5 ] * m[2 ]);
+ break;
+
+ // r=3, c=3
+ /* 00 04 08
+ 01 05 09
+ 02 06 10 */
+ case 15:
+ result = + m[0 ] * (m[5 ] * m[10] - m[9 ] * m[6 ])
+ - m[4 ] * (m[1 ] * m[10] - m[9 ] * m[2 ])
+ + m[8 ] * (m[1 ] * m[6 ] - m[5 ] * m[2 ]);
+ break;
+
+ default:
+ break;
+ }
- //! Calculates the multiplication of this matrix * given matrix
- /** \a right right-hand matrix
- \returns multiplication result */
- inline Matrix Multiply(const Matrix &right) const
- {
- float result[16] = { 0.0f };
+ return result;
+ }
- for (int c = 0; c < 4; ++c)
+ //! Calculates the inverse matrix
+ /** The determinant of the matrix must not be zero.
+ \returns the inverted matrix */
+ inline Matrix Inverse() const
{
- for (int r = 0; r < 4; ++r)
- {
- result[4*c+r] = 0.0f;
- for (int i = 0; i < 4; ++i)
+ float d = Det();
+ assert(! IsZero(d));
+
+ float result[16] = { 0.0f };
+
+ for (int r = 0; r < 4; ++r)
{
- result[4*c+r] += m[4*i+r] * right.m[4*c+i];
+ for (int c = 0; c < 4; ++c)
+ {
+ // Already transposed!
+ result[4*r+c] = (1.0f / d) * Cofactor(r, c);
+ }
}
- }
+
+ return Matrix(result);
}
- return Matrix(result);
- }
+ //! Calculates the multiplication of this matrix * given matrix
+ /** \a right right-hand matrix
+ \returns multiplication result */
+ inline Matrix Multiply(const Matrix &right) const
+ {
+ float result[16] = { 0.0f };
+
+ for (int c = 0; c < 4; ++c)
+ {
+ for (int r = 0; r < 4; ++r)
+ {
+ result[4*c+r] = 0.0f;
+ for (int i = 0; i < 4; ++i)
+ {
+ result[4*c+r] += m[4*i+r] * right.m[4*c+i];
+ }
+ }
+ }
+
+ return Matrix(result);
+ }
}; // struct Matrix
//! Checks if two matrices are equal within given \a tolerance
inline bool MatricesEqual(const Matrix &m1, const Matrix &m2,
- float tolerance = TOLERANCE)
+ float tolerance = TOLERANCE)
{
- for (int i = 0; i < 16; ++i)
- {
- if (! IsEqual(m1.m[i], m2.m[i], tolerance))
- return false;
- }
+ for (int i = 0; i < 16; ++i)
+ {
+ if (! IsEqual(m1.m[i], m2.m[i], tolerance))
+ return false;
+ }
- return true;
+ return true;
}
//! Convenience function for getting transposed matrix
inline Matrix Transpose(const Matrix &m)
{
- Matrix result = m;
- result.Transpose();
- return result;
+ Matrix result = m;
+ result.Transpose();
+ return result;
}
//! Convenience function for multiplying a matrix
@@ -395,7 +395,7 @@ inline Matrix Transpose(const Matrix &m)
\returns multiplied matrices */
inline Matrix MultiplyMatrices(const Matrix &left, const Matrix &right)
{
- return left.Multiply(right);
+ return left.Multiply(right);
}
//! Calculates the result of multiplying m * v
@@ -405,27 +405,27 @@ inline Matrix MultiplyMatrices(const Matrix &left, const Matrix &right)
[ m.m[2 ] m.m[6 ] m.m[10] m.m[14] ] * [ v.z ]
[ m.m[3 ] m.m[7 ] m.m[11] m.m[15] ] [ 1 ] \endverbatim
- The result, a 4x1 vector is then converted to 3x1 by dividing
- x,y,z coords by the fourth coord (w). */
+ The result, a 4x1 vector is then converted to 3x1 by dividing
+ x,y,z coords by the fourth coord (w). */
inline Vector MatrixVectorMultiply(const Matrix &m, const Vector &v, bool wDivide = false)
{
- float x = v.x * m.m[0 ] + v.y * m.m[4 ] + v.z * m.m[8 ] + m.m[12];
- float y = v.x * m.m[1 ] + v.y * m.m[5 ] + v.z * m.m[9 ] + m.m[13];
- float z = v.x * m.m[2 ] + v.y * m.m[6 ] + v.z * m.m[10] + m.m[14];
+ float x = v.x * m.m[0 ] + v.y * m.m[4 ] + v.z * m.m[8 ] + m.m[12];
+ float y = v.x * m.m[1 ] + v.y * m.m[5 ] + v.z * m.m[9 ] + m.m[13];
+ float z = v.x * m.m[2 ] + v.y * m.m[6 ] + v.z * m.m[10] + m.m[14];
- if (!wDivide)
- return Vector(x, y, z);
+ if (!wDivide)
+ return Vector(x, y, z);
- float w = v.x * m.m[3 ] + v.y * m.m[7 ] + v.z * m.m[11] + m.m[15];
+ float w = v.x * m.m[3 ] + v.y * m.m[7 ] + v.z * m.m[11] + m.m[15];
- if (IsZero(w))
- return Vector(x, y, z);
+ if (IsZero(w))
+ return Vector(x, y, z);
- x /= w;
- y /= w;
- z /= w;
+ x /= w;
+ y /= w;
+ z /= w;
- return Vector(x, y, z);
+ return Vector(x, y, z);
}
/* @} */ // end of group
diff --git a/src/math/point.h b/src/math/point.h
index fdb3051..84be190 100644
--- a/src/math/point.h
+++ b/src/math/point.h
@@ -12,10 +12,10 @@
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
+// * along with this program. If not, see http://www.gnu.org/licenses/.
/** @defgroup MathPointModule math/point.h
- Contains the Point struct and related functions.
+ Contains the Point struct and related functions.
*/
#pragma once
@@ -35,111 +35,111 @@ namespace Math
/** \struct Point math/point.h
\brief 2D point
- Represents a 2D point (x, y).
- Contains the required methods for operating on points.
+ Represents a 2D point (x, y).
+ Contains the required methods for operating on points.
- All methods are made inline to maximize optimization.
+ All methods are made inline to maximize optimization.
*/
struct Point
{
- //! X coord
- float x;
- //! Y coord
- float y;
-
- //! Constructs a zero point: (0,0)
- inline Point()
- {
- LoadZero();
- }
-
- //! Constructs a point from given coords: (x,y)
- inline explicit Point(float x, float y)
- {
- this->x = x;
- this->y = y;
- }
-
- //! Sets the zero point: (0,0)
- inline void LoadZero()
- {
- x = y = 0.0f;
- }
-
- //! Returns the distance from (0,0) to the point (x,y)
- inline float Length()
- {
- return sqrtf(x*x + y*y);
- }
-
- //! Returns the inverted point
- inline Point operator-() const
- {
- return Point(-x, -y);
- }
-
- //! Adds the given point
- inline const Point& operator+=(const Point &right)
- {
- x += right.x;
- y += right.y;
- return *this;
- }
-
- //! Adds two points
- inline friend const Point operator+(const Point &left, const Point &right)
- {
- return Point(left.x + right.x, left.y + right.y);
- }
-
- //! Subtracts the given vector
- inline const Point& operator-=(const Point &right)
- {
- x -= right.x;
- y -= right.y;
- return *this;
- }
-
- //! Subtracts two points
- inline friend const Point operator-(const Point &left, const Point &right)
- {
- return Point(left.x - right.x, left.y - right.y);
- }
-
- //! Multiplies by given scalar
- inline const Point& operator*=(const float &right)
- {
- x *= right;
- y *= right;
- return *this;
- }
-
- //! Multiplies point by scalar
- inline friend const Point operator*(const float &left, const Point &right)
- {
- return Point(left * right.x, left * right.y);
- }
-
- //! Multiplies point by scalar
- inline friend const Point operator*(const Point &left, const float &right)
- {
- return Point(left.x * right, left.y * right);
- }
-
- //! Divides by given scalar
- inline const Point& operator/=(const float &right)
- {
- x /= right;
- y /= right;
- return *this;
- }
-
- //! Divides point by scalar
- inline friend const Point operator/(const Point &left, const float &right)
- {
- return Point(left.x / right, left.y / right);
- }
+ //! X coord
+ float x;
+ //! Y coord
+ float y;
+
+ //! Constructs a zero point: (0,0)
+ inline Point()
+ {
+ LoadZero();
+ }
+
+ //! Constructs a point from given coords: (x,y)
+ inline explicit Point(float x, float y)
+ {
+ this->x = x;
+ this->y = y;
+ }
+
+ //! Sets the zero point: (0,0)
+ inline void LoadZero()
+ {
+ x = y = 0.0f;
+ }
+
+ //! Returns the distance from (0,0) to the point (x,y)
+ inline float Length()
+ {
+ return sqrtf(x*x + y*y);
+ }
+
+ //! Returns the inverted point
+ inline Point operator-() const
+ {
+ return Point(-x, -y);
+ }
+
+ //! Adds the given point
+ inline const Point& operator+=(const Point &right)
+ {
+ x += right.x;
+ y += right.y;
+ return *this;
+ }
+
+ //! Adds two points
+ inline friend const Point operator+(const Point &left, const Point &right)
+ {
+ return Point(left.x + right.x, left.y + right.y);
+ }
+
+ //! Subtracts the given vector
+ inline const Point& operator-=(const Point &right)
+ {
+ x -= right.x;
+ y -= right.y;
+ return *this;
+ }
+
+ //! Subtracts two points
+ inline friend const Point operator-(const Point &left, const Point &right)
+ {
+ return Point(left.x - right.x, left.y - right.y);
+ }
+
+ //! Multiplies by given scalar
+ inline const Point& operator*=(const float &right)
+ {
+ x *= right;
+ y *= right;
+ return *this;
+ }
+
+ //! Multiplies point by scalar
+ inline friend const Point operator*(const float &left, const Point &right)
+ {
+ return Point(left * right.x, left * right.y);
+ }
+
+ //! Multiplies point by scalar
+ inline friend const Point operator*(const Point &left, const float &right)
+ {
+ return Point(left.x * right, left.y * right);
+ }
+
+ //! Divides by given scalar
+ inline const Point& operator/=(const float &right)
+ {
+ x /= right;
+ y /= right;
+ return *this;
+ }
+
+ //! Divides point by scalar
+ inline friend const Point operator/(const Point &left, const float &right)
+ {
+ return Point(left.x / right, left.y / right);
+ }
}; // struct Point
@@ -147,23 +147,23 @@ struct Point
//! Checks if two vectors are equal within given \a tolerance
inline bool PointsEqual(const Point &a, const Point &b, float tolerance = TOLERANCE)
{
- return IsEqual(a.x, b.x, tolerance) && IsEqual(a.y, b.y, tolerance);
+ return IsEqual(a.x, b.x, tolerance) && IsEqual(a.y, b.y, tolerance);
}
//! Permutes two points
inline void Swap(Point &a, Point &b)
{
- Point c;
+ Point c;
- c = a;
- a = b;
- b = c;
+ c = a;
+ a = b;
+ b = c;
}
//! Returns the distance between two points
inline float Distance(const Point &a, const Point &b)
{
- return sqrtf((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
+ return sqrtf((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
/* @} */ // end of group
diff --git a/src/math/test/geometry_test.cpp b/src/math/test/geometry_test.cpp
index d6dbd9b..07fa2cf 100644
--- a/src/math/test/geometry_test.cpp
+++ b/src/math/test/geometry_test.cpp
@@ -35,367 +35,367 @@ const float TEST_TOLERANCE = 1e-5;
// Test for rewritten function RotateAngle()
int TestRotateAngle()
{
- if (! Math::IsEqual(Math::RotateAngle(0.0f, 0.0f), 0.0f, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::IsEqual(Math::RotateAngle(0.0f, 0.0f), 0.0f, TEST_TOLERANCE))
+ return __LINE__;
- if (! Math::IsEqual(Math::RotateAngle(1.0f, 0.0f), 0.0f, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::IsEqual(Math::RotateAngle(1.0f, 0.0f), 0.0f, TEST_TOLERANCE))
+ return __LINE__;
- if (! Math::IsEqual(Math::RotateAngle(1.0f, 1.0f), 0.25f * Math::PI, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::IsEqual(Math::RotateAngle(1.0f, 1.0f), 0.25f * Math::PI, TEST_TOLERANCE))
+ return __LINE__;
- if (! Math::IsEqual(Math::RotateAngle(0.0f, 2.0f), 0.5f * Math::PI, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::IsEqual(Math::RotateAngle(0.0f, 2.0f), 0.5f * Math::PI, TEST_TOLERANCE))
+ return __LINE__;
- if (! Math::IsEqual(Math::RotateAngle(-0.5f, 0.5f), 0.75f * Math::PI, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::IsEqual(Math::RotateAngle(-0.5f, 0.5f), 0.75f * Math::PI, TEST_TOLERANCE))
+ return __LINE__;
- if (! Math::IsEqual(Math::RotateAngle(-1.0f, 0.0f), Math::PI, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::IsEqual(Math::RotateAngle(-1.0f, 0.0f), Math::PI, TEST_TOLERANCE))
+ return __LINE__;
- if (! Math::IsEqual(Math::RotateAngle(-1.0f, -1.0f), 1.25f * Math::PI, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::IsEqual(Math::RotateAngle(-1.0f, -1.0f), 1.25f * Math::PI, TEST_TOLERANCE))
+ return __LINE__;
- if (! Math::IsEqual(Math::RotateAngle(0.0f, -2.0f), 1.5f * Math::PI, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::IsEqual(Math::RotateAngle(0.0f, -2.0f), 1.5f * Math::PI, TEST_TOLERANCE))
+ return __LINE__;
- if (! Math::IsEqual(Math::RotateAngle(1.0f, -1.0f), 1.75f * Math::PI, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::IsEqual(Math::RotateAngle(1.0f, -1.0f), 1.75f * Math::PI, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
// Tests for other altered, complex or uncertain functions
int TestAngle()
{
- const Math::Vector u(-0.0786076246943884, 0.2231249091714256, -1.1601361718477805);
- const Math::Vector v(-1.231228742001907, -1.720549809950561, -0.690468438834111);
+ const Math::Vector u(-0.0786076246943884, 0.2231249091714256, -1.1601361718477805);
+ const Math::Vector v(-1.231228742001907, -1.720549809950561, -0.690468438834111);
- float mathResult = Math::Angle(u, v);
- float oldMathResult = Angle(VEC_TO_D3DVEC(u), VEC_TO_D3DVEC(v));
+ float mathResult = Math::Angle(u, v);
+ float oldMathResult = Angle(VEC_TO_D3DVEC(u), VEC_TO_D3DVEC(v));
- if (! Math::IsEqual(mathResult, oldMathResult, TEST_TOLERANCE) )
- return __LINE__;
+ if (! Math::IsEqual(mathResult, oldMathResult, TEST_TOLERANCE) )
+ return __LINE__;
- return 0;
+ return 0;
}
int TestRotateView()
{
- const Math::Vector center(0.617909142705555, 0.896939729454538, -0.615041943652284);
- const float angleH = 44.5;
- const float angleV = 12.3;
- const float dist = 34.76;
+ const Math::Vector center(0.617909142705555, 0.896939729454538, -0.615041943652284);
+ const float angleH = 44.5;
+ const float angleV = 12.3;
+ const float dist = 34.76;
- Math::Vector mathResult = Math::RotateView(center, angleH, angleV, dist);
- Math::Vector oldMathResult = D3DVEC_TO_VEC(RotateView(VEC_TO_D3DVEC(center), angleH, angleV, dist));
+ Math::Vector mathResult = Math::RotateView(center, angleH, angleV, dist);
+ Math::Vector oldMathResult = D3DVEC_TO_VEC(RotateView(VEC_TO_D3DVEC(center), angleH, angleV, dist));
- if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestLookatPoint()
{
- const Math::Vector eye(-2.451183170579471, 0.241270270546559, -0.490677411454893);
- const float angleH = 48.4;
- const float angleV = 32.4;
- const float length = 74.44;
+ const Math::Vector eye(-2.451183170579471, 0.241270270546559, -0.490677411454893);
+ const float angleH = 48.4;
+ const float angleV = 32.4;
+ const float length = 74.44;
- Math::Vector mathResult = Math::LookatPoint(eye, angleH, angleV, length);
- Math::Vector oldMathResult = D3DVEC_TO_VEC(LookatPoint(VEC_TO_D3DVEC(eye), angleH, angleV, length));
+ Math::Vector mathResult = Math::LookatPoint(eye, angleH, angleV, length);
+ Math::Vector oldMathResult = D3DVEC_TO_VEC(LookatPoint(VEC_TO_D3DVEC(eye), angleH, angleV, length));
- if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestProjection()
{
- const Math::Vector a(0.852064846846319, -0.794279497087496, -0.655779805476688);
- const Math::Vector b(-0.245838834102304, -0.841115596038861, 0.470457161487799);
- const Math::Vector p(2.289326061164255, -0.505511362271196, 0.660204551169491);
+ const Math::Vector a(0.852064846846319, -0.794279497087496, -0.655779805476688);
+ const Math::Vector b(-0.245838834102304, -0.841115596038861, 0.470457161487799);
+ const Math::Vector p(2.289326061164255, -0.505511362271196, 0.660204551169491);
- Math::Vector mathResult = Math::Projection(a, b, p);
- Math::Vector oldMathResult = D3DVEC_TO_VEC(Projection(VEC_TO_D3DVEC(a), VEC_TO_D3DVEC(b), VEC_TO_D3DVEC(p)));
+ Math::Vector mathResult = Math::Projection(a, b, p);
+ Math::Vector oldMathResult = D3DVEC_TO_VEC(Projection(VEC_TO_D3DVEC(a), VEC_TO_D3DVEC(b), VEC_TO_D3DVEC(p)));
- if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestLoadViewMatrix()
{
- const Math::Vector from(2.5646013154868874, -0.6058794133917031, -0.0441195127419744);
- const Math::Vector at(0.728044925765569, -0.206343977871841, 2.543158236935463);
- const Math::Vector worldUp(-1.893738133660711, -1.009584441407070, 0.521745988225582);
-
- Math::Matrix mathResult;
- Math::LoadViewMatrix(mathResult, from, at, worldUp);
-
- Math::Matrix oldMathResult;
- {
- D3DMATRIX mat;
- D3DVECTOR fromD3D = VEC_TO_D3DVEC(from);
- D3DVECTOR atD3D = VEC_TO_D3DVEC(at);
- D3DVECTOR worldUpD3D = VEC_TO_D3DVEC(worldUp);
- D3DUtil_SetViewMatrix(mat, fromD3D, atD3D, worldUpD3D);
- oldMathResult = D3DMAT_TO_MAT(mat);
- }
-
- if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
-
- return 0;
+ const Math::Vector from(2.5646013154868874, -0.6058794133917031, -0.0441195127419744);
+ const Math::Vector at(0.728044925765569, -0.206343977871841, 2.543158236935463);
+ const Math::Vector worldUp(-1.893738133660711, -1.009584441407070, 0.521745988225582);
+
+ Math::Matrix mathResult;
+ Math::LoadViewMatrix(mathResult, from, at, worldUp);
+
+ Math::Matrix oldMathResult;
+ {
+ D3DMATRIX mat;
+ D3DVECTOR fromD3D = VEC_TO_D3DVEC(from);
+ D3DVECTOR atD3D = VEC_TO_D3DVEC(at);
+ D3DVECTOR worldUpD3D = VEC_TO_D3DVEC(worldUp);
+ D3DUtil_SetViewMatrix(mat, fromD3D, atD3D, worldUpD3D);
+ oldMathResult = D3DMAT_TO_MAT(mat);
+ }
+
+ if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
+
+ return 0;
}
int TestLoadProjectionMatrix()
{
- const float fov = 76.3f;
- const float aspect = 0.891f;
- const float nearPlane = 12.3f;
- const float farPlane = 1238.9f;
+ const float fov = 76.3f;
+ const float aspect = 0.891f;
+ const float nearPlane = 12.3f;
+ const float farPlane = 1238.9f;
- Math::Matrix mathResult;
- Math::LoadProjectionMatrix(mathResult, fov, aspect, nearPlane, farPlane);
+ Math::Matrix mathResult;
+ Math::LoadProjectionMatrix(mathResult, fov, aspect, nearPlane, farPlane);
- Math::Matrix oldMathResult;
- {
- D3DMATRIX mat;
- D3DUtil_SetProjectionMatrix(mat, fov, aspect, nearPlane, farPlane);
- oldMathResult = D3DMAT_TO_MAT(mat);
- }
+ Math::Matrix oldMathResult;
+ {
+ D3DMATRIX mat;
+ D3DUtil_SetProjectionMatrix(mat, fov, aspect, nearPlane, farPlane);
+ oldMathResult = D3DMAT_TO_MAT(mat);
+ }
- if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestLoadTranslationMatrix()
{
- const Math::Vector translation(-0.3631590720995237, 1.6976327614875211, 0.0148815191502145);
+ const Math::Vector translation(-0.3631590720995237, 1.6976327614875211, 0.0148815191502145);
- Math::Matrix mathResult;
- Math::LoadTranslationMatrix(mathResult, translation);
+ Math::Matrix mathResult;
+ Math::LoadTranslationMatrix(mathResult, translation);
- Math::Matrix oldMathResult;
- {
- D3DMATRIX mat;
- D3DUtil_SetTranslateMatrix(mat, translation.x, translation.y, translation.z);
- oldMathResult = D3DMAT_TO_MAT(mat);
- }
+ Math::Matrix oldMathResult;
+ {
+ D3DMATRIX mat;
+ D3DUtil_SetTranslateMatrix(mat, translation.x, translation.y, translation.z);
+ oldMathResult = D3DMAT_TO_MAT(mat);
+ }
- if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestLoadScaleMatrix()
{
- const Math::Vector scale(0.612236460285503, -0.635566935025364, -0.254321375332065);
+ const Math::Vector scale(0.612236460285503, -0.635566935025364, -0.254321375332065);
- Math::Matrix mathResult;
- Math::LoadScaleMatrix(mathResult, scale);
+ Math::Matrix mathResult;
+ Math::LoadScaleMatrix(mathResult, scale);
- Math::Matrix oldMathResult;
- {
- D3DMATRIX mat;
- D3DUtil_SetScaleMatrix(mat, scale.x, scale.y, scale.z);
- oldMathResult = D3DMAT_TO_MAT(mat);
- }
+ Math::Matrix oldMathResult;
+ {
+ D3DMATRIX mat;
+ D3DUtil_SetScaleMatrix(mat, scale.x, scale.y, scale.z);
+ oldMathResult = D3DMAT_TO_MAT(mat);
+ }
- if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestLoadRotationXMatrix()
{
- const float angle = 0.513790685774275;
+ const float angle = 0.513790685774275;
- Math::Matrix mathResult;
- Math::LoadRotationXMatrix(mathResult, angle);
+ Math::Matrix mathResult;
+ Math::LoadRotationXMatrix(mathResult, angle);
- Math::Matrix oldMathResult;
- {
- D3DMATRIX mat;
- D3DUtil_SetRotateXMatrix(mat, angle);
- oldMathResult = D3DMAT_TO_MAT(mat);
- }
+ Math::Matrix oldMathResult;
+ {
+ D3DMATRIX mat;
+ D3DUtil_SetRotateXMatrix(mat, angle);
+ oldMathResult = D3DMAT_TO_MAT(mat);
+ }
- if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestLoadRotationYMatrix()
{
- const float angle = -0.569166650127303;
+ const float angle = -0.569166650127303;
- Math::Matrix mathResult;
- Math::LoadRotationYMatrix(mathResult, angle);
+ Math::Matrix mathResult;
+ Math::LoadRotationYMatrix(mathResult, angle);
- Math::Matrix oldMathResult;
- {
- D3DMATRIX mat;
- D3DUtil_SetRotateYMatrix(mat, angle);
- oldMathResult = D3DMAT_TO_MAT(mat);
- }
+ Math::Matrix oldMathResult;
+ {
+ D3DMATRIX mat;
+ D3DUtil_SetRotateYMatrix(mat, angle);
+ oldMathResult = D3DMAT_TO_MAT(mat);
+ }
- if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestLoadRotationZMatrix()
{
- const float angle = 0.380448034347452;
+ const float angle = 0.380448034347452;
- Math::Matrix mathResult;
- Math::LoadRotationZMatrix(mathResult, angle);
+ Math::Matrix mathResult;
+ Math::LoadRotationZMatrix(mathResult, angle);
- Math::Matrix oldMathResult;
- {
- D3DMATRIX mat;
- D3DUtil_SetRotateZMatrix(mat, angle);
- oldMathResult = D3DMAT_TO_MAT(mat);
- }
+ Math::Matrix oldMathResult;
+ {
+ D3DMATRIX mat;
+ D3DUtil_SetRotateZMatrix(mat, angle);
+ oldMathResult = D3DMAT_TO_MAT(mat);
+ }
- if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestLoadRotationMatrix()
{
- const float angle = -0.987747190637790;
- const Math::Vector dir(-0.113024727688331, -0.781265998072571, 1.838972397076884);
+ const float angle = -0.987747190637790;
+ const Math::Vector dir(-0.113024727688331, -0.781265998072571, 1.838972397076884);
- Math::Matrix mathResult;
- Math::LoadRotationMatrix(mathResult, dir, angle);
+ Math::Matrix mathResult;
+ Math::LoadRotationMatrix(mathResult, dir, angle);
- Math::Matrix oldMathResult;
- {
- D3DMATRIX mat;
- D3DVECTOR dirD3D = VEC_TO_D3DVEC(dir);
- D3DUtil_SetRotationMatrix(mat, dirD3D, angle);
- oldMathResult = D3DMAT_TO_MAT(mat);
- }
+ Math::Matrix oldMathResult;
+ {
+ D3DMATRIX mat;
+ D3DVECTOR dirD3D = VEC_TO_D3DVEC(dir);
+ D3DUtil_SetRotationMatrix(mat, dirD3D, angle);
+ oldMathResult = D3DMAT_TO_MAT(mat);
+ }
- if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestLoadRotationXZYMatrix()
{
- const Math::Vector angles(-0.841366567984597, -0.100543315396357, 1.610647811559988);
+ const Math::Vector angles(-0.841366567984597, -0.100543315396357, 1.610647811559988);
- Math::Matrix mathResult;
- Math::LoadRotationXZYMatrix(mathResult, angles);
+ Math::Matrix mathResult;
+ Math::LoadRotationXZYMatrix(mathResult, angles);
- Math::Matrix oldMathResult;
- {
- D3DMATRIX mat;
- MatRotateXZY(mat, VEC_TO_D3DVEC(angles));
- oldMathResult = D3DMAT_TO_MAT(mat);
- }
+ Math::Matrix oldMathResult;
+ {
+ D3DMATRIX mat;
+ MatRotateXZY(mat, VEC_TO_D3DVEC(angles));
+ oldMathResult = D3DMAT_TO_MAT(mat);
+ }
- if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestLoadRotationZXYMatrix()
{
- const Math::Vector angles(0.275558495480206, -0.224328265970090, 0.943077216574253);
+ const Math::Vector angles(0.275558495480206, -0.224328265970090, 0.943077216574253);
- Math::Matrix mathResult;
- Math::LoadRotationZXYMatrix(mathResult, angles);
+ Math::Matrix mathResult;
+ Math::LoadRotationZXYMatrix(mathResult, angles);
- Math::Matrix oldMathResult;
- {
- D3DMATRIX mat;
- MatRotateZXY(mat, VEC_TO_D3DVEC(angles));
- oldMathResult = D3DMAT_TO_MAT(mat);
- }
+ Math::Matrix oldMathResult;
+ {
+ D3DMATRIX mat;
+ MatRotateZXY(mat, VEC_TO_D3DVEC(angles));
+ oldMathResult = D3DMAT_TO_MAT(mat);
+ }
- if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
+ if (! Math::MatricesEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
- return 0;
+ return 0;
}
int TestTransform()
{
- Math::Matrix transformMatrix(
- (float[4][4])
- {
- { -0.9282074720977896, 0.6794734970319730, -1.3234304946882685, 0.0925294727863890 },
- { -0.0395527963683484, 0.2897634352353881, 1.9144398570315440, -1.4062267508968478 },
- { 0.9133323625282361, -0.6741836434774530, -0.2188812951424338, -1.0089184339952666 },
- { 0.0f, 0.0f, 0.0f, 1.0f }
- }
- );
- Math::Vector vector(-0.314596433318370, -0.622681232583150, -0.371307535743574);
-
- Math::Vector mathResult = Math::Transform(transformMatrix, vector);
- Math::Vector oldMathResult = Transform(transformMatrix, vector);
-
- if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
- return __LINE__;
-
- return 0;
+ Math::Matrix transformMatrix(
+ (float[4][4])
+ {
+ { -0.9282074720977896, 0.6794734970319730, -1.3234304946882685, 0.0925294727863890 },
+ { -0.0395527963683484, 0.2897634352353881, 1.9144398570315440, -1.4062267508968478 },
+ { 0.9133323625282361, -0.6741836434774530, -0.2188812951424338, -1.0089184339952666 },
+ { 0.0f, 0.0f, 0.0f, 1.0f }
+ }
+ );
+ Math::Vector vector(-0.314596433318370, -0.622681232583150, -0.371307535743574);
+
+ Math::Vector mathResult = Math::Transform(transformMatrix, vector);
+ Math::Vector oldMathResult = Transform(transformMatrix, vector);
+
+ if (! Math::VectorsEqual(mathResult, oldMathResult, TEST_TOLERANCE))
+ return __LINE__;
+
+ return 0;
}
int main()
{
- // Functions to test
- int (*TESTS[])() =
- {
- TestRotateAngle,
- TestAngle,
- TestRotateView,
- TestLookatPoint,
- TestProjection,
- TestLoadViewMatrix,
- TestLoadProjectionMatrix,
- TestLoadTranslationMatrix,
- TestLoadScaleMatrix,
- TestLoadRotationXMatrix,
- TestLoadRotationYMatrix,
- TestLoadRotationZMatrix,
- TestLoadRotationMatrix,
- TestLoadRotationXZYMatrix,
- TestLoadRotationZXYMatrix,
- TestTransform
- };
- const int TESTS_SIZE = sizeof(TESTS) / sizeof(*TESTS);
-
- int result = 0;
- for (int i = 0; i < TESTS_SIZE; ++i)
- {
- result = TESTS[i]();
- if (result != 0)
+ // Functions to test
+ int (*TESTS[])() =
+ {
+ TestRotateAngle,
+ TestAngle,
+ TestRotateView,
+ TestLookatPoint,
+ TestProjection,
+ TestLoadViewMatrix,
+ TestLoadProjectionMatrix,
+ TestLoadTranslationMatrix,
+ TestLoadScaleMatrix,
+ TestLoadRotationXMatrix,
+ TestLoadRotationYMatrix,
+ TestLoadRotationZMatrix,
+ TestLoadRotationMatrix,
+ TestLoadRotationXZYMatrix,
+ TestLoadRotationZXYMatrix,
+ TestTransform
+ };
+ const int TESTS_SIZE = sizeof(TESTS) / sizeof(*TESTS);
+
+ int result = 0;
+ for (int i = 0; i < TESTS_SIZE; ++i)
{
- fprintf(stderr, "Test function %d failed at line %d\n", i+1, result);
- return result;
+ result = TESTS[i]();
+ if (result != 0)
+ {
+ fprintf(stderr, "Test function %d failed at line %d\n", i+1, result);
+ return result;
+ }
}
- }
- fprintf(stderr, "All tests successful\n");
+ fprintf(stderr, "All tests successful\n");
- return 0;
+ return 0;
}
diff --git a/src/math/test/matrix_test.cpp b/src/math/test/matrix_test.cpp
index 95f1ed7..663234c 100644
--- a/src/math/test/matrix_test.cpp
+++ b/src/math/test/matrix_test.cpp
@@ -16,11 +16,11 @@
// math/test/matrix_test.cpp
-/* Unit tests for Matrix struct
-
- Test data was randomly generated and the expected results
- calculated using GNU Octave.
+/*
+ Unit tests for Matrix struct
+ Test data was randomly generated and the expected results
+ calculated using GNU Octave.
*/
#include "../func.h"
@@ -34,369 +34,369 @@ const float TEST_TOLERANCE = 1e-6;
int TestTranspose()
{
- const Math::Matrix mat(
- (float[4][4])
- {
- { -0.07011674491203920, 1.26145596067429810, 2.09476603598066902, 0.35560176915570696 },
- { -1.34075615966224704, 1.17988499016709314, 0.00601713429241016, -0.75213676977972566 },
- { 0.59186722295223981, 0.88089224074765293, 0.70994467464257294, 0.36730385425340212 },
- { -0.95649396555068111, 0.75912182022565566, 1.34883305778387186, -1.34957997578168754 }
- }
- );
-
- const Math::Matrix expectedTranspose(
- (float[4][4])
+ const Math::Matrix mat(
+ (float[4][4])
+ {
+ { -0.07011674491203920, 1.26145596067429810, 2.09476603598066902, 0.35560176915570696 },
+ { -1.34075615966224704, 1.17988499016709314, 0.00601713429241016, -0.75213676977972566 },
+ { 0.59186722295223981, 0.88089224074765293, 0.70994467464257294, 0.36730385425340212 },
+ { -0.95649396555068111, 0.75912182022565566, 1.34883305778387186, -1.34957997578168754 }
+ }
+ );
+
+ const Math::Matrix expectedTranspose(
+ (float[4][4])
+ {
+ { -0.07011674491203920, -1.34075615966224704, 0.59186722295223981, -0.95649396555068111 },
+ { 1.26145596067429810, 1.17988499016709314, 0.88089224074765293, 0.75912182022565566 },
+ { 2.09476603598066902, 0.00601713429241016, 0.70994467464257294, 1.34883305778387186 },
+ { 0.35560176915570696, -0.75213676977972566, 0.36730385425340212, -1.34957997578168754 }
+ }
+ );
+
+ Math::Matrix transpose = Math::Transpose(mat);
+
+ if (! Math::MatricesEqual(transpose, expectedTranspose, TEST_TOLERANCE))
{
- { -0.07011674491203920, -1.34075615966224704, 0.59186722295223981, -0.95649396555068111 },
- { 1.26145596067429810, 1.17988499016709314, 0.88089224074765293, 0.75912182022565566 },
- { 2.09476603598066902, 0.00601713429241016, 0.70994467464257294, 1.34883305778387186 },
- { 0.35560176915570696, -0.75213676977972566, 0.36730385425340212, -1.34957997578168754 }
+ fprintf(stderr, "Transpose mismatch!\n");
+ return __LINE__;
}
- );
-
- Math::Matrix transpose = Math::Transpose(mat);
- if (! Math::MatricesEqual(transpose, expectedTranspose, TEST_TOLERANCE))
- {
- fprintf(stderr, "Transpose mismatch!\n");
- return __LINE__;
- }
-
- return 0;
+ return 0;
}
int TestCofactor()
{
- const Math::Matrix mat1(
- (float[4][4])
- {
- { 0.610630320796245, 1.059932357918312, -1.581674311378210, 1.782214448453331 },
- { 0.191028848211526, -0.813898708757524, 1.516114203870644, 0.395202639476002 },
- { 0.335142750345279, -0.346586619596529, 0.545382042472336, -0.879268918923072 },
- { 1.417588151657198, 1.450841789070141, 0.219080104196171, 0.378724047481655 }
- }
- );
-
- const Math::Matrix expectedCofactors1(
- (float[4][4])
- {
- { -2.402679369186782, 2.282452509293019, 1.722732204057644, -0.746939701104385 },
- { -0.687677756877654, 1.168949180331164, -0.985354966837796, -1.334071111592705 },
- { -5.115621958424845, 4.229724770159009, 2.529000630782808, 1.481632618355891 },
- { 0.147480897398694, -2.140677680337111, -1.207189492265546, 0.151236920408051 }
- }
- );
-
- for (int r = 0; r < 4; ++r)
- {
- for (int c = 0; c < 4; ++c)
- {
- float ret = mat1.Cofactor(r, c);
- float exp = expectedCofactors1.m[4*c+r];
- if (! Math::IsEqual(ret, exp, TEST_TOLERANCE))
- {
- fprintf(stderr, "Cofactors 1 mismatch!\n");
- fprintf(stderr, "r=%d, c=%d, %f (returned) != %f (expected)\n", r, c, ret, exp);
- return __LINE__;
- }
- }
- }
-
- const Math::Matrix mat2(
- (float[4][4])
- {
- { 0.9845099464982393, -0.9091233416532389, -0.6272243714245945, 0.4645001858944354 },
- { -0.1333308471483736, 0.9128181433725897, -1.0937461393836190, 0.3180936795928376 },
- { -0.0654324396846289, 0.1014641705415945, 1.5107709042683430, -0.0240560430414690 },
- { 0.0179638644093347, -1.0695585982782767, -0.1741250853101032, 1.0803106709464336 }
- }
- );
-
- const Math::Matrix expectedCofactors2(
- (float[4][4])
+ const Math::Matrix mat1(
+ (float[4][4])
+ {
+ { 0.610630320796245, 1.059932357918312, -1.581674311378210, 1.782214448453331 },
+ { 0.191028848211526, -0.813898708757524, 1.516114203870644, 0.395202639476002 },
+ { 0.335142750345279, -0.346586619596529, 0.545382042472336, -0.879268918923072 },
+ { 1.417588151657198, 1.450841789070141, 0.219080104196171, 0.378724047481655 }
+ }
+ );
+
+ const Math::Matrix expectedCofactors1(
+ (float[4][4])
+ {
+ { -2.402679369186782, 2.282452509293019, 1.722732204057644, -0.746939701104385 },
+ { -0.687677756877654, 1.168949180331164, -0.985354966837796, -1.334071111592705 },
+ { -5.115621958424845, 4.229724770159009, 2.529000630782808, 1.481632618355891 },
+ { 0.147480897398694, -2.140677680337111, -1.207189492265546, 0.151236920408051 }
+ }
+ );
+
+ for (int r = 0; r < 4; ++r)
{
- { 2.0861102207614466, 0.2989010779528912, 0.0746276150537432, 0.2732659822656097 },
- { 0.6850002886584565, 1.5513169659641379, -0.0503743176545917, 1.5163672441575642 },
- { 1.2385556680997216, 1.1827709562505695, 1.2282813085138962, 1.3483789679871401 },
- { -1.0710790241539783, -0.5589604503588883, 0.0100959837872308, 1.1897872684455839 }
+ for (int c = 0; c < 4; ++c)
+ {
+ float ret = mat1.Cofactor(r, c);
+ float exp = expectedCofactors1.m[4*c+r];
+ if (! Math::IsEqual(ret, exp, TEST_TOLERANCE))
+ {
+ fprintf(stderr, "Cofactors 1 mismatch!\n");
+ fprintf(stderr, "r=%d, c=%d, %f (returned) != %f (expected)\n", r, c, ret, exp);
+ return __LINE__;
+ }
+ }
}
- );
-
- for (int r = 0; r < 4; ++r)
- {
- for (int c = 0; c < 4; ++c)
+ const Math::Matrix mat2(
+ (float[4][4])
+ {
+ { 0.9845099464982393, -0.9091233416532389, -0.6272243714245945, 0.4645001858944354 },
+ { -0.1333308471483736, 0.9128181433725897, -1.0937461393836190, 0.3180936795928376 },
+ { -0.0654324396846289, 0.1014641705415945, 1.5107709042683430, -0.0240560430414690 },
+ { 0.0179638644093347, -1.0695585982782767, -0.1741250853101032, 1.0803106709464336 }
+ }
+ );
+
+ const Math::Matrix expectedCofactors2(
+ (float[4][4])
+ {
+ { 2.0861102207614466, 0.2989010779528912, 0.0746276150537432, 0.2732659822656097 },
+ { 0.6850002886584565, 1.5513169659641379, -0.0503743176545917, 1.5163672441575642 },
+ { 1.2385556680997216, 1.1827709562505695, 1.2282813085138962, 1.3483789679871401 },
+ { -1.0710790241539783, -0.5589604503588883, 0.0100959837872308, 1.1897872684455839 }
+ }
+ );
+
+
+ for (int r = 0; r < 4; ++r)
{
- float ret = mat2.Cofactor(r, c);
- float exp = expectedCofactors2.m[4*c+r];
- if (! Math::IsEqual(ret, exp, TEST_TOLERANCE))
- {
- fprintf(stderr, "Cofactors 2 mismatch!\n");
- fprintf(stderr, "r=%d, c=%d, %f (returned) != %f (expected)\n", r, c, ret, exp);
- return __LINE__;
- }
+ for (int c = 0; c < 4; ++c)
+ {
+ float ret = mat2.Cofactor(r, c);
+ float exp = expectedCofactors2.m[4*c+r];
+ if (! Math::IsEqual(ret, exp, TEST_TOLERANCE))
+ {
+ fprintf(stderr, "Cofactors 2 mismatch!\n");
+ fprintf(stderr, "r=%d, c=%d, %f (returned) != %f (expected)\n", r, c, ret, exp);
+ return __LINE__;
+ }
+ }
}
- }
- return 0;
+ return 0;
}
int TestDet()
{
- const Math::Matrix mat1(
- (float[4][4])
+ const Math::Matrix mat1(
+ (float[4][4])
+ {
+ { -0.95880162984708284, 0.24004047608997131, -0.78172309932665407, -0.11604124457222834 },
+ { -0.36230592086261376, -0.75778166876017261, 0.33041059404631740, -1.06001391941094836 },
+ { 0.00260215210936187, 1.27485610196385113, -0.26149859846418033, -0.59669701186364876 },
+ { 0.36899429848485432, 3.01720896813933104, 2.10311476609438719, -1.68627076626448269 }
+ }
+ );
+
+ const float expectedDet1 = 4.07415413729671;
+
+ float ret1 = mat1.Det();
+ if (! Math::IsEqual(ret1, expectedDet1, TEST_TOLERANCE))
{
- { -0.95880162984708284, 0.24004047608997131, -0.78172309932665407, -0.11604124457222834 },
- { -0.36230592086261376, -0.75778166876017261, 0.33041059404631740, -1.06001391941094836 },
- { 0.00260215210936187, 1.27485610196385113, -0.26149859846418033, -0.59669701186364876 },
- { 0.36899429848485432, 3.01720896813933104, 2.10311476609438719, -1.68627076626448269 }
+ fprintf(stderr, "Det mismatch!\n");
+ fprintf(stderr, "%f (returned) != %f (expected)\n", ret1, expectedDet1);
+ return __LINE__;
}
- );
- const float expectedDet1 = 4.07415413729671;
+ const Math::Matrix mat2(
+ (float[4][4])
+ {
+ { -1.0860073221346871, 0.9150354098189495, -0.2723201933559999, 0.2922832160271507 },
+ { -1.0248331304801788, -2.5081237461125205, -1.0277123574586633, -0.2254690663329798 },
+ { -1.4227635282899367, -0.0403846809122684, 0.9216148477171653, 1.2517067488015878 },
+ { -0.1160254467152022, 0.8270675274393656, 1.0327218739781614, -0.3674886870220400 }
+ }
+ );
- float ret1 = mat1.Det();
- if (! Math::IsEqual(ret1, expectedDet1, TEST_TOLERANCE))
- {
- fprintf(stderr, "Det mismatch!\n");
- fprintf(stderr, "%f (returned) != %f (expected)\n", ret1, expectedDet1);
- return __LINE__;
- }
+ const float expectedDet2 = -6.35122307880942;
- const Math::Matrix mat2(
- (float[4][4])
+ float ret2 = mat2.Det();
+ if (! Math::IsEqual(ret2, expectedDet2, TEST_TOLERANCE))
{
- { -1.0860073221346871, 0.9150354098189495, -0.2723201933559999, 0.2922832160271507 },
- { -1.0248331304801788, -2.5081237461125205, -1.0277123574586633, -0.2254690663329798 },
- { -1.4227635282899367, -0.0403846809122684, 0.9216148477171653, 1.2517067488015878 },
- { -0.1160254467152022, 0.8270675274393656, 1.0327218739781614, -0.3674886870220400 }
+ fprintf(stderr, "Det mismatch!\n");
+ fprintf(stderr, "%f (returned) != %f (expected)\n", ret2, expectedDet2);
+ return __LINE__;
}
- );
- const float expectedDet2 = -6.35122307880942;
-
- float ret2 = mat2.Det();
- if (! Math::IsEqual(ret2, expectedDet2, TEST_TOLERANCE))
- {
- fprintf(stderr, "Det mismatch!\n");
- fprintf(stderr, "%f (returned) != %f (expected)\n", ret2, expectedDet2);
- return __LINE__;
- }
-
- return 0;
+ return 0;
}
int TestInverse()
{
- const Math::Matrix mat1(
- (float[4][4])
- {
- { -2.2829352811514658, -0.9103222363187888, 0.2792976509411680, -0.7984393573193174 },
- { 2.4823665798689589, -0.0599056759070980, 0.3832364352926366, -1.6404257204372739 },
- { -0.3841952272526398, -0.8377700696457873, -0.3416328338427138, 1.1746577275723329 },
- { 0.1746031241954947, -0.4952532117949962, 0.2155084379835037, -1.6586460437329220 }
- }
- );
-
- const Math::Matrix expectedInverse1(
- (float[4][4])
- {
- { -0.119472603171041, 0.331675963276297, 0.187516809009720, -0.137720814290806 },
- { -0.387591686166085, -0.487284946727583, -0.798527541290274, 0.102991635972060 },
- { 2.601905603425902, 2.606899016264679, -0.528006148839176, -4.204703326522837 },
- { 0.441220327151392, 0.519128136207318, 0.189567009205522, -1.194469716136194 }
- }
- );
-
- Math::Matrix inverse1 = mat1.Inverse();
-
- if (! Math::MatricesEqual(inverse1, expectedInverse1, TEST_TOLERANCE))
- {
- fprintf(stderr, "Inverse 1 mismatch!\n");
- return __LINE__;
- }
-
- const Math::Matrix mat2(
- (float[4][4])
+ const Math::Matrix mat1(
+ (float[4][4])
+ {
+ { -2.2829352811514658, -0.9103222363187888, 0.2792976509411680, -0.7984393573193174 },
+ { 2.4823665798689589, -0.0599056759070980, 0.3832364352926366, -1.6404257204372739 },
+ { -0.3841952272526398, -0.8377700696457873, -0.3416328338427138, 1.1746577275723329 },
+ { 0.1746031241954947, -0.4952532117949962, 0.2155084379835037, -1.6586460437329220 }
+ }
+ );
+
+ const Math::Matrix expectedInverse1(
+ (float[4][4])
+ {
+ { -0.119472603171041, 0.331675963276297, 0.187516809009720, -0.137720814290806 },
+ { -0.387591686166085, -0.487284946727583, -0.798527541290274, 0.102991635972060 },
+ { 2.601905603425902, 2.606899016264679, -0.528006148839176, -4.204703326522837 },
+ { 0.441220327151392, 0.519128136207318, 0.189567009205522, -1.194469716136194 }
+ }
+ );
+
+ Math::Matrix inverse1 = mat1.Inverse();
+
+ if (! Math::MatricesEqual(inverse1, expectedInverse1, TEST_TOLERANCE))
{
- { -0.05464332404298505, -0.64357755258235749, -0.13017671677619302, -0.56742332785888006 },
- { 0.29048383600458222, -0.91517047043724875, 0.84517524415561684, 0.51628195547960565 },
- { 0.00946488004480186, -0.89077382212689293, 0.73565573766341397, -0.15932513521840930 },
- { -1.01244718912499132, -0.27840911963972276, -0.39189681211309862, 1.18315064340192055 }
+ fprintf(stderr, "Inverse 1 mismatch!\n");
+ return __LINE__;
}
- );
- const Math::Matrix expectedInverse2(
- (float[4][4])
+ const Math::Matrix mat2(
+ (float[4][4])
+ {
+ { -0.05464332404298505, -0.64357755258235749, -0.13017671677619302, -0.56742332785888006 },
+ { 0.29048383600458222, -0.91517047043724875, 0.84517524415561684, 0.51628195547960565 },
+ { 0.00946488004480186, -0.89077382212689293, 0.73565573766341397, -0.15932513521840930 },
+ { -1.01244718912499132, -0.27840911963972276, -0.39189681211309862, 1.18315064340192055 }
+ }
+ );
+
+ const Math::Matrix expectedInverse2(
+ (float[4][4])
+ {
+ { 0.771302711132012, 1.587542278361995, -2.003075114445104, -0.592574156227379 },
+ { -1.208929259769431, -0.786598967848473, 0.607335305808052, -0.154759693303324 },
+ { -1.500037668208218, -0.774300278997914, 1.917800427261255, -0.123268572651291 },
+ { -0.121314770937944, 0.916925149209746, -0.935924950785014, 0.260875394250671 }
+ }
+ );
+
+ Math::Matrix inverse2 = mat2.Inverse();
+
+ if (! Math::MatricesEqual(inverse2, expectedInverse2, TEST_TOLERANCE))
{
- { 0.771302711132012, 1.587542278361995, -2.003075114445104, -0.592574156227379 },
- { -1.208929259769431, -0.786598967848473, 0.607335305808052, -0.154759693303324 },
- { -1.500037668208218, -0.774300278997914, 1.917800427261255, -0.123268572651291 },
- { -0.121314770937944, 0.916925149209746, -0.935924950785014, 0.260875394250671 }
+ fprintf(stderr, "Inverse 2 mismatch!\n");
+ return __LINE__;
}
- );
- Math::Matrix inverse2 = mat2.Inverse();
-
- if (! Math::MatricesEqual(inverse2, expectedInverse2, TEST_TOLERANCE))
- {
- fprintf(stderr, "Inverse 2 mismatch!\n");
- return __LINE__;
- }
-
- return 0;
+ return 0;
}
int TestMultiply()
{
- const Math::Matrix mat1A(
- (float[4][4])
- {
- { 0.6561727049162027, -1.4180263627131411, -0.8271026046117423, 2.3919331748512578 },
- { -0.6035665535146352, 0.0150827348790615, -0.7090794192822540, 0.9057604704594814 },
- { -0.9871045001223655, -0.4980646811455065, 0.3806177002298990, 0.1520583649240934 },
- { -0.2721911170792712, 0.7627928194552067, -0.1504091336784158, 0.9747545351840121 }
- }
- );
-
- const Math::Matrix mat1B(
- (float[4][4])
- {
- { -0.2643735892448818, -0.7542994492819621, 0.6082322350568750, 0.0581733424861419 },
- { 1.0293246070431237, 0.1979285388251341, -0.2932031385332818, 0.8838407179018929 },
- { 0.3448687251553114, 0.5031654871245456, 0.7554693012922442, -0.4845315903845708 },
- { -1.8662838497278593, -0.7843850624747805, 0.1389026096476257, -1.3686415408300689 }
- }
- );
-
- const Math::Matrix expectedMultiply1(
- (float[4][4])
- {
- { -6.382352236417988, -3.067984733682130, 0.522270304251466, -4.088079444498280 },
- { -1.759853366848825, -0.608994052024491, -0.781406179437379, -0.917870775786188 },
- { -0.404226802169062, 0.718232546720114, -0.145688356880835, -0.890167707987175 },
- { -1.013918490922430, -0.483971504099758, -0.367442194643757, -0.602858486133615 }
- }
- );
-
- Math::Matrix multiply1 = Math::MultiplyMatrices(mat1A, mat1B);
- if (! Math::MatricesEqual(multiply1, expectedMultiply1, TEST_TOLERANCE ) )
- {
- fprintf(stderr, "Multiply 1 mismath!\n");
- return __LINE__;
- }
-
- const Math::Matrix mat2A(
- (float[4][4])
+ const Math::Matrix mat1A(
+ (float[4][4])
+ {
+ { 0.6561727049162027, -1.4180263627131411, -0.8271026046117423, 2.3919331748512578 },
+ { -0.6035665535146352, 0.0150827348790615, -0.7090794192822540, 0.9057604704594814 },
+ { -0.9871045001223655, -0.4980646811455065, 0.3806177002298990, 0.1520583649240934 },
+ { -0.2721911170792712, 0.7627928194552067, -0.1504091336784158, 0.9747545351840121 }
+ }
+ );
+
+ const Math::Matrix mat1B(
+ (float[4][4])
+ {
+ { -0.2643735892448818, -0.7542994492819621, 0.6082322350568750, 0.0581733424861419 },
+ { 1.0293246070431237, 0.1979285388251341, -0.2932031385332818, 0.8838407179018929 },
+ { 0.3448687251553114, 0.5031654871245456, 0.7554693012922442, -0.4845315903845708 },
+ { -1.8662838497278593, -0.7843850624747805, 0.1389026096476257, -1.3686415408300689 }
+ }
+ );
+
+ const Math::Matrix expectedMultiply1(
+ (float[4][4])
+ {
+ { -6.382352236417988, -3.067984733682130, 0.522270304251466, -4.088079444498280 },
+ { -1.759853366848825, -0.608994052024491, -0.781406179437379, -0.917870775786188 },
+ { -0.404226802169062, 0.718232546720114, -0.145688356880835, -0.890167707987175 },
+ { -1.013918490922430, -0.483971504099758, -0.367442194643757, -0.602858486133615 }
+ }
+ );
+
+ Math::Matrix multiply1 = Math::MultiplyMatrices(mat1A, mat1B);
+ if (! Math::MatricesEqual(multiply1, expectedMultiply1, TEST_TOLERANCE ) )
{
- { 0.8697203025776754, 2.1259475710644935, 1.7856691009707812, -2.1563963348328126 },
- { 1.5888074489288735, -0.0794849733953615, 0.7307782768677457, 0.7943129159612630 },
- { 0.2859761537233830, -0.6231231890384962, -0.0496743172880377, -0.8137857518646087 },
- { 1.2670547229512983, -0.5305171374831831, -0.4987412674062375, -1.1257327113869595 }
- }
- );
-
- const Math::Matrix mat2B(
- (float[4][4])
- {
- { 1.1321105701165317, 0.1759563504574463, -2.0675778912000418, 1.4840339814245538 },
- { -1.5117280888829916, -0.0933013188828093, -0.2079262944351640, 0.9575727579539316 },
- { 0.3615378398970173, 1.2465163589027248, 1.1326150997082589, 0.9921208694352303 },
- { -0.7357104529373861, -0.4774022005969588, -0.2118739096676499, 1.1427567093270703 }
+ fprintf(stderr, "Multiply 1 mismath!\n");
+ return __LINE__;
}
- );
- const Math::Matrix expectedMultiply2(
- (float[4][4])
+ const Math::Matrix mat2A(
+ (float[4][4])
+ {
+ { 0.8697203025776754, 2.1259475710644935, 1.7856691009707812, -2.1563963348328126 },
+ { 1.5888074489288735, -0.0794849733953615, 0.7307782768677457, 0.7943129159612630 },
+ { 0.2859761537233830, -0.6231231890384962, -0.0496743172880377, -0.8137857518646087 },
+ { 1.2670547229512983, -0.5305171374831831, -0.4987412674062375, -1.1257327113869595 }
+ }
+ );
+
+ const Math::Matrix mat2B(
+ (float[4][4])
+ {
+ { 1.1321105701165317, 0.1759563504574463, -2.0675778912000418, 1.4840339814245538 },
+ { -1.5117280888829916, -0.0933013188828093, -0.2079262944351640, 0.9575727579539316 },
+ { 0.3615378398970173, 1.2465163589027248, 1.1326150997082589, 0.9921208694352303 },
+ { -0.7357104529373861, -0.4774022005969588, -0.2118739096676499, 1.1427567093270703 }
+ }
+ );
+
+ const Math::Matrix expectedMultiply2(
+ (float[4][4])
+ {
+ { 0.00283516267056338, 3.21001319965989307, 0.23910503934370686, 2.63380716363006107 },
+ { 1.59868505822469742, 0.81869715594617765, -2.60905981088293570, 3.91445839239110294 },
+ { 1.84650099286297942, 0.43504079532852930, -0.34555619012424243, -1.15152951542451487 },
+ { 2.88434318563174585, 0.18818239851585700, -2.83579436909308980, -0.40890672198610400 }
+ }
+ );
+
+ Math::Matrix multiply2 = Math::MultiplyMatrices(mat2A, mat2B);
+ if (! Math::MatricesEqual(multiply2, expectedMultiply2, TEST_TOLERANCE ) )
{
- { 0.00283516267056338, 3.21001319965989307, 0.23910503934370686, 2.63380716363006107 },
- { 1.59868505822469742, 0.81869715594617765, -2.60905981088293570, 3.91445839239110294 },
- { 1.84650099286297942, 0.43504079532852930, -0.34555619012424243, -1.15152951542451487 },
- { 2.88434318563174585, 0.18818239851585700, -2.83579436909308980, -0.40890672198610400 }
+ fprintf(stderr, "Multiply 2 mismath!\n");
+ return __LINE__;
}
- );
-
- Math::Matrix multiply2 = Math::MultiplyMatrices(mat2A, mat2B);
- if (! Math::MatricesEqual(multiply2, expectedMultiply2, TEST_TOLERANCE ) )
- {
- fprintf(stderr, "Multiply 2 mismath!\n");
- return __LINE__;
- }
- return 0;
+ return 0;
}
int TestMultiplyVector()
{
- const Math::Matrix mat1(
- (float[4][4])
+ const Math::Matrix mat1(
+ (float[4][4])
+ {
+ { 0.188562846910008, -0.015148651460679, 0.394512304108827, 0.906910631257135 },
+ { -0.297506779519667, 0.940119328178913, 0.970957796752517, 0.310559318965526 },
+ { -0.819770525290873, -2.316574438778879, 0.155756069319732, -0.855661405742964 },
+ { 0.000000000000000, 0.000000000000000, 0.000000000000000, 1.000000000000000 }
+ }
+ );
+
+ const Math::Vector vec1(-0.824708565156661, -1.598287748103842, -0.422498044734181);
+
+ const Math::Vector expectedMultiply1(0.608932463260470, -1.356893266403749, 3.457156276255142);
+
+ Math::Vector multiply1 = Math::MatrixVectorMultiply(mat1, vec1, false);
+ if (! Math::VectorsEqual(multiply1, expectedMultiply1, TEST_TOLERANCE ) )
{
- { 0.188562846910008, -0.015148651460679, 0.394512304108827, 0.906910631257135 },
- { -0.297506779519667, 0.940119328178913, 0.970957796752517, 0.310559318965526 },
- { -0.819770525290873, -2.316574438778879, 0.155756069319732, -0.855661405742964 },
- { 0.000000000000000, 0.000000000000000, 0.000000000000000, 1.000000000000000 }
+ fprintf(stderr, "Multiply vector 1 mismath!\n");
+ return __LINE__;
}
- );
- const Math::Vector vec1(-0.824708565156661, -1.598287748103842, -0.422498044734181);
+ const Math::Matrix mat2(
+ (float[4][4])
+ {
+ { -0.63287117038834284, 0.55148060401816856, -0.02042395559467368, -1.50367083897656850 },
+ { 0.69629042156335297, 0.12982747869796774, -1.16250029235919405, 1.19084447253756909 },
+ { 0.44164132914357224, -0.15169304045662041, -0.00880583574621390, -0.55817802940035310 },
+ { 0.95680476533530789, -1.51912346889253125, -0.74209769406615944, -0.20938988867903682 }
+ }
+ );
- const Math::Vector expectedMultiply1(0.608932463260470, -1.356893266403749, 3.457156276255142);
+ const Math::Vector vec2(0.330987381051962, 1.494375516393466, 1.483422335561857);
- Math::Vector multiply1 = Math::MatrixVectorMultiply(mat1, vec1, false);
- if (! Math::VectorsEqual(multiply1, expectedMultiply1, TEST_TOLERANCE ) )
- {
- fprintf(stderr, "Multiply vector 1 mismath!\n");
- return __LINE__;
- }
+ const Math::Vector expectedMultiply2(0.2816820577317669, 0.0334468811767428, 0.1996974284970455);
- const Math::Matrix mat2(
- (float[4][4])
+ Math::Vector multiply2 = Math::MatrixVectorMultiply(mat2, vec2, true);
+ if (! Math::VectorsEqual(multiply2, expectedMultiply2, TEST_TOLERANCE ) )
{
- { -0.63287117038834284, 0.55148060401816856, -0.02042395559467368, -1.50367083897656850 },
- { 0.69629042156335297, 0.12982747869796774, -1.16250029235919405, 1.19084447253756909 },
- { 0.44164132914357224, -0.15169304045662041, -0.00880583574621390, -0.55817802940035310 },
- { 0.95680476533530789, -1.51912346889253125, -0.74209769406615944, -0.20938988867903682 }
+ fprintf(stderr, "Multiply vector 2 mismath!\n");
+ return __LINE__;
}
- );
- const Math::Vector vec2(0.330987381051962, 1.494375516393466, 1.483422335561857);
-
- const Math::Vector expectedMultiply2(0.2816820577317669, 0.0334468811767428, 0.1996974284970455);
-
- Math::Vector multiply2 = Math::MatrixVectorMultiply(mat2, vec2, true);
- if (! Math::VectorsEqual(multiply2, expectedMultiply2, TEST_TOLERANCE ) )
- {
- fprintf(stderr, "Multiply vector 2 mismath!\n");
- return __LINE__;
- }
-
- return 0;
+ return 0;
}
int main()
{
- // Functions to test
- int (*TESTS[])() =
- {
- TestTranspose,
- TestCofactor,
- TestDet,
- TestInverse,
- TestMultiply,
- TestMultiplyVector
- };
- const int TESTS_SIZE = sizeof(TESTS) / sizeof(*TESTS);
-
- int result = 0;
- for (int i = 0; i < TESTS_SIZE; ++i)
- {
- result = TESTS[i]();
- if (result != 0)
- return result;
- }
-
- fprintf(stderr, "All tests successful\n");
-
- return 0;
+ // Functions to test
+ int (*TESTS[])() =
+ {
+ TestTranspose,
+ TestCofactor,
+ TestDet,
+ TestInverse,
+ TestMultiply,
+ TestMultiplyVector
+ };
+ const int TESTS_SIZE = sizeof(TESTS) / sizeof(*TESTS);
+
+ int result = 0;
+ for (int i = 0; i < TESTS_SIZE; ++i)
+ {
+ result = TESTS[i]();
+ if (result != 0)
+ return result;
+ }
+
+ fprintf(stderr, "All tests successful\n");
+
+ return 0;
}
diff --git a/src/math/test/vector_test.cpp b/src/math/test/vector_test.cpp
index d2bf231..899a580 100644
--- a/src/math/test/vector_test.cpp
+++ b/src/math/test/vector_test.cpp
@@ -16,11 +16,11 @@
// math/test/vector_test.cpp
-/* Unit tests for Vector struct
-
- Test data was randomly generated and the expected results
- calculated using GNU Octave.
+/*
+ Unit tests for Vector struct
+ Test data was randomly generated and the expected results
+ calculated using GNU Octave.
*/
#include "../func.h"
@@ -34,94 +34,94 @@ const float TEST_TOLERANCE = 1e-6;
int TestLength()
{
- Math::Vector vec(-1.288447945923275, 0.681452565308134, -0.633761098985957);
- const float expectedLength = 1.58938001708428;
+ Math::Vector vec(-1.288447945923275, 0.681452565308134, -0.633761098985957);
+ const float expectedLength = 1.58938001708428;
- if (! Math::IsEqual(vec.Length(), expectedLength, TEST_TOLERANCE) )
- {
- fprintf(stderr, "Length mismatch!\n");
- return __LINE__;
- }
+ if (! Math::IsEqual(vec.Length(), expectedLength, TEST_TOLERANCE) )
+ {
+ fprintf(stderr, "Length mismatch!\n");
+ return __LINE__;
+ }
- return 0;
+ return 0;
}
int TestNormalize()
{
- Math::Vector vec(1.848877241804398, -0.157262961268577, -1.963031403332377);
- const Math::Vector expectedNormalized(0.6844609421393856, -0.0582193085618106, -0.7267212194481797);
+ Math::Vector vec(1.848877241804398, -0.157262961268577, -1.963031403332377);
+ const Math::Vector expectedNormalized(0.6844609421393856, -0.0582193085618106, -0.7267212194481797);
- vec.Normalize();
+ vec.Normalize();
- if (! Math::VectorsEqual(vec, expectedNormalized, TEST_TOLERANCE))
- {
- fprintf(stderr, "Normalize mismatch!\n");
- return __LINE__;
- }
+ if (! Math::VectorsEqual(vec, expectedNormalized, TEST_TOLERANCE))
+ {
+ fprintf(stderr, "Normalize mismatch!\n");
+ return __LINE__;
+ }
- return 0;
+ return 0;
}
int TestDot()
{
- Math::Vector vecA(0.8202190530968309, 0.0130926060162780, 0.2411914183883510);
- Math::Vector vecB(-0.0524083951404069, 1.5564932716738220, -0.8971342631500536);
+ Math::Vector vecA(0.8202190530968309, 0.0130926060162780, 0.2411914183883510);
+ Math::Vector vecB(-0.0524083951404069, 1.5564932716738220, -0.8971342631500536);
- float expectedDot = -0.238988896477326;
+ float expectedDot = -0.238988896477326;
- if (! Math::IsEqual(Math::DotProduct(vecA, vecB), expectedDot, TEST_TOLERANCE) )
- {
- fprintf(stderr, "Dot product mismatch!\n");
- return __LINE__;
- }
+ if (! Math::IsEqual(Math::DotProduct(vecA, vecB), expectedDot, TEST_TOLERANCE) )
+ {
+ fprintf(stderr, "Dot product mismatch!\n");
+ return __LINE__;
+ }
- return 0;
+ return 0;
}
int TestCross()
{
- Math::Vector vecA(1.37380499798567, 1.18054518384682, 1.95166361293121);
- Math::Vector vecB(0.891657855926886, 0.447591335394532, -0.901604070087823);
+ Math::Vector vecA(1.37380499798567, 1.18054518384682, 1.95166361293121);
+ Math::Vector vecB(0.891657855926886, 0.447591335394532, -0.901604070087823);
- Math::Vector expectedCross(-1.937932065431669, 2.978844370287636, -0.437739173833581);
- Math::Vector expectedReverseCross = -expectedCross;
+ Math::Vector expectedCross(-1.937932065431669, 2.978844370287636, -0.437739173833581);
+ Math::Vector expectedReverseCross = -expectedCross;
- if (! Math::VectorsEqual(vecA.CrossMultiply(vecB), expectedCross, TEST_TOLERANCE) )
- {
- fprintf(stderr, "Cross product mismatch!\n");
- return __LINE__;
- }
+ if (! Math::VectorsEqual(vecA.CrossMultiply(vecB), expectedCross, TEST_TOLERANCE) )
+ {
+ fprintf(stderr, "Cross product mismatch!\n");
+ return __LINE__;
+ }
- if (! Math::VectorsEqual(vecB.CrossMultiply(vecA), expectedReverseCross, TEST_TOLERANCE) )
- {
- fprintf(stderr, "Reverse cross product mismatch!\n");
- return __LINE__;
- }
+ if (! Math::VectorsEqual(vecB.CrossMultiply(vecA), expectedReverseCross, TEST_TOLERANCE) )
+ {
+ fprintf(stderr, "Reverse cross product mismatch!\n");
+ return __LINE__;
+ }
- return 0;
+ return 0;
}
int main()
{
- // Functions to test
- int (*TESTS[])() =
- {
- TestLength,
- TestNormalize,
- TestDot,
- TestCross
- };
- const int TESTS_SIZE = sizeof(TESTS) / sizeof(*TESTS);
-
- int result = 0;
- for (int i = 0; i < TESTS_SIZE; ++i)
- {
- result = TESTS[i]();
- if (result != 0)
- return result;
- }
-
- fprintf(stderr, "All tests successful\n");
-
- return 0;
+ // Functions to test
+ int (*TESTS[])() =
+ {
+ TestLength,
+ TestNormalize,
+ TestDot,
+ TestCross
+ };
+ const int TESTS_SIZE = sizeof(TESTS) / sizeof(*TESTS);
+
+ int result = 0;
+ for (int i = 0; i < TESTS_SIZE; ++i)
+ {
+ result = TESTS[i]();
+ if (result != 0)
+ return result;
+ }
+
+ fprintf(stderr, "All tests successful\n");
+
+ return 0;
}
diff --git a/src/math/vector.h b/src/math/vector.h
index fd9aa52..3c756f2 100644
--- a/src/math/vector.h
+++ b/src/math/vector.h
@@ -35,209 +35,209 @@ namespace Math
/** \struct Vector math/vector.h
\brief 3D (3x1) vector
- Represents a universal 3x1 vector that can be used in OpenGL and DirectX engines.
- Contains the required methods for operating on vectors.
+ Represents a universal 3x1 vector that can be used in OpenGL and DirectX engines.
+ Contains the required methods for operating on vectors.
- All methods are made inline to maximize optimization.
+ All methods are made inline to maximize optimization.
- Unit tests for the structure and related functions are in module: math/test/vector_test.cpp.
+ Unit tests for the structure and related functions are in module: math/test/vector_test.cpp.
*/
struct Vector
{
- //! X - 1st coord
- float x;
- //! Y - 2nd coord
- float y;
- //! Z - 3rd coord
- float z;
-
- //! Creates a zero vector (0, 0, 0)
- inline Vector()
- {
- LoadZero();
- }
-
- //! Creates a vector from given values
- inline explicit Vector(float x, float y, float z)
- {
- this->x = x;
- this->y = y;
- this->z = z;
- }
-
- //! Loads the zero vector (0, 0, 0)
- inline void LoadZero()
- {
- x = y = z = 0.0f;
- }
-
- //! Returns the vector length
- inline float Length() const
- {
- return sqrtf(x*x + y*y + z*z);
- }
-
- //! Normalizes the vector
- inline void Normalize()
- {
- float l = Length();
- if (IsZero(l))
- return;
-
- x /= l;
- y /= l;
- z /= l;
- }
-
- //! Calculates the cross product with another vector
- /** \a right right-hand side vector
- \returns the cross product*/
- inline Vector CrossMultiply(const Vector &right) const
- {
- float px = y * right.z - z * right.y;
- float py = z * right.x - x * right.z;
- float pz = x * right.y - y * right.x;
- return Vector(px, py, pz);
- }
-
- //! Calculates the dot product with another vector
- /** \a right right-hand side vector
- \returns the dot product */
- inline float DotMultiply(const Vector &right) const
- {
- return x * right.x + y * right.y + z * right.z;
- }
-
- //! Returns the cosine of angle between this and another vector
- inline float CosAngle(const Vector &right) const
- {
- return DotMultiply(right) / (Length() * right.Length());
- }
-
- //! Returns angle (in radians) between this and another vector
- inline float Angle(const Vector &right) const
- {
- return acos(CosAngle(right));
- }
-
-
- /* Operators */
-
- //! Returns the inverted vector
- inline Vector operator-() const
- {
- return Vector(-x, -y, -z);
- }
-
- //! Adds the given vector
- inline const Vector& operator+=(const Vector &right)
- {
- x += right.x;
- y += right.y;
- z += right.z;
- return *this;
- }
-
- //! Adds two vectors
- inline friend const Vector operator+(const Vector &left, const Vector &right)
- {
- return Vector(left.x + right.x, left.y + right.y, left.z + right.z);
- }
-
- //! Subtracts the given vector
- inline const Vector& operator-=(const Vector &right)
- {
- x -= right.x;
- y -= right.y;
- z -= right.z;
- return *this;
- }
-
- //! Subtracts two vectors
- inline friend const Vector operator-(const Vector &left, const Vector &right)
- {
- return Vector(left.x - right.x, left.y - right.y, left.z - right.z);
- }
-
- //! Multiplies by given scalar
- inline const Vector& operator*=(const float &right)
- {
- x *= right;
- y *= right;
- z *= right;
- return *this;
- }
-
- //! Multiplies vector by scalar
- inline friend const Vector operator*(const float &left, const Vector &right)
- {
- return Vector(left * right.x, left * right.y, left * right.z);
- }
-
- //! Multiplies vector by scalar
- inline friend const Vector operator*(const Vector &left, const float &right)
- {
- return Vector(left.x * right, left.y * right, left.z * right);
- }
-
- //! Divides by given scalar
- inline const Vector& operator/=(const float &right)
- {
- x /= right;
- y /= right;
- z /= right;
- return *this;
- }
-
- //! Divides vector by scalar
- inline friend const Vector operator/(const Vector &left, const float &right)
- {
- return Vector(left.x / right, left.y / right, left.z / right);
- }
+ //! X - 1st coord
+ float x;
+ //! Y - 2nd coord
+ float y;
+ //! Z - 3rd coord
+ float z;
+
+ //! Creates a zero vector (0, 0, 0)
+ inline Vector()
+ {
+ LoadZero();
+ }
+
+ //! Creates a vector from given values
+ inline explicit Vector(float x, float y, float z)
+ {
+ this->x = x;
+ this->y = y;
+ this->z = z;
+ }
+
+ //! Loads the zero vector (0, 0, 0)
+ inline void LoadZero()
+ {
+ x = y = z = 0.0f;
+ }
+
+ //! Returns the vector length
+ inline float Length() const
+ {
+ return sqrtf(x*x + y*y + z*z);
+ }
+
+ //! Normalizes the vector
+ inline void Normalize()
+ {
+ float l = Length();
+ if (IsZero(l))
+ return;
+
+ x /= l;
+ y /= l;
+ z /= l;
+ }
+
+ //! Calculates the cross product with another vector
+ /** \a right right-hand side vector
+ \returns the cross product*/
+ inline Vector CrossMultiply(const Vector &right) const
+ {
+ float px = y * right.z - z * right.y;
+ float py = z * right.x - x * right.z;
+ float pz = x * right.y - y * right.x;
+ return Vector(px, py, pz);
+ }
+
+ //! Calculates the dot product with another vector
+ /** \a right right-hand side vector
+ \returns the dot product */
+ inline float DotMultiply(const Vector &right) const
+ {
+ return x * right.x + y * right.y + z * right.z;
+ }
+
+ //! Returns the cosine of angle between this and another vector
+ inline float CosAngle(const Vector &right) const
+ {
+ return DotMultiply(right) / (Length() * right.Length());
+ }
+
+ //! Returns angle (in radians) between this and another vector
+ inline float Angle(const Vector &right) const
+ {
+ return acos(CosAngle(right));
+ }
+
+
+ /* Operators */
+
+ //! Returns the inverted vector
+ inline Vector operator-() const
+ {
+ return Vector(-x, -y, -z);
+ }
+
+ //! Adds the given vector
+ inline const Vector& operator+=(const Vector &right)
+ {
+ x += right.x;
+ y += right.y;
+ z += right.z;
+ return *this;
+ }
+
+ //! Adds two vectors
+ inline friend const Vector operator+(const Vector &left, const Vector &right)
+ {
+ return Vector(left.x + right.x, left.y + right.y, left.z + right.z);
+ }
+
+ //! Subtracts the given vector
+ inline const Vector& operator-=(const Vector &right)
+ {
+ x -= right.x;
+ y -= right.y;
+ z -= right.z;
+ return *this;
+ }
+
+ //! Subtracts two vectors
+ inline friend const Vector operator-(const Vector &left, const Vector &right)
+ {
+ return Vector(left.x - right.x, left.y - right.y, left.z - right.z);
+ }
+
+ //! Multiplies by given scalar
+ inline const Vector& operator*=(const float &right)
+ {
+ x *= right;
+ y *= right;
+ z *= right;
+ return *this;
+ }
+
+ //! Multiplies vector by scalar
+ inline friend const Vector operator*(const float &left, const Vector &right)
+ {
+ return Vector(left * right.x, left * right.y, left * right.z);
+ }
+
+ //! Multiplies vector by scalar
+ inline friend const Vector operator*(const Vector &left, const float &right)
+ {
+ return Vector(left.x * right, left.y * right, left.z * right);
+ }
+
+ //! Divides by given scalar
+ inline const Vector& operator/=(const float &right)
+ {
+ x /= right;
+ y /= right;
+ z /= right;
+ return *this;
+ }
+
+ //! Divides vector by scalar
+ inline friend const Vector operator/(const Vector &left, const float &right)
+ {
+ return Vector(left.x / right, left.y / right, left.z / right);
+ }
}; // struct Point
//! Checks if two vectors are equal within given \a tolerance
inline bool VectorsEqual(const Vector &a, const Vector &b, float tolerance = TOLERANCE)
{
- return IsEqual(a.x, b.x, tolerance)
- && IsEqual(a.y, b.y, tolerance)
- && IsEqual(a.z, b.z, tolerance);
+ return IsEqual(a.x, b.x, tolerance)
+ && IsEqual(a.y, b.y, tolerance)
+ && IsEqual(a.z, b.z, tolerance);
}
//! Convenience function for getting normalized vector
inline Vector Normalize(const Vector &v)
{
- Vector result = v;
- result.Normalize();
- return result;
+ Vector result = v;
+ result.Normalize();
+ return result;
}
//! Convenience function for calculating dot product
inline float DotProduct(const Vector &left, const Vector &right)
{
- return left.DotMultiply(right);
+ return left.DotMultiply(right);
}
//! Convenience function for calculating cross product
inline Vector CrossProduct(const Vector &left, const Vector &right)
{
- return left.CrossMultiply(right);
+ return left.CrossMultiply(right);
}
//! Convenience function for calculating angle (in radians) between two vectors
inline float Angle(const Vector &a, const Vector &b)
{
- return a.Angle(b);
+ return a.Angle(b);
}
//! Returns the distance between the ends of two vectors
inline float Distance(const Vector &a, const Vector &b)
{
- return sqrtf( (a.x-b.x)*(a.x-b.x) +
- (a.y-b.y)*(a.y-b.y) +
- (a.z-b.z)*(a.z-b.z) );
+ return sqrtf( (a.x-b.x)*(a.x-b.x) +
+ (a.y-b.y)*(a.y-b.y) +
+ (a.z-b.z)*(a.z-b.z) );
}
/* @} */ // end of group