Migrate from google-test to jtest.
Some checks failed
Build Docs With Doxygen / Explore-Gitea-Actions (push) Waiting to run
Run tests / Explore-Gitea-Actions (push) Has been cancelled

This commit is contained in:
2024-06-26 11:43:29 -04:00
parent 1684efa6c8
commit 4d9a9d3a95
19 changed files with 1069 additions and 764 deletions

View File

@@ -16,9 +16,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Enable Package Managers
include(cmake/CPM.cmake)
#include(cmake/gtest.cmake)
include(CTest)
file(GLOB_RECURSE J3ML_HEADERS "include/J3ML/*.h" "include/J3ML/*.hpp")
file(GLOB_RECURSE J3ML_SRC "src/J3ML/*.c" "src/J3ML/*.cpp")
@@ -33,6 +31,16 @@ if (WIN32)
add_library(J3ML STATIC ${J3ML_SRC})
endif()
set_target_properties(J3ML PROPERTIES LINKER_LANGUAGE CXX)
CPMAddPackage(
NAME jtest
URL https://git.redacted.cc/josh/jtest/archive/Prerelease-3.zip
)
target_include_directories(J3ML PUBLIC ${jtest_SOURCE_DIR}/include)
target_link_libraries(J3ML PUBLIC jtest)
if(WIN32)
#target_compile_options(J3ML PRIVATE -Wno-multichar)
endif()
@@ -46,6 +54,8 @@ add_subdirectory(tests)
add_executable(MathDemo main.cpp)
target_link_libraries(MathDemo ${PROJECT_NAME})
if(WIN32)
#target_compile_options(MathDemo PRIVATE -mwindows)
endif()

View File

@@ -1,68 +0,0 @@
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
#-----------------------------------------------------------------------
# CPM configuration
#-----------------------------------------------------------------------
set(CPM_MODULE_NAME google_test)
set(CPM_LIB_TARGET_NAME ${CPM_MODULE_NAME})
if ((DEFINED CPM_DIR) AND (DEFINED CPM_UNIQUE_ID) AND (DEFINED CPM_TARGET_NAME))
set(CPM_LIB_TARGET_NAME ${CPM_TARGET_NAME})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CPM_DIR})
include(CPM)
else()
set(CPM_DIR "${CMAKE_CURRENT_BINARY_DIR}/cpm-packages" CACHE TYPE STRING)
find_package(Git)
if(NOT GIT_FOUND)
message(FATAL_ERROR "CPM requires Git.")
endif()
if (NOT EXISTS ${CPM_DIR}/CPM.cmake)
execute_process(
COMMAND "${GIT_EXECUTABLE}" clone https://github.com/iauns/cpm ${CPM_DIR}
RESULT_VARIABLE error_code
OUTPUT_VARIABLE head_sha)
if(error_code)
message(FATAL_ERROR "CPM failed to get the hash for HEAD")
endif()
endif()
include(${CPM_DIR}/CPM.cmake)
endif()
# All externals *must* define this.
CPM_ForceOnlyOneModuleVersion()
CPM_InitModule(${CPM_MODULE_NAME})
#------------------------------------------------------------------------------
# Google Test
#------------------------------------------------------------------------------
# Google test as an external project is a bad idea! You really should add it
# as a subdirectory so that it can capture your compiler flags
set(GOOGLE_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdParty/gtest)
CPM_EnsureRepoIsCurrent(
TARGET_DIR ${GOOGLE_TEST_DIR}
SVN_REPOSITORY "http://googletest.googlecode.com/svn/trunk"
SVN_REVISION "664"
USE_CACHING TRUE
)
# Compiler flags for MSVC 2010
if (MSVC_VERSION EQUAL 1600)
add_definitions(-DGTEST_USE_OWN_TR1_TUPLE=0)
CPM_ExportAdditionalDefinition("-DGTEST_USE_OWN_TR1_TUPLE=0")
endif()
# Compiler flags for MSVC 2012
if(MSVC_VERSION EQUAL 1700)
add_definitions(-D_VARIADIC_MAX=10)
endif()
# For All versions of gtest, we force shared CRT.
set(gtest_force_shared_crt ON)
set(gtest_force_shared_crt ON)
# Add gtest now that we have the appropriate flags set.
add_subdirectory(${GOOGLE_TEST_DIR})
CPM_ExportAdditionalIncludeDir("${GOOGLE_TEST_DIR}/include")
CPM_ExportAdditionalLibraryTarget("gtest")

View File

@@ -0,0 +1,132 @@
#include <J3ML/Algorithm/RNG.h>
#include <jtest/jtest.hpp>
using J3ML::Algorithm::RNG;
int RNGTests()
{
TEST("RNG::IntFast", []{
RNG rng;
u32 prev = rng.IntFast();
for (int i = 0; i < 1000; ++i)
{
u32 next = rng.IntFast();
jtest::check(next != prev);
prev = next;
}
});
TEST("RNG::Int", []{
RNG rng;
assert(rng.lastNumber != 0 || rng.increment != 0);
bool allEqual = true;
for (int i = 0; i < 1000; ++i)
{
int prev = rng.Int();
int next = rng.Int();
jtest::check(prev != 0 || next != 0);
if (prev != next)
allEqual = false;
}
jtest::check(!allEqual);
});
TEST("Rng::Int_A_B", []{
RNG rng;
for (int i = 0; i < 1000; ++i)
{
int a = rng.Int();
int b = rng.Int();
if (b < a)
Swap(a, b);
int val = rng.Int(a, b);
jtest::check( a <= val);
jtest::check(val <= b);
}
});
TEST("Rng::Float", []{
RNG rng;
bool allEqual = true;
for (int i = 0; i < 1000; ++i)
{
float f = rng.Float();
float f2 = rng.Float();
jtest::check(f < 1.f);
jtest::check(f >= 0.f);
jtest::check(f != 0.f || f2 != 0.f);
if (f != f2)
allEqual = false;
}
jtest::check(!allEqual);
});
TEST("Rng::Float01Incl", []{
RNG rng;
bool allEqual = true;
for (int i = 0; i < 1000; ++i)
{
float f = rng.Float01Incl();
float f2 = rng.Float01Incl();
jtest::check(f <= 1.f);
jtest::check(f >= 0.f);
jtest::check(f != 0.f || f2 != 0.f);
if (f != f2)
allEqual = false;
}
jtest::check(!allEqual);
});
TEST("Rng::FloatNeg1_1", []{
RNG rng;
bool allEqual = true;
for (int i = 0; i < 1000; ++i)
{
float f = rng.FloatNeg1_1();
float f2 = rng.FloatNeg1_1();
jtest::check(f < 1.f);
jtest::check(f > -1.f);
jtest::check(f != 0.f || f2 != 0.f);
if (f != f2)
allEqual = false;
}
jtest::check(!allEqual);
});
TEST("Rng, Float_A_B", []{
RNG rng;
for (int i = 0; i < 1000; ++i)
{
float a = rng.Float();
float b = rng.Float();
if (a == b)
continue;
if (b < a)
Swap(a, b);
float f = rng.Float(a, b);
jtest::check(a <= f);
jtest::check(f < b);
}
});
TEST("Rng::Float_A_B_Incl", []{
RNG rng;
for (int i = 0; i < 1000; ++i)
{
float a = rng.Float();
float b = rng.Float();
if (b > a)
Swap(a, b);
float f = rng.FloatIncl(a, b);
jtest::check(a <= f);
jtest::check(f <= b);
}
});
return 0;
}

