init commit
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
enable_testing()
|
||||
|
||||
include_directories(
|
||||
${DV_AUTO_INCLUDE_PATH}
|
||||
${DV_CORE_INCLUDE_PATH}
|
||||
${DV_UTILS_INCLUDE_PATH}
|
||||
)
|
||||
|
||||
set(DVT_UNIT_SOURCE_FILES
|
||||
dvt_unit_main.cpp
|
||||
dvt_unit_vector2.cpp
|
||||
dvt_unit_vector3.cpp
|
||||
dvt_unit_vector4.cpp
|
||||
dvt_unit_matrix3.cpp
|
||||
dvt_unit_matrix4.cpp
|
||||
dvt_unit_math_util.cpp
|
||||
dvt_unit_rasterizer.cpp
|
||||
)
|
||||
|
||||
add_definitions(-DGLM_FORCE_PURE -DGLM_FORCE_LEFT_HANDED -DGLM_FORCE_DEPTH_ZERO_TO_ONE)
|
||||
|
||||
add_executable(dvt_unit
|
||||
dvt_unit_common.h
|
||||
${DVT_UNIT_SOURCE_FILES}
|
||||
)
|
||||
|
||||
set_property(TARGET dvt_unit PROPERTY FOLDER "test")
|
||||
|
||||
target_link_libraries(dvt_unit
|
||||
dv_core
|
||||
dv_utils
|
||||
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
glm::glm
|
||||
)
|
||||
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(dvt_unit)
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <math/dvc_math_util.h>
|
||||
|
||||
using namespace davinci;
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
inline float _randomFloat(void) {
|
||||
return MathUtil::rangeRandom(-65521 / 16.f, 65521 / 16.f);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
inline bool _floatEqualWithRange(float a, float b, float t = std::numeric_limits<float>::epsilon()) {
|
||||
if (MathUtil::floatEqual(a, b)) return true;
|
||||
|
||||
float d = std::abs(a - b) / std::min(std::abs(a), std::abs(b));
|
||||
return MathUtil::floatEqual(d, 0.f, t);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
#define TWO_RANDOM_FLOAT _randomFloat(), _randomFloat()
|
||||
#define THREE_RANDOM_FLOAT _randomFloat(), _randomFloat(), _randomFloat()
|
||||
#define FOUR_RANDOM_FLOAT _randomFloat(), _randomFloat(), _randomFloat(), _randomFloat()
|
||||
|
||||
#define NINE_RANDOM_FLOAT THREE_RANDOM_FLOAT, THREE_RANDOM_FLOAT, THREE_RANDOM_FLOAT
|
||||
#define SIXTEEN_RANDOM_FLOAT FOUR_RANDOM_FLOAT, FOUR_RANDOM_FLOAT, FOUR_RANDOM_FLOAT, FOUR_RANDOM_FLOAT
|
||||
|
||||
#define THREE_ELEMENT(data) data[0], data[1], data[2]
|
||||
#define FOUR_ELEMENT(data) data[0], data[1], data[2], data[3]
|
||||
#define NINE_ELEMENT_ROW(data) data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]
|
||||
#define NINE_ELEMENT_COL(data) data[0], data[3], data[6], data[1], data[4], data[7], data[2], data[5], data[8]
|
||||
#define SIXTEEN_ELEMENT_ROW(data) data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]
|
||||
#define SIXTEEN_ELEMENT_COL(data) data[0], data[4], data[8], data[12], data[1], data[5], data[9], data[13], data[2], data[6], data[10], data[14], data[3], data[7], data[11], data[15]
|
||||
|
||||
#define EXPECT_EQ_3X3(a, b) for(int32_t i=0; i<3; i++) for(int32_t j=0; j<3; j++) EXPECT_EQ(a[i][j], b[i][j]);
|
||||
#define EXPECT_EQ_3X3_T(a, b) for(int32_t i=0; i<3; i++) for(int32_t j=0; j<3; j++) EXPECT_EQ(a[i][j], b[j][i]);
|
||||
#define EXPECT_EQ_4X4(a, b) for(int32_t i=0; i<4; i++) for(int32_t j=0; j<4; j++) EXPECT_EQ(a[i][j], b[i][j]);
|
||||
#define EXPECT_EQ_4X4_T(a, b) for(int32_t i=0; i<4; i++) for(int32_t j=0; j<4; j++) EXPECT_EQ(a[i][j], b[j][i]);
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
#define SIXTEEN_RANDOM_FLOAT2 THREE_RANDOM_FLOAT, 0.f, THREE_RANDOM_FLOAT, 0.f, THREE_RANDOM_FLOAT, 0.f, THREE_RANDOM_FLOAT, 1.f
|
||||
|
||||
#define EXPECT_EQ_4X4_APPROX(a, b, t) for(int32_t ii=0; ii<4; ii++) for(int32_t jj=0; jj<4; jj++) \
|
||||
EXPECT_TRUE(_floatEqualWithRange(a[ii][jj], b[ii][jj], t));
|
||||
|
||||
#define EXPECT_EQ_4X4_T_APPROX(a, b, t) for(int32_t ii=0; ii<4; ii++) for(int32_t jj=0; jj<4; jj++) \
|
||||
EXPECT_TRUE(_floatEqualWithRange(a[ii][jj], b[jj][ii], t));
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
uint32_t seed = (uint32_t)::time(0);
|
||||
//seed = 1748961760;
|
||||
srand(seed);
|
||||
printf("seed=%d\n", seed);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
#include <math/dvc_math_util.h>
|
||||
#include <math/dvc_matrix4.h>
|
||||
#include <math/dvc_vector3.h>
|
||||
#include <math/dvc_vector4.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include "dvt_unit_common.h"
|
||||
|
||||
using namespace davinci;
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(MathUtil, Basic)
|
||||
{
|
||||
|
||||
//lookat view matrix
|
||||
{
|
||||
float dEye[3] = { 0.0f, 4.0f, -10.0f };
|
||||
float dAt[3] = { 0.0f, 1.0f, 0.0f };
|
||||
float dUp[3] = { 0.0f, 1.0f, 0.0f };
|
||||
|
||||
fMatrix4 m1 = MathUtil::lookatRH(
|
||||
fVector3(THREE_ELEMENT(dEye)),
|
||||
fVector3(THREE_ELEMENT(dAt)),
|
||||
fVector3(THREE_ELEMENT(dUp)));
|
||||
|
||||
glm::mat4 gm1 = glm::lookAtRH(glm::vec3(THREE_ELEMENT(dEye)), glm::vec3(THREE_ELEMENT(dAt)), glm::vec3(THREE_ELEMENT(dUp)));
|
||||
EXPECT_EQ_4X4_T(m1, gm1);
|
||||
}
|
||||
|
||||
//lookat view matrix(random)
|
||||
{
|
||||
for (int i = 0; i < 10; i++) {
|
||||
fVector3 dEye, dAt, dUp;
|
||||
do {
|
||||
dEye[0] = _randomFloat(); dEye[1] = _randomFloat(); dEye[2] = _randomFloat();
|
||||
dAt[0] = _randomFloat(); dAt[1] = _randomFloat(); dAt[2] = _randomFloat();
|
||||
dUp[0] = _randomFloat(); dUp[1] = _randomFloat(); dUp[2] = _randomFloat();
|
||||
|
||||
} while ((dEye == dAt) || (dUp == fVector3::ZERO));
|
||||
|
||||
fMatrix4 m1 = MathUtil::lookatRH(
|
||||
fVector3(THREE_ELEMENT(dEye)),
|
||||
fVector3(THREE_ELEMENT(dAt)),
|
||||
fVector3(THREE_ELEMENT(dUp)));
|
||||
|
||||
glm::mat4 gm1 = glm::lookAtRH(glm::vec3(THREE_ELEMENT(dEye)), glm::vec3(THREE_ELEMENT(dAt)), glm::vec3(THREE_ELEMENT(dUp)));
|
||||
|
||||
EXPECT_EQ_4X4_T_APPROX(m1, gm1, std::numeric_limits<float>::epsilon() * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
//perspective
|
||||
{
|
||||
float width = 640.f, height = 480.f;
|
||||
|
||||
fMatrix4 m1 = MathUtil::perspectiveFovRH(MathUtil::PI_DIV4, width / height, 0.01f, 100.f);
|
||||
glm::mat4 gm1 = glm::perspectiveRH(MathUtil::PI_DIV4, width / height, 0.01f, 100.f);
|
||||
|
||||
EXPECT_EQ_4X4_T_APPROX(m1, gm1, std::numeric_limits<float>::epsilon());
|
||||
}
|
||||
|
||||
//perspective(random)
|
||||
{
|
||||
for (int i = 0; i < 10; i++) {
|
||||
float fov = MathUtil::rangeRandom(0.1f, MathUtil::PI);
|
||||
float aspect = MathUtil::rangeRandom(0.1f, 100.f);
|
||||
float zNear = MathUtil::rangeRandom(0.00001f, 0.01f);
|
||||
float zFar = MathUtil::rangeRandom(100.f, 10000.f);
|
||||
|
||||
fMatrix4 m1 = MathUtil::perspectiveFovRH(fov, aspect, zNear, zFar);
|
||||
glm::mat4 gm1 = glm::perspectiveRH(fov, aspect, zNear, zFar);
|
||||
|
||||
EXPECT_EQ_4X4_T_APPROX(m1, gm1, std::numeric_limits<float>::epsilon() * 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
#include <math/dvc_matrix3.h>
|
||||
#include <math/dvc_vector3.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "dvt_unit_common.h"
|
||||
|
||||
using namespace davinci;
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(Math_Matrix3, Basic)
|
||||
{
|
||||
{
|
||||
float data[3][3] = { { THREE_RANDOM_FLOAT }, { THREE_RANDOM_FLOAT }, { THREE_RANDOM_FLOAT } };
|
||||
|
||||
fMatrix3 m1(data), m2(m1);
|
||||
fMatrix3 m3(
|
||||
data[0][0], data[0][1], data[0][2],
|
||||
data[1][0], data[1][1], data[1][2],
|
||||
data[2][0], data[2][1], data[2][2]
|
||||
);
|
||||
|
||||
EXPECT_EQ_3X3(m1, data);
|
||||
EXPECT_EQ_3X3(m2, data);
|
||||
EXPECT_EQ_3X3(m3, data);
|
||||
}
|
||||
|
||||
{
|
||||
fMatrix3 m1(NINE_RANDOM_FLOAT), m2;
|
||||
|
||||
m2 = m1;
|
||||
EXPECT_EQ_3X3(m1, m2);
|
||||
EXPECT_TRUE(m1 == m2);
|
||||
|
||||
m2[0][0] += 1.0;
|
||||
EXPECT_TRUE(m1 != m2);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(Math_Matrix3, Algorithm)
|
||||
{
|
||||
//+
|
||||
{
|
||||
float data1[9] = { NINE_RANDOM_FLOAT };
|
||||
float data2[9] = { NINE_RANDOM_FLOAT };
|
||||
|
||||
fMatrix3 m1(NINE_ELEMENT_ROW(data1)), m2(NINE_ELEMENT_ROW(data2));
|
||||
glm::mat3 gm1(NINE_ELEMENT_COL(data1)), gm2(NINE_ELEMENT_COL(data2));
|
||||
|
||||
fMatrix3 m3 = m1 + m2;
|
||||
glm::mat3 gm3 = gm1 + gm2;
|
||||
|
||||
EXPECT_EQ_3X3_T(m3, gm3);
|
||||
}
|
||||
|
||||
//-
|
||||
{
|
||||
float data1[9] = { NINE_RANDOM_FLOAT };
|
||||
float data2[9] = { NINE_RANDOM_FLOAT };
|
||||
|
||||
fMatrix3 m1(NINE_ELEMENT_ROW(data1)), m2(NINE_ELEMENT_ROW(data2));
|
||||
glm::mat3 gm1(NINE_ELEMENT_COL(data1)), gm2(NINE_ELEMENT_COL(data2));
|
||||
|
||||
fMatrix3 m3 = m1 - m2;
|
||||
glm::mat3 gm3 = gm1 - gm2;
|
||||
|
||||
EXPECT_EQ_3X3_T(m3, gm3);
|
||||
}
|
||||
|
||||
//*
|
||||
{
|
||||
float data1[9] = { NINE_RANDOM_FLOAT };
|
||||
float data2[9] = { NINE_RANDOM_FLOAT };
|
||||
|
||||
fMatrix3 m1(NINE_ELEMENT_ROW(data1)), m2(NINE_ELEMENT_ROW(data2));
|
||||
glm::mat3 gm1(NINE_ELEMENT_COL(data1)), gm2(NINE_ELEMENT_COL(data2));
|
||||
|
||||
fMatrix3 m3 = m1 * m2;
|
||||
glm::mat3 gm3 = gm1 * gm2;
|
||||
|
||||
EXPECT_EQ_3X3_T(m3, gm3);
|
||||
}
|
||||
|
||||
// -
|
||||
{
|
||||
float data1[9] = { NINE_RANDOM_FLOAT };
|
||||
|
||||
fMatrix3 m1(NINE_ELEMENT_ROW(data1));
|
||||
glm::mat3 gm1(NINE_ELEMENT_COL(data1));
|
||||
|
||||
fMatrix3 m2 = -m1;
|
||||
glm::mat3 gm2 = -gm1;
|
||||
|
||||
EXPECT_EQ_3X3_T(m2, gm2);
|
||||
}
|
||||
|
||||
|
||||
// vector * matrix
|
||||
{
|
||||
float data1[9] = { NINE_RANDOM_FLOAT };
|
||||
float data2[3] = { THREE_RANDOM_FLOAT };
|
||||
|
||||
fMatrix3 m1(NINE_ELEMENT_ROW(data1));
|
||||
fVector3 v1(data2);
|
||||
fVector3 v2 = v1 * m1;
|
||||
|
||||
glm::mat3 gm1(NINE_ELEMENT_COL(data1));
|
||||
glm::vec3 gv1(data2[0], data2[1], data2[2]);
|
||||
glm::vec3 gv2 = gv1*gm1;
|
||||
|
||||
EXPECT_EQ(v2.x, gv2.x);
|
||||
EXPECT_EQ(v2.y, gv2.y);
|
||||
EXPECT_EQ(v2.z, gv2.z);
|
||||
}
|
||||
|
||||
// matrix * vector
|
||||
{
|
||||
float data1[9] = { NINE_RANDOM_FLOAT };
|
||||
float data2[3] = { THREE_RANDOM_FLOAT };
|
||||
|
||||
fMatrix3 m1(NINE_ELEMENT_ROW(data1));
|
||||
fVector3 v1(data2);
|
||||
fVector3 v2 = m1 * v1;
|
||||
|
||||
glm::mat3 gm1(NINE_ELEMENT_COL(data1));
|
||||
glm::vec3 gv1(data2[0], data2[1], data2[2]);
|
||||
glm::vec3 gv2 = gm1 * gv1;
|
||||
|
||||
EXPECT_EQ(v2.x, gv2.x);
|
||||
EXPECT_EQ(v2.y, gv2.y);
|
||||
EXPECT_EQ(v2.z, gv2.z);
|
||||
}
|
||||
|
||||
// * float
|
||||
{
|
||||
float data1[9] = { NINE_RANDOM_FLOAT };
|
||||
float a = _randomFloat();
|
||||
|
||||
fMatrix3 m1(NINE_ELEMENT_ROW(data1));
|
||||
fMatrix3 m2 = m1 * a, m3 = a * m1;
|
||||
|
||||
glm::mat3 gm1(NINE_ELEMENT_COL(data1));
|
||||
glm::mat3 gm2 = gm1 * a;
|
||||
|
||||
|
||||
EXPECT_EQ_3X3_T(m2, gm2);
|
||||
EXPECT_TRUE(m2 == m3);
|
||||
}
|
||||
|
||||
// transpose
|
||||
{
|
||||
float data1[9] = { NINE_RANDOM_FLOAT };
|
||||
|
||||
fMatrix3 m1(NINE_ELEMENT_ROW(data1));
|
||||
fMatrix3 m2 = m1.transpose();
|
||||
|
||||
glm::mat3 gm1(NINE_ELEMENT_COL(data1));
|
||||
glm::mat3 gm2 = glm::transpose(gm1);
|
||||
|
||||
EXPECT_EQ_3X3_T(m2, gm2);
|
||||
}
|
||||
|
||||
// inverse
|
||||
{
|
||||
float data1[9] = { NINE_RANDOM_FLOAT };
|
||||
|
||||
fMatrix3 m1(NINE_ELEMENT_ROW(data1)), m2;
|
||||
bool inv = m1.inverse(m2);
|
||||
|
||||
glm::mat3 gm1(NINE_ELEMENT_COL(data1));
|
||||
glm::mat3 gm2 = glm::inverse(gm1);
|
||||
|
||||
if (inv)
|
||||
EXPECT_EQ_3X3_T(m2, gm2);
|
||||
|
||||
EXPECT_FALSE(fMatrix3::ZERO.inverse(m2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
#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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
#include <pipe/dvc_rasterizer.h>
|
||||
#include <buffer/dvu_dump_buffer.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
using namespace davinci;
|
||||
|
||||
class Edge
|
||||
{
|
||||
public:
|
||||
|
||||
Edge(const fVector2 &_p1, const fVector2 &_p2) : p1(_p1), p2(_p2) {};
|
||||
Edge(const Edge &e) : p1(e.p1), p2(e.p2) {};
|
||||
|
||||
fVector2 p1;
|
||||
fVector2 p2;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
inline bool operator == (const Edge & e1, const Edge & e2)
|
||||
{
|
||||
return (e1.p1 == e2.p1 && e1.p2 == e2.p2) ||
|
||||
(e1.p1 == e2.p2 && e1.p2 == e2.p1);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
class Triangle
|
||||
{
|
||||
public:
|
||||
|
||||
Triangle(const fVector2 &_p1, const fVector2 &_p2, const fVector2 &_p3)
|
||||
: p1(_p1), p2(_p2), p3(_p3)
|
||||
{}
|
||||
|
||||
bool containsVertex(const fVector2 &v)
|
||||
{
|
||||
return p1 == v || p2 == v || p3 == v;
|
||||
}
|
||||
|
||||
bool circumCircleContains(const fVector2 &v)
|
||||
{
|
||||
float ab = (p1.x * p1.x) + (p1.y * p1.y);
|
||||
float cd = (p2.x * p2.x) + (p2.y * p2.y);
|
||||
float ef = (p3.x * p3.x) + (p3.y * p3.y);
|
||||
|
||||
float circum_x = (ab * (p3.y - p2.y) + cd * (p1.y - p3.y) + ef * (p2.y - p1.y)) / (p1.x * (p3.y - p2.y) + p2.x * (p1.y - p3.y) + p3.x * (p2.y - p1.y)) / 2.f;
|
||||
float circum_y = (ab * (p3.x - p2.x) + cd * (p1.x - p3.x) + ef * (p2.x - p1.x)) / (p1.y * (p3.x - p2.x) + p2.y * (p1.x - p3.x) + p3.y * (p2.x - p1.x)) / 2.f;
|
||||
float circum_radius = sqrtf(((p1.x - circum_x) * (p1.x - circum_x)) + ((p1.y - circum_y) * (p1.y - circum_y)));
|
||||
|
||||
float dist = sqrtf(((v.x - circum_x) * (v.x - circum_x)) + ((v.y - circum_y) * (v.y - circum_y)));
|
||||
return dist <= circum_radius;
|
||||
}
|
||||
|
||||
fVector2 p1;
|
||||
fVector2 p2;
|
||||
fVector2 p3;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
inline bool operator == (const Triangle &t1, const Triangle &t2)
|
||||
{
|
||||
return (t1.p1 == t2.p1 || t1.p1 == t2.p2 || t1.p1 == t2.p3) &&
|
||||
(t1.p2 == t2.p1 || t1.p2 == t2.p2 || t1.p2 == t2.p3) &&
|
||||
(t1.p3 == t2.p1 || t1.p3 == t2.p2 || t1.p3 == t2.p3);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
class Delaunay
|
||||
{
|
||||
/*
|
||||
https://github.com/Bl4ckb0ne/delaunay-triangulation
|
||||
*/
|
||||
public:
|
||||
static void triangulate(const std::vector<fVector2> & vertices, std::vector<Triangle>& _triangles)
|
||||
{
|
||||
// Determinate the super triangle
|
||||
float minX = vertices[0].x;
|
||||
float minY = vertices[0].y;
|
||||
float maxX = minX;
|
||||
float maxY = minY;
|
||||
|
||||
for (std::size_t i = 0; i < vertices.size(); ++i)
|
||||
{
|
||||
if (vertices[i].x < minX) minX = vertices[i].x;
|
||||
if (vertices[i].y < minY) minY = vertices[i].y;
|
||||
if (vertices[i].x > maxX) maxX = vertices[i].x;
|
||||
if (vertices[i].y > maxY) maxY = vertices[i].y;
|
||||
}
|
||||
|
||||
float dx = maxX - minX;
|
||||
float dy = maxY - minY;
|
||||
float deltaMax = std::max(dx, dy);
|
||||
float midx = (minX + maxX) / 2.f;
|
||||
float midy = (minY + maxY) / 2.f;
|
||||
|
||||
fVector2 p1(midx - 20 * deltaMax, midy - deltaMax);
|
||||
fVector2 p2(midx, midy + 20 * deltaMax);
|
||||
fVector2 p3(midx + 20 * deltaMax, midy - deltaMax);
|
||||
|
||||
// Create a list of triangles, and add the supertriangle in it
|
||||
_triangles.push_back(Triangle(p1, p2, p3));
|
||||
|
||||
for (auto p = begin(vertices); p != end(vertices); p++) {
|
||||
std::vector<Triangle> badTriangles;
|
||||
std::vector<Edge> polygon;
|
||||
|
||||
for (auto t = begin(_triangles); t != end(_triangles); t++) {
|
||||
if (t->circumCircleContains(*p)) {
|
||||
badTriangles.push_back(*t);
|
||||
|
||||
polygon.push_back(Edge(t->p1, t->p2));
|
||||
polygon.push_back(Edge(t->p2, t->p3));
|
||||
polygon.push_back(Edge(t->p3, t->p1));
|
||||
}
|
||||
}
|
||||
|
||||
_triangles.erase(std::remove_if(begin(_triangles), end(_triangles), [badTriangles](Triangle &t) {
|
||||
for (auto bt = begin(badTriangles); bt != end(badTriangles); bt++) {
|
||||
if (*bt == t) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}), end(_triangles));
|
||||
|
||||
std::vector<Edge> badEdges;
|
||||
for (auto e1 = begin(polygon); e1 != end(polygon); e1++) {
|
||||
for (auto e2 = begin(polygon); e2 != end(polygon); e2++) {
|
||||
if (e1 == e2) continue;
|
||||
|
||||
if (*e1 == *e2) {
|
||||
badEdges.push_back(*e1);
|
||||
badEdges.push_back(*e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
polygon.erase(std::remove_if(begin(polygon), end(polygon), [badEdges](Edge &e) {
|
||||
for (auto it = begin(badEdges); it != end(badEdges); it++) {
|
||||
if (*it == e) return true;
|
||||
}
|
||||
return false;
|
||||
}), end(polygon));
|
||||
|
||||
for (auto e = begin(polygon); e != end(polygon); e++)
|
||||
_triangles.push_back(Triangle(e->p1, e->p2, *p));
|
||||
}
|
||||
|
||||
_triangles.erase(std::remove_if(begin(_triangles), end(_triangles), [p1, p2, p3](Triangle &t) {
|
||||
return t.containsVertex(p1) || t.containsVertex(p2) || t.containsVertex(p3);
|
||||
}), end(_triangles));
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
struct Pixel
|
||||
{
|
||||
int32_t x, y;
|
||||
};
|
||||
typedef std::vector<Pixel> PixelBuf;
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
class Canvas
|
||||
{
|
||||
public:
|
||||
Canvas() : m_width(0), m_height(0), m_pixelBuf(nullptr), m_errorFlag(false) { }
|
||||
~Canvas() {
|
||||
delete[] m_pixelBuf;
|
||||
m_pixelBuf = nullptr;
|
||||
}
|
||||
|
||||
int32_t getWidth(void) const { return m_width; }
|
||||
int32_t getHeight(void) const { return m_height; }
|
||||
|
||||
void init(int32_t width, int32_t height) {
|
||||
if (m_width != width || m_height != height) {
|
||||
if (m_pixelBuf) delete[] m_pixelBuf;
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
//alloc pixels
|
||||
m_pixelBuf = new std::atomic<uint32_t>[m_width*m_height];
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < (size_t)(m_width*m_height); i++) {
|
||||
m_pixelBuf[i] = 0;
|
||||
}
|
||||
m_errorFlag = false;
|
||||
}
|
||||
|
||||
void clear(void) {
|
||||
for (size_t i = 0; i < (size_t)(m_width*m_height); i++) {
|
||||
m_pixelBuf[i] = 0;
|
||||
}
|
||||
m_errorFlag = false;
|
||||
}
|
||||
|
||||
void razFunction_fetchadd(const std::pair<int32_t, int32_t>& pixel, const fVector3& b) {
|
||||
if (m_errorFlag.load()) return;
|
||||
|
||||
if (pixel.first < 0 || pixel.first >= m_width || pixel.second < 0 || pixel.second >= m_height) {
|
||||
bool _false = false;
|
||||
m_errorFlag.compare_exchange_strong(_false, true);
|
||||
return;
|
||||
}
|
||||
m_pixelBuf[pixel.second*m_width + pixel.first].fetch_add(1);
|
||||
}
|
||||
|
||||
void razFunction(const std::pair<int32_t, int32_t>& pixel, const fVector3& b, uint32_t randCol) {
|
||||
if (m_errorFlag.load()) return;
|
||||
|
||||
if (pixel.first < 0 || pixel.first >= m_width || pixel.second < 0 || pixel.second >= m_height) {
|
||||
bool _false = false;
|
||||
m_errorFlag.compare_exchange_strong(_false, true);
|
||||
return;
|
||||
}
|
||||
m_pixelBuf[pixel.second*m_width + pixel.first] = randCol;
|
||||
}
|
||||
|
||||
bool checkResult(bool debug=false) {
|
||||
if (m_errorFlag) return false;
|
||||
|
||||
if (debug) {
|
||||
bool succ = true;
|
||||
uint32_t* colBuf = new uint32_t[m_width*m_height];
|
||||
|
||||
for (int32_t i = 0; i < m_width*m_height; i++) {
|
||||
colBuf[i] = m_pixelBuf[i].load();
|
||||
if (m_pixelBuf[i] == 0) {
|
||||
if (debug) printf("error: %d,%d=%d\n", i%m_width, i/ m_width, m_pixelBuf[(size_t)i].load());
|
||||
succ = false;
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
|
||||
davinci_utils::dump_pixel_buffer("debug.png", m_width, m_height, colBuf, PF_UINT8_RGBA);
|
||||
delete[] colBuf;
|
||||
return succ;
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < (size_t)(m_width*m_height); i++) {
|
||||
if (m_pixelBuf[i] == 0) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkResult(const PixelBuf& pixelExpected) {
|
||||
if (m_errorFlag) return false;
|
||||
|
||||
for (const auto& pixel : pixelExpected) {
|
||||
assert(pixel.x >= 0 && pixel.x < m_width && pixel.y >= 0 && pixel.y < m_height);
|
||||
auto& p = m_pixelBuf[pixel.y*m_width + pixel.x];
|
||||
if (p != 1) return false;
|
||||
p = 0;
|
||||
}
|
||||
for (size_t i = 0; i < (size_t)(m_width*m_height); i++) {
|
||||
if (m_pixelBuf[i] != 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t m_width, m_height;
|
||||
std::atomic<uint32_t>* m_pixelBuf;
|
||||
|
||||
std::atomic<bool> m_errorFlag;
|
||||
std::string m_strError;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
static bool _triangleRasterizationRules(Canvas& canvas, const Triangle& triangle, const PixelBuf& pixelExpect, bool ccw=true)
|
||||
{
|
||||
auto razFunc = std::bind(&Canvas::razFunction_fetchadd, &canvas, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
canvas.clear();
|
||||
|
||||
Rasterizer::drawTriangleLarrabee(canvas.getWidth(), canvas.getHeight(),
|
||||
triangle.p1, triangle.p2, triangle.p3,
|
||||
razFunc, ccw);
|
||||
|
||||
return canvas.checkResult(pixelExpect);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(Rasterizer, Basic)
|
||||
{
|
||||
const int32_t canvasWidth = 64, canvasHeight = 64;
|
||||
|
||||
Canvas canvas;
|
||||
canvas.init(canvasWidth, canvasHeight);
|
||||
|
||||
/*
|
||||
Triangle Rasterization rules test(Without Multisampling)
|
||||
https://msdn.microsoft.com/en-us/library/windows/desktop/cc627092(v=vs.85).aspx
|
||||
*/
|
||||
{
|
||||
Triangle triangle(fVector2(4.5f, 7.5f), fVector2(4.5f, 7.5f), fVector2(4.5f, 7.5f));
|
||||
PixelBuf pixels = {};
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(1, 2), fVector2(7, 4), fVector2(5, 2));
|
||||
PixelBuf pixels = { {2, 2}, {3, 2}, {4, 2}, {5, 3} };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(5, 2), fVector2(7, 4), fVector2(8, 1));
|
||||
PixelBuf pixels = { { 5, 2 },{ 6, 1 },{ 6, 2 },{ 6, 3 }, {7, 1} };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(8, 1), fVector2(7, 4), fVector2(9.5f, 2.5f));
|
||||
PixelBuf pixels = { { 7, 2 },{ 7, 3 }, { 8, 2 } };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(1, 7), fVector2(6, 6), fVector2(2, 4));
|
||||
PixelBuf pixels = { { 2, 4 }, {1, 5 }, { 2, 5 }, { 3, 5 }, { 4, 5 }, { 1, 6 }, { 2, 6 }, };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(5.25f, 6.75f), fVector2(6.25f, 7.75f), fVector2(6.25f, 6.75f));
|
||||
PixelBuf pixels = { };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(6.5f, 5.5f), fVector2(7.5f, 7.5f), fVector2(7.5f, 6.5f));
|
||||
PixelBuf pixels = {};
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(7.6f, 5.5f), fVector2(9.75f, 7.25f), fVector2(11.6f, 5.5f));
|
||||
PixelBuf pixels = { { 9,6 },{ 10, 6 } };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(7.6f, 5.5f), fVector2(11.6f, 5.5f), fVector2(9.5f, 2.6f));
|
||||
PixelBuf pixels = { {8, 5}, { 9, 5 }, { 10, 5 }, { 11, 5 }, { 8, 4 }, { 9, 4 }, { 10, 4 }, {9, 3} };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(11.5f, 1.5f), fVector2(11.5f, 3.5f), fVector2(12.5f, 2.5f));
|
||||
PixelBuf pixels = { {11,2} };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(9.5f, 0.5f), fVector2(10.5f, 0.5f), fVector2(9.5f, -1.5f));
|
||||
PixelBuf pixels = { { 9,0 } };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(13.5f, 0.5f), fVector2(13.5f, 2.5f), fVector2(15.5f, 2.5f));
|
||||
PixelBuf pixels = { { 13,1 }, {13, 2}, {14, 2} };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(13.5f, 0.5f), fVector2(15.5f, 2.5f), fVector2(15.5f, 0.5f));
|
||||
PixelBuf pixels = { { 14, 1 } };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(13.5f, 6.5f), fVector2(14.5f, 5.5f), fVector2(14.5f, 3.5f));
|
||||
PixelBuf pixels = { };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
{
|
||||
Triangle triangle(fVector2(13.5f, 6.5f), fVector2(15, 8), fVector2(14.5f, 5.5f) );
|
||||
PixelBuf pixels = { {13, 6}, {14, 6}, {14, 7} };
|
||||
EXPECT_TRUE(_triangleRasterizationRules(canvas, triangle, pixels, false));
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(Rasterizer, Delaunay)
|
||||
{
|
||||
//seed=1499743811, counts=5, range=0.8f;
|
||||
//seed=1499670829, counts=5, range=1.f;
|
||||
|
||||
const int32_t width = 1024, height = 1024;
|
||||
const int32_t verticesCounts = MathUtil::rangeRandom(5, 30);
|
||||
|
||||
float range = 0.8f;
|
||||
std::vector<fVector2> vertices;
|
||||
for (int32_t i = 0; i < verticesCounts; i++) {
|
||||
float32_t x = MathUtil::rangeRandom(width * (1 - range) / 2.f, width * (1 + range) / 2.f);
|
||||
float32_t y = MathUtil::rangeRandom(height * (1 - range) / 2.f, height * (1 + range) / 2.f);
|
||||
vertices.push_back(fVector2(x, y));
|
||||
}
|
||||
vertices.push_back(fVector2(0, 0));
|
||||
vertices.push_back(fVector2((float)width, 0));
|
||||
vertices.push_back(fVector2((float)width, (float)height));
|
||||
vertices.push_back(fVector2(0, (float)height));
|
||||
|
||||
std::vector<Triangle> triangles;
|
||||
Delaunay::triangulate(vertices, triangles);
|
||||
|
||||
Canvas canvas;
|
||||
canvas.init(width, height);
|
||||
canvas.clear();
|
||||
|
||||
for (size_t i = 0; i < triangles.size(); i++) {
|
||||
const Triangle& triangle = triangles[i];
|
||||
|
||||
uint32_t randCol = 0xFF000000 + ((uint32_t)(rand() / 240) << 16) + ((uint32_t)(rand() / 240) << 8) + ((uint32_t)(rand() / 240));
|
||||
|
||||
auto razFunc = std::bind(&Canvas::razFunction, &canvas, std::placeholders::_1, std::placeholders::_2, randCol);
|
||||
Rasterizer::drawTriangleLarrabee(canvas.getWidth(), canvas.getHeight(),
|
||||
triangle.p1, triangle.p2, triangle.p3,
|
||||
razFunc, false);
|
||||
}
|
||||
EXPECT_TRUE(canvas.checkResult(true));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
#include <math/dvc_vector2.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "dvt_unit_common.h"
|
||||
|
||||
using namespace davinci;
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(Math_Vector2, Basic)
|
||||
{
|
||||
{
|
||||
fVector2 v1;
|
||||
EXPECT_EQ(v1.x, 0.f);
|
||||
EXPECT_EQ(v1.y, 0.f);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat(), b = _randomFloat();
|
||||
fVector2 v1(a, b), v2(v1);
|
||||
EXPECT_EQ(v1.x, a);
|
||||
EXPECT_EQ(v1.y, b);
|
||||
|
||||
EXPECT_EQ(v2.x, a);
|
||||
EXPECT_EQ(v2.y, b);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat(), b = _randomFloat();
|
||||
fVector2 v1;
|
||||
v1[0] = a; v1[1] = b;
|
||||
|
||||
EXPECT_EQ(v1.x, a);
|
||||
EXPECT_EQ(v1.y, b);
|
||||
|
||||
EXPECT_EQ(v1[0], a);
|
||||
EXPECT_EQ(v1[1], b);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat();
|
||||
fVector2 v2(a);
|
||||
EXPECT_EQ(v2.x, a);
|
||||
EXPECT_EQ(v2.y, a);
|
||||
}
|
||||
{
|
||||
float a[2] = { TWO_RANDOM_FLOAT };
|
||||
fVector2 v2(a);
|
||||
EXPECT_EQ(v2.x, a[0]);
|
||||
EXPECT_EQ(v2.y, a[1]);
|
||||
}
|
||||
{
|
||||
int a[2] = { rand() - RAND_MAX/2, rand() - RAND_MAX / 2 };
|
||||
fVector2 v2(a);
|
||||
EXPECT_EQ(v2.x, (float)a[0]);
|
||||
EXPECT_EQ(v2.y, (float)a[1]);
|
||||
}
|
||||
|
||||
//operator
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT), v2;
|
||||
v2 = v1;
|
||||
EXPECT_EQ(v1.x, v2.x);
|
||||
EXPECT_EQ(v1.y, v2.y);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat();
|
||||
fVector2 v1;
|
||||
v1 = a;
|
||||
EXPECT_EQ(v1.x, a);
|
||||
EXPECT_EQ(v1.y, a);
|
||||
}
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT), v2(v1);
|
||||
EXPECT_TRUE(v1 == v2);
|
||||
v2.x += 1.f;
|
||||
EXPECT_TRUE(v1 != v2);
|
||||
}
|
||||
|
||||
{
|
||||
float a = 0.f;
|
||||
while (a == 0.f) { a = _randomFloat(); }
|
||||
|
||||
fVector2 v1(TWO_RANDOM_FLOAT);
|
||||
|
||||
fVector2 v2;// (_randomFloat(), _randomFloat());
|
||||
while (v2.x == 0.f || v2.y == 0.f) {
|
||||
v2 = fVector2(TWO_RANDOM_FLOAT);
|
||||
}
|
||||
fVector2 v3;
|
||||
|
||||
v3 = v1 + v2;
|
||||
EXPECT_EQ(v3.x, v1.x + v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y + v2.y);
|
||||
v3 = v1 - v2;
|
||||
EXPECT_EQ(v3.x, v1.x - v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y - v2.y);
|
||||
v3 = v1 * a;
|
||||
EXPECT_EQ(v3.x, v1.x * a);
|
||||
EXPECT_EQ(v3.y, v1.y * a);
|
||||
v3 = v1 * v2;
|
||||
EXPECT_EQ(v3.x, v1.x * v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y * v2.y);
|
||||
v3 = v1 / a;
|
||||
EXPECT_EQ(v3.x, v1.x / a);
|
||||
EXPECT_EQ(v3.y, v1.y / a);
|
||||
v3 = v1 / v2;
|
||||
EXPECT_EQ(v3.x, v1.x / v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y / v2.y);
|
||||
}
|
||||
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT), v2;
|
||||
v2 = +v1;
|
||||
EXPECT_TRUE(v1 == v2);
|
||||
|
||||
v2 = -v1;
|
||||
EXPECT_EQ(v1.x, -v2.x);
|
||||
EXPECT_EQ(v1.y, -v2.y);
|
||||
}
|
||||
|
||||
{
|
||||
float a = _randomFloat();
|
||||
fVector2 v1, v2;
|
||||
while (v1.x == 0.f || v1.y == 0.f) {
|
||||
v1 = fVector2(TWO_RANDOM_FLOAT);
|
||||
}
|
||||
|
||||
v2 = a * v1;
|
||||
EXPECT_EQ(v2.x, a*v1.x);
|
||||
EXPECT_EQ(v2.y, a*v1.y);
|
||||
|
||||
v2 = a / v1;
|
||||
EXPECT_EQ(v2.x, a/v1.x);
|
||||
EXPECT_EQ(v2.y, a/v1.y);
|
||||
|
||||
v2 = v1 + a;
|
||||
EXPECT_EQ(v2.x, a + v1.x);
|
||||
EXPECT_EQ(v2.y, a + v1.y);
|
||||
|
||||
v2 = a + v1;
|
||||
EXPECT_EQ(v2.x, a + v1.x);
|
||||
EXPECT_EQ(v2.y, a + v1.y);
|
||||
|
||||
v2 = v1 - a;
|
||||
EXPECT_EQ(v2.x, v1.x - a);
|
||||
EXPECT_EQ(v2.y, v1.y - a);
|
||||
|
||||
v2 = a + v1;
|
||||
EXPECT_EQ(v2.x, a + v1.x);
|
||||
EXPECT_EQ(v2.y, a + v1.y);
|
||||
}
|
||||
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT), v2, v3;
|
||||
while (v2.x == 0.f || v2.y == 0.f) {
|
||||
v2 = fVector2(TWO_RANDOM_FLOAT);
|
||||
}
|
||||
|
||||
float a = _randomFloat();
|
||||
while (a == 0.f) { a = _randomFloat(); }
|
||||
|
||||
v3 = v1;
|
||||
v3 += v2;
|
||||
EXPECT_TRUE(v3 == v1+v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 += a;
|
||||
EXPECT_TRUE(v3 == v1 + a);
|
||||
|
||||
v3 = v1;
|
||||
v3 -= v2;
|
||||
EXPECT_TRUE(v3 == v1 - v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 -= a;
|
||||
EXPECT_TRUE(v3 == v1 - a);
|
||||
|
||||
v3 = v1;
|
||||
v3 *= v2;
|
||||
EXPECT_TRUE(v3 == v1 * v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 *= a;
|
||||
EXPECT_TRUE(v3 == v1 * a);
|
||||
|
||||
v3 = v1;
|
||||
v3 /= v2;
|
||||
EXPECT_TRUE(v3 == v1 / v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 /= a;
|
||||
EXPECT_TRUE(v3 == v1 / a);
|
||||
}
|
||||
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT), v2(v1);
|
||||
|
||||
v2 += 1.f;
|
||||
EXPECT_TRUE(v2 > v1);
|
||||
|
||||
v2 -= 2.f;
|
||||
EXPECT_TRUE(v2 < v1);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(Math_Vector2, Algorithm)
|
||||
{
|
||||
//length
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT);
|
||||
glm::vec2 gv1(v1.x, v1.y);
|
||||
|
||||
EXPECT_EQ(v1.length(), glm::length(gv1));
|
||||
}
|
||||
|
||||
//squaredLength
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT);
|
||||
glm::vec2 gv1(v1.x, v1.y);
|
||||
|
||||
EXPECT_EQ(v1.squaredLength(), glm::dot(gv1, gv1));
|
||||
}
|
||||
|
||||
//distance
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT), v2(TWO_RANDOM_FLOAT);
|
||||
glm::vec2 gv1(v1.x, v1.y), gv2(v2.x, v2.y);
|
||||
|
||||
EXPECT_EQ(v1.distance(v2), glm::distance(gv1, gv2));
|
||||
}
|
||||
|
||||
//squaredDistance
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT), v2(TWO_RANDOM_FLOAT);
|
||||
glm::vec2 gv1(v1.x, v1.y), gv2(v2.x, v2.y);
|
||||
glm::vec2 dis = gv1 - gv2;
|
||||
|
||||
EXPECT_EQ(v1.squaredDistance(v2), glm::dot(dis, dis));
|
||||
}
|
||||
|
||||
//dotProduct
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT), v2(TWO_RANDOM_FLOAT);
|
||||
glm::vec2 gv1(v1.x, v1.y), gv2(v2.x, v2.y);
|
||||
|
||||
EXPECT_EQ(v1.dotProduct(v2), glm::dot(gv1, gv2));
|
||||
}
|
||||
|
||||
//crossProduct
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT), v2(TWO_RANDOM_FLOAT);
|
||||
glm::vec3 gv1(v1.x, v1.y, 0), gv2(v2.x, v2.y, 0);
|
||||
|
||||
EXPECT_EQ(v1.crossProduct(v2), glm::cross(gv1, gv2).z);
|
||||
}
|
||||
|
||||
//normalise
|
||||
{
|
||||
fVector2 v1(TWO_RANDOM_FLOAT);
|
||||
glm::vec2 gv1(v1.x, v1.y);
|
||||
|
||||
v1.normalise();
|
||||
glm::vec2 gv1_normal = glm::normalize(gv1);
|
||||
|
||||
EXPECT_EQ(v1.x, gv1_normal.x);
|
||||
EXPECT_EQ(v1.y, gv1_normal.y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
#include <math/dvc_vector2.h>
|
||||
#include <math/dvc_vector3.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "dvt_unit_common.h"
|
||||
|
||||
using namespace davinci;
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(Math_Vector3, Basic)
|
||||
{
|
||||
{
|
||||
fVector3 v1;
|
||||
EXPECT_EQ(v1.x, 0.f);
|
||||
EXPECT_EQ(v1.y, 0.f);
|
||||
EXPECT_EQ(v1.z, 0.f);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat(), b = _randomFloat(), c = _randomFloat();
|
||||
fVector3 v1(a, b, c), v2(v1);
|
||||
EXPECT_EQ(v1.x, a);
|
||||
EXPECT_EQ(v1.y, b);
|
||||
EXPECT_EQ(v1.z, c);
|
||||
|
||||
EXPECT_EQ(v2.x, a);
|
||||
EXPECT_EQ(v2.y, b);
|
||||
EXPECT_EQ(v2.z, c);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat(), b = _randomFloat(), c = _randomFloat();
|
||||
fVector3 v1;
|
||||
v1[0] = a; v1[1] = b; v1[2] = c;
|
||||
|
||||
EXPECT_EQ(v1.x, a);
|
||||
EXPECT_EQ(v1.y, b);
|
||||
EXPECT_EQ(v1.z, c);
|
||||
|
||||
EXPECT_EQ(v1[0], a);
|
||||
EXPECT_EQ(v1[1], b);
|
||||
EXPECT_EQ(v1[2], c);
|
||||
|
||||
fVector2 v1_xy = v1.xy();
|
||||
EXPECT_EQ(v1_xy.x, a);
|
||||
EXPECT_EQ(v1_xy.y, b);
|
||||
|
||||
fVector2 v1_xz = v1.xz();
|
||||
EXPECT_EQ(v1_xz.x, a);
|
||||
EXPECT_EQ(v1_xz.y, c);
|
||||
|
||||
fVector2 v1_yz = v1.yz();
|
||||
EXPECT_EQ(v1_yz.x, b);
|
||||
EXPECT_EQ(v1_yz.y, c);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat();
|
||||
fVector3 v2(a);
|
||||
EXPECT_EQ(v2.x, a);
|
||||
EXPECT_EQ(v2.y, a);
|
||||
EXPECT_EQ(v2.z, a);
|
||||
}
|
||||
{
|
||||
float a[3] = { THREE_RANDOM_FLOAT };
|
||||
fVector3 v2(a);
|
||||
EXPECT_EQ(v2.x, a[0]);
|
||||
EXPECT_EQ(v2.y, a[1]);
|
||||
EXPECT_EQ(v2.z, a[2]);
|
||||
}
|
||||
{
|
||||
int a[3] = { rand() - RAND_MAX / 2, rand() - RAND_MAX / 2, rand() - RAND_MAX / 2 };
|
||||
fVector3 v2(a);
|
||||
EXPECT_EQ(v2.x, (float)a[0]);
|
||||
EXPECT_EQ(v2.y, (float)a[1]);
|
||||
EXPECT_EQ(v2.z, (float)a[2]);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat(), b = _randomFloat(), c = _randomFloat();
|
||||
fVector2 v1(a, b);
|
||||
fVector3 v2(v1, c);
|
||||
EXPECT_EQ(v2.x, a);
|
||||
EXPECT_EQ(v2.y, b);
|
||||
EXPECT_EQ(v2.z, c);
|
||||
|
||||
fVector2 v3(a, b);
|
||||
fVector3 v4(c, v3);
|
||||
EXPECT_EQ(v4.x, c);
|
||||
EXPECT_EQ(v4.y, a);
|
||||
EXPECT_EQ(v4.z, b);
|
||||
}
|
||||
|
||||
//operator
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT), v2;
|
||||
v2 = v1;
|
||||
EXPECT_EQ(v1.x, v2.x);
|
||||
EXPECT_EQ(v1.y, v2.y);
|
||||
EXPECT_EQ(v1.z, v2.z);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat();
|
||||
fVector3 v1;
|
||||
v1 = a;
|
||||
EXPECT_EQ(v1.x, a);
|
||||
EXPECT_EQ(v1.y, a);
|
||||
EXPECT_EQ(v1.z, a);
|
||||
}
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT), v2(v1);
|
||||
EXPECT_TRUE(v1 == v2);
|
||||
v2.x += 1.f;
|
||||
EXPECT_TRUE(v1 != v2);
|
||||
}
|
||||
{
|
||||
float a = 0.f;
|
||||
while (a == 0.f) { a = _randomFloat(); }
|
||||
|
||||
fVector3 v1(THREE_RANDOM_FLOAT);
|
||||
|
||||
fVector3 v2;
|
||||
while (v2.x == 0.f || v2.y == 0.f || v2.z == 0.f) {
|
||||
v2 = fVector3(THREE_RANDOM_FLOAT);
|
||||
}
|
||||
fVector3 v3;
|
||||
|
||||
v3 = v1 + v2;
|
||||
EXPECT_EQ(v3.x, v1.x + v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y + v2.y);
|
||||
EXPECT_EQ(v3.z, v1.z + v2.z);
|
||||
v3 = v1 - v2;
|
||||
EXPECT_EQ(v3.x, v1.x - v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y - v2.y);
|
||||
EXPECT_EQ(v3.z, v1.z - v2.z);
|
||||
v3 = v1 * a;
|
||||
EXPECT_EQ(v3.x, v1.x * a);
|
||||
EXPECT_EQ(v3.y, v1.y * a);
|
||||
EXPECT_EQ(v3.z, v1.z * a);
|
||||
v3 = v1 * v2;
|
||||
EXPECT_EQ(v3.x, v1.x * v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y * v2.y);
|
||||
EXPECT_EQ(v3.z, v1.z * v2.z);
|
||||
v3 = v1 / a;
|
||||
EXPECT_EQ(v3.x, v1.x / a);
|
||||
EXPECT_EQ(v3.y, v1.y / a);
|
||||
EXPECT_EQ(v3.z, v1.z / a);
|
||||
v3 = v1 / v2;
|
||||
EXPECT_EQ(v3.x, v1.x / v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y / v2.y);
|
||||
EXPECT_EQ(v3.z, v1.z / v2.z);
|
||||
}
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT), v2;
|
||||
v2 = +v1;
|
||||
EXPECT_TRUE(v1 == v2);
|
||||
|
||||
v2 = -v1;
|
||||
EXPECT_EQ(v1.x, -v2.x);
|
||||
EXPECT_EQ(v1.y, -v2.y);
|
||||
EXPECT_EQ(v1.z, -v2.z);
|
||||
}
|
||||
|
||||
{
|
||||
float a = _randomFloat();
|
||||
fVector3 v1, v2;
|
||||
while (v1.x == 0.f || v1.y == 0.f || v1.z == 0.f) {
|
||||
v1 = fVector3(THREE_RANDOM_FLOAT);
|
||||
}
|
||||
|
||||
v2 = a * v1;
|
||||
EXPECT_EQ(v2.x, a*v1.x);
|
||||
EXPECT_EQ(v2.y, a*v1.y);
|
||||
EXPECT_EQ(v2.z, a*v1.z);
|
||||
|
||||
v2 = a / v1;
|
||||
EXPECT_EQ(v2.x, a / v1.x);
|
||||
EXPECT_EQ(v2.y, a / v1.y);
|
||||
EXPECT_EQ(v2.z, a / v1.z);
|
||||
|
||||
v2 = v1 + a;
|
||||
EXPECT_EQ(v2.x, a + v1.x);
|
||||
EXPECT_EQ(v2.y, a + v1.y);
|
||||
EXPECT_EQ(v2.z, a + v1.z);
|
||||
|
||||
v2 = a + v1;
|
||||
EXPECT_EQ(v2.x, a + v1.x);
|
||||
EXPECT_EQ(v2.y, a + v1.y);
|
||||
EXPECT_EQ(v2.z, a + v1.z);
|
||||
|
||||
v2 = v1 - a;
|
||||
EXPECT_EQ(v2.x, v1.x - a);
|
||||
EXPECT_EQ(v2.y, v1.y - a);
|
||||
EXPECT_EQ(v2.z, v1.z - a);
|
||||
|
||||
v2 = a + v1;
|
||||
EXPECT_EQ(v2.x, a + v1.x);
|
||||
EXPECT_EQ(v2.y, a + v1.y);
|
||||
EXPECT_EQ(v2.z, a + v1.z);
|
||||
}
|
||||
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT), v2, v3;
|
||||
while (v2.x == 0.f || v2.y == 0.f || v2.z == 0.f) {
|
||||
v2 = fVector3(THREE_RANDOM_FLOAT);
|
||||
}
|
||||
|
||||
float a = _randomFloat();
|
||||
while (a == 0.f) { a = _randomFloat(); }
|
||||
|
||||
v3 = v1;
|
||||
v3 += v2;
|
||||
EXPECT_TRUE(v3 == v1 + v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 += a;
|
||||
EXPECT_TRUE(v3 == v1 + a);
|
||||
|
||||
v3 = v1;
|
||||
v3 -= v2;
|
||||
EXPECT_TRUE(v3 == v1 - v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 -= a;
|
||||
EXPECT_TRUE(v3 == v1 - a);
|
||||
|
||||
v3 = v1;
|
||||
v3 *= v2;
|
||||
EXPECT_TRUE(v3 == v1 * v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 *= a;
|
||||
EXPECT_TRUE(v3 == v1 * a);
|
||||
|
||||
v3 = v1;
|
||||
v3 /= v2;
|
||||
EXPECT_TRUE(v3 == v1 / v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 /= a;
|
||||
EXPECT_TRUE(v3 == v1 / a);
|
||||
}
|
||||
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT), v2(v1);
|
||||
|
||||
v2 += 1.f;
|
||||
EXPECT_TRUE(v2 > v1);
|
||||
|
||||
v2 -= 2.f;
|
||||
EXPECT_TRUE(v2 < v1);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(Math_Vector3, Algorithm)
|
||||
{
|
||||
//length
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT);
|
||||
glm::vec3 gv1(v1.x, v1.y, v1.z);
|
||||
|
||||
EXPECT_EQ(v1.length(), glm::length(gv1));
|
||||
}
|
||||
|
||||
//squaredLength
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT);
|
||||
glm::vec3 gv1(v1.x, v1.y, v1.z);
|
||||
|
||||
EXPECT_EQ(v1.squaredLength(), glm::dot(gv1, gv1));
|
||||
}
|
||||
|
||||
//distance
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT), v2(THREE_RANDOM_FLOAT);
|
||||
glm::vec3 gv1(v1.x, v1.y, v1.z), gv2(v2.x, v2.y, v2.z);
|
||||
|
||||
EXPECT_EQ(v1.distance(v2), glm::distance(gv1, gv2));
|
||||
}
|
||||
|
||||
//squaredDistance
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT), v2(THREE_RANDOM_FLOAT);
|
||||
glm::vec3 gv1(v1.x, v1.y, v1.z), gv2(v2.x, v2.y, v2.z);
|
||||
glm::vec3 len(gv1 - gv2);
|
||||
|
||||
EXPECT_EQ(v1.squaredDistance(v2), glm::dot(len, len));
|
||||
}
|
||||
|
||||
//dotProduct
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT), v2(THREE_RANDOM_FLOAT);
|
||||
glm::vec3 gv1(v1.x, v1.y, v1.z), gv2(v2.x, v2.y, v2.z);
|
||||
|
||||
EXPECT_EQ(v1.dotProduct(v2), glm::dot(gv1, gv2));
|
||||
}
|
||||
|
||||
//crossProduct
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT), v2(THREE_RANDOM_FLOAT);
|
||||
glm::vec3 gv1(v1.x, v1.y, v1.z), gv2(v2.x, v2.y, v2.z);
|
||||
|
||||
fVector3 v3 = v1.crossProduct(v2);
|
||||
glm::vec3 gv1_cross = glm::cross(gv1, gv2);
|
||||
|
||||
EXPECT_EQ(v3.x, gv1_cross.x);
|
||||
EXPECT_EQ(v3.y, gv1_cross.y);
|
||||
EXPECT_EQ(v3.z, gv1_cross.z);
|
||||
}
|
||||
|
||||
//normalise
|
||||
{
|
||||
fVector3 v1(THREE_RANDOM_FLOAT);
|
||||
glm::vec3 gv1(v1.x, v1.y, v1.z);
|
||||
|
||||
v1.normalise();
|
||||
glm::vec3 gv1_nor = glm::normalize(gv1);
|
||||
|
||||
EXPECT_EQ(v1.x, gv1_nor.x);
|
||||
EXPECT_EQ(v1.y, gv1_nor.y);
|
||||
EXPECT_EQ(v1.z, gv1_nor.z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
#include <math/dvc_vector4.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "dvt_unit_common.h"
|
||||
|
||||
using namespace davinci;
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(Math_Vector4, Basic)
|
||||
{
|
||||
{
|
||||
fVector4 v1;
|
||||
EXPECT_EQ(v1.x, 0.f);
|
||||
EXPECT_EQ(v1.y, 0.f);
|
||||
EXPECT_EQ(v1.z, 0.f);
|
||||
EXPECT_EQ(v1.w, 0.f);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat(), b = _randomFloat(), c = _randomFloat(), d = _randomFloat();
|
||||
fVector4 v1(a, b, c, d), v2(v1);
|
||||
EXPECT_EQ(v1.x, a);
|
||||
EXPECT_EQ(v1.y, b);
|
||||
EXPECT_EQ(v1.z, c);
|
||||
EXPECT_EQ(v1.w, d);
|
||||
|
||||
EXPECT_EQ(v2.x, a);
|
||||
EXPECT_EQ(v2.y, b);
|
||||
EXPECT_EQ(v2.z, c);
|
||||
EXPECT_EQ(v2.w, d);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat(), b = _randomFloat(), c = _randomFloat(), d = _randomFloat();
|
||||
fVector4 v1;
|
||||
v1[0] = a; v1[1] = b; v1[2] = c; v1[3] = d;
|
||||
|
||||
EXPECT_EQ(v1.x, a);
|
||||
EXPECT_EQ(v1.y, b);
|
||||
EXPECT_EQ(v1.z, c);
|
||||
EXPECT_EQ(v1.w, d);
|
||||
|
||||
EXPECT_EQ(v1[0], a);
|
||||
EXPECT_EQ(v1[1], b);
|
||||
EXPECT_EQ(v1[2], c);
|
||||
EXPECT_EQ(v1[3], d);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat();
|
||||
fVector4 v2(a);
|
||||
EXPECT_EQ(v2.x, a);
|
||||
EXPECT_EQ(v2.y, a);
|
||||
EXPECT_EQ(v2.z, a);
|
||||
EXPECT_EQ(v2.w, a);
|
||||
}
|
||||
{
|
||||
float a[4] = { FOUR_RANDOM_FLOAT };
|
||||
fVector4 v2(a);
|
||||
EXPECT_EQ(v2.x, a[0]);
|
||||
EXPECT_EQ(v2.y, a[1]);
|
||||
EXPECT_EQ(v2.z, a[2]);
|
||||
EXPECT_EQ(v2.w, a[3]);
|
||||
}
|
||||
{
|
||||
int a[4] = { rand() - RAND_MAX / 2, rand() - RAND_MAX / 2, rand() - RAND_MAX / 2, rand() - RAND_MAX / 2 };
|
||||
fVector4 v2(a);
|
||||
EXPECT_EQ(v2.x, (float)a[0]);
|
||||
EXPECT_EQ(v2.y, (float)a[1]);
|
||||
EXPECT_EQ(v2.z, (float)a[2]);
|
||||
EXPECT_EQ(v2.w, (float)a[3]);
|
||||
}
|
||||
|
||||
//operator
|
||||
{
|
||||
fVector4 v1(FOUR_RANDOM_FLOAT), v2;
|
||||
v2 = v1;
|
||||
EXPECT_EQ(v1.x, v2.x);
|
||||
EXPECT_EQ(v1.y, v2.y);
|
||||
EXPECT_EQ(v1.z, v2.z);
|
||||
EXPECT_EQ(v1.w, v2.w);
|
||||
}
|
||||
{
|
||||
float a = _randomFloat();
|
||||
fVector4 v1;
|
||||
v1 = a;
|
||||
EXPECT_EQ(v1.x, a);
|
||||
EXPECT_EQ(v1.y, a);
|
||||
EXPECT_EQ(v1.z, a);
|
||||
EXPECT_EQ(v1.w, a);
|
||||
}
|
||||
{
|
||||
fVector4 v1(FOUR_RANDOM_FLOAT), v2(v1);
|
||||
EXPECT_TRUE(v1 == v2);
|
||||
v2.x += 1.f;
|
||||
EXPECT_TRUE(v1 != v2);
|
||||
}
|
||||
{
|
||||
float a = 0.f;
|
||||
while (a == 0.f) { a = _randomFloat(); }
|
||||
|
||||
fVector4 v1(FOUR_RANDOM_FLOAT);
|
||||
|
||||
fVector4 v2;
|
||||
while (v2.x == 0.f || v2.y == 0.f || v2.z == 0.f || v2.w == 0.f) {
|
||||
v2 = fVector4(FOUR_RANDOM_FLOAT);
|
||||
}
|
||||
fVector4 v3;
|
||||
|
||||
v3 = v1 + v2;
|
||||
EXPECT_EQ(v3.x, v1.x + v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y + v2.y);
|
||||
EXPECT_EQ(v3.z, v1.z + v2.z);
|
||||
EXPECT_EQ(v3.w, v1.w + v2.w);
|
||||
v3 = v1 - v2;
|
||||
EXPECT_EQ(v3.x, v1.x - v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y - v2.y);
|
||||
EXPECT_EQ(v3.z, v1.z - v2.z);
|
||||
EXPECT_EQ(v3.w, v1.w - v2.w);
|
||||
v3 = v1 * a;
|
||||
EXPECT_EQ(v3.x, v1.x * a);
|
||||
EXPECT_EQ(v3.y, v1.y * a);
|
||||
EXPECT_EQ(v3.z, v1.z * a);
|
||||
EXPECT_EQ(v3.w, v1.w * a);
|
||||
v3 = v1 * v2;
|
||||
EXPECT_EQ(v3.x, v1.x * v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y * v2.y);
|
||||
EXPECT_EQ(v3.z, v1.z * v2.z);
|
||||
EXPECT_EQ(v3.w, v1.w * v2.w);
|
||||
v3 = v1 / a;
|
||||
EXPECT_EQ(v3.x, v1.x / a);
|
||||
EXPECT_EQ(v3.y, v1.y / a);
|
||||
EXPECT_EQ(v3.z, v1.z / a);
|
||||
EXPECT_EQ(v3.w, v1.w / a);
|
||||
v3 = v1 / v2;
|
||||
EXPECT_EQ(v3.x, v1.x / v2.x);
|
||||
EXPECT_EQ(v3.y, v1.y / v2.y);
|
||||
EXPECT_EQ(v3.z, v1.z / v2.z);
|
||||
EXPECT_EQ(v3.w, v1.w / v2.w);
|
||||
}
|
||||
{
|
||||
fVector4 v1(FOUR_RANDOM_FLOAT), v2;
|
||||
v2 = +v1;
|
||||
EXPECT_TRUE(v1 == v2);
|
||||
|
||||
v2 = -v1;
|
||||
EXPECT_EQ(v1.x, -v2.x);
|
||||
EXPECT_EQ(v1.y, -v2.y);
|
||||
EXPECT_EQ(v1.z, -v2.z);
|
||||
EXPECT_EQ(v1.w, -v2.w);
|
||||
}
|
||||
|
||||
{
|
||||
float a = _randomFloat();
|
||||
fVector4 v1, v2;
|
||||
while (v1.x == 0.f || v1.y == 0.f || v1.z == 0.f || v1.w == 0.f) {
|
||||
v1 = fVector4(FOUR_RANDOM_FLOAT);
|
||||
}
|
||||
|
||||
v2 = a * v1;
|
||||
EXPECT_EQ(v2.x, a*v1.x);
|
||||
EXPECT_EQ(v2.y, a*v1.y);
|
||||
EXPECT_EQ(v2.z, a*v1.z);
|
||||
EXPECT_EQ(v2.w, a*v1.w);
|
||||
|
||||
v2 = a / v1;
|
||||
EXPECT_EQ(v2.x, a / v1.x);
|
||||
EXPECT_EQ(v2.y, a / v1.y);
|
||||
EXPECT_EQ(v2.z, a / v1.z);
|
||||
EXPECT_EQ(v2.w, a / v1.w);
|
||||
|
||||
v2 = v1 + a;
|
||||
EXPECT_EQ(v2.x, a + v1.x);
|
||||
EXPECT_EQ(v2.y, a + v1.y);
|
||||
EXPECT_EQ(v2.z, a + v1.z);
|
||||
EXPECT_EQ(v2.w, a + v1.w);
|
||||
|
||||
v2 = a + v1;
|
||||
EXPECT_EQ(v2.x, a + v1.x);
|
||||
EXPECT_EQ(v2.y, a + v1.y);
|
||||
EXPECT_EQ(v2.z, a + v1.z);
|
||||
EXPECT_EQ(v2.w, a + v1.w);
|
||||
|
||||
v2 = v1 - a;
|
||||
EXPECT_EQ(v2.x, v1.x - a);
|
||||
EXPECT_EQ(v2.y, v1.y - a);
|
||||
EXPECT_EQ(v2.z, v1.z - a);
|
||||
EXPECT_EQ(v2.w, v1.w - a);
|
||||
|
||||
v2 = a + v1;
|
||||
EXPECT_EQ(v2.x, a + v1.x);
|
||||
EXPECT_EQ(v2.y, a + v1.y);
|
||||
EXPECT_EQ(v2.z, a + v1.z);
|
||||
EXPECT_EQ(v2.w, a + v1.w);
|
||||
}
|
||||
|
||||
{
|
||||
fVector4 v1(FOUR_RANDOM_FLOAT), v2, v3;
|
||||
while (v2.x == 0.f || v2.y == 0.f || v2.z == 0.f || v2.w == 0.f) {
|
||||
v2 = fVector4(FOUR_RANDOM_FLOAT);
|
||||
}
|
||||
|
||||
float a = _randomFloat();
|
||||
while (a == 0.f) { a = _randomFloat(); }
|
||||
|
||||
v3 = v1;
|
||||
v3 += v2;
|
||||
EXPECT_TRUE(v3 == v1 + v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 += a;
|
||||
EXPECT_TRUE(v3 == v1 + a);
|
||||
|
||||
v3 = v1;
|
||||
v3 -= v2;
|
||||
EXPECT_TRUE(v3 == v1 - v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 -= a;
|
||||
EXPECT_TRUE(v3 == v1 - a);
|
||||
|
||||
v3 = v1;
|
||||
v3 *= v2;
|
||||
EXPECT_TRUE(v3 == v1 * v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 *= a;
|
||||
EXPECT_TRUE(v3 == v1 * a);
|
||||
|
||||
v3 = v1;
|
||||
v3 /= v2;
|
||||
EXPECT_TRUE(v3 == v1 / v2);
|
||||
|
||||
v3 = v1;
|
||||
v3 /= a;
|
||||
EXPECT_TRUE(v3 == v1 / a);
|
||||
}
|
||||
|
||||
{
|
||||
fVector4 v1(FOUR_RANDOM_FLOAT), v2(v1);
|
||||
|
||||
v2 += 1.f;
|
||||
EXPECT_TRUE(v2 > v1);
|
||||
|
||||
v2 -= 2.f;
|
||||
EXPECT_TRUE(v2 < v1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
TEST(Math_Vector4, Algorithm)
|
||||
{
|
||||
|
||||
//dotProduct
|
||||
{
|
||||
fVector4 v1(FOUR_RANDOM_FLOAT), v2(FOUR_RANDOM_FLOAT);
|
||||
glm::vec4 gv1(v1.x, v1.y, v1.z, v1.w), gv2(v2.x, v2.y, v2.z, v2.w);
|
||||
|
||||
EXPECT_EQ(v1.dotProduct(v2), glm::dot(gv1, gv2));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user