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:
Gawaboumga
2017-11-21 12:16:46 +01:00
committed by Jérôme Leclercq
parent f2506ee918
commit f991a9529e
52 changed files with 1287 additions and 272 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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")

View File

@@ -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));
}
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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")

View File

@@ -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);
}
}
}
}