General bug fixes (#142)
* Core/Bitset: Fix TestAll method * Fix documentation * Fix color and their conversions * Core/ByteStream: Fix return of Write * Fix compiler warnings * Math/Algorithm: Fix angle normalization * Math/BoundingVolume: Fix lerp * Math: Fix relation between Matrix4 and Quaternion * More tests * X11/Window: Fix mouse moved event generated when doing Mouse::SetPosition * Update ChangeLog * Should fix compilation on Windows * Should fix compilation on Windows Forgot to include array for Windows
This commit is contained in:
committed by
Jérôme Leclercq
parent
f2506ee918
commit
f991a9529e
@@ -30,9 +30,63 @@ TEST_CASE("Apply", "[CORE][ALGORITHM]")
|
||||
|
||||
TEST_CASE("ComputeHash", "[CORE][ALGORITHM]")
|
||||
{
|
||||
SECTION("Compute hash of '0'")
|
||||
/*SECTION("Compute CRC32 of '1234'")
|
||||
{
|
||||
auto result = Nz::ComputeHash(Nz::HashType_CRC32, "1234");
|
||||
REQUIRE(result.ToHex().ToUpper() == "596A3B55");
|
||||
}
|
||||
|
||||
SECTION("Compute CRC64 of '1234'")
|
||||
{
|
||||
auto result = Nz::ComputeHash(Nz::HashType_CRC64, "1234");
|
||||
REQUIRE(result.ToHex().ToUpper() == "33302B9FC23855A8");
|
||||
}
|
||||
|
||||
SECTION("Compute Fletcher16 of '1234'")
|
||||
{
|
||||
auto result = Nz::ComputeHash(Nz::HashType_Fletcher16, "1234");
|
||||
REQUIRE(result.ToHex().ToUpper() == "F5CA");
|
||||
}*/
|
||||
|
||||
SECTION("Compute MD5 of '1234'")
|
||||
{
|
||||
auto result = Nz::ComputeHash(Nz::HashType_MD5, "1234");
|
||||
REQUIRE(result.ToHex().ToUpper() == "81DC9BDB52D04DC20036DBD8313ED055");
|
||||
}
|
||||
|
||||
SECTION("Compute SHA1 of '1234'")
|
||||
{
|
||||
auto result = Nz::ComputeHash(Nz::HashType_SHA1, "1234");
|
||||
REQUIRE(result.ToHex().ToUpper() == "7110EDA4D09E062AA5E4A390B0A572AC0D2C0220");
|
||||
}
|
||||
|
||||
SECTION("Compute SHA224 of '1234'")
|
||||
{
|
||||
auto result = Nz::ComputeHash(Nz::HashType_SHA224, "1234");
|
||||
REQUIRE(result.ToHex().ToUpper() == "99FB2F48C6AF4761F904FC85F95EB56190E5D40B1F44EC3A9C1FA319");
|
||||
}
|
||||
|
||||
SECTION("Compute SHA256 of '1234'")
|
||||
{
|
||||
auto result = Nz::ComputeHash(Nz::HashType_SHA256, "1234");
|
||||
REQUIRE(result.ToHex().ToUpper() == "03AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4");
|
||||
}
|
||||
|
||||
SECTION("Compute SHA384 of '1234'")
|
||||
{
|
||||
auto result = Nz::ComputeHash(Nz::HashType_SHA384, "1234");
|
||||
REQUIRE(result.ToHex().ToUpper() == "504F008C8FCF8B2ED5DFCDE752FC5464AB8BA064215D9C5B5FC486AF3D9AB8C81B14785180D2AD7CEE1AB792AD44798C");
|
||||
}
|
||||
|
||||
SECTION("Compute SHA512 of '1234'")
|
||||
{
|
||||
auto result = Nz::ComputeHash(Nz::HashType_SHA512, "1234");
|
||||
REQUIRE(result.ToHex().ToUpper() == "D404559F602EAB6FD602AC7680DACBFAADD13630335E951F097AF3900E9DE176B6DB28512F2E000B9D04FBA5133E8B1C6E8DF59DB3A8AB9D60BE4B97CC9E81DB");
|
||||
}
|
||||
|
||||
SECTION("Compute Whirlpool of '1234'")
|
||||
{
|
||||
auto result = Nz::ComputeHash(Nz::HashType_Whirlpool, "1234");
|
||||
REQUIRE(result.ToHex().ToUpper() == "2F9959B230A44678DD2DC29F037BA1159F233AA9AB183CE3A0678EAAE002E5AA6F27F47144A1A4365116D3DB1B58EC47896623B92D85CB2F191705DAF11858B8");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
template<typename Block> void Check(const char* title);
|
||||
template<typename Block> void CheckAppend(const char* title);
|
||||
template<typename Block> void CheckBitOps(const char* title);
|
||||
template<typename Block> void CheckBitOpsMultipleBlocks(const char* title);
|
||||
template<typename Block> void CheckConstructor(const char* title);
|
||||
template<typename Block> void CheckCopyMoveSwap(const char* title);
|
||||
template<typename Block> void CheckRead(const char* title);
|
||||
@@ -28,6 +29,7 @@ void Check(const char* title)
|
||||
CheckCopyMoveSwap<Block>(title);
|
||||
|
||||
CheckBitOps<Block>(title);
|
||||
CheckBitOpsMultipleBlocks<Block>(title);
|
||||
|
||||
CheckAppend<Block>(title);
|
||||
CheckRead<Block>(title);
|
||||
@@ -111,7 +113,68 @@ void CheckBitOps(const char* title)
|
||||
{
|
||||
CHECK(andBitset == Nz::Bitset<Block>("00001"));
|
||||
CHECK(orBitset == Nz::Bitset<Block>("11111"));
|
||||
CHECK(orBitset.TestAll());
|
||||
CHECK(xorBitset == Nz::Bitset<Block>("11110"));
|
||||
CHECK(!xorBitset.TestAll());
|
||||
CHECK((~orBitset).TestNone());
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We perform bit shifts")
|
||||
{
|
||||
first.ShiftLeft(1);
|
||||
second.ShiftRight(2);
|
||||
|
||||
THEN("We should obtain these")
|
||||
{
|
||||
CHECK(first == Nz::Bitset<Block>("10010"));
|
||||
CHECK(second == Nz::Bitset<Block>("101"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Block>
|
||||
void CheckBitOpsMultipleBlocks(const char* title)
|
||||
{
|
||||
SECTION(title)
|
||||
{
|
||||
GIVEN("Two bitsets")
|
||||
{
|
||||
Nz::Bitset<Block> first("01001011010010101001010011010101001");
|
||||
Nz::Bitset<Block> second("10111111101101110110111101101110110");
|
||||
|
||||
WHEN("We perform operators")
|
||||
{
|
||||
Nz::Bitset<Block> andBitset = first & second;
|
||||
Nz::Bitset<Block> orBitset = first | second;
|
||||
Nz::Bitset<Block> xorBitset = first ^ second;
|
||||
|
||||
THEN("They should operate as logical operators")
|
||||
{
|
||||
CHECK(andBitset == Nz::Bitset<Block>("00001011000000100000010001000100000"));
|
||||
CHECK(orBitset == Nz::Bitset<Block>("11111111111111111111111111111111111"));
|
||||
CHECK(orBitset.TestAll());
|
||||
CHECK(xorBitset == Nz::Bitset<Block>("11110100111111011111101110111011111"));
|
||||
CHECK(!xorBitset.TestAll());
|
||||
CHECK((~orBitset).TestNone());
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We perform bit shifts")
|
||||
{
|
||||
first.ShiftLeft(16);
|
||||
second.ShiftRight(16);
|
||||
|
||||
THEN("We should obtain these")
|
||||
{
|
||||
CHECK(first == Nz::Bitset<Block>("10010100110101010010000000000000000"));
|
||||
first.ShiftLeft(1);
|
||||
CHECK(first == Nz::Bitset<Block>("00101001101010100100000000000000000"));
|
||||
CHECK(second == Nz::Bitset<Block>("1011111110110111011"));
|
||||
second.ShiftRight(1);
|
||||
CHECK(second == Nz::Bitset<Block>("101111111011011101"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
73
tests/Engine/Core/ByteStream.cpp
Normal file
73
tests/Engine/Core/ByteStream.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#include <Nazara/Core/ByteStream.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
SCENARIO("ByteStream", "[CORE][BYTESTREAM]")
|
||||
{
|
||||
GIVEN("A bytestream from a bunch of bytes")
|
||||
{
|
||||
const int numberOfBytes = 16;
|
||||
std::array<Nz::Int8, numberOfBytes> data;
|
||||
|
||||
Nz::ByteStream byteStream(data.data(), numberOfBytes);
|
||||
|
||||
WHEN("We write some data in it")
|
||||
{
|
||||
int value = 5;
|
||||
byteStream << value;
|
||||
Nz::String string = "string";
|
||||
byteStream << string;
|
||||
|
||||
byteStream.FlushBits();
|
||||
|
||||
THEN("We can retrieve them")
|
||||
{
|
||||
const void* const ptrData = data.data();
|
||||
Nz::ByteStream readStream;
|
||||
CHECK(readStream.GetSize() == 0);
|
||||
readStream = Nz::ByteStream(ptrData, byteStream.GetSize());
|
||||
int retrievedValue = 0;
|
||||
readStream >> retrievedValue;
|
||||
Nz::String retrievedString;
|
||||
readStream >> retrievedString;
|
||||
|
||||
CHECK(value == retrievedValue);
|
||||
CHECK(string == retrievedString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A bytestream with a byte array and a different endianness")
|
||||
{
|
||||
const int numberOfBytes = 16;
|
||||
Nz::ByteArray byteArray(numberOfBytes);
|
||||
Nz::ByteStream byteStream(&byteArray);
|
||||
|
||||
byteStream.SetDataEndianness(Nz::GetPlatformEndianness() == Nz::Endianness_BigEndian ? Nz::Endianness_LittleEndian : Nz::Endianness_BigEndian);
|
||||
|
||||
WHEN("We write an integer")
|
||||
{
|
||||
int value = 7;
|
||||
byteStream.Write(&value, sizeof(int));
|
||||
bool boolean = true;
|
||||
byteStream << boolean;
|
||||
byteStream.FlushBits();
|
||||
|
||||
THEN("We can retrieve it properly")
|
||||
{
|
||||
Nz::ByteStream tmpStream(&byteArray);
|
||||
tmpStream.SetDataEndianness(byteStream.GetDataEndianness());
|
||||
|
||||
int retrievedValue = 0;
|
||||
tmpStream.Read(&retrievedValue, sizeof(int));
|
||||
CHECK(value == retrievedValue);
|
||||
|
||||
Nz::ByteStream readStream(std::move(tmpStream));
|
||||
bool retrievedBoolean = false;
|
||||
readStream >> retrievedBoolean;
|
||||
CHECK(boolean == retrievedBoolean);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,24 +6,43 @@ SCENARIO("Clock", "[CORE][CLOCK]")
|
||||
{
|
||||
GIVEN("A clock paused")
|
||||
{
|
||||
Nz::UInt64 initialTime = 1;
|
||||
Nz::UInt64 initialTime = 100;
|
||||
Nz::Clock clock(initialTime, true);
|
||||
|
||||
WHEN("We get time")
|
||||
WHEN("We get time since it is paused")
|
||||
{
|
||||
THEN("Time must be the initialTime")
|
||||
{
|
||||
REQUIRE(clock.GetMicroseconds() == initialTime);
|
||||
CHECK(clock.GetMicroseconds() == initialTime);
|
||||
CHECK(clock.IsPaused());
|
||||
}
|
||||
}
|
||||
|
||||
AND_WHEN("We unpause it")
|
||||
WHEN("We unpause it")
|
||||
{
|
||||
clock.Unpause();
|
||||
REQUIRE(!clock.IsPaused());
|
||||
|
||||
THEN("Time must not be the initialTime")
|
||||
{
|
||||
clock.Unpause();
|
||||
THEN("Time must not be the initialTime")
|
||||
{
|
||||
Nz::Thread::Sleep(1);
|
||||
REQUIRE(clock.GetMicroseconds() != initialTime);
|
||||
}
|
||||
Nz::Thread::Sleep(1);
|
||||
Nz::UInt64 microSeconds = clock.GetMicroseconds();
|
||||
CHECK(microSeconds != initialTime);
|
||||
CHECK(microSeconds / 1000 <= clock.GetMilliseconds());
|
||||
CHECK(microSeconds / (1000.f * 1000.f) <= clock.GetSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We restart it")
|
||||
{
|
||||
clock.Restart();
|
||||
|
||||
THEN("It is unpaused and we can pause it")
|
||||
{
|
||||
CHECK(!clock.IsPaused());
|
||||
clock.Pause();
|
||||
CHECK(clock.IsPaused());
|
||||
CHECK(clock.GetMicroseconds() != initialTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,63 @@
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
|
||||
const float epsilon = 0.01f;
|
||||
|
||||
void CompareColor(const Nz::Color& lhs, const Nz::Color& rhs)
|
||||
{
|
||||
Nz::UInt8 tolerance = 3;
|
||||
REQUIRE(Nz::NumberEquals(lhs.r, rhs.r, tolerance));
|
||||
REQUIRE(Nz::NumberEquals(lhs.g, rhs.g, tolerance));
|
||||
REQUIRE(Nz::NumberEquals(lhs.b, rhs.b, tolerance));
|
||||
REQUIRE(Nz::NumberEquals(lhs.a, rhs.a, tolerance));
|
||||
}
|
||||
|
||||
void CompareCMY(const Nz::Color& color, float cyan, float magenta, float yellow)
|
||||
{
|
||||
float retrievedCyan = 0.f, retrievedMagenta = 0.f, retrievedYellow = 0.f;
|
||||
Nz::Color::ToCMY(color, &retrievedCyan, &retrievedMagenta, &retrievedYellow);
|
||||
CHECK(retrievedCyan == Approx(cyan).epsilon(epsilon));
|
||||
CHECK(retrievedMagenta == Approx(magenta).epsilon(epsilon));
|
||||
CHECK(retrievedYellow == Approx(yellow).epsilon(epsilon));
|
||||
}
|
||||
|
||||
void CompareCMYK(const Nz::Color& color, float cyan, float magenta, float yellow, float black)
|
||||
{
|
||||
float retrievedCyan = 0.f, retrievedMagenta = 0.f, retrievedYellow = 0.f, retrievedBlack = 0.f;
|
||||
Nz::Color::ToCMYK(color, &retrievedCyan, &retrievedMagenta, &retrievedYellow, &retrievedBlack);
|
||||
CHECK(retrievedCyan == Approx(cyan).epsilon(epsilon));
|
||||
CHECK(retrievedMagenta == Approx(magenta).epsilon(epsilon));
|
||||
CHECK(retrievedYellow == Approx(yellow).epsilon(epsilon));
|
||||
CHECK(retrievedBlack == Approx(black).epsilon(epsilon));
|
||||
}
|
||||
|
||||
void CompareHSL(const Nz::Color& color, float hue, float saturation, float luminosity)
|
||||
{
|
||||
float retrievedHue = 0.f, retrievedSaturation = 0.f, retrievedLuminosity = 0.f;
|
||||
Nz::Color::ToHSL(color, &retrievedHue, &retrievedSaturation, &retrievedLuminosity);
|
||||
CHECK(retrievedHue == Approx(hue).epsilon(epsilon));
|
||||
CHECK(retrievedSaturation == Approx(saturation).epsilon(epsilon));
|
||||
CHECK(retrievedLuminosity == Approx(luminosity).epsilon(epsilon));
|
||||
}
|
||||
|
||||
void CompareHSV(const Nz::Color& color, float hue, float saturation, float value)
|
||||
{
|
||||
float retrievedHue = 0.f, retrievedSaturation = 0.f, retrievedValue = 0.f;
|
||||
Nz::Color::ToHSV(color, &retrievedHue, &retrievedSaturation, &retrievedValue);
|
||||
CHECK(retrievedHue == Approx(hue).epsilon(epsilon));
|
||||
CHECK(retrievedSaturation == Approx(saturation).epsilon(epsilon));
|
||||
CHECK(retrievedValue == Approx(value).epsilon(epsilon));
|
||||
}
|
||||
|
||||
void CompareXYZ(const Nz::Color& color, float x, float y, float z)
|
||||
{
|
||||
Nz::Vector3f retrievedValues = Nz::Vector3f::Zero();
|
||||
Nz::Color::ToXYZ(color, &retrievedValues);
|
||||
CHECK(retrievedValues.x == Approx(x).epsilon(epsilon));
|
||||
CHECK(retrievedValues.y == Approx(y).epsilon(epsilon));
|
||||
CHECK(retrievedValues.z == Approx(z).epsilon(epsilon));
|
||||
}
|
||||
|
||||
SCENARIO("Color", "[CORE][COLOR]")
|
||||
{
|
||||
GIVEN("Two colors, one red (255) and one gray (128)")
|
||||
@@ -19,4 +76,74 @@ SCENARIO("Color", "[CORE][COLOR]")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A special color in different formats")
|
||||
{
|
||||
struct ColorData
|
||||
{
|
||||
const char* name;
|
||||
Nz::Color rgb;
|
||||
float cyan, magenta, yellow;
|
||||
float cyanK, magentaK, yellowK, black;
|
||||
float hue, saturation, luminosity;
|
||||
float hueV, saturationV, valueV;
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
std::vector<ColorData> colors;
|
||||
|
||||
colors.push_back({
|
||||
"blue",
|
||||
Nz::Color(0, 0, 255),
|
||||
1.f, 1.f, 0.f, // cmy
|
||||
1.f, 1.f, 0.f, 0.f, // cmyk
|
||||
240.f, 1.f, 0.5f, // hsl
|
||||
240.f, 1.f, 1.f, // hsv
|
||||
18.05f, 7.22f, 95.05f // xyz
|
||||
});
|
||||
|
||||
colors.push_back({
|
||||
"white",
|
||||
Nz::Color(255, 255, 255),
|
||||
0.f, 0.f, 0.f, // cmy
|
||||
0.f, 0.f, 0.f, 0.f, // cmyk
|
||||
0.f, 0.f, 1.f, // hsl
|
||||
0.f, 0.f, 1.f, // hsv
|
||||
95.05f, 100.f, 108.09f // xyz
|
||||
});
|
||||
|
||||
colors.push_back({
|
||||
"greenish",
|
||||
Nz::Color(5, 191, 25),
|
||||
0.980f, 0.251f, 0.902f, // cmy
|
||||
0.974f, 0.000f, 0.869f, 0.251f, // cmyk
|
||||
126.f, 0.95f, 0.38f, // hsl
|
||||
126.f, 0.97f, 0.75f, // hsv
|
||||
18.869f, 37.364f, 7.137f // xyz
|
||||
});
|
||||
|
||||
for (const ColorData& color : colors)
|
||||
{
|
||||
WHEN("We perform conversion for: " + color.name)
|
||||
{
|
||||
THEN("From other color spaces")
|
||||
{
|
||||
CompareColor(color.rgb, Nz::Color::FromCMY(color.cyan, color.magenta, color.yellow));
|
||||
CompareColor(color.rgb, Nz::Color::FromCMYK(color.cyanK, color.magentaK, color.yellowK, color.black));
|
||||
CompareColor(color.rgb, Nz::Color::FromHSL(color.hue, color.saturation, color.luminosity));
|
||||
CompareColor(color.rgb, Nz::Color::FromHSV(color.hueV, color.saturationV, color.valueV));
|
||||
CompareColor(color.rgb, Nz::Color::FromXYZ(Nz::Vector3f(color.x, color.y, color.z)));
|
||||
}
|
||||
|
||||
THEN("To other color spaces")
|
||||
{
|
||||
CompareCMY(color.rgb, color.cyan, color.magenta, color.yellow);
|
||||
CompareCMYK(color.rgb, color.cyanK, color.magentaK, color.yellowK, color.black);
|
||||
CompareHSL(color.rgb, color.hue, color.saturation, color.luminosity);
|
||||
CompareHSV(color.rgb, color.hueV, color.saturationV, color.valueV);
|
||||
CompareXYZ(color.rgb, color.x, color.y, color.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,5 +24,21 @@ SCENARIO("MemoryPool", "[CORE][MEMORYPOOL]")
|
||||
memoryPool.Delete(vector2);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We construct three vectors")
|
||||
{
|
||||
Nz::Vector2<int>* vector1 = memoryPool.New<Nz::Vector2<int>>(1, 2);
|
||||
Nz::Vector2<int>* vector2 = memoryPool.New<Nz::Vector2<int>>(3, 4);
|
||||
Nz::Vector2<int>* vector3 = memoryPool.New<Nz::Vector2<int>>(5, 6);
|
||||
|
||||
THEN("Memory is available")
|
||||
{
|
||||
vector1->x = 3;
|
||||
vector2->y = 5;
|
||||
CHECK(*vector1 == Nz::Vector2<int>(3, 2));
|
||||
CHECK(*vector2 == Nz::Vector2<int>(3, 5));
|
||||
CHECK(vector3->GetSquaredLength() == Approx(61.f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,35 +3,204 @@
|
||||
|
||||
#include <Nazara/Core/String.hpp>
|
||||
|
||||
void nullAction(void*)
|
||||
{
|
||||
}
|
||||
|
||||
SCENARIO("ParameterList", "[CORE][PARAMETERLIST]")
|
||||
{
|
||||
GIVEN("An empty ParameterList")
|
||||
{
|
||||
Nz::ParameterList parameterList;
|
||||
|
||||
WHEN("We add String 'string'")
|
||||
WHEN("We add Bool 'true' and analogous")
|
||||
{
|
||||
bool boolean = true;
|
||||
parameterList.SetParameter("bool", boolean);
|
||||
|
||||
long long intTrue = 1;
|
||||
parameterList.SetParameter("intTrue", intTrue);
|
||||
long long intFalse = 0;
|
||||
parameterList.SetParameter("intFalse", intFalse);
|
||||
|
||||
Nz::String strTrue = "true";
|
||||
parameterList.SetParameter("strTrue", strTrue);
|
||||
Nz::String strFalse = "false";
|
||||
parameterList.SetParameter("strFalse", strFalse);
|
||||
|
||||
THEN("We can get it back")
|
||||
{
|
||||
bool retrievedValue = false;
|
||||
CHECK(parameterList.GetBooleanParameter("bool", &retrievedValue));
|
||||
CHECK(retrievedValue == boolean);
|
||||
}
|
||||
|
||||
THEN("Conversion from int to bool should also work")
|
||||
{
|
||||
bool retrievedValue = false;
|
||||
CHECK(parameterList.GetBooleanParameter("intTrue", &retrievedValue));
|
||||
CHECK(retrievedValue);
|
||||
CHECK(parameterList.GetBooleanParameter("intFalse", &retrievedValue));
|
||||
CHECK(!retrievedValue);
|
||||
}
|
||||
|
||||
THEN("Conversion from str to bool should also work")
|
||||
{
|
||||
bool retrievedValue = false;
|
||||
CHECK(parameterList.GetBooleanParameter("strTrue", &retrievedValue));
|
||||
CHECK(retrievedValue);
|
||||
CHECK(parameterList.GetBooleanParameter("strFalse", &retrievedValue));
|
||||
CHECK(!retrievedValue);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We add Color 'rgb(1, 2, 3)'")
|
||||
{
|
||||
Nz::Color rgb(1, 2, 3);
|
||||
parameterList.SetParameter("color", rgb);
|
||||
|
||||
THEN("We can get it back")
|
||||
{
|
||||
Nz::Color retrievedColor;
|
||||
CHECK(parameterList.GetColorParameter("color", &retrievedColor));
|
||||
CHECK(retrievedColor == rgb);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We add Double '3.0' and analogous")
|
||||
{
|
||||
double fl = 3.0;
|
||||
parameterList.SetParameter("double", fl);
|
||||
|
||||
long long intDouble = 3;
|
||||
parameterList.SetParameter("intDouble", intDouble);
|
||||
|
||||
Nz::String strDouble = "3.0";
|
||||
parameterList.SetParameter("strDouble", strDouble);
|
||||
|
||||
THEN("We can get it back")
|
||||
{
|
||||
double retrievedValue;
|
||||
CHECK(parameterList.GetDoubleParameter("double", &retrievedValue));
|
||||
CHECK(retrievedValue == fl);
|
||||
}
|
||||
|
||||
THEN("Conversion from int to double should also work")
|
||||
{
|
||||
double retrievedValue;
|
||||
CHECK(parameterList.GetDoubleParameter("intDouble", &retrievedValue));
|
||||
CHECK(retrievedValue == fl);
|
||||
}
|
||||
|
||||
THEN("Conversion from string to double should also work")
|
||||
{
|
||||
double retrievedValue;
|
||||
CHECK(parameterList.GetDoubleParameter("strDouble", &retrievedValue));
|
||||
CHECK(retrievedValue == fl);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We add Int '3' and analogous")
|
||||
{
|
||||
long long i = 3;
|
||||
parameterList.SetParameter("int", i);
|
||||
|
||||
bool trueInt = 1;
|
||||
parameterList.SetParameter("trueInt", trueInt);
|
||||
bool falseInt = 0;
|
||||
parameterList.SetParameter("falseInt", falseInt);
|
||||
|
||||
double doubleInt = 3;
|
||||
parameterList.SetParameter("doubleInt", doubleInt);
|
||||
|
||||
Nz::String strInt = "3";
|
||||
parameterList.SetParameter("strInt", strInt);
|
||||
|
||||
THEN("We can get it back")
|
||||
{
|
||||
long long retrievedValue;
|
||||
CHECK(parameterList.GetIntegerParameter("int", &retrievedValue));
|
||||
CHECK(retrievedValue == i);
|
||||
}
|
||||
|
||||
THEN("Conversion from bool to int should also work")
|
||||
{
|
||||
long long retrievedValue;
|
||||
CHECK(parameterList.GetIntegerParameter("trueInt", &retrievedValue));
|
||||
CHECK(retrievedValue == trueInt);
|
||||
CHECK(parameterList.GetIntegerParameter("falseInt", &retrievedValue));
|
||||
CHECK(retrievedValue == falseInt);
|
||||
}
|
||||
|
||||
THEN("Conversion from double to int should also work")
|
||||
{
|
||||
long long retrievedValue;
|
||||
CHECK(parameterList.GetIntegerParameter("doubleInt", &retrievedValue));
|
||||
CHECK(retrievedValue == i);
|
||||
}
|
||||
|
||||
THEN("Conversion from string to int should also work")
|
||||
{
|
||||
long long retrievedValue;
|
||||
CHECK(parameterList.GetIntegerParameter("strInt", &retrievedValue));
|
||||
CHECK(retrievedValue == i);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We add String 'string' and analogous")
|
||||
{
|
||||
Nz::String string("string");
|
||||
parameterList.SetParameter("string", string);
|
||||
|
||||
bool trueString = 1;
|
||||
parameterList.SetParameter("trueString", trueString);
|
||||
bool falseString = 0;
|
||||
parameterList.SetParameter("falseString", falseString);
|
||||
|
||||
Nz::Color colorString(1, 2, 3);
|
||||
parameterList.SetParameter("colorString", colorString);
|
||||
|
||||
double doubleString = 3.0;
|
||||
parameterList.SetParameter("doubleString", doubleString);
|
||||
|
||||
long long intString = 3;
|
||||
parameterList.SetParameter("intString", intString);
|
||||
|
||||
THEN("We can get it back")
|
||||
{
|
||||
Nz::String newString;
|
||||
REQUIRE(parameterList.GetStringParameter("string", &newString));
|
||||
REQUIRE(newString == string);
|
||||
CHECK(parameterList.GetStringParameter("string", &newString));
|
||||
CHECK(newString == string);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We add Float '3.f'")
|
||||
{
|
||||
double fl = 3.f;
|
||||
parameterList.SetParameter("double", fl);
|
||||
|
||||
THEN("We can get it back")
|
||||
THEN("Conversion from bool to str should also work")
|
||||
{
|
||||
double newFl;
|
||||
REQUIRE(parameterList.GetDoubleParameter("double", &newFl));
|
||||
REQUIRE(newFl == fl);
|
||||
Nz::String retrievedValue;
|
||||
CHECK(parameterList.GetStringParameter("trueString", &retrievedValue));
|
||||
CHECK(retrievedValue == "true");
|
||||
CHECK(parameterList.GetStringParameter("falseString", &retrievedValue));
|
||||
CHECK(retrievedValue == "false");
|
||||
}
|
||||
|
||||
THEN("Conversion from color to string should also work")
|
||||
{
|
||||
Nz::String retrievedValue;
|
||||
CHECK(parameterList.GetStringParameter("colorString", &retrievedValue));
|
||||
CHECK(retrievedValue == colorString.ToString());
|
||||
}
|
||||
|
||||
THEN("Conversion from string to double should also work")
|
||||
{
|
||||
Nz::String retrievedValue;
|
||||
CHECK(parameterList.GetStringParameter("doubleString", &retrievedValue));
|
||||
CHECK(retrievedValue == "3");
|
||||
}
|
||||
|
||||
THEN("Conversion from string to int should also work")
|
||||
{
|
||||
Nz::String retrievedValue;
|
||||
CHECK(parameterList.GetStringParameter("intString", &retrievedValue));
|
||||
CHECK(retrievedValue == "3");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +213,71 @@ SCENARIO("ParameterList", "[CORE][PARAMETERLIST]")
|
||||
THEN("We can get it back")
|
||||
{
|
||||
void* newPtrToStackValue = nullptr;
|
||||
REQUIRE(parameterList.GetPointerParameter("ptr", &newPtrToStackValue));
|
||||
REQUIRE(newPtrToStackValue == ptrToStackValue);
|
||||
CHECK(parameterList.GetPointerParameter("ptr", &newPtrToStackValue));
|
||||
CHECK(newPtrToStackValue == ptrToStackValue);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We set our own data")
|
||||
{
|
||||
struct Data {
|
||||
int i;
|
||||
float f;
|
||||
};
|
||||
|
||||
Data data{ 1, 3.f };
|
||||
parameterList.SetParameter("userData", &data, nullAction);
|
||||
|
||||
THEN("We can get it back")
|
||||
{
|
||||
Data retrievedValue;
|
||||
void* ptrToData = &retrievedValue;
|
||||
|
||||
CHECK(parameterList.GetUserdataParameter("userData", &ptrToData));
|
||||
Data* dataPtr = reinterpret_cast<Data*>(ptrToData);
|
||||
CHECK(dataPtr->i == data.i);
|
||||
CHECK(dataPtr->f == data.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A parameter list with some values")
|
||||
{
|
||||
Nz::ParameterList parameterList;
|
||||
|
||||
long long i = 3;
|
||||
parameterList.SetParameter("i", i);
|
||||
double d = 1.0;
|
||||
parameterList.SetParameter("d", d);
|
||||
|
||||
parameterList.SetParameter("toaster");
|
||||
parameterList.SetParameter("str", "ing");
|
||||
|
||||
WHEN("We remove two elements")
|
||||
{
|
||||
CHECK(parameterList.HasParameter("i"));
|
||||
CHECK(parameterList.HasParameter("toaster"));
|
||||
|
||||
parameterList.RemoveParameter("i");
|
||||
parameterList.RemoveParameter("toaster");
|
||||
|
||||
THEN("They do not exist anymore")
|
||||
{
|
||||
CHECK(!parameterList.HasParameter("i"));
|
||||
CHECK(!parameterList.HasParameter("toaster"));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We copy this list")
|
||||
{
|
||||
Nz::ParameterList copy = parameterList;
|
||||
|
||||
THEN("It has the same elements")
|
||||
{
|
||||
CHECK(parameterList.HasParameter("i"));
|
||||
CHECK(parameterList.HasParameter("d"));
|
||||
CHECK(parameterList.HasParameter("toaster"));
|
||||
CHECK(parameterList.HasParameter("str"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +204,69 @@ TEST_CASE("MultiplyAdd", "[MATH][ALGORITHM]")
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("NormalizeAngle", "[MATH][ALGORITHM]")
|
||||
{
|
||||
SECTION("-90 should be normalized to +270")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-90.f)) == Nz::FromDegrees(270.f));
|
||||
}
|
||||
|
||||
SECTION("-540 should be normalized to +180")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-540.f)) == Nz::FromDegrees(180.f));
|
||||
}
|
||||
|
||||
SECTION("0 should remain 0")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(0.f)) == Nz::FromDegrees(0.f));
|
||||
}
|
||||
|
||||
SECTION("90 should remain 90")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(90.f)) == Nz::FromDegrees(90.f));
|
||||
}
|
||||
|
||||
SECTION("360 should be normalized to 0")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(360.f)) == Nz::FromDegrees(0.f));
|
||||
}
|
||||
|
||||
SECTION("450 should be normalized to 90")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(450.f)) == Nz::FromDegrees(90.f));
|
||||
}
|
||||
|
||||
SECTION("-90 should be normalized to +270")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-90)) == Nz::FromDegrees(270));
|
||||
}
|
||||
|
||||
SECTION("-540 should be normalized to +180")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(-540)) == Nz::FromDegrees(180));
|
||||
}
|
||||
|
||||
SECTION("0 should remain 0")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(0)) == Nz::FromDegrees(0));
|
||||
}
|
||||
|
||||
SECTION("90 should remain 90")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(90)) == Nz::FromDegrees(90));
|
||||
}
|
||||
|
||||
SECTION("360 should be normalized to 0")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(360)) == Nz::FromDegrees(0));
|
||||
}
|
||||
|
||||
SECTION("450 should be normalized to 90")
|
||||
{
|
||||
REQUIRE(Nz::NormalizeAngle(Nz::FromDegrees(450)) == Nz::FromDegrees(90));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("NumberEquals", "[MATH][ALGORITHM]")
|
||||
{
|
||||
SECTION("2.35 and 2.351 should be the same at 0.01")
|
||||
@@ -211,11 +274,16 @@ TEST_CASE("NumberEquals", "[MATH][ALGORITHM]")
|
||||
CHECK(Nz::NumberEquals(2.35, 2.35, 0.01));
|
||||
}
|
||||
|
||||
SECTION("0 and 4 unsigned should be the same at 1")
|
||||
SECTION("0 and 4 unsigned should be the same at 4")
|
||||
{
|
||||
CHECK(Nz::NumberEquals(0U, 4U, 4U));
|
||||
}
|
||||
|
||||
SECTION("1 and -1 signed should be the same at 2")
|
||||
{
|
||||
CHECK(Nz::NumberEquals(1, -1, 2));
|
||||
}
|
||||
|
||||
SECTION("Maximum integer and -1 should not be equal")
|
||||
{
|
||||
CHECK_FALSE(Nz::NumberEquals(std::numeric_limits<int>::max(), -1));
|
||||
@@ -229,6 +297,11 @@ TEST_CASE("NumberEquals", "[MATH][ALGORITHM]")
|
||||
|
||||
TEST_CASE("NumberToString", "[MATH][ALGORITHM]")
|
||||
{
|
||||
SECTION("0 to string")
|
||||
{
|
||||
REQUIRE(Nz::NumberToString(0) == "0");
|
||||
}
|
||||
|
||||
SECTION("235 to string")
|
||||
{
|
||||
REQUIRE(Nz::NumberToString(235) == "235");
|
||||
@@ -265,8 +338,20 @@ TEST_CASE("StringToNumber", "[MATH][ALGORITHM]")
|
||||
REQUIRE(Nz::StringToNumber("-235") == -235);
|
||||
}
|
||||
|
||||
SECTION("235 157 in string")
|
||||
{
|
||||
REQUIRE(Nz::StringToNumber("235 157") == 235157);
|
||||
}
|
||||
|
||||
SECTION("16 in base 16 in string")
|
||||
{
|
||||
REQUIRE(Nz::StringToNumber("10", 16) == 16);
|
||||
}
|
||||
|
||||
SECTION("8 in base 4 in string should not be valid")
|
||||
{
|
||||
bool ok = true;
|
||||
REQUIRE(Nz::StringToNumber("8", 4, &ok) == 0);
|
||||
REQUIRE(!ok);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,5 +114,52 @@ SCENARIO("BoundingVolume", "[MATH][BOUNDINGVOLUME]")
|
||||
REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, centerAndUnit, 0.5f) == result);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We lerp with special cases")
|
||||
{
|
||||
Nz::OrientedBoxf centerAndUnitOBB(0.f, 0.f, 0.f, 1.f, 1.f, 1.f);
|
||||
centerAndUnitOBB.Update(Nz::Matrix4f::Identity());
|
||||
|
||||
Nz::BoundingVolumef centerAndUnit(centerAndUnitOBB);
|
||||
|
||||
Nz::BoundingVolumef nullBoundingVolume(Nz::Extend_Null);
|
||||
Nz::BoundingVolumef infiniteBoundingVolume(Nz::Extend_Infinite);
|
||||
|
||||
THEN("Normal to null should give a smaller volume")
|
||||
{
|
||||
Nz::BoundingVolumef result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f);
|
||||
result.Update(Nz::Matrix4f::Identity());
|
||||
|
||||
REQUIRE(Nz::BoundingVolumef::Lerp(centerAndUnit, nullBoundingVolume, 0.5f) == result);
|
||||
}
|
||||
|
||||
THEN("Normal to infinite should give an infinite volume")
|
||||
{
|
||||
REQUIRE(Nz::BoundingVolumef::Lerp(centerAndUnit, infiniteBoundingVolume, 0.5f) == infiniteBoundingVolume);
|
||||
}
|
||||
|
||||
THEN("Null to normal should give a small volume")
|
||||
{
|
||||
Nz::BoundingVolumef result(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f);
|
||||
result.Update(Nz::Matrix4f::Identity());
|
||||
|
||||
REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, centerAndUnit, 0.5f) == result);
|
||||
}
|
||||
|
||||
THEN("Infinite to normal should give an infinite volume")
|
||||
{
|
||||
REQUIRE(Nz::BoundingVolumef::Lerp(infiniteBoundingVolume, centerAndUnit, 0.5f) == infiniteBoundingVolume);
|
||||
}
|
||||
|
||||
THEN("Infinite to null should give an infinite volume")
|
||||
{
|
||||
REQUIRE(Nz::BoundingVolumef::Lerp(infiniteBoundingVolume, nullBoundingVolume, 0.5f) == infiniteBoundingVolume);
|
||||
}
|
||||
|
||||
THEN("Null to null should give a null volume")
|
||||
{
|
||||
REQUIRE(Nz::BoundingVolumef::Lerp(nullBoundingVolume, nullBoundingVolume, 0.5f) == nullBoundingVolume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,16 @@ SCENARIO("Box", "[MATH][BOX]")
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We ask for the intersection when there are none")
|
||||
{
|
||||
firstCenterAndUnit.Translate(Nz::Vector3f::UnitZ() * 5.f);
|
||||
THEN("We should have a center and unit")
|
||||
{
|
||||
Nz::Boxf thirdCenterAndUnit;
|
||||
CHECK(!firstCenterAndUnit.Intersect(secondCenterAndUnit, &thirdCenterAndUnit));
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We use the constructor of conversion")
|
||||
{
|
||||
THEN("Shouldn't be a problem")
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include <Nazara/Math/Matrix4.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
|
||||
SCENARIO("Matrix4", "[MATH][Matrix4]")
|
||||
#include <array>
|
||||
|
||||
SCENARIO("Matrix4", "[MATH][MATRIX4]")
|
||||
{
|
||||
GIVEN("Two identity matrix")
|
||||
{
|
||||
@@ -20,9 +22,9 @@ SCENARIO("Matrix4", "[MATH][Matrix4]")
|
||||
{
|
||||
THEN("Nz::Vector stay the same")
|
||||
{
|
||||
REQUIRE(firstIdentity.Transform(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit());
|
||||
REQUIRE(firstIdentity.Transform(Nz::Vector3f::Unit()) == Nz::Vector3f::Unit());
|
||||
REQUIRE(firstIdentity.Transform(Nz::Vector4f(1.f, 1.f, 1.f, 1.f)) == Nz::Vector4f(1.f, 1.f, 1.f, 1.f));
|
||||
CHECK(firstIdentity * Nz::Vector2f::Unit() == Nz::Vector2f::Unit());
|
||||
CHECK(firstIdentity * Nz::Vector3f::Unit() == Nz::Vector3f::Unit());
|
||||
CHECK(firstIdentity * Nz::Vector4f(1.f, 1.f, 1.f, 1.f) == Nz::Vector4f(1.f, 1.f, 1.f, 1.f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +32,11 @@ SCENARIO("Matrix4", "[MATH][Matrix4]")
|
||||
{
|
||||
THEN("It keeps being a identity")
|
||||
{
|
||||
REQUIRE(firstIdentity.Concatenate(secondIdentity) == firstIdentity);
|
||||
REQUIRE(firstIdentity.ConcatenateAffine(secondIdentity) == firstIdentity);
|
||||
REQUIRE((firstIdentity * secondIdentity) == firstIdentity);
|
||||
REQUIRE((1.f * firstIdentity) == firstIdentity);
|
||||
REQUIRE(firstIdentity.Inverse() == secondIdentity.InverseAffine());
|
||||
CHECK(firstIdentity.Concatenate(secondIdentity) == firstIdentity);
|
||||
CHECK(firstIdentity.ConcatenateAffine(secondIdentity) == firstIdentity);
|
||||
CHECK((firstIdentity * secondIdentity) == firstIdentity);
|
||||
CHECK((1.f * firstIdentity) == firstIdentity);
|
||||
CHECK(firstIdentity.Inverse() == secondIdentity.InverseAffine());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,8 +67,8 @@ SCENARIO("Matrix4", "[MATH][Matrix4]")
|
||||
{
|
||||
THEN("These results are expected")
|
||||
{
|
||||
REQUIRE(matrix1.GetDeterminant() == Approx(24.f));
|
||||
REQUIRE(matrix2.GetDeterminant() == Approx(-1.f));
|
||||
CHECK(matrix1.GetDeterminant() == Approx(24.f));
|
||||
CHECK(matrix2.GetDeterminant() == Approx(-1.f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,12 +83,12 @@ SCENARIO("Matrix4", "[MATH][Matrix4]")
|
||||
THEN("We get the identity")
|
||||
{
|
||||
Nz::Matrix4f tmp = matrix1 * invMatrix1;
|
||||
REQUIRE(tmp.m32 == Approx(0.f));
|
||||
REQUIRE(tmp.m42 == Approx(0.f));
|
||||
CHECK(tmp.m32 == Approx(0.f));
|
||||
CHECK(tmp.m42 == Approx(0.f));
|
||||
tmp.m32 = 0.f;
|
||||
tmp.m42 = 0.f;
|
||||
REQUIRE(tmp == Nz::Matrix4f::Identity());
|
||||
REQUIRE((matrix2 * invMatrix2) == Nz::Matrix4f::Identity());
|
||||
CHECK(tmp == Nz::Matrix4f::Identity());
|
||||
CHECK((matrix2 * invMatrix2) == Nz::Matrix4f::Identity());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,10 +108,10 @@ SCENARIO("Matrix4", "[MATH][Matrix4]")
|
||||
0.f, -std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
REQUIRE(transformedMatrix == rotation45X);
|
||||
CHECK(transformedMatrix == rotation45X);
|
||||
transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(Nz::FromDegrees(45.f), 0.f, 0.f).ToQuaternion());
|
||||
rotation45X.ApplyTranslation(Nz::Vector3f::Unit());
|
||||
REQUIRE(transformedMatrix == rotation45X);
|
||||
CHECK(transformedMatrix == rotation45X);
|
||||
}
|
||||
|
||||
THEN("Rotation around Y")
|
||||
@@ -120,10 +122,10 @@ SCENARIO("Matrix4", "[MATH][Matrix4]")
|
||||
std::sqrt(2.f) / 2.f, 0.f, std::sqrt(2.f) / 2.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
REQUIRE(transformedMatrix == rotation45Y);
|
||||
CHECK(transformedMatrix == rotation45Y);
|
||||
transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(0.f, Nz::FromDegrees(45.f), 0.f).ToQuaternion());
|
||||
rotation45Y.ApplyTranslation(Nz::Vector3f::Unit());
|
||||
REQUIRE(transformedMatrix == rotation45Y);
|
||||
CHECK(transformedMatrix == rotation45Y);
|
||||
}
|
||||
|
||||
THEN("Rotation around Z")
|
||||
@@ -134,10 +136,172 @@ SCENARIO("Matrix4", "[MATH][Matrix4]")
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
REQUIRE(transformedMatrix == rotation45Z);
|
||||
CHECK(transformedMatrix == rotation45Z);
|
||||
transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(45.f)).ToQuaternion()));
|
||||
rotation45Z.ApplyTranslation(Nz::Vector3f::Unit());
|
||||
REQUIRE(transformedMatrix == rotation45Z);
|
||||
CHECK(transformedMatrix == rotation45Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("An identity matrix")
|
||||
{
|
||||
std::array<float, 16> content{{ 1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f
|
||||
}};
|
||||
|
||||
Nz::Matrix4f identity(content.data());
|
||||
REQUIRE(identity.IsIdentity());
|
||||
|
||||
WHEN("We rotate it from pitch 30")
|
||||
{
|
||||
Nz::Quaternionf rotation(Nz::EulerAnglesf(Nz::FromDegrees(30.f), 0.f, 0.f));
|
||||
identity.ApplyRotation(rotation);
|
||||
|
||||
THEN("We should retrieve it")
|
||||
{
|
||||
REQUIRE(identity.GetRotation() == rotation);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We rotate it from yaw 30")
|
||||
{
|
||||
Nz::Quaternionf rotation(Nz::EulerAnglesf(0.f, Nz::FromDegrees(30.f), 0.f));
|
||||
identity.ApplyRotation(rotation);
|
||||
|
||||
THEN("We should retrieve it")
|
||||
{
|
||||
REQUIRE(identity.GetRotation() == rotation);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We rotate it from roll 30")
|
||||
{
|
||||
Nz::Quaternionf rotation(Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(30.f)));
|
||||
identity.ApplyRotation(rotation);
|
||||
|
||||
THEN("We should retrieve it")
|
||||
{
|
||||
REQUIRE(identity.GetRotation() == rotation);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We rotate it from a strange rotation")
|
||||
{
|
||||
Nz::Quaternionf rotation(Nz::EulerAnglesf(Nz::FromDegrees(10.f), Nz::FromDegrees(20.f), Nz::FromDegrees(30.f)));
|
||||
identity.ApplyRotation(rotation);
|
||||
|
||||
THEN("We should retrieve it")
|
||||
{
|
||||
REQUIRE(identity.GetRotation() == rotation);
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We scale it")
|
||||
{
|
||||
Nz::Vector3f scale(1.f, 2.f, 3.f);
|
||||
Nz::Vector3f squaredScale(scale.x * scale.x, scale.y * scale.y, scale.z * scale.z);
|
||||
identity.ApplyScale(scale);
|
||||
|
||||
THEN("We should retrieve it")
|
||||
{
|
||||
CHECK(identity.GetScale() == scale);
|
||||
CHECK(identity.GetSquaredScale() == squaredScale);
|
||||
}
|
||||
|
||||
AND_THEN("With a rotation")
|
||||
{
|
||||
identity.ApplyRotation(Nz::EulerAnglesf(Nz::FromDegrees(10.f), Nz::FromDegrees(20.f), Nz::FromDegrees(30.f)));
|
||||
Nz::Vector3f retrievedScale = identity.GetScale();
|
||||
CHECK(retrievedScale.x == Approx(scale.x));
|
||||
CHECK(retrievedScale.y == Approx(scale.y));
|
||||
CHECK(retrievedScale.z == Approx(scale.z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("A matrix with a negative determinant")
|
||||
{
|
||||
Nz::Matrix4f negativeDeterminant( -1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
WHEN("We ask information about determinant")
|
||||
{
|
||||
THEN("We expect those to be true")
|
||||
{
|
||||
CHECK(negativeDeterminant.GetDeterminant() == Approx(-1.f));
|
||||
CHECK(!negativeDeterminant.HasScale());
|
||||
CHECK(negativeDeterminant.HasNegativeScale());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("Some transformed matrices")
|
||||
{
|
||||
Nz::Vector3f simpleTranslation = Nz::Vector3f::Zero();
|
||||
Nz::Quaternionf simpleRotation = Nz::Quaternionf::Identity();
|
||||
Nz::Vector3f simpleScale = Nz::Vector3f::Unit();
|
||||
Nz::Matrix4f simple = Nz::Matrix4f::Transform(simpleTranslation, simpleRotation, simpleScale);
|
||||
|
||||
Nz::Vector3f complexTranslation = Nz::Vector3f(-5.f, 7.f, 3.5f);
|
||||
Nz::Quaternionf complexRotation = Nz::EulerAnglesf(Nz::FromDegrees(-22.5f), Nz::FromDegrees(30.f), Nz::FromDegrees(15.f));
|
||||
Nz::Vector3f complexScale = Nz::Vector3f(1.f, 2.f, 0.5f);
|
||||
Nz::Matrix4f complex = Nz::Matrix4f::Transform(complexTranslation, complexRotation, complexScale);
|
||||
|
||||
Nz::Vector3f oppositeTranslation = Nz::Vector3f(-5.f, 7.f, 3.5f);
|
||||
Nz::Quaternionf oppositeRotation = Nz::EulerAnglesf(Nz::FromDegrees(-90.f), Nz::FromDegrees(0.f), Nz::FromDegrees(0.f));
|
||||
Nz::Vector3f oppositeScale = Nz::Vector3f(1.f, 2.f, 0.5f);
|
||||
Nz::Matrix4f opposite = Nz::Matrix4f::Transform(oppositeTranslation, oppositeRotation, oppositeScale);
|
||||
|
||||
WHEN("We retrieve the different components")
|
||||
{
|
||||
THEN("It should be the original ones")
|
||||
{
|
||||
CHECK(simple.GetTranslation() == simpleTranslation);
|
||||
CHECK(simple.GetRotation() == simpleRotation);
|
||||
CHECK(simple.GetScale() == simpleScale);
|
||||
|
||||
/*CHECK(complex.GetTranslation() == complexTranslation);
|
||||
CHECK(complex.GetRotation() == complexRotation);
|
||||
CHECK(complex.GetScale() == complexScale);
|
||||
|
||||
CHECK(opposite.GetTranslation() == oppositeTranslation);
|
||||
CHECK(opposite.GetRotation() == oppositeRotation);
|
||||
CHECK(opposite.GetScale() == oppositeScale);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("Some defined matrix and its opposite")
|
||||
{
|
||||
Nz::Vector3f translation(-5.f, 3.f, 0.5);
|
||||
Nz::Matrix4f initial = Nz::Matrix4f::Translate(translation);
|
||||
Nz::Quaternionf rotation = Nz::EulerAnglesf(Nz::FromDegrees(30.f), Nz::FromDegrees(-90.f), 0.f);
|
||||
initial.ApplyRotation(rotation);
|
||||
|
||||
Nz::Matrix4f simple = Nz::Matrix4f::Transform(-translation, rotation.GetInverse(), Nz::Vector3f::Unit());
|
||||
|
||||
WHEN("We multiply them together")
|
||||
{
|
||||
Nz::Matrix4f result = Nz::Matrix4f::Concatenate(simple, initial);
|
||||
|
||||
THEN("We should get the identity")
|
||||
{
|
||||
Nz::Matrix4f identity = Nz::Matrix4f::Identity();
|
||||
for (int i = 0; i != 4; ++i)
|
||||
{
|
||||
Nz::Vector4f row = result.GetRow(i);
|
||||
Nz::Vector4f column = result.GetColumn(i);
|
||||
for (int j = 0; j != 4; ++j)
|
||||
{
|
||||
CHECK(Nz::NumberEquals(row[j], identity(i, j), 0.00001f));
|
||||
CHECK(Nz::NumberEquals(column[j], identity(i, j), 0.00001f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,13 +173,34 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]")
|
||||
|
||||
WHEN("We get the rotation between two vectors")
|
||||
{
|
||||
Nz::Quaternionf rotationBetweenXY = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitY());
|
||||
|
||||
THEN("The rotation in right-handed is 90 degree on z")
|
||||
{
|
||||
Nz::Quaternionf rotationBetweenXY = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitY());
|
||||
Nz::Quaternionf rotation90Z(Nz::FromDegrees(90.f), Nz::Vector3f::UnitZ());
|
||||
REQUIRE(rotation90Z == rotationBetweenXY);
|
||||
}
|
||||
|
||||
THEN("The rotation in right-handed is 90 degree on y")
|
||||
{
|
||||
Nz::Quaternionf rotationBetweenXZ = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitZ());
|
||||
Nz::Quaternionf rotation90Y(Nz::FromDegrees(-90.f), Nz::Vector3f::UnitY());
|
||||
REQUIRE(rotation90Y == rotationBetweenXZ);
|
||||
}
|
||||
|
||||
THEN("The rotation in right-handed is 90 degree on x")
|
||||
{
|
||||
Nz::Quaternionf rotationBetweenYZ = Nz::Quaternionf::RotationBetween(Nz::Vector3f::UnitY(), Nz::Vector3f::UnitZ());
|
||||
Nz::Quaternionf rotation90X(Nz::FromDegrees(90.f), Nz::Vector3f::UnitX());
|
||||
REQUIRE(rotation90X == rotationBetweenYZ);
|
||||
}
|
||||
|
||||
THEN("The rotation in right-handed is 90 degree on y with non-unit vectors")
|
||||
{
|
||||
Nz::Vector3f origin(1.f, 0.f, 1.f);
|
||||
Nz::Vector3f extremity(-1.f, 0.f, 1.f);
|
||||
Nz::Quaternionf rotation = Nz::Quaternionf::RotationBetween(origin, extremity);
|
||||
REQUIRE(rotation * origin == extremity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ SCENARIO("Rect", "[MATH][RECT]")
|
||||
{
|
||||
THEN("They should be")
|
||||
{
|
||||
REQUIRE(firstCenterAndUnit == secondCenterAndUnit);
|
||||
REQUIRE(firstCenterAndUnit.GetCenter() == secondCenterAndUnit.GetCenter());
|
||||
REQUIRE(firstCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom) == secondCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom));
|
||||
CHECK(firstCenterAndUnit == secondCenterAndUnit);
|
||||
CHECK(firstCenterAndUnit.GetCenter() == secondCenterAndUnit.GetCenter());
|
||||
CHECK(firstCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom) == secondCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom));
|
||||
CHECK(firstCenterAndUnit.IsValid());
|
||||
}
|
||||
}
|
||||
@@ -43,16 +43,24 @@ SCENARIO("Rect", "[MATH][RECT]")
|
||||
{
|
||||
THEN("These results are expected")
|
||||
{
|
||||
REQUIRE(firstCenterAndUnit.GetLengths() == Nz::Vector2f::Unit());
|
||||
REQUIRE(firstCenterAndUnit.GetMaximum() == Nz::Vector2f::Unit());
|
||||
REQUIRE(firstCenterAndUnit.GetMinimum() == Nz::Vector2f::Zero());
|
||||
REQUIRE(firstCenterAndUnit.GetNegativeVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Zero());
|
||||
REQUIRE(firstCenterAndUnit.GetPosition() == Nz::Vector2f::Zero());
|
||||
REQUIRE(firstCenterAndUnit.GetPositiveVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit());
|
||||
CHECK(firstCenterAndUnit.GetLengths() == Nz::Vector2f::Unit());
|
||||
CHECK(firstCenterAndUnit.GetMaximum() == Nz::Vector2f::Unit());
|
||||
CHECK(firstCenterAndUnit.GetMinimum() == Nz::Vector2f::Zero());
|
||||
CHECK(firstCenterAndUnit.GetNegativeVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Zero());
|
||||
CHECK(firstCenterAndUnit.GetPosition() == Nz::Vector2f::Zero());
|
||||
CHECK(firstCenterAndUnit.GetPositiveVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
WHEN("We ask for intersection")
|
||||
{
|
||||
Nz::Rectf intersection;
|
||||
CHECK(firstCenterAndUnit.Intersect(secondCenterAndUnit, &intersection));
|
||||
CHECK(intersection == Nz::Rectf(1.f, 1.f));
|
||||
CHECK(intersection == Nz::Rectf(Nz::Vector2f(1.f, 1.f)));
|
||||
}
|
||||
|
||||
WHEN("We try to lerp")
|
||||
{
|
||||
THEN("Compilation should be fine")
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <Nazara/Math/Vector3.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Math/Vector4.hpp>
|
||||
|
||||
SCENARIO("Vector3", "[MATH][VECTOR3]")
|
||||
@@ -97,4 +98,24 @@ SCENARIO("Vector3", "[MATH][VECTOR3]")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("Two vectors")
|
||||
{
|
||||
Nz::Vector2f unit = Nz::Vector2f::Unit();
|
||||
Nz::Vector3f smaller(-1.f, unit);
|
||||
|
||||
float data[3] = { 1.f, unit.x, unit.y };
|
||||
Nz::Vector3f bigger(data);
|
||||
|
||||
WHEN("We combine divisions and multiplications")
|
||||
{
|
||||
Nz::Vector3f result = smaller / bigger;
|
||||
result *= bigger;
|
||||
|
||||
THEN("We should get the identity")
|
||||
{
|
||||
REQUIRE(result == smaller);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,94 @@ SCENARIO("PhysWorld2D", "[PHYSICS2D][PHYSWORLD2D]")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GIVEN("Three entities, a character, a wall and a trigger zone")
|
||||
{
|
||||
unsigned int CHARACTER_COLLISION_ID = 1;
|
||||
unsigned int WALL_COLLISION_ID = 2;
|
||||
unsigned int TRIGGER_COLLISION_ID = 3;
|
||||
|
||||
Nz::PhysWorld2D world;
|
||||
|
||||
Nz::Rectf characterAABB(0.f, 0.f, 1.f, 1.f);
|
||||
Nz::Collider2DRef characterBox = Nz::BoxCollider2D::New(characterAABB);
|
||||
characterBox->SetCollisionId(CHARACTER_COLLISION_ID);
|
||||
Nz::RigidBody2D character(&world, 1.f, characterBox);
|
||||
character.SetPosition(Nz::Vector2f::Zero());
|
||||
|
||||
Nz::Rectf wallAABB(0.f, 0.f, 1.f, 2.f);
|
||||
Nz::Collider2DRef wallBox = Nz::BoxCollider2D::New(wallAABB);
|
||||
wallBox->SetCollisionId(WALL_COLLISION_ID);
|
||||
Nz::RigidBody2D wall(&world, 0.f, wallBox);
|
||||
wall.SetPosition(Nz::Vector2f(5.f, 0.f));
|
||||
|
||||
Nz::Rectf triggerAABB(0.f, 0.f, 1.f, 1.f);
|
||||
Nz::Collider2DRef triggerBox = Nz::BoxCollider2D::New(triggerAABB);
|
||||
triggerBox->SetTrigger(true);
|
||||
triggerBox->SetCollisionId(TRIGGER_COLLISION_ID);
|
||||
Nz::RigidBody2D trigger(&world, 0.f, triggerBox);
|
||||
trigger.SetPosition(Nz::Vector2f(2.f, 0.f));
|
||||
|
||||
world.Step(0.f);
|
||||
|
||||
int statusTriggerCollision = 0;
|
||||
Nz::PhysWorld2D::Callback characterTriggerCallback;
|
||||
characterTriggerCallback.startCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) -> bool {
|
||||
statusTriggerCollision = statusTriggerCollision | 1 << 0;
|
||||
return true;
|
||||
};
|
||||
characterTriggerCallback.preSolveCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) -> bool {
|
||||
statusTriggerCollision = statusTriggerCollision | 1 << 1;
|
||||
return true;
|
||||
};
|
||||
characterTriggerCallback.postSolveCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) {
|
||||
statusTriggerCollision = statusTriggerCollision | 1 << 2;
|
||||
};
|
||||
characterTriggerCallback.endCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) {
|
||||
statusTriggerCollision = statusTriggerCollision | 1 << 3;
|
||||
};
|
||||
world.RegisterCallbacks(CHARACTER_COLLISION_ID, TRIGGER_COLLISION_ID, characterTriggerCallback);
|
||||
|
||||
int statusWallCollision = 0;
|
||||
Nz::PhysWorld2D::Callback characterWallCallback;
|
||||
characterWallCallback.startCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) -> bool {
|
||||
statusWallCollision = statusWallCollision | 1 << 0;
|
||||
return true;
|
||||
};
|
||||
characterWallCallback.endCallback = [&](Nz::PhysWorld2D&, Nz::RigidBody2D&, Nz::RigidBody2D&, void*) {
|
||||
statusWallCollision = statusWallCollision | 1 << 1;
|
||||
};
|
||||
world.RegisterCallbacks(CHARACTER_COLLISION_ID, WALL_COLLISION_ID, characterWallCallback);
|
||||
|
||||
WHEN("We make our character go towards the wall")
|
||||
{
|
||||
character.SetVelocity(Nz::Vector2f(1.f, 0.f));
|
||||
for (int i = 0; i != 11; ++i)
|
||||
world.Step(0.1f);
|
||||
|
||||
THEN("It should trigger several collisions")
|
||||
{
|
||||
CHECK(statusTriggerCollision == 3);
|
||||
for (int i = 0; i != 20; ++i)
|
||||
world.Step(0.1f);
|
||||
CHECK(statusTriggerCollision == 11);
|
||||
|
||||
CHECK(character.GetPosition().x == Approx(3.1f).epsilon(0.01f));
|
||||
|
||||
for (int i = 0; i != 9; ++i)
|
||||
world.Step(0.1f);
|
||||
CHECK(character.GetPosition().x == Approx(4.f).epsilon(0.01f));
|
||||
world.Step(0.1f);
|
||||
CHECK(character.GetPosition().x == Approx(4.f).epsilon(0.01f));
|
||||
CHECK(statusWallCollision == 1); // It should be close to the wall
|
||||
|
||||
character.SetVelocity(Nz::Vector2f(-2.f, 0.f));
|
||||
for (int i = 0; i != 10; ++i)
|
||||
world.Step(0.1f);
|
||||
CHECK(statusWallCollision == 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Nz::RigidBody2D CreateBody(Nz::PhysWorld2D& world, const Nz::Vector2f& position, bool isMoving, const Nz::Vector2f& lengths)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <NDK/Systems/RenderSystem.hpp>
|
||||
#include <NDK/World.hpp>
|
||||
#include <NDK/Components.hpp>
|
||||
#include <NDK/Systems/PhysicsSystem2D.hpp>
|
||||
#include <Nazara/Graphics/ForwardRenderTechnique.hpp>
|
||||
#include <Nazara/Graphics/Sprite.hpp>
|
||||
#include <Catch/catch.hpp>
|
||||
@@ -62,6 +63,7 @@ SCENARIO("RenderSystem", "[NDK][RenderSystem]")
|
||||
entity->AddComponent<Ndk::CollisionComponent2D>(boxCollider2D);
|
||||
Ndk::PhysicsComponent2D& physicsComponent2D = entity->AddComponent<Ndk::PhysicsComponent2D>();
|
||||
|
||||
world.GetSystem<Ndk::PhysicsSystem2D>().SetFixedUpdateRate(30.f);
|
||||
world.Update(1.f);
|
||||
|
||||
WHEN("We move it")
|
||||
|
||||
Reference in New Issue
Block a user