View File

@@ -1,20 +1,9 @@
cmake_minimum_required(VERSION 3.18)
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.11.0
)
FetchContent_MakeAvailable(googletest)
add_library(GTest::GTest INTERFACE IMPORTED)
target_link_libraries(GTest::GTest INTERFACE gtest_main)
file(GLOB_RECURSE TEST_FILES "*.hpp")
add_executable(J3MLTestSuite tests.cpp)
file(GLOB_RECURSE TEST_SRC "tests.cpp" "*.cpp")
add_executable(Test ${TEST_SRC})
target_link_libraries(Test PUBLIC J3ML)
#find_package(GTest REQUIRED)
target_link_libraries(Test PRIVATE GTest::GTest)
include_directories("include")
add_test(NAME "J3MLTestSuite" COMMAND Test)
target_include_directories(J3MLTestSuite PUBLIC "include" $TEST_FILES)
target_link_libraries(J3MLTestSuite PUBLIC J3ML)

View File

@@ -1,89 +0,0 @@
#include <gtest/gtest.h>
#include <J3ML/Geometry/Triangle.h>
using J3ML::Geometry::Interval;
using J3ML::Geometry::Triangle;
TEST(TriangleTests, FaceNormal)
{
Triangle t{
Vector3{-1, -1, -1},
Vector3{0, 1, 0},
Vector3{1, -1, 1}
};
EXPECT_EQ(t.FaceNormal(), (Vector3{4, 0, -4}));
}
TEST(TriangleTests, IntersectTriangle)
{
Triangle xyTriangle{
{0.0f, 0.0f, 0.0f},
{1.0f, 1.0f, 0.0f},
{2.0f, 0.0f, 0.0f}
};
// Triangle collides with itself
EXPECT_EQ(Intersects(xyTriangle, xyTriangle), true);
// Translate 1 towards x -- should collide
EXPECT_EQ(Intersects(xyTriangle, xyTriangle.Translated(Vector3(1.0f, 0.0f, 0.0f))), true);
// Translate 2 towards x -- should collide exactly on V1
EXPECT_EQ(Intersects(xyTriangle, xyTriangle.Translated(Vector3(2.0f, 0.0f, 0.0f))), true);
// Translate 2 towards negative x -- should collide exactly on V0
EXPECT_EQ(Intersects(xyTriangle, xyTriangle.Translated(Vector3(-2.0f, 0.0f, 0.0f))), true);
// Translate 3 towards x -- should not collide
EXPECT_EQ(Intersects(xyTriangle, xyTriangle.Translated(Vector3(3.0f, 0.0f, 0.0f))), false);
// Translate 3 towards negative x -- should not collide
EXPECT_EQ(Intersects(xyTriangle, xyTriangle.Translated(Vector3(-3.0f, 0.0f, 0.0f))), false);
// Translate 1 towards z -- should not collide
EXPECT_EQ(Intersects(xyTriangle, xyTriangle.Translated(Vector3(0.0f, 0.0f, 1.0f))), false);
// Triangle collides with contained smaller triangle
EXPECT_EQ(Intersects(xyTriangle, xyTriangle.Scaled(Vector3(0.5f, 0.5f, 0.5f)).Translated(Vector3(0.25f, 0.25f, 0.0f))), true);
Triangle zxTriangle {
{0.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 1.0f},
{0.0f, 0.0f, 2.0f}
};
// Should collide exactly on V0
EXPECT_EQ(Intersects(xyTriangle, zxTriangle), true);
// Should collide across xyTriangle's edge and zxTriangle's face
EXPECT_EQ(Intersects(xyTriangle, zxTriangle.Translated(Vector3(0.0f, 0.0f, -1.0))), true);
// Should collide exactly on V1
EXPECT_EQ(Intersects(xyTriangle, zxTriangle.Translated(Vector3(0.0f, 0.0f, -2.0))), true);
// xyTriangle's face should be poked by zxTriangle's V0
EXPECT_EQ(Intersects(xyTriangle, zxTriangle.Translated(Vector3(1.0f, 1.0f, 0.0f))), true);
// xyTriangle's face should be cut by zxTriangle
EXPECT_EQ(Intersects(xyTriangle, zxTriangle.Translated(Vector3(1.0f, 1.0f, -0.5f))), true);
// Should not collide
EXPECT_EQ(Intersects(xyTriangle, zxTriangle.Translated(Vector3(1.0f, 1.0f, 1.0f))), false);
// Should not collide
EXPECT_EQ(Intersects(xyTriangle, zxTriangle.Translated(Vector3(0.0f, 0.0f, -3.0f))), false);
Triangle yxTriangle{
{0.0f, 0.0f, 0.0f},
{1.0f, 1.0f, 0.0f},
{0.0f, 2.0f, 0.0f}
};
// Should collide on V0-V1 edge
EXPECT_EQ(Intersects(yxTriangle, yxTriangle), true);
// Should not collide
EXPECT_EQ(Intersects(xyTriangle, yxTriangle.Translated(Vector3(0.0f, 1.0f, 0.0f))), false);
// Should not collide
EXPECT_EQ(Intersects(yxTriangle, yxTriangle.Translated(Vector3(0.0f, 0.0f, 1.0f))), false);
Triangle zyInvertedTriangle{
{0.0f, 1.0f, -1.0f},
{0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 1.0f}
};
// Should collide exactly on V1
EXPECT_EQ(Intersects(xyTriangle, zyInvertedTriangle), true);
// Should not collide
EXPECT_EQ(Intersects(xyTriangle, zyInvertedTriangle.Translated(Vector3(0.0f, 1.0f, 0.0f))), false);
// Should not collide
EXPECT_EQ(Intersects(xyTriangle, zyInvertedTriangle.Translated(Vector3(0.25f, 0.75f, 0.0f))), false);
}

View File

@@ -0,0 +1,97 @@
#include <jtest/jtest.hpp>
#include <J3ML/Geometry/Triangle.h>
using J3ML::Geometry::Interval;
using J3ML::Geometry::Triangle;
int TriangleTests() {
TEST("Triangle::FaceNormal", [] {
Triangle t(
{-1, -1, -1},
{0, 1, 0},
{1, -1, 1}
);
jtest::check(t.FaceNormal() == Vector3{4, 0, -4});
});
TEST("Triangle::IntersectTriangle", []
{
Triangle xyTriangle(
{0.0f, 0.0f, 0.0f},
{1.0f, 1.0f, 0.0f},
{2.0f, 0.0f, 0.0f}
);
// Triangle collides with itself
jtest::check(Intersects(xyTriangle, xyTriangle));
// Translate 1 towards x -- should collide
jtest::check(Intersects(xyTriangle, xyTriangle.Translated(Vector3(1.0f, 0.0f, 0.0f))));
// Translate 2 towards x -- should collide exactly on V1
jtest::check(Intersects(xyTriangle, xyTriangle.Translated(Vector3(2.0f, 0.0f, 0.0f))));
// Translate 2 towards negative x -- should collide exactly on V0
jtest::check(Intersects(xyTriangle, xyTriangle.Translated(Vector3(-2.0f, 0.0f, 0.0f))));
// Translate 3 towards x -- should not collide
jtest::check(!Intersects(xyTriangle, xyTriangle.Translated(Vector3(3.0f, 0.0f, 0.0f))));
// Translate 3 towards negative x -- should not collide
jtest::check(!Intersects(xyTriangle, xyTriangle.Translated(Vector3(-3.0f, 0.0f, 0.0f))));
// Translate 1 towards z -- should not collide
jtest::check(!Intersects(xyTriangle, xyTriangle.Translated(Vector3(0.0f, 0.0f, 1.0f))));
// Triangle collides with contained smaller triangle
jtest::check(!Intersects(xyTriangle, xyTriangle.Scaled(Vector3(0.5f, 0.5f, 0.5f)).Translated(Vector3(0.25f, 0.25f, 0.0f))));
Triangle zxTriangle (
{0.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 1.0f},
{0.0f, 0.0f, 2.0f}
);
// Should collide exactly on V0
jtest::check(Intersects(xyTriangle, zxTriangle));
// Should collide across xyTriangle's edge and zxTriangle's face
jtest::check(Intersects(xyTriangle, zxTriangle.Translated(Vector3(0.0f, 0.0f, -1.0))));
// Should collide exactly on V1
jtest::check(Intersects(xyTriangle, zxTriangle.Translated(Vector3(0.0f, 0.0f, -2.0))));
// xyTriangle's face should be poked by zxTriangle's V0
jtest::check(Intersects(xyTriangle, zxTriangle.Translated(Vector3(1.0f, 1.0f, 0.0f))));
// xyTriangle's face should be cut by zxTriangle
jtest::check(Intersects(xyTriangle, zxTriangle.Translated(Vector3(1.0f, 1.0f, -0.5f))));
// Should not collide
jtest::check(!Intersects(xyTriangle, zxTriangle.Translated(Vector3(1.0f, 1.0f, 1.0f))));
// Should not collide
jtest::check(!Intersects(xyTriangle, zxTriangle.Translated(Vector3(0.0f, 0.0f, -3.0f))));
Triangle yxTriangle(
{0.0f, 0.0f, 0.0f},
{1.0f, 1.0f, 0.0f},
{0.0f, 2.0f, 0.0f}
);
// Should collide on V0-V1 edge
jtest::check(Intersects(yxTriangle, yxTriangle));
// Should not collide
jtest::check(!Intersects(xyTriangle, yxTriangle.Translated(Vector3(0.0f, 1.0f, 0.0f))));
// Should not collide
jtest::check(!Intersects(yxTriangle, yxTriangle.Translated(Vector3(0.0f, 0.0f, 1.0f))));
Triangle zyInvertedTriangle(
{0.0f, 1.0f, -1.0f},
{0.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 1.0f}
);
// Should collide exactly on V1
jtest::check(Intersects(xyTriangle, zyInvertedTriangle));
// Should not collide
jtest::check(!Intersects(xyTriangle, zyInvertedTriangle.Translated(Vector3(0.0f, 1.0f, 0.0f))));
// Should not collide
jtest::check(!Intersects(xyTriangle, zyInvertedTriangle.Translated(Vector3(0.25f, 0.75f, 0.0f))));
});
return 0;
}

View File

@@ -1,3 +1,7 @@
//
// Created by josh on 12/26/2023.
//
int EulerAngleTests() {
return 0;
}

View File

@@ -1,5 +1,8 @@
#include <gtest/gtest.h>
#include <J3ML/LinearAlgebra/Matrix3x3.h>
using namespace J3ML::LinearAlgebra;
int Matrix2x2Tests() {
return 0;
}

View File

@@ -1,90 +0,0 @@
#include <gtest/gtest.h>
#include <J3ML/LinearAlgebra/Matrix3x3.h>
#include <J3ML/LinearAlgebra/Matrix4x4.h>
using namespace J3ML::LinearAlgebra;
// TODO: create RNG instance
RNG rng;
TEST(Mat3x3, Add_Unary)
{
Matrix3x3 m(1,2,3, 4,5,6, 7,8,9);
Matrix3x3 m2 = +m;
assert(m.Equals(m2));
}
TEST(Mat3x3, Solve_Axb)
{
Matrix3x3 A = Matrix3x3::RandomGeneral(rng, -10.f, 10.f);
bool mayFail = Math::EqualAbs(A.Determinant(), 0.f, 1e-2f);
Vector3 b = Vector3::RandomBox(rng, Vector3::FromScalar(-10.f), Vector3::FromScalar(10.f));
Vector3 x;
bool success = A.SolveAxb(b, x);
assert(success || mayFail);
if (success)
{
Vector3 b2 = A*x;
assert(b2.Equals(b, 1e-1f));
}
}
TEST(Mat3x3, Inverse_Case)
{
Matrix3x3 m(-8.75243664f,6.71196938f,-5.95816374f,6.81996822f,-6.85106039f,2.38949537f,-0.856015682f,3.45762491f,3.311584f);
bool success = m.Inverse();
assert(success);
}
TEST(Mat3x3, Inverse)
{
Matrix3x3 A = Matrix3x3::RandomGeneral(rng, -10.f, 10.f);
bool mayFail = Math::EqualAbs(A.Determinant(), 0.f, 1e-2f);
Matrix3x3 A2 = A;
bool success = A2.Inverse();
assert(success || mayFail);
if (success)
{
Matrix3x3 id = A * A2;
Matrix3x3 id2 = A2 * A;
assert(id.Equals(Matrix3x3::Identity, 0.3f));
assert(id2.Equals(Matrix3x3::Identity, 0.3f));
}
}
TEST(Mat3x3, InverseFast)
{
// TODO: Fix implementation of InverseFast
/*
Matrix3x3 A = Matrix3x3::RandomGeneral(rng, -10.f, 10.f);
bool mayFail = Math::EqualAbs(A.Determinant(), 0.f, 1e-2f);
Matrix3x3 A2 = A;
bool success = A2.InverseFast();
assert(success || mayFail);
if (success)
{
Matrix3x3 id = A * A2;
Matrix3x3 id2 = A2 * A;
assert(id.Equals(Matrix3x3::Identity, 0.3f));
assert(id2.Equals(Matrix3x3::Identity, 0.3f));
}
*/
}
TEST(Mat3x3, MulMat4x4)
{
Matrix3x3 m = Matrix3x3::RandomGeneral(rng, -10.f, 10.f);
Matrix4x4 m_ = m;
Matrix4x4 m2 = Matrix4x4::RandomGeneral(rng, -10.f, 10.f);
Matrix4x4 test = m * m2;
Matrix4x4 correct = m_ * m2;
assert(test.Equals(correct));
}

View File

@@ -0,0 +1,96 @@
#include <J3ML/LinearAlgebra/Matrix3x3.h>
#include <jtest/jtest.hpp>
using namespace J3ML::LinearAlgebra;
// TODO: create RNG instance
int Matrix3x3Tests() {
TEST("Mat3x3::Add_Unary", []
{
Matrix3x3 m(1,2,3, 4,5,6, 7,8,9);
Matrix3x3 m2 = +m;
jtest::check(m.Equals(m2));
});
TEST("Mat3x3::Solve_Axb", []{
RNG rng;
Matrix3x3 A = Matrix3x3::RandomGeneral(rng, -10.f, 10.f);
bool mayFail = Math::EqualAbs(A.Determinant(), 0.f, 1e-2f);
Vector3 b = Vector3::RandomBox(rng, Vector3::FromScalar(-10.f), Vector3::FromScalar(10.f));
Vector3 x;
bool success = A.SolveAxb(b, x);
jtest::check(success || mayFail);
if (success)
{
Vector3 b2 = A*x;
jtest::check(b2.Equals(b, 1e-1f));
}
});
TEST("Mat3x3::Inverse_Case", []
{
Matrix3x3 m(-8.75243664f,6.71196938f,-5.95816374f,6.81996822f,-6.85106039f,2.38949537f,-0.856015682f,3.45762491f,3.311584f);
bool success = m.Inverse();
jtest::check(success);
});
TEST("Mat3x3::Inverse", []
{
RNG rng;
Matrix3x3 A = Matrix3x3::RandomGeneral(rng, -10.f, 10.f);
bool mayFail = Math::EqualAbs(A.Determinant(), 0.f, 1e-2f);
Matrix3x3 A2 = A;
bool success = A2.Inverse();
jtest::check(success || mayFail);
if (success)
{
Matrix3x3 id = A * A2;
Matrix3x3 id2 = A2 * A;
jtest::check(id.Equals(Matrix3x3::Identity, 0.3f));
jtest::check(id2.Equals(Matrix3x3::Identity, 0.3f));
}
});
TEST("Mat3x3::InverseFast", []
{
// TODO: Fix implementation of InverseFast
/*
Matrix3x3 A = Matrix3x3::RandomGeneral(rng, -10.f, 10.f);
bool mayFail = Math::EqualAbs(A.Determinant(), 0.f, 1e-2f);
Matrix3x3 A2 = A;
bool success = A2.InverseFast();
assert(success || mayFail);
if (success)
{
Matrix3x3 id = A * A2;
Matrix3x3 id2 = A2 * A;
assert(id.Equals(Matrix3x3::Identity, 0.3f));
assert(id2.Equals(Matrix3x3::Identity, 0.3f));
}
*/
});
TEST("Mat3x3::MulMat4x4", []
{
RNG rng;
Matrix3x3 m = Matrix3x3::RandomGeneral(rng, -10.f, 10.f);
Matrix4x4 m_ = m;
Matrix4x4 m2 = Matrix4x4::RandomGeneral(rng, -10.f, 10.f);
Matrix4x4 test = m * m2;
Matrix4x4 correct = m_ * m2;
jtest::check(test.Equals(correct));
});
return 0;
}

View File

@@ -1,11 +0,0 @@
#include <gtest/gtest.h>
#include <J3ML/LinearAlgebra/Matrix4x4.h>
using namespace J3ML::LinearAlgebra;
TEST(Mat4x4, Add_Unary)
{
Matrix4x4 m(1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16);
Matrix4x4 m2 = +m;
assert(m.Equals(m2));
}

View File

@@ -0,0 +1,129 @@
#include <jtest/jtest.hpp>
#include <J3ML/LinearAlgebra/Matrix4x4.h>
#include <J3ML/LinearAlgebra/Quaternion.h>
using namespace J3ML::LinearAlgebra;
int Matrix4x4Tests() {
TEST("Mat4x4::Add_Unary", []
{
Matrix4x4 m(1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16);
Matrix4x4 m2 = +m;
jtest::check(m.Equals(m2));
});
TEST("Mat4x4::Inverse", [] {
RNG rng;
Matrix4x4 A = Matrix4x4::RandomGeneral(rng, -10.f, 10.f);
bool mayFail = Math::EqualAbs(A.Determinant(), 0.f, 1e-2f);
Matrix4x4 A2 = A;
bool success = A2.Inverse();
jtest::check(success || mayFail);
if (success)
{
Matrix4x4 id = A * A2;
Matrix4x4 id2 = A2 * A;
jtest::check(id.Equals(Matrix4x4::Identity, 0.3f));
jtest::check(id2.Equals(Matrix4x4::Identity, 0.3f));
}
});
TEST("Mat4x4::Ctor", []{
RNG rng;
Matrix3x3 m = Matrix3x3::RandomGeneral(rng, -10.f, 10.f);
Matrix4x4 m2(m);
for (int y = 0; y < 3; ++y)
for (int x = 0; x < 3; ++x)
assert(Math::EqualAbs(m.At(y, x), m2.At(y, x)));
jtest::check(Math::EqualAbs(m2[0][3], 0.f));
jtest::check(Math::EqualAbs(m2[1][3], 0.f));
jtest::check(Math::EqualAbs(m2[2][3], 0.f));
jtest::check(Math::EqualAbs(m2[3][0], 0.f));
jtest::check(Math::EqualAbs(m2[3][1], 0.f));
jtest::check(Math::EqualAbs(m2[3][2], 0.f));
jtest::check(Math::EqualAbs(m2[3][3], 0.f));
});
TEST("Mat4x4::SetRow", []
{
Matrix4x4 m;
m.SetRow(0, 1,2,3,4);
m.SetRow(1, Vector4(5,6,7,8));
m.SetRow(2, 9,10,11,12);
m.SetRow(3, 13, 14, 15, 16);
Matrix4x4 m3(1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16);
Matrix4x4 m2;
m2.Set(1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16);
jtest::check(m.Equals(m2));
jtest::check(m.Equals(m3));
});
TEST("Mat4x4::SwapRows", []
{
Matrix4x4 m(1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16);
Matrix4x4 m2(13,14,15,16, 9,10,11,12, 5,6,7,8, 1,2,3,4);
m.SwapRows(0,3);
m.SwapRows(1,2);
jtest::check(m.Equals(m2));
});
TEST("Mat4x4::CtorCols", []
{
Matrix4x4 m(Vector4(1,2,3,4), Vector4(5,6,7,8), Vector4(9,10,11,12), Vector4(13,14,15,16));
Matrix4x4 m2(1,5,9,13, 2,6,10,14, 3,7,11,15, 4,8,12,16);
jtest::check(m.Equals(m2));
});
TEST("Mat4x4::CtorFromQuat", []
{
RNG rng;
// TODO: Multiple random passes
Quaternion q = Quaternion::RandomRotation(rng);
Matrix4x4 m(q);
Vector3 v = Vector3(-1, 5, 20.f);
Vector3 v1 = q * v;
Vector3 v2 = m.Transform(v); //m.TransformPos(v);
jtest::check(v1.Equals(v2));
});
TEST("Mat4x4::CtorFromQuatTrans", [] {});
TEST("Mat4x4::Translate", [] {});
TEST("Mat4x4::Scale", [] {});
TEST("Mat4x4::InverseOrthogonalUniformScale", [] {});
TEST("Mat4x4::InverseOrthonormal", [] {});
TEST("Mat4x4::DeterminantCorrectness", [] { });
TEST("Mat4x4::MulMat3x3", [] {});
return 0;
}

View File

@@ -0,0 +1,75 @@
#include <J3ML/LinearAlgebra/Quaternion.h>
using namespace J3ML::LinearAlgebra;
Quaternion PreciseSlerp(const Quaternion &a, const Quaternion& b, float t)
{
double angle = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
double sign = 1.0;
if (angle > 0) {
angle = -angle;
sign = -1.0;
}
double A;
double B;
if (angle <= 1.0) // perform spherical linear interpolation
{
angle = std::acos(angle); // After this, angle is in the range pi / 2 -> 0 as the original angle variable ranged from 0 -> 1.
double angleT = t * angle;
double s[3] = { std::sin(angle), std::sin(angle - angleT), std::sin(angleT)};
double c = 1.0 / s[0];
A = s[1] * c;
B = s[2] * c;
} else { // If angle is close to taking the denominator to zero, resort to linear interpolation (and normalization).
A = 1.0 - t;
B = t;
}
Quaternion C;
C.x = (float)(a.x*A*sign + b.x*B);
C.y = (float)(a.y*A*sign + b.y*B);
C.z = (float)(a.z*A*sign + b.z*B);
C.w = (float)(a.w*A*sign + b.w*B);
return C.Normalized();
}
int QuaternionTests()
{
TEST("Quat::SlerpPrecision", [] {
RNG rng;
float maxError = 0;
float maxLerpError = 0;
float magnitudeError = 0;
for (int i = 0; i < 10000; ++i)
{
Quaternion q = Quaternion::RandomRotation(rng);
Quaternion q2 = Quaternion::RandomRotation(rng);
float t = rng.Float01Incl();
Quaternion correct = PreciseSlerp(q, q2, t);
Quaternion fast = q.Slerp(q2, t);
magnitudeError = std::max(magnitudeError, std::abs(1.f - fast.LengthSquared()));
Quaternion lerp = q.Lerp(q2, t);
}
});
TEST("Quat::Mat4x4Conversion", [] {});
TEST("Quat::MulOpQuat", [] {});
TEST("Quat::DivOpQuat", [] {});
TEST("Quat::Lerp", [] {});
TEST("Quat::RotateFromTo", [] {});
TEST("Quat::Transform", [] {});
return 0;
}

View File

@@ -1,183 +0,0 @@
#include <gtest/gtest.h>
#include <J3ML/LinearAlgebra/Vector2.h>
using J3ML::LinearAlgebra::Vector2;
TEST(Vector2Test, V2_Constructor_Default)
{
EXPECT_EQ(Vector2(), Vector2::Zero);
}
TEST(Vector2Test, V2_Constructor_XY)
{
Vector2 vec {1, 0};
EXPECT_EQ(vec, Vector2::Right);
}
TEST(Vector2Test, V2_Addition_Op)
{
Vector2 A {1,1};
Vector2 B {2,2};
Vector2 C {3, 3};
EXPECT_EQ(A+B, C);
}
TEST(Vector2Test, V2_Addition_Method)
{
Vector2 A {2,2};
Vector2 B {2,2};
Vector2 C {4, 4};
EXPECT_EQ(A.Add(B), C);
}
TEST(Vector2Test, V2_Addition_Static)
{
Vector2 A {3, 3};
Vector2 B {2, 2};
Vector2 C {5, 5};
EXPECT_EQ(Vector2::Add(A, B), C);
}
TEST(Vector2Test, V2_Subtract_Op)
{
Vector2 A {1,1};
Vector2 B {2,2};
Vector2 C {-1, -1};
EXPECT_EQ(A-B, C);
}
TEST(Vector2Test, V2_Subtract_Method)
{
Vector2 A {1,1};
Vector2 B {2,2};
Vector2 C {-1, -1};
EXPECT_EQ(A.Sub(B), C);
}
TEST(Vector2Test, V2_Subtract_Static)
{
Vector2 A {1,1};
Vector2 B {2,2};
Vector2 C {-1, -1};
EXPECT_EQ(Vector2::Sub(A, B), C);
}
TEST(Vector2Test, V2_Scalar_Multiplication)
{
Vector2 A {5, 1};
float B = 0.5f;
Vector2 C = {2.5f, .5f};
EXPECT_EQ(A*B, C);
}
TEST(Vector2Test, V2_Size)
{
EXPECT_EQ(sizeof(Vector2), 8);
}
TEST(Vector2Test, V2_NaN)
{
EXPECT_NE(Vector2::Zero, Vector2::NaN);
EXPECT_NE(Vector2::Up, Vector2::NaN);
EXPECT_NE(Vector2::Left, Vector2::NaN);
EXPECT_NE(Vector2::Down, Vector2::NaN);
EXPECT_NE(Vector2::Right, Vector2::NaN);
EXPECT_NE(Vector2::NaN, Vector2::NaN);
}
TEST(Vector2Test, V2_MarginOfError)
{
Vector2 A {2,2};
Vector2 B {1.85, 1.85};
EXPECT_TRUE(A.IsWithinMarginOfError(B, 0.5f));
}
TEST(Vector2Test, V2_Min)
{
Vector2 A {2,2};
Vector2 B {1.85, 1.85};
EXPECT_EQ( Vector2::Min(A, B), B);
}
TEST(Vector2Test, V2_Max)
{
Vector2 A {2,2};
Vector2 B {1.85, 1.85};
EXPECT_EQ( Vector2::Max(A, B), A);
}
TEST(Vector2Test, V2_Clamp)
{
Vector2 Input{0, 20};
Vector2 Minimum { 2, 2};
Vector2 Maximum {16, 16};
Vector2 ExpectedResult {2, 16};
EXPECT_EQ(Input.Clamp(Minimum, Maximum), ExpectedResult);
}
TEST(Vector2Test, V2_DotProduct)
{
// TODO: Equality
Vector2 A {2, 2};
Vector2 B {1, 1};
EXPECT_FLOAT_EQ(A.Dot(B), 4.f);
}
TEST(Vector2Test, V2_Project)
{
Vector2 Base {4, 4};
Vector2 Projected {1, 0};
Vector2 ExpectedResult {4, 0};
EXPECT_EQ(Base.Project(Projected), ExpectedResult);
}
TEST(Vector2Test, V2_Normalize)
{
Vector2 A{2, 0};
Vector2 B{1, 0};
EXPECT_EQ(A.Normalized(), B);
}
TEST(Vector2Test, V2_Lerp)
{
Vector2 A {2,2};
Vector2 B {10, 10};
Vector2 C {6, 6};
EXPECT_EQ(A.Lerp(B, 0.f), A);
EXPECT_EQ(A.Lerp(B, 1.f), B);
EXPECT_EQ(A.Lerp(B, 0.5f), C);
}
TEST(Vector2Test, V2_AngleBetween)
{
Vector2 A {0.5f, 0.5};
Vector2 B {0.5f, 0.1f};
A = A.Normalized();
B = B.Normalized();
// TODO: AngleBetween returns not a number
EXPECT_FLOAT_EQ(A.AngleBetween(B), 0.58800244);
}

View File

@@ -0,0 +1,191 @@
#include <J3ML/LinearAlgebra/Vector2.h>
using J3ML::LinearAlgebra::Vector2;
int Vector2Tests()
{
TEST("Vector2::Ctor_Default", []
{
// TODO: implement check_eq
jtest::check(Vector2() == Vector2::Zero);
});
TEST("Vector2::Ctor_XY", []
{
Vector2 vec (1, 0);
// TODO: implement check_eq
jtest::check(vec == Vector2::Right);
});
TEST("Vector2::Addition_Op", []
{
Vector2 A (1,1);
Vector2 B (2,2);
Vector2 C (3, 3);
// TODO: implement check_eq
jtest::check(A+B == C);
});
TEST("Vector2::Addition_Method", []
{
Vector2 A (2,2);
Vector2 B (2,2);
Vector2 C (4, 4);
// TODO: implement check_eq
jtest::check(A.Add(B) == C);
});
TEST("Vector2::Addition_Static", []
{
Vector2 A (3, 3);
Vector2 B (2, 2);
Vector2 C (5, 5);
// TODO: implement check_eq
jtest::check(Vector2::Add(A, B) == C);
});
TEST("Vector2::Subtract_Op", []
{
Vector2 A (1,1);
Vector2 B (2,2);
Vector2 C (-1, -1);
jtest::check(A-B == C);
});
TEST("Vector2::Subtract_Method", []
{
Vector2 A (1,1);
Vector2 B (2,2);
Vector2 C (-1, -1);
jtest::check(A.Sub(B) == C);
});
TEST("Vector2::Subtract_Static", []
{
Vector2 A (1,1);
Vector2 B (2,2);
Vector2 C (-1, -1);
jtest::check(Vector2::Sub(A, B) == C);
});
TEST("Vector2::Scalar_Multiplication", []
{
Vector2 A (5, 1);
float B = 0.5f;
Vector2 C (2.5f, .5f);
jtest::check(A*B == C);
});
TEST("Vector2::Size", []
{
jtest::check(sizeof(Vector2) == 8);
});
TEST("Vector2::NaN", []
{
jtest::check(Vector2::Zero != Vector2::NaN);
jtest::check(Vector2::Up != Vector2::NaN);
jtest::check(Vector2::Left != Vector2::NaN);
jtest::check(Vector2::Down != Vector2::NaN);
jtest::check(Vector2::Right != Vector2::NaN);
jtest::check(Vector2::NaN != Vector2::NaN);
});
TEST("Vector2::MarginOfError", []
{
Vector2 A (2,2);
Vector2 B (1.85, 1.85);
jtest::check(A.IsWithinMarginOfError(B, 0.5f));
});
TEST("Vector2::Min", []
{
Vector2 A (2,2);
Vector2 B (1.85, 1.85);
jtest::check( Vector2::Min(A, B) == B);
});
TEST("Vector2::Max", []
{
Vector2 A (2,2);
Vector2 B (1.85, 1.85);
jtest::check( Vector2::Max(A, B) == A);
});
TEST("Vector2::Clamp", []
{
Vector2 Input (0, 20);
Vector2 Minimum ( 2, 2);
Vector2 Maximum (16, 16);
Vector2 ExpectedResult (2, 16);
jtest::check(Input.Clamp(Minimum, Maximum) == ExpectedResult);
});
TEST("Vector2::DotProduct", []
{
Vector2 A (2, 2);
Vector2 B (1, 1);
jtest::check(A.Dot(B) == 4.f);
});
TEST("Vector2::Project", []
{
Vector2 Base (4, 4);
Vector2 Projected (1, 0);
Vector2 ExpectedResult (4, 0);
jtest::check(Base.Project(Projected) == ExpectedResult);
});
TEST("Vector2::Normalize", []
{
Vector2 A(2, 0);
Vector2 B(1, 0);
jtest::check(A.Normalized() == B);
});
TEST("Vector2::Lerp", []
{
Vector2 A (2,2);
Vector2 B (10, 10);
Vector2 C (6, 6);
jtest::check(A.Lerp(B, 0.f) == A);
jtest::check(A.Lerp(B, 1.f) == B);
jtest::check(A.Lerp(B, 0.5f) == C);
});
TEST("Vector2::AngleBetween", []
{
Vector2 A (0.5f, 0.5);
Vector2 B (0.5f, 0.1f);
A = A.Normalized();
B = B.Normalized();
// TODO: AngleBetween returns not a number
// TODO: implement jtest::check_float_eq
jtest::check(A.AngleBetween(B) == 0.58800244);
});
return 0;
}

View File

@@ -1,198 +0,0 @@
#include <gtest/gtest.h>
#include <J3ML/LinearAlgebra/Vector3.h>
using J3ML::LinearAlgebra::Vector3;
void EXPECT_V3_EQ(const Vector3& lhs, const Vector3& rhs)
{
EXPECT_FLOAT_EQ(lhs.x, rhs.x);
EXPECT_FLOAT_EQ(lhs.y, rhs.y);
EXPECT_FLOAT_EQ(lhs.z, rhs.z);
}
TEST(Vector3Test, V3_Constructor_Default)
{
EXPECT_V3_EQ(Vector3(), Vector3::Zero);
}
TEST(Vector3Test, V3_Constructor_XYZ)
{
Vector3 Input {0, 1, 0};
EXPECT_V3_EQ(Input, Vector3::Down);
}
TEST(Vector3Test, V3_Addition_Op) {
Vector3 A {1,1,1};
Vector3 B {2,2,2};
Vector3 ExpectedResult {3,3,3};
EXPECT_V3_EQ(A + B, ExpectedResult);
}
TEST(Vector3Test, V3_Addition_Method) {
Vector3 A {1,1,1};
Vector3 B {2,2,2};
Vector3 ExpectedResult {3,3,3};
EXPECT_V3_EQ(A.Add(B), ExpectedResult);
}
TEST(Vector3Test, V3_Addition_Static) {
Vector3 A {1,1,1};
Vector3 B {3,3,3};
Vector3 ExpectedResult {4,4,4};
EXPECT_V3_EQ(Vector3::Add(A, B), ExpectedResult);
}
TEST(Vector3Test, V3_Subtract_Op) {
Vector3 A {2,2,2};
Vector3 B {.5f, .5f, .5f};
Vector3 ExpectedResult {1.5f, 1.5f, 1.5f};
EXPECT_V3_EQ(A - B, ExpectedResult);
}
TEST(Vector3Test, V3_Subtract_Method) {
Vector3 A {3,3,3};
Vector3 B {1,1,1};
Vector3 ExpectedResult {2,2,2};
EXPECT_V3_EQ(A.Sub(B), ExpectedResult);
}
TEST(Vector3Test, V3_Subtract_Static) {
Vector3 A {4,4,4};
Vector3 B {1,1,1};
Vector3 ExpectedResult {3,3,3};
EXPECT_V3_EQ(Vector3::Sub(A, B), ExpectedResult);
}
TEST(Vector3Test, V3_Scalar_Mult_Op) {
Vector3 A { 1,1,1};
float B = 1.5f;
Vector3 ExpectedResult {1.5f, 1.5f, 1.5f};
EXPECT_V3_EQ(A * B, ExpectedResult);
}
TEST(Vector3Test, V3_Scalar_Mult_Method) {
Vector3 A {3,3,3};
float B = 1.5f;
Vector3 ExpectedResult {4.5f, 4.5f, 4.5f};
EXPECT_V3_EQ(A.Mul(B), ExpectedResult);
}
TEST(Vector3Test, V3_Scalar_Mult_Static) {
Vector3 A {2,2,2};
float B = 1.5f;
Vector3 ExpectedResult {3.f, 3.f, 3.f};
EXPECT_V3_EQ(Vector3::Mul(A, B), ExpectedResult);
}
TEST(Vector3Test, V3_Scalar_Div_Op) {
Vector3 A {4,4,4};
float B = 2.f;
Vector3 ExpectedResult {2,2,2};
EXPECT_V3_EQ(A / B, ExpectedResult);
}
TEST(Vector3Test, V3_Scalar_Div_Method) {
Vector3 A {6,6,6};
float B = 2.f;
Vector3 ExpectedResult { 3,3,3};
EXPECT_V3_EQ(A.Div(B), ExpectedResult);
}
TEST(Vector3Test, V3_Scalar_Div_Static) {
Vector3 A {3,3,3};
float B = 1.5f;
Vector3 ExpectedResult { 2.f, 2.f, 2.f};
EXPECT_V3_EQ(Vector3::Div(A, B), ExpectedResult);
}
TEST(Vector3Test, V3_Sizeof) {
EXPECT_EQ(sizeof(Vector3), 12);
}
TEST(Vector3Test, V3_NaN) {
EXPECT_NE(Vector3(0, 0, 0), Vector3::NaN);
}
TEST(Vector3Test, V3_Min) {
Vector3 Input {2,2,2};
Vector3 Minimum {3,3,3};
Vector3 ExpectedResult {2,2,2};
EXPECT_V3_EQ(Input.Min(Minimum), ExpectedResult);
}
TEST(Vector3Test, V3_Max) {
Vector3 Input {2,2,2};
Vector3 Maximum {3,3,3};
Vector3 ExpectedResult {3,3,3};
EXPECT_V3_EQ(Input.Max(Maximum), ExpectedResult);
}
TEST(Vector3Test, V3_Clamp) {
Vector3 Input {5,-1,8};
Vector3 Minimum {1,1,1};
Vector3 Maximum {5,5,5};
Vector3 ExpectedResult {5,1,5};
EXPECT_V3_EQ(Input.Clamp(Minimum, Maximum), ExpectedResult);
}
TEST(Vector3Test, V3_DotProduct) {
Vector3 A{6,6,6};
Vector3 B{1,1,1};
float ExpectedResult = 18;
EXPECT_FLOAT_EQ(A.Dot(B), ExpectedResult);
}
TEST(Vector3Test, V3_CrossProduct) {
Vector3 A{1,1,1};
Vector3 B{2,2,2};
Vector3 ExpectedResult {0,0,0};
EXPECT_V3_EQ(A.Cross(B), ExpectedResult);
}
TEST(Vector3Test, V3_Project) {
Vector3 Base {};
Vector3 Projection {};
Vector3 ExpectedResult {};
}
TEST(Vector3Test, V3_Normalize) {
Vector3 Input {2, 0, 0};
Vector3 ExpectedResult {1, 0, 0};
EXPECT_V3_EQ(Input.Normalized(), ExpectedResult);
}
TEST(Vector3Test, V3_Lerp)
{
Vector3 Start {};
Vector3 Finish {};
float Percent = 50;
Vector3 ExpectedResult {};
EXPECT_V3_EQ(Start.Lerp(Finish, Percent), ExpectedResult);
}
TEST(Vector3Test, V3_AngleBetween) {
using J3ML::LinearAlgebra::Angle2D;
Vector3 A{ .5f, .5f, .5f};
Vector3 B {.25f, .75f, .25f};
A = A.Normalized();
B = B.Normalized();
Angle2D ExpectedResult {-0.69791365, -2.3561945};
std::cout << A.AngleBetween(B).x << ", " << A.AngleBetween(B).y << "";
auto angle = A.AngleBetween(B);
EXPECT_FLOAT_EQ(angle.x, ExpectedResult.x);
EXPECT_FLOAT_EQ(angle.y, ExpectedResult.y);
}

View File

@@ -0,0 +1,208 @@
#include <J3ML/LinearAlgebra/Vector3.h>
using J3ML::LinearAlgebra::Vector3;
inline void EXPECT_V3_EQ(const Vector3& lhs, const Vector3& rhs)
{
jtest::check(lhs.x == rhs.x);
jtest::check(lhs.y == rhs.y);
jtest::check(lhs.z == rhs.z);
}
int Vector3Tests() {
TEST("Vector3::Ctor_Default", []
{
EXPECT_V3_EQ(Vector3(), Vector3::Zero);
});
TEST("Vector3::Ctor_XYZ", []
{
Vector3 Input (0, 1, 0);
EXPECT_V3_EQ(Input, Vector3::Down);
});
TEST("Vector3::Addition_Op", [] {
Vector3 A (1,1,1);
Vector3 B (2,2,2);
Vector3 ExpectedResult (3,3,3);
EXPECT_V3_EQ(A + B, ExpectedResult);
});
TEST("Vector3::Addition_Method", [] {
Vector3 A (1,1,1);
Vector3 B (2,2,2);
Vector3 ExpectedResult (3,3,3);
EXPECT_V3_EQ(A.Add(B), ExpectedResult);
});
TEST("Vector3::Addition_Static", [] {
Vector3 A (1,1,1);
Vector3 B (3,3,3);
Vector3 ExpectedResult (4,4,4);
EXPECT_V3_EQ(Vector3::Add(A, B), ExpectedResult);
});
TEST("Vector3::Subtract_Op", [] {
Vector3 A (2,2,2);
Vector3 B (.5f, .5f, .5f);
Vector3 ExpectedResult (1.5f, 1.5f, 1.5f);
EXPECT_V3_EQ(A - B, ExpectedResult);
});
TEST("Vector3::Subtract_Method", [] {
Vector3 A (3,3,3);
Vector3 B (1,1,1);
Vector3 ExpectedResult (2,2,2);
EXPECT_V3_EQ(A.Sub(B), ExpectedResult);
});
TEST("Vector3Test, V3_Subtract_Static", [] {
Vector3 A (4,4,4);
Vector3 B (1,1,1);
Vector3 ExpectedResult (3,3,3);
EXPECT_V3_EQ(Vector3::Sub(A, B), ExpectedResult);
});
TEST("Vector3::Scalar_Mult_Op", [] {
Vector3 A ( 1,1,1);
float B = 1.5f;
Vector3 ExpectedResult (1.5f, 1.5f, 1.5f);
EXPECT_V3_EQ(A * B, ExpectedResult);
});
TEST("Vector3::Scalar_Mult_Method", [] {
Vector3 A (3,3,3);
float B = 1.5f;
Vector3 ExpectedResult (4.5f, 4.5f, 4.5f);
EXPECT_V3_EQ(A.Mul(B), ExpectedResult);
});
TEST("Vector3::Scalar_Mult_Static", [] {
Vector3 A (2,2,2);
float B = 1.5f;
Vector3 ExpectedResult (3.f, 3.f, 3.f);
EXPECT_V3_EQ(Vector3::Mul(A, B), ExpectedResult);
});
TEST("Vector3::Scalar_Div_Op", [] {
Vector3 A (4,4,4);
float B = 2.f;
Vector3 ExpectedResult (2,2,2);
EXPECT_V3_EQ(A / B, ExpectedResult);
});
TEST("Vector3::Scalar_Div_Method", [] {
Vector3 A (6,6,6);
float B = 2.f;
Vector3 ExpectedResult ( 3,3,3);
EXPECT_V3_EQ(A.Div(B), ExpectedResult);
});
TEST("Vector3::Scalar_Div_Static", [] {
Vector3 A (3,3,3);
float B = 1.5f;
Vector3 ExpectedResult ( 2.f, 2.f, 2.f);
EXPECT_V3_EQ(Vector3::Div(A, B), ExpectedResult);
});
TEST("Vector3::Sizeof", [] {
jtest::check(sizeof(Vector3) == 12);
});
TEST("Vector3::NaN", [] {
jtest::check(Vector3(0, 0, 0) != Vector3::NaN);
});
TEST("Vector3::Min", [] {
Vector3 Input (2,2,2);
Vector3 Minimum (3,3,3);
Vector3 ExpectedResult (2,2,2);
EXPECT_V3_EQ(Input.Min(Minimum), ExpectedResult);
});
TEST("Vector3::Max", [] {
Vector3 Input (2,2,2);
Vector3 Maximum (3,3,3);
Vector3 ExpectedResult (3,3,3);
EXPECT_V3_EQ(Input.Max(Maximum), ExpectedResult);
});
TEST("Vector3::Clamp", [] {
Vector3 Input (5,-1,8);
Vector3 Minimum (1,1,1);
Vector3 Maximum (5,5,5);
Vector3 ExpectedResult (5,1,5);
EXPECT_V3_EQ(Input.Clamp(Minimum, Maximum), ExpectedResult);
});
TEST("Vector3::DotProduct", [] {
Vector3 A(6,6,6);
Vector3 B(1,1,1);
float ExpectedResult = 18;
// TODO: Add check_float_eq
jtest::check(A.Dot(B) == ExpectedResult);
});
TEST("Vector3::CrossProduct", [] {
Vector3 A(1,1,1);
Vector3 B(2,2,2);
Vector3 ExpectedResult (0,0,0);
EXPECT_V3_EQ(A.Cross(B), ExpectedResult);
});
TEST("Vector3::Project", [] {
Vector3 Base;
Vector3 Projection;
Vector3 ExpectedResult;
});
TEST("Vector3::Normalize", [] {
Vector3 Input (2, 0, 0);
Vector3 ExpectedResult (1, 0, 0);
EXPECT_V3_EQ(Input.Normalized(), ExpectedResult);
});
TEST("Vector3::Lerp", []
{
Vector3 Start;
Vector3 Finish;
float Percent = 50;
Vector3 ExpectedResult;
EXPECT_V3_EQ(Start.Lerp(Finish, Percent), ExpectedResult);
});
TEST("Vector3::AngleBetween", [] {
using J3ML::LinearAlgebra::Angle2D;
Vector3 A ( .5f, .5f, .5f);
Vector3 B (.25f, .75f, .25f);
A = A.Normalized();
B = B.Normalized();
Angle2D ExpectedResult (-0.69791365, -2.3561945);
//std::cout << A.AngleBetween(B).x << ", " << A.AngleBetween(B).y << "";
auto angle = A.AngleBetween(B);
jtest::check(angle.x == ExpectedResult.x);
jtest::check(angle.y == ExpectedResult.y);
});
return 0;
}

View File

@@ -1,106 +0,0 @@
#include <gtest/gtest.h>
#include <J3ML/LinearAlgebra/Vector4.h>
using Vector4 = J3ML::LinearAlgebra::Vector4;
void EXPECT_V4_EQ(const Vector4& lhs, const Vector4& rhs)
{
}
TEST(Vector4Test, V4_Constructor_Default)
{
EXPECT_V4_EQ(Vector4(), Vector4::Zero);
}
TEST(Vector4Test, V4_Constructor_XYZW)
{
Vector4 Input {0, 1, 0, 1};
EXPECT_FLOAT_EQ(Input.x, 0);
EXPECT_FLOAT_EQ(Input.y, 1);
EXPECT_FLOAT_EQ(Input.z, 0);
EXPECT_FLOAT_EQ(Input.w, 1);
}
TEST(Vector4Test, V4_Addition_Op) {
Vector4 A {1, 1, 1, 1};
Vector4 B {2, 2, 2, 2};
Vector4 ExpectedResult {3, 3, 3, 3};
EXPECT_V4_EQ(A + B, ExpectedResult);
}
TEST(Vector4Test, V4_Addition_Method)
{
}
TEST(Vector4Test, V4_Addition_Static)
{
}
TEST(Vector4Test, V4_Subtract_Op)
{
}
TEST(Vector4Test, V4_Subtract_Method)
{
}
TEST(Vector4Test, V4_Subtract_Static)
{
}
TEST(Vector4Test, V4_Scalar_Mult_Op)
{
}
TEST(Vector4Test, V4_Scalar_Mult_Method)
{
}
TEST(Vector4Test, V4_Scalar_Mult_Static)
{
}
TEST(Vector4Test, V4_Scalar_Div_Op)
{
}
TEST(Vector4Test, V4_Scalar_Div_Method)
{
}
TEST(Vector4Test, V4_Scalar_Div_Static)
{
}
TEST(Vector4Test, V4_Sizeof)
{
}
TEST(Vector4Test, V4_NaN)
{
}
TEST(Vector4Tests, V4_Min) {}
TEST(Vector4Tests, V4_Max) {}
TEST(Vector4Tests, V4_Clamp) {}
TEST(Vector4Tests, V4_DotProduct) {}
TEST(Vector4Tests, V4_CrossProduct) {}
TEST(Vector4Tests, V4_Project) {}
TEST(Vector4Test, V4_Normalize) {}

View File

@@ -0,0 +1,116 @@
#include <J3ML/LinearAlgebra/Vector4.h>
using Vector4 = J3ML::LinearAlgebra::Vector4;
void EXPECT_V4_EQ(const Vector4& lhs, const Vector4& rhs)
{
jtest::check(lhs.x == rhs.x);
jtest::check(lhs.y == rhs.y);
jtest::check(lhs.z == rhs.z);
jtest::check(lhs.w == rhs.w);
}
int Vector4Tests()
{
TEST("Vector4::Ctor_Default", []
{
EXPECT_V4_EQ(Vector4(), Vector4::Zero);
});
TEST("Vector4::Constructor_XYZW", []
{
Vector4 Input (0, 1, 0, 1);
// TODO: implement jtest::check_float_eq
jtest::check(Input.x == 0);
jtest::check(Input.y == 1);
jtest::check(Input.z == 0);
jtest::check(Input.w == 1);
});
TEST("Vector4::Addition_Op", [] {
Vector4 A (1, 1, 1, 1);
Vector4 B (2, 2, 2, 2);
Vector4 ExpectedResult (3, 3, 3, 3);
EXPECT_V4_EQ(A + B, ExpectedResult);
});
/*TEST(Vector4Test, V4_Addition_Method)
{
}
TEST(Vector4Test, V4_Addition_Static)
{
}
TEST(Vector4Test, V4_Subtract_Op)
{
}
TEST(Vector4Test, V4_Subtract_Method)
{
}
TEST(Vector4Test, V4_Subtract_Static)
{
}
TEST(Vector4Test, V4_Scalar_Mult_Op)
{
}
TEST(Vector4Test, V4_Scalar_Mult_Method)
{
}
TEST(Vector4Test, V4_Scalar_Mult_Static)
{
}
TEST(Vector4Test, V4_Scalar_Div_Op)
{
}
TEST(Vector4Test, V4_Scalar_Div_Method)
{
}
TEST(Vector4Test, V4_Scalar_Div_Static)
{
}
TEST(Vector4Test, V4_Sizeof)
{
}
TEST(Vector4Test, V4_NaN)
{
}
TEST(Vector4Tests, V4_Min) {}
TEST(Vector4Tests, V4_Max) {}
TEST(Vector4Tests, V4_Clamp) {}
TEST(Vector4Tests, V4_DotProduct) {}
TEST(Vector4Tests, V4_CrossProduct) {}
TEST(Vector4Tests, V4_Project) {}
TEST(Vector4Test, V4_Normalize) {}*/
return 0;
}