Migrate from google-test to jtest.
This commit is contained in:
@@ -16,9 +16,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
|||||||
|
|
||||||
# Enable Package Managers
|
# Enable Package Managers
|
||||||
include(cmake/CPM.cmake)
|
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_HEADERS "include/J3ML/*.h" "include/J3ML/*.hpp")
|
||||||
file(GLOB_RECURSE J3ML_SRC "src/J3ML/*.c" "src/J3ML/*.cpp")
|
file(GLOB_RECURSE J3ML_SRC "src/J3ML/*.c" "src/J3ML/*.cpp")
|
||||||
@@ -33,6 +31,16 @@ if (WIN32)
|
|||||||
add_library(J3ML STATIC ${J3ML_SRC})
|
add_library(J3ML STATIC ${J3ML_SRC})
|
||||||
endif()
|
endif()
|
||||||
set_target_properties(J3ML PROPERTIES LINKER_LANGUAGE CXX)
|
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)
|
if(WIN32)
|
||||||
#target_compile_options(J3ML PRIVATE -Wno-multichar)
|
#target_compile_options(J3ML PRIVATE -Wno-multichar)
|
||||||
endif()
|
endif()
|
||||||
@@ -46,6 +54,8 @@ add_subdirectory(tests)
|
|||||||
add_executable(MathDemo main.cpp)
|
add_executable(MathDemo main.cpp)
|
||||||
target_link_libraries(MathDemo ${PROJECT_NAME})
|
target_link_libraries(MathDemo ${PROJECT_NAME})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
#target_compile_options(MathDemo PRIVATE -mwindows)
|
#target_compile_options(MathDemo PRIVATE -mwindows)
|
||||||
endif()
|
endif()
|
@@ -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")
|
|
132
tests/Algorithm/RNGTests.hpp
Normal file
132
tests/Algorithm/RNGTests.hpp
Normal 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;
|
||||||
|
}
|
@@ -1,20 +1,9 @@
|
|||||||
cmake_minimum_required(VERSION 3.18)
|
cmake_minimum_required(VERSION 3.18)
|
||||||
include(FetchContent)
|
|
||||||
|
|
||||||
FetchContent_Declare(
|
file(GLOB_RECURSE TEST_FILES "*.hpp")
|
||||||
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)
|
|
||||||
|
|
||||||
|
add_executable(J3MLTestSuite tests.cpp)
|
||||||
|
|
||||||
file(GLOB_RECURSE TEST_SRC "tests.cpp" "*.cpp")
|
target_include_directories(J3MLTestSuite PUBLIC "include" $TEST_FILES)
|
||||||
add_executable(Test ${TEST_SRC})
|
|
||||||
target_link_libraries(Test PUBLIC J3ML)
|
target_link_libraries(J3MLTestSuite PUBLIC J3ML)
|
||||||
#find_package(GTest REQUIRED)
|
|
||||||
target_link_libraries(Test PRIVATE GTest::GTest)
|
|
||||||
include_directories("include")
|
|
||||||
add_test(NAME "J3MLTestSuite" COMMAND Test)
|
|
@@ -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);
|
|
||||||
}
|
|
||||||
|
|
97
tests/Geometry/TriangleTests.hpp
Normal file
97
tests/Geometry/TriangleTests.hpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -1,3 +1,7 @@
|
|||||||
//
|
//
|
||||||
// Created by josh on 12/26/2023.
|
// Created by josh on 12/26/2023.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
int EulerAngleTests() {
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -1,5 +1,8 @@
|
|||||||
#include <gtest/gtest.h>
|
|
||||||
#include <J3ML/LinearAlgebra/Matrix3x3.h>
|
#include <J3ML/LinearAlgebra/Matrix3x3.h>
|
||||||
|
|
||||||
using namespace J3ML::LinearAlgebra;
|
using namespace J3ML::LinearAlgebra;
|
||||||
|
|
||||||
|
int Matrix2x2Tests() {
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -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));
|
|
||||||
}
|
|
96
tests/LinearAlgebra/Matrix3x3Tests.hpp
Normal file
96
tests/LinearAlgebra/Matrix3x3Tests.hpp
Normal 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;
|
||||||
|
}
|
@@ -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));
|
|
||||||
}
|
|
129
tests/LinearAlgebra/Matrix4x4Tests.hpp
Normal file
129
tests/LinearAlgebra/Matrix4x4Tests.hpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
75
tests/LinearAlgebra/QuaternionTests.hpp
Normal file
75
tests/LinearAlgebra/QuaternionTests.hpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -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);
|
|
||||||
}
|
|
191
tests/LinearAlgebra/Vector2Tests.hpp
Normal file
191
tests/LinearAlgebra/Vector2Tests.hpp
Normal 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;
|
||||||
|
}
|
@@ -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);
|
|
||||||
}
|
|
208
tests/LinearAlgebra/Vector3Tests.hpp
Normal file
208
tests/LinearAlgebra/Vector3Tests.hpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -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) {}
|
|
116
tests/LinearAlgebra/Vector4Tests.hpp
Normal file
116
tests/LinearAlgebra/Vector4Tests.hpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user