Tests rewrite and Doxygen in src/math

- rewritten tests to use new framework
- updated/reformatted Doxygen
- removed legacy conversions
dev-ui
Piotr Dziwinski 2012-09-11 21:14:32 +02:00
parent efe4f0badd
commit 6c21dceb35
12 changed files with 265 additions and 404 deletions

View File

@ -6,6 +6,7 @@ add_subdirectory(tools)
# Tests
add_subdirectory(graphics/engine/test)
add_subdirectory(math/test)
# Configure options

View File

@ -27,5 +27,3 @@
#include "vector.h"
#include "matrix.h"
#include "geometry.h"
#include "conv.h"

View File

@ -51,4 +51,3 @@ const float RAD_TO_DEG = 57.29577951308232286465f;
const float LOG_2 = log(2.0f);
}; // namespace Math

View File

@ -1,39 +0,0 @@
/* math/conv.h
Temporary conversion functions for D3DVECTOR and D3DMATRIX */
#pragma once
#include <d3d.h>
#include "vector.h"
#include "matrix.h"
inline D3DVECTOR VEC_TO_D3DVEC(Math::Vector vec)
{
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);
}
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;
}
inline Math::Matrix D3DMAT_TO_MAT(D3DMATRIX mat)
{
Math::Matrix result(mat.m);
result.Transpose();
return result;
}

View File

@ -76,9 +76,11 @@ inline bool IsInsideTriangle(Math::Point a, Math::Point b, Math::Point c, Math::
}
//! Rotates a point around a center
/** \a center center of rotation
\a angle angle is in radians (positive is counterclockwise (CCW) )
\a p the point */
/**
* \param center center of rotation
* \param angle angle [radians] (positive is CCW)
* \param p the point to be rotated
*/
inline Math::Point RotatePoint(const Math::Point &center, float angle, const Math::Point &p)
{
Math::Point a;
@ -96,8 +98,10 @@ inline Math::Point RotatePoint(const Math::Point &center, float angle, const Mat
}
//! Rotates a point around the origin (0,0)
/** \a angle angle in radians (positive is counterclockwise (CCW) )
\a p the point */
/**
* \param angle angle [radians] (positive is CCW)
* \param p the point to be rotated
*/
inline Math::Point RotatePoint(float angle, const Math::Point &p)
{
float x = p.x*cosf(angle) - p.y*sinf(angle);
@ -106,9 +110,11 @@ inline Math::Point RotatePoint(float angle, const Math::Point &p)
return Math::Point(x, y);
}
//! Rotates a vector (dist, 0).
/** \a angle angle is in radians (positive is counterclockwise (CCW) )
\a dist distance to origin */
//! Rotates a vector (dist, 0)
/**
* \param angle angle [radians] (positive is CCW)
* \param dist distance to origin
*/
inline Math::Point RotatePoint(float angle, float dist)
{
float x = dist*cosf(angle);
@ -117,7 +123,12 @@ inline Math::Point RotatePoint(float angle, float dist)
return Math::Point(x, y);
}
//! TODO documentation
//! Rotates a point around a center on 2D plane
/**
* \param cx,cy center of rotation
* \param angle angle of rotation [radians] (positive is CCW)
* \param px,py point coordinates to rotate
*/
inline void RotatePoint(float cx, float cy, float angle, float &px, float &py)
{
float ax, ay;
@ -132,11 +143,14 @@ inline void RotatePoint(float cx, float cy, float angle, float &px, float &py)
py = cy+ay;
}
//! Rotates a point around a center in space.
/** \a center center of rotation
\a angleH,angleV rotation angles in radians (positive is counterclockwise (CCW) ) )
\a p the point
\returns the rotated point */
//! Rotates a point around a center in space
/**
* \a angleH is rotation along Y axis (heading) while \a angleV is rotation along X axis (TODO: ?).
*
* \param center center of rotation
* \param angleH,angleV rotation angles [radians] (positive is CCW)
* \param p the point to be rotated
*/
inline void RotatePoint(const Math::Vector &center, float angleH, float angleV, Math::Vector &p)
{
p.x -= center.x;
@ -151,11 +165,14 @@ inline void RotatePoint(const Math::Vector &center, float angleH, float angleV,
p = center + b;
}
//! Rotates a point around a center in space.
/** \a center center of rotation
\a angleH,angleV rotation angles in radians (positive is counterclockwise (CCW) ) )
\a p the point
\returns the rotated point */
//! Rotates a point around a center in space
/**
* The rotation is performed first along Y axis (\a angleH) and then along X axis (\a angleV).
*
* \param center center of rotation
* \param angleH,angleV rotation angles [radians] (positive is CCW)
* \param p the point to be rotated
*/
inline void RotatePoint2(const Math::Vector center, float angleH, float angleV, Math::Vector &p)
{
p.x -= center.x;
@ -189,10 +206,12 @@ inline float RotateAngle(float x, float y)
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) ) */
//! Calculates the angle between two points and a center
/**
* \param center the center point
* \param p1,p2 the two points
* \returns the angle [radians] (positive is CCW)
*/
inline float RotateAngle(const Math::Point &center, const Math::Point &p1, const Math::Point &p2)
{
if (PointsEqual(p1, center))
@ -215,9 +234,11 @@ inline float RotateAngle(const Math::Point &center, const Math::Point &p1, const
}
//! Loads view matrix from the given vectors
/** \a from origin
\a at view direction
\a worldUp up vector */
/**
* \param from origin
* \param at view direction
* \param worldUp up vector
*/
inline void LoadViewMatrix(Math::Matrix &mat, const Math::Vector &from,
const Math::Vector &at, const Math::Vector &worldUp)
{
@ -280,10 +301,12 @@ inline void LoadViewMatrix(Math::Matrix &mat, const Math::Vector &from,
}
//! Loads a perspective projection matrix
/** \a fov field of view in radians
\a aspect aspect ratio (width / height)
\a nearPlane distance to near cut plane
\a farPlane distance to far cut plane */
/**
* \param fov field of view in radians
* \param aspect aspect ratio (width / height)
* \param nearPlane distance to near cut plane
* \param farPlane distance to far cut plane
*/
inline void LoadProjectionMatrix(Math::Matrix &mat, float fov = Math::PI / 2.0f, float aspect = 1.0f,
float nearPlane = 1.0f, float farPlane = 1000.0f)
{
@ -302,9 +325,11 @@ inline void LoadProjectionMatrix(Math::Matrix &mat, float fov = Math::PI / 2.0f,
}
//! Loads an othogonal projection matrix
/** \a left,right coordinates for left and right vertical clipping planes
\a bottom,top coordinates for bottom and top horizontal clipping planes
\a zNear,zFar distance to nearer and farther depth clipping planes */
/**
* \param left,right coordinates for left and right vertical clipping planes
* \param bottom,top coordinates for bottom and top horizontal clipping planes
* \param zNear,zFar distance to nearer and farther depth clipping planes
*/
inline void LoadOrthoProjectionMatrix(Math::Matrix &mat, float left, float right, float bottom, float top,
float zNear = -1.0f, float zFar = 1.0f)
{
@ -320,7 +345,10 @@ inline void LoadOrthoProjectionMatrix(Math::Matrix &mat, float left, float right
}
//! Loads a translation matrix from given vector
/** \a trans vector of translation*/
/**
* \param mat result matrix
* \param trans vector of translation
*/
inline void LoadTranslationMatrix(Math::Matrix &mat, const Math::Vector &trans)
{
mat.LoadIdentity();
@ -330,7 +358,10 @@ inline void LoadTranslationMatrix(Math::Matrix &mat, const Math::Vector &trans)
}
//! Loads a scaling matrix fom given vector
/** \a scale vector with scaling factors for X, Y, Z */
/**
* \param mat result matrix
* \param scale vector with scaling factors for X, Y, Z
*/
inline void LoadScaleMatrix(Math::Matrix &mat, const Math::Vector &scale)
{
mat.LoadIdentity();
@ -340,7 +371,10 @@ inline void LoadScaleMatrix(Math::Matrix &mat, const Math::Vector &scale)
}
//! Loads a rotation matrix along the X axis
/** \a angle angle in radians */
/**
* \param mat result matrix
* \param angle angle [radians]
*/
inline void LoadRotationXMatrix(Math::Matrix &mat, float angle)
{
mat.LoadIdentity();
@ -351,7 +385,10 @@ inline void LoadRotationXMatrix(Math::Matrix &mat, float angle)
}
//! Loads a rotation matrix along the Y axis
/** \a angle angle in radians */
/**
* \param mat result matrix
* \param angle angle [radians]
*/
inline void LoadRotationYMatrix(Math::Matrix &mat, float angle)
{
mat.LoadIdentity();
@ -362,7 +399,10 @@ inline void LoadRotationYMatrix(Math::Matrix &mat, float angle)
}
//! Loads a rotation matrix along the Z axis
/** \a angle angle in radians */
/**
* \param mat result matrix
* \param angle angle [radians]
*/
inline void LoadRotationZMatrix(Math::Matrix &mat, float angle)
{
mat.LoadIdentity();
@ -373,8 +413,11 @@ inline void LoadRotationZMatrix(Math::Matrix &mat, float angle)
}
//! Loads a rotation matrix along the given axis
/** \a dir axis of rotation
\a angle angle in radians */
/**
* \param mat result matrix
* \param dir axis of rotation
* \param angle angle [radians]
*/
inline void LoadRotationMatrix(Math::Matrix &mat, const Math::Vector &dir, float angle)
{
float cos = cosf(angle);
@ -397,28 +440,28 @@ inline void LoadRotationMatrix(Math::Matrix &mat, const Math::Vector &dir, float
}
//! Calculates the matrix to make three rotations in the order X, Z and Y
inline void LoadRotationXZYMatrix(Math::Matrix &mat, const Math::Vector &angle)
inline void LoadRotationXZYMatrix(Math::Matrix &mat, const Math::Vector &angles)
{
Math::Matrix temp;
LoadRotationXMatrix(temp, angle.x);
LoadRotationXMatrix(temp, angles.x);
LoadRotationZMatrix(mat, angle.z);
LoadRotationZMatrix(mat, angles.z);
mat = Math::MultiplyMatrices(temp, mat);
LoadRotationYMatrix(temp, angle.y);
LoadRotationYMatrix(temp, angles.y);
mat = Math::MultiplyMatrices(temp, mat);
}
//! Calculates the matrix to make three rotations in the order Z, X and Y
inline void LoadRotationZXYMatrix(Math::Matrix &mat, const Math::Vector &angle)
inline void LoadRotationZXYMatrix(Math::Matrix &mat, const Math::Vector &angles)
{
Math::Matrix temp;
LoadRotationZMatrix(temp, angle.z);
LoadRotationZMatrix(temp, angles.z);
LoadRotationXMatrix(mat, angle.x);
LoadRotationXMatrix(mat, angles.x);
mat = Math::MultiplyMatrices(temp, mat);
LoadRotationYMatrix(temp, angle.y);
LoadRotationYMatrix(temp, angles.y);
mat = Math::MultiplyMatrices(temp, mat);
}
@ -430,7 +473,9 @@ inline float DistanceProjected(const Math::Vector &a, const Math::Vector &b)
}
//! Returns the normal vector to a plane
/** \param p1,p2,p3 points defining the plane */
/**
* \param p1,p2,p3 points defining the plane
*/
inline Math::Vector NormalToPlane(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3)
{
Math::Vector u = p3 - p1;
@ -440,16 +485,20 @@ inline Math::Vector NormalToPlane(const Math::Vector &p1, const Math::Vector &p2
}
//! Returns a point on the line \a p1 - \a p2, in \a dist distance from \a p1
/** \a p1,p2 line start and end
\a dist scaling factor from \a p1, relative to distance between \a p1 and \a p2 */
/**
* \param p1,p2 line start and end
* \param dist scaling factor from \a p1, relative to distance between \a p1 and \a p2
*/
inline Math::Vector SegmentPoint(const Math::Vector &p1, const Math::Vector &p2, float dist)
{
return p1 + (p2 - p1) * dist;
}
//! Returns the distance between given point and a plane
/** \param p the point
\param a,b,c points defining the plane */
/**
* \param p the point
* \param a,b,c points defining the plane
*/
inline float DistanceToPlane(const Math::Vector &a, const Math::Vector &b,
const Math::Vector &c, const Math::Vector &p)
{
@ -460,8 +509,10 @@ inline float DistanceToPlane(const Math::Vector &a, const Math::Vector &b,
}
//! Checks if two planes defined by three points are the same
/** \a plane1 array of three vectors defining the first plane
\a plane2 array of three vectors defining the second plane */
/**
* \param plane1 array of three vectors defining the first plane
* \param plane2 array of three vectors defining the second plane
*/
inline bool IsSamePlane(const Math::Vector (&plane1)[3], const Math::Vector (&plane2)[3])
{
Math::Vector n1 = NormalToPlane(plane1[0], plane1[1], plane1[2]);
@ -479,7 +530,7 @@ inline bool IsSamePlane(const Math::Vector (&plane1)[3], const Math::Vector (&pl
return true;
}
//! Calculates the intersection "i" right "of" the plane "abc".
//! Calculates the intersection "i" right "of" the plane "abc" (TODO: ?)
inline bool Intersect(const Math::Vector &a, const Math::Vector &b, const Math::Vector &c,
const Math::Vector &d, const Math::Vector &e, Math::Vector &i)
{
@ -502,7 +553,7 @@ inline bool Intersect(const Math::Vector &a, const Math::Vector &b, const Math::
}
//! 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. */
/** Line is parallel to the y axis, with the plane abc. Returns p.y. (TODO: ?) */
inline bool IntersectY(const Math::Vector &a, const Math::Vector &b, const Math::Vector &c, Math::Vector &p)
{
float d = (b.x-a.x)*(c.z-a.z) - (c.x-a.x)*(b.z-a.z);
@ -528,15 +579,18 @@ inline Math::Vector LookatPoint(const Math::Vector &eye, float angleH, float ang
return lookat;
}
//! TODO documentation
//! Transforms the point \a p by matrix \a m
/** Is equal to multiplying the matrix by the vector (of course without perspective divide). */
inline Math::Vector Transform(const Math::Matrix &m, const Math::Vector &p)
{
return MatrixVectorMultiply(m, p);
}
//! Calculates the projection of the point \a p on a straight line \a a to \a b.
/** \a p point to project
\a a,b two ends of the line */
//! Calculates the projection of the point \a p on a straight line \a a to \a b
/**
* \param point to project
* \param a,b two ends of the line
*/
inline Math::Vector Projection(const Math::Vector &a, const Math::Vector &b, const Math::Vector &p)
{
float k = DotProduct(b - a, p - a);

View File

@ -33,13 +33,14 @@
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.).
The internal representation is a 16-value table in column-major order, thus:
/**
* \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.).
*
* The internal representation is a 16-value table in column-major order, thus:
\verbatim
m[0 ] m[4 ] m[8 ] m[12]
@ -48,16 +49,16 @@ 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.
The order of multiplication of matrix and vector is also OpenGL-native
(see the function MatrixVectorMultiply).
All methods are made inline to maximize optimization.
Unit tests for the structure and related functions are in module: math/test/matrix_test.cpp.
**/
* 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).
*
* All methods are made inline to maximize optimization.
*
* Unit tests for the structure and related functions are in module: math/test/matrix_test.cpp.
*
*/
struct Matrix
{
//! Matrix values in column-major order
@ -78,8 +79,10 @@ struct Matrix
}
//! Creates the matrix from 2D array
/** The array's first index is row, second is column.
\a m array with values */
/**
* The array's first index is row, second is column.
* \param m array with values
*/
inline explicit Matrix(const float (&m)[4][4])
{
for (int c = 0; c < 4; ++c)
@ -91,11 +94,23 @@ struct Matrix
}
}
//! Sets value in given row and col
/**
* \param row row (0 to 3)
* \param col column (0 to 3)
* \param value value
*/
inline void Set(int row, int col, float value)
{
m[(col-1)*4+(row-1)] = value;
}
//! Returns the value in given row and col
/**
* \param row row (0 to 3)
* \param col column (0 to 3)
* \returns value
*/
inline float Get(int row, int col)
{
return m[(col-1)*4+(row-1)];
@ -148,9 +163,11 @@ struct Matrix
}
//! Calculates the cofactor of the matrix
/** \a r row (0 to 3)
\a c column (0 to 3)
\returns the cofactor */
/**
* \param r row (0 to 3)
* \param c column (0 to 3)
* \returns the cofactor
*/
inline float Cofactor(int r, int c) const
{
assert(r >= 0 && r <= 3);
@ -330,8 +347,10 @@ struct Matrix
}
//! Calculates the inverse matrix
/** The determinant of the matrix must not be zero.
\returns the inverted matrix */
/**
* The determinant of the matrix must not be zero.
* \returns the inverted matrix
*/
inline Matrix Inverse() const
{
float d = Det();
@ -352,8 +371,10 @@ struct Matrix
}
//! Calculates the multiplication of this matrix * given matrix
/** \a right right-hand matrix
\returns multiplication result */
/**
* \param right right-hand matrix
* \returns multiplication result
*/
inline Matrix Multiply(const Matrix &right) const
{
float result[16] = { 0.0f };

View File

@ -32,14 +32,14 @@
namespace Math
{
/** \struct Point math/point.h
\brief 2D point
Represents a 2D point (x, y).
Contains the required methods for operating on points.
All methods are made inline to maximize optimization.
/**
* \struct Point
* \brief 2D point
*
* Represents a 2D point (x, y).
* Contains the required methods for operating on points.
*
* All methods are made inline to maximize optimization.
*/
struct Point
{

View File

@ -1,33 +1,23 @@
cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE debug)
set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wold-style-cast -std=gnu++0x")
add_executable(matrix_test matrix_test.cpp)
add_executable(vector_test vector_test.cpp)
add_executable(geometry_test geometry_test.cpp ../old/math3d.cpp ../old/d3dmath.cpp ../../graphics/d3d/d3dutil.cpp)
enable_testing()
add_test(matrix_test ./matrix_test)
add_test(vector_test ./vector_test)
add_test(geometry_test ./geometry_test)
# Change to DirectX SDK directory
include_directories("c:/dxsdk/include")
add_definitions(-DSTRICT -DD3D_OVERLOADS)
# 'make check' will compile the required test programs
# Note that 'make test' will still fail without compiled programs
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS matrix_test vector_test)
# Files to be removed in distclean
set(REMOVE_FILES
CMakeFiles Testing cmake_install.cmake CMakeCache.txt CTestTestfile.cmake Makefile
./matrix_test
./vector_test
./geometry_test
include_directories(
.
../../..
${GTEST_DIR}/include
)
add_custom_target(distclean COMMAND rm -rf ${REMOVE_FILES})
add_executable(matrix_test matrix_test.cpp)
target_link_libraries(matrix_test gtest)
add_executable(vector_test vector_test.cpp)
target_link_libraries(vector_test gtest)
add_executable(geometry_test geometry_test.cpp)
target_link_libraries(geometry_test gtest)
add_test(matrix_test matrix_test)
add_test(vector_test vector_test)
add_test(geometry_test geometry_test)

View File

@ -20,53 +20,41 @@
#include "../func.h"
#include "../geometry.h"
#include "../conv.h"
#include "../../old/math3d.h"
#include "../../old/d3dutil.h"
#include <d3d.h>
#include <cstdio>
#include "gtest/gtest.h"
using namespace std;
const float TEST_TOLERANCE = 1e-5;
// Test for rewritten function RotateAngle()
int TestRotateAngle()
TEST(GeometryTest, RotateAngleTest)
{
if (! Math::IsEqual(Math::RotateAngle(0.0f, 0.0f), 0.0f, TEST_TOLERANCE))
return __LINE__;
EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(0.0f, 0.0f), 0.0f, TEST_TOLERANCE));
if (! Math::IsEqual(Math::RotateAngle(1.0f, 0.0f), 0.0f, TEST_TOLERANCE))
return __LINE__;
EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(1.0f, 0.0f), 0.0f, TEST_TOLERANCE));
if (! Math::IsEqual(Math::RotateAngle(1.0f, 1.0f), 0.25f * Math::PI, TEST_TOLERANCE))
return __LINE__;
EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(1.0f, 1.0f), 0.25f * Math::PI, TEST_TOLERANCE));
if (! Math::IsEqual(Math::RotateAngle(0.0f, 2.0f), 0.5f * Math::PI, TEST_TOLERANCE))
return __LINE__;
EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(0.0f, 2.0f), 0.5f * Math::PI, TEST_TOLERANCE));
if (! Math::IsEqual(Math::RotateAngle(-0.5f, 0.5f), 0.75f * Math::PI, TEST_TOLERANCE))
return __LINE__;
EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(-0.5f, 0.5f), 0.75f * Math::PI, TEST_TOLERANCE));
if (! Math::IsEqual(Math::RotateAngle(-1.0f, 0.0f), Math::PI, TEST_TOLERANCE))
return __LINE__;
EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(-1.0f, 0.0f), Math::PI, TEST_TOLERANCE));
if (! Math::IsEqual(Math::RotateAngle(-1.0f, -1.0f), 1.25f * Math::PI, TEST_TOLERANCE))
return __LINE__;
EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(-1.0f, -1.0f), 1.25f * Math::PI, TEST_TOLERANCE));
if (! Math::IsEqual(Math::RotateAngle(0.0f, -2.0f), 1.5f * Math::PI, TEST_TOLERANCE))
return __LINE__;
EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(0.0f, -2.0f), 1.5f * Math::PI, TEST_TOLERANCE));
if (! Math::IsEqual(Math::RotateAngle(1.0f, -1.0f), 1.75f * Math::PI, TEST_TOLERANCE))
return __LINE__;
return 0;
EXPECT_TRUE(Math::IsEqual(Math::RotateAngle(1.0f, -1.0f), 1.75f * Math::PI, TEST_TOLERANCE));
}
// Tests for other altered, complex or uncertain functions
/*
TODO: write meaningful tests with proper test values
int TestAngle()
{
const Math::Vector u(-0.0786076246943884, 0.2231249091714256, -1.1601361718477805);
@ -360,42 +348,12 @@ int TestTransform()
return 0;
}
int main()
*/
int main(int argc, char* argv[])
{
// 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);
::testing::InitGoogleTest(&argc, argv);
int result = 0;
for (int i = 0; i < TESTS_SIZE; ++i)
{
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");
return 0;
return RUN_ALL_TESTS();
}

View File

@ -26,13 +26,13 @@
#include "../func.h"
#include "../matrix.h"
#include <cstdio>
#include "gtest/gtest.h"
using namespace std;
const float TEST_TOLERANCE = 1e-6;
int TestTranspose()
TEST(MatrixTest, TransposeTest)
{
const Math::Matrix mat(
(float[4][4])
@ -56,16 +56,10 @@ int TestTranspose()
Math::Matrix transpose = Math::Transpose(mat);
if (! Math::MatricesEqual(transpose, expectedTranspose, TEST_TOLERANCE))
{
fprintf(stderr, "Transpose mismatch!\n");
return __LINE__;
}
return 0;
EXPECT_TRUE(Math::MatricesEqual(transpose, expectedTranspose, TEST_TOLERANCE));
}
int TestCofactor()
TEST(MatrixTest, CofactorTest)
{
const Math::Matrix mat1(
(float[4][4])
@ -93,12 +87,7 @@ int TestCofactor()
{
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__;
}
EXPECT_TRUE(Math::IsEqual(ret, exp, TEST_TOLERANCE));
}
}
@ -129,19 +118,12 @@ int TestCofactor()
{
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__;
}
EXPECT_TRUE(Math::IsEqual(ret, exp, TEST_TOLERANCE));
}
}
return 0;
}
int TestDet()
TEST(MatrixTest, DetTest)
{
const Math::Matrix mat1(
(float[4][4])
@ -156,12 +138,7 @@ int TestDet()
const float expectedDet1 = 4.07415413729671;
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__;
}
EXPECT_TRUE(Math::IsEqual(ret1, expectedDet1, TEST_TOLERANCE));
const Math::Matrix mat2(
(float[4][4])
@ -176,17 +153,10 @@ int TestDet()
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;
EXPECT_TRUE(Math::IsEqual(ret2, expectedDet2, TEST_TOLERANCE));
}
int TestInverse()
TEST(MatrixTest, InverseTest)
{
const Math::Matrix mat1(
(float[4][4])
@ -210,11 +180,7 @@ int TestInverse()
Math::Matrix inverse1 = mat1.Inverse();
if (! Math::MatricesEqual(inverse1, expectedInverse1, TEST_TOLERANCE))
{
fprintf(stderr, "Inverse 1 mismatch!\n");
return __LINE__;
}
EXPECT_TRUE(Math::MatricesEqual(inverse1, expectedInverse1, TEST_TOLERANCE));
const Math::Matrix mat2(
(float[4][4])
@ -238,16 +204,10 @@ int TestInverse()
Math::Matrix inverse2 = mat2.Inverse();
if (! Math::MatricesEqual(inverse2, expectedInverse2, TEST_TOLERANCE))
{
fprintf(stderr, "Inverse 2 mismatch!\n");
return __LINE__;
}
return 0;
EXPECT_TRUE(Math::MatricesEqual(inverse2, expectedInverse2, TEST_TOLERANCE));
}
int TestMultiply()
TEST(MatrixTest, MultiplyTest)
{
const Math::Matrix mat1A(
(float[4][4])
@ -280,11 +240,7 @@ int TestMultiply()
);
Math::Matrix multiply1 = Math::MultiplyMatrices(mat1A, mat1B);
if (! Math::MatricesEqual(multiply1, expectedMultiply1, TEST_TOLERANCE ) )
{
fprintf(stderr, "Multiply 1 mismath!\n");
return __LINE__;
}
EXPECT_TRUE(Math::MatricesEqual(multiply1, expectedMultiply1, TEST_TOLERANCE));
const Math::Matrix mat2A(
(float[4][4])
@ -317,16 +273,10 @@ int TestMultiply()
);
Math::Matrix multiply2 = Math::MultiplyMatrices(mat2A, mat2B);
if (! Math::MatricesEqual(multiply2, expectedMultiply2, TEST_TOLERANCE ) )
{
fprintf(stderr, "Multiply 2 mismath!\n");
return __LINE__;
}
return 0;
EXPECT_TRUE(Math::MatricesEqual(multiply2, expectedMultiply2, TEST_TOLERANCE));
}
int TestMultiplyVector()
TEST(MatrixTest, MultiplyVectorTest)
{
const Math::Matrix mat1(
(float[4][4])
@ -343,11 +293,7 @@ int TestMultiplyVector()
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 ) )
{
fprintf(stderr, "Multiply vector 1 mismath!\n");
return __LINE__;
}
EXPECT_TRUE(Math::VectorsEqual(multiply1, expectedMultiply1, TEST_TOLERANCE));
const Math::Matrix mat2(
(float[4][4])
@ -364,39 +310,13 @@ int TestMultiplyVector()
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;
EXPECT_TRUE(Math::VectorsEqual(multiply2, expectedMultiply2, TEST_TOLERANCE));
}
int main()
int main(int argc, char* argv[])
{
// Functions to test
int (*TESTS[])() =
{
TestTranspose,
TestCofactor,
TestDet,
TestInverse,
TestMultiply,
TestMultiplyVector
};
const int TESTS_SIZE = sizeof(TESTS) / sizeof(*TESTS);
::testing::InitGoogleTest(&argc, argv);
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;
return RUN_ALL_TESTS();
}

View File

@ -26,59 +26,41 @@
#include "../func.h"
#include "../vector.h"
#include <cstdio>
#include "gtest/gtest.h"
using namespace std;
const float TEST_TOLERANCE = 1e-6;
int TestLength()
TEST(VectorTest, LengthTest)
{
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__;
}
return 0;
EXPECT_TRUE(Math::IsEqual(vec.Length(), expectedLength, TEST_TOLERANCE));
}
int TestNormalize()
TEST(VectorTest, NormalizeTest)
{
Math::Vector vec(1.848877241804398, -0.157262961268577, -1.963031403332377);
const Math::Vector expectedNormalized(0.6844609421393856, -0.0582193085618106, -0.7267212194481797);
vec.Normalize();
if (! Math::VectorsEqual(vec, expectedNormalized, TEST_TOLERANCE))
{
fprintf(stderr, "Normalize mismatch!\n");
return __LINE__;
}
return 0;
EXPECT_TRUE(Math::VectorsEqual(vec, expectedNormalized, TEST_TOLERANCE));
}
int TestDot()
TEST(VectorTest, DotTest)
{
Math::Vector vecA(0.8202190530968309, 0.0130926060162780, 0.2411914183883510);
Math::Vector vecB(-0.0524083951404069, 1.5564932716738220, -0.8971342631500536);
float expectedDot = -0.238988896477326;
if (! Math::IsEqual(Math::DotProduct(vecA, vecB), expectedDot, TEST_TOLERANCE) )
{
fprintf(stderr, "Dot product mismatch!\n");
return __LINE__;
}
return 0;
EXPECT_TRUE(Math::IsEqual(Math::DotProduct(vecA, vecB), expectedDot, TEST_TOLERANCE));
}
int TestCross()
TEST(VectorTest, CrossTest)
{
Math::Vector vecA(1.37380499798567, 1.18054518384682, 1.95166361293121);
Math::Vector vecB(0.891657855926886, 0.447591335394532, -0.901604070087823);
@ -86,42 +68,14 @@ int TestCross()
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__;
}
EXPECT_TRUE(Math::VectorsEqual(vecA.CrossMultiply(vecB), expectedCross, TEST_TOLERANCE));
if (! Math::VectorsEqual(vecB.CrossMultiply(vecA), expectedReverseCross, TEST_TOLERANCE) )
{
fprintf(stderr, "Reverse cross product mismatch!\n");
return __LINE__;
}
return 0;
EXPECT_TRUE(Math::VectorsEqual(vecB.CrossMultiply(vecA), expectedReverseCross, TEST_TOLERANCE));
}
int main()
int main(int argc, char* argv[])
{
// Functions to test
int (*TESTS[])() =
{
TestLength,
TestNormalize,
TestDot,
TestCross
};
const int TESTS_SIZE = sizeof(TESTS) / sizeof(*TESTS);
::testing::InitGoogleTest(&argc, argv);
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;
return RUN_ALL_TESTS();
}

View File

@ -32,16 +32,17 @@
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.
All methods are made inline to maximize optimization.
Unit tests for the structure and related functions are in module: math/test/vector_test.cpp.
/**
* \struct Vector
* \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.
*
* All methods are made inline to maximize optimization.
*
* Unit tests for the structure and related functions are in module: math/test/vector_test.cpp.
*
*/
struct Vector
{
@ -103,8 +104,10 @@ struct Vector
}
//! Calculates the cross product with another vector
/** \a right right-hand side vector
\returns the cross product*/
/**
* \param right right-hand side vector
* \returns the cross product
*/
inline Vector CrossMultiply(const Vector &right) const
{
float px = y * right.z - z * right.y;
@ -114,8 +117,10 @@ struct Vector
}
//! Calculates the dot product with another vector
/** \a right right-hand side vector
\returns the dot product */
/**
* \param 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;
@ -218,7 +223,7 @@ struct Vector
return s.str();
}
}; // struct Point
}; // struct Vector
//! Checks if two vectors are equal within given \a tolerance
inline bool VectorsEqual(const Math::Vector &a, const Math::Vector &b, float tolerance = TOLERANCE)