286 lines
7.9 KiB
C++
286 lines
7.9 KiB
C++
#include <math/dvc_matrix4.h>
|
|
#include <math/dvc_vector3.h>
|
|
#include <math/dvc_vector4.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#define GLM_FORCE_CTOR_INIT
|
|
#include <glm/glm.hpp>
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
#include <glm/gtc/quaternion.hpp>
|
|
|
|
#include "dvt_unit_common.h"
|
|
|
|
using namespace davinci;
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
TEST(Math_Matrix4, Basic)
|
|
{
|
|
{
|
|
float data[4][4] = { { FOUR_RANDOM_FLOAT },{ FOUR_RANDOM_FLOAT },{ FOUR_RANDOM_FLOAT }, { FOUR_RANDOM_FLOAT } };
|
|
|
|
fMatrix4 m1(data), m2(m1);
|
|
fMatrix4 m3(
|
|
data[0][0], data[0][1], data[0][2], data[0][3],
|
|
data[1][0], data[1][1], data[1][2], data[1][3],
|
|
data[2][0], data[2][1], data[2][2], data[2][3],
|
|
data[3][0], data[3][1], data[3][2], data[3][3]
|
|
);
|
|
|
|
EXPECT_EQ_4X4(m1, data);
|
|
EXPECT_EQ_4X4(m2, data);
|
|
EXPECT_EQ_4X4(m3, data);
|
|
}
|
|
|
|
{
|
|
fMatrix4 m1(SIXTEEN_RANDOM_FLOAT), m2;
|
|
|
|
m2 = m1;
|
|
EXPECT_EQ_4X4(m1, m2);
|
|
EXPECT_TRUE(m1 == m2);
|
|
|
|
m2[0][0] += 1.0;
|
|
EXPECT_TRUE(m1 != m2);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------
|
|
TEST(Math_Matrix4, Algorithm)
|
|
{
|
|
//+
|
|
{
|
|
float data1[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
float data2[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data1)), m2(SIXTEEN_ELEMENT_ROW(data2));
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data1)), gm2(SIXTEEN_ELEMENT_COL(data2));
|
|
|
|
fMatrix4 m3 = m1 + m2;
|
|
glm::mat4 gm3 = gm1 + gm2;
|
|
|
|
EXPECT_EQ_4X4_T(m3, gm3);
|
|
}
|
|
|
|
//-
|
|
{
|
|
float data1[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
float data2[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data1)), m2(SIXTEEN_ELEMENT_ROW(data2));
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data1)), gm2(SIXTEEN_ELEMENT_COL(data2));
|
|
|
|
fMatrix4 m3 = m1 - m2;
|
|
glm::mat4 gm3 = gm1 - gm2;
|
|
|
|
EXPECT_EQ_4X4_T(m3, gm3);
|
|
}
|
|
|
|
//*
|
|
{
|
|
float data1[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
float data2[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data1)), m2(SIXTEEN_ELEMENT_ROW(data2));
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data1)), gm2(SIXTEEN_ELEMENT_COL(data2));
|
|
|
|
fMatrix4 m3 = m1 * m2;
|
|
glm::mat4 gm3 = gm1 * gm2;
|
|
|
|
EXPECT_EQ_4X4_T(m3, gm3);
|
|
}
|
|
|
|
// -
|
|
{
|
|
float data1[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data1));
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data1));
|
|
|
|
fMatrix4 m2 = -m1;
|
|
glm::mat4 gm2 = -gm1;
|
|
|
|
EXPECT_EQ_4X4_T(m2, gm2);
|
|
}
|
|
|
|
// vector4 * matrix
|
|
{
|
|
float data1[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
float data2[4] = { FOUR_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data1));
|
|
fVector4 v1(data2);
|
|
fVector4 v2 = v1 * m1;
|
|
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data1));
|
|
glm::vec4 gv1(FOUR_ELEMENT(data2));
|
|
glm::vec4 gv2 = gv1 * gm1;
|
|
|
|
//fVector4 v2 = v1 * m1;
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.x, gv2.x, std::numeric_limits<float>::epsilon() * 100));
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.y, gv2.y, std::numeric_limits<float>::epsilon() * 100));
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.z, gv2.z, std::numeric_limits<float>::epsilon() * 100));
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.w, gv2.w, std::numeric_limits<float>::epsilon() * 100));
|
|
}
|
|
|
|
// matrix * vector4
|
|
{
|
|
float data1[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
float data2[4] = { FOUR_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data1));
|
|
fVector4 v1(data2);
|
|
fVector4 v2 = m1 * v1;
|
|
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data1));
|
|
glm::vec4 gv1(FOUR_ELEMENT(data2));
|
|
glm::vec4 gv2 = gm1 * gv1;
|
|
|
|
//fVector4 v2 = v1 * m1;
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.x, gv2.x, std::numeric_limits<float>::epsilon() * 100));
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.y, gv2.y, std::numeric_limits<float>::epsilon() * 100));
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.z, gv2.z, std::numeric_limits<float>::epsilon() * 100));
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.w, gv2.w, std::numeric_limits<float>::epsilon() * 100));
|
|
}
|
|
|
|
// matrix * vector3
|
|
{
|
|
float data1[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
float data2[3] = { THREE_RANDOM_FLOAT};
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data1));
|
|
fVector3 v1(data2);
|
|
fVector3 v2 = m1 * v1;
|
|
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data1));
|
|
glm::vec4 gv1(THREE_ELEMENT(data2), 1);
|
|
glm::vec4 gv2 = gm1 * gv1;
|
|
gv2 /= gv2.w;
|
|
|
|
//fVector4 v2 = v1 * m1;
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.x, gv2.x, std::numeric_limits<float>::epsilon() * 100));
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.y, gv2.y, std::numeric_limits<float>::epsilon() * 100));
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.z, gv2.z, std::numeric_limits<float>::epsilon() * 100));
|
|
}
|
|
|
|
// vector3 * matrix
|
|
{
|
|
float data1[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
float data2[3] = { THREE_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data1));
|
|
fVector3 v1(data2);
|
|
fVector3 v2 = v1 * m1;
|
|
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data1));
|
|
glm::vec4 gv1(THREE_ELEMENT(data2), 1);
|
|
glm::vec4 gv2 = gv1 * gm1;
|
|
gv2 /= gv2.w;
|
|
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.x, gv2.x, std::numeric_limits<float>::epsilon() * 100));
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.y, gv2.y, std::numeric_limits<float>::epsilon() * 100));
|
|
EXPECT_TRUE(_floatEqualWithRange(v2.z, gv2.z, std::numeric_limits<float>::epsilon() * 100));
|
|
}
|
|
|
|
// * float
|
|
{
|
|
float data[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
float a = _randomFloat();
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data));
|
|
fMatrix4 m2 = m1 * a, m3 = a * m1;
|
|
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data));
|
|
glm::mat4 gm2 = gm1 * a;
|
|
|
|
EXPECT_EQ_4X4_T(m2, gm2);
|
|
EXPECT_TRUE(m2 == m3);
|
|
}
|
|
|
|
// translation
|
|
{
|
|
float trans_data[] = { THREE_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1 = fMatrix4::makeTrans(THREE_ELEMENT(trans_data));
|
|
glm::mat4 gm1 = glm::translate(glm::mat4(1), glm::vec3(THREE_ELEMENT(trans_data)));
|
|
|
|
EXPECT_EQ_4X4_T(m1, gm1);
|
|
|
|
fVector3 p0(THREE_RANDOM_FLOAT);
|
|
fVector3 p1 = m1 * p0;
|
|
EXPECT_TRUE(p1 == p0 + fVector3(trans_data));
|
|
}
|
|
|
|
// scale
|
|
{
|
|
float scale_data[] = { THREE_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1 = fMatrix4::makeScale(THREE_ELEMENT(scale_data));
|
|
glm::mat4 gm1 = glm::scale(glm::mat4(1.0f), glm::vec3(THREE_ELEMENT(scale_data)));
|
|
|
|
EXPECT_EQ_4X4_T(m1, gm1);
|
|
}
|
|
|
|
// transpose
|
|
{
|
|
float data[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data));
|
|
fMatrix4 m2 = m1.transpose();
|
|
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data));
|
|
glm::mat4 gm2 = glm::transpose(gm1);
|
|
|
|
EXPECT_EQ_4X4_T(m2, gm2);
|
|
}
|
|
|
|
// rotation
|
|
{
|
|
float data[3] = { THREE_RANDOM_FLOAT };
|
|
|
|
fVector3 axis(data);
|
|
axis = axis.normalise();
|
|
|
|
float angle(_randomFloat());
|
|
float c = cos(angle*0.5);
|
|
float s = sin(angle*0.5);
|
|
|
|
fMatrix4 mx = fMatrix4::makeRotate_X(angle);
|
|
fMatrix4 my = fMatrix4::makeRotate_Y(angle);
|
|
fMatrix4 mz = fMatrix4::makeRotate_Z(angle);
|
|
fMatrix4 mv = fMatrix4::makeRotate(axis, angle);
|
|
fMatrix4 mq = fMatrix4::makeRotate(fVector4(s * axis.x, s * axis.y, s * axis.z, c));
|
|
|
|
EXPECT_EQ_4X4_APPROX(mv, mq, std::numeric_limits<float>::epsilon() * 1000);
|
|
|
|
glm::vec3 gmaxis(data[0], data[1], data[2]);
|
|
gmaxis = glm::normalize(gmaxis);
|
|
|
|
glm::mat4 gmx = glm::rotate(glm::mat4(), angle, glm::vec3(1, 0, 0));
|
|
glm::mat4 gmy = glm::rotate(glm::mat4(), angle, glm::vec3(0, 1, 0));
|
|
glm::mat4 gmz = glm::rotate(glm::mat4(), angle, glm::vec3(0, 0, 1));
|
|
glm::mat4 gmv = glm::rotate(glm::mat4(), angle, gmaxis);
|
|
|
|
glm::qua quaternion = glm::qua(c, s * gmaxis.x, s * gmaxis.y, s * gmaxis.z);
|
|
glm::mat4 gmq = glm::mat4_cast(quaternion);
|
|
|
|
EXPECT_EQ_4X4_T_APPROX(mx, gmx, std::numeric_limits<float>::epsilon() * 1000);
|
|
EXPECT_EQ_4X4_T_APPROX(my, gmy, std::numeric_limits<float>::epsilon() * 1000);
|
|
EXPECT_EQ_4X4_T_APPROX(mz, gmz, std::numeric_limits<float>::epsilon() * 1000);
|
|
EXPECT_EQ_4X4_T_APPROX(mv, gmv, std::numeric_limits<float>::epsilon() * 1000);
|
|
EXPECT_EQ_4X4_T_APPROX(mq, gmq, std::numeric_limits<float>::epsilon() * 1000);
|
|
}
|
|
|
|
// inverse
|
|
{
|
|
float data[16] = { SIXTEEN_RANDOM_FLOAT };
|
|
|
|
fMatrix4 m1(SIXTEEN_ELEMENT_ROW(data));
|
|
fMatrix4 m2 = m1.inverse();
|
|
|
|
glm::mat4 gm1(SIXTEEN_ELEMENT_COL(data));
|
|
glm::mat4 gm2 = glm::inverse(gm1);
|
|
|
|
EXPECT_EQ_4X4_T_APPROX(m2, gm2, std::numeric_limits<float>::epsilon()*10000);
|
|
}
|
|
}
|