Merge pull request 'Tests & fixes for various parts of Math module' (#137) from tests_math into master
Reviewed-on: https://git.madvoxel.net/OpenVulkano/OpenVulkano/pulls/137 Reviewed-by: Georg Hagen <georg.hagen@madvoxel.com>
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <bit>
|
||||
#include <cassert>
|
||||
#include <cinttypes>
|
||||
|
||||
@@ -98,12 +98,12 @@ namespace OpenVulkano::Math
|
||||
|
||||
[[nodiscard]] bool InBounds(const Math::Vector3f& position) const
|
||||
{
|
||||
return Math::Utils::all(Math::Utils::greaterThanEqual(min, position)) && Math::Utils::all(Math::Utils::lessThanEqual(position, max));
|
||||
return Math::Utils::all(Math::Utils::lessThanEqual(min, position)) && Math::Utils::all(Math::Utils::lessThanEqual(position, max));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool Inside(const Math::Vector3f& position) const
|
||||
{
|
||||
return Math::Utils::all(Math::Utils::greaterThan(min, position)) && Math::Utils::all(Math::Utils::lessThan(position, max));
|
||||
return Math::Utils::all(Math::Utils::lessThan(min, position)) && Math::Utils::all(Math::Utils::lessThan(position, max));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsEmpty() const
|
||||
|
||||
@@ -134,9 +134,9 @@ namespace OpenVulkano
|
||||
operator std::string() const { return Format(); }
|
||||
|
||||
ByteSize operator +(const ByteSize other) const { return bytes + other.bytes; }
|
||||
ByteSize operator -(const ByteSize other) const { return bytes + other.bytes; }
|
||||
ByteSize operator -(const ByteSize other) const { return bytes - other.bytes; }
|
||||
ByteSize operator +(const size_t other) const { return bytes + other; }
|
||||
ByteSize operator -(const size_t other) const { return bytes + other; }
|
||||
ByteSize operator -(const size_t other) const { return bytes - other; }
|
||||
ByteSize& operator =(const size_t other) { bytes = other; return *this; }
|
||||
ByteSize& operator =(const ByteSize other) { bytes = other.bytes; return *this; }
|
||||
ByteSize& operator +=(const size_t other) { bytes += other; return *this; }
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace OpenVulkano::Math
|
||||
|
||||
[[nodiscard]] constexpr bool operator !=(DenseVec3 rhs) const
|
||||
{
|
||||
return data == rhs.data;
|
||||
return data != rhs.data;
|
||||
}
|
||||
|
||||
[[nodiscard]] explicit constexpr operator Math::Vector3i() const
|
||||
|
||||
@@ -30,21 +30,21 @@ namespace OpenVulkano::Math
|
||||
|
||||
RGB10A2(TYPE value = 0) : value(value) {}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_unsigned_v<T> || std::is_signed_v<TYPE>>>
|
||||
template<typename T, typename = std::enable_if_t<std::is_integral_v<TYPE>>>
|
||||
void Set(Vector3<T> vec3)
|
||||
{
|
||||
vec3 &= VALUE_BITMASK;
|
||||
SetUnchecked(vec3);
|
||||
}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_unsigned_v<T> || std::is_signed_v<TYPE>>>
|
||||
template<typename T, typename = std::enable_if_t<std::is_integral_v<TYPE>>>
|
||||
void Set(Vector3_SIMD<T> vec3)
|
||||
{
|
||||
vec3 &= VALUE_BITMASK;
|
||||
SetUnchecked(vec3);
|
||||
}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_unsigned_v<T> || std::is_signed_v<TYPE>>>
|
||||
template<typename T, typename = std::enable_if_t<std::is_integral_v<TYPE>>>
|
||||
void Set(Vector4<T> vec4)
|
||||
{
|
||||
vec4 &= VALUE_BITMASK;
|
||||
@@ -69,19 +69,19 @@ namespace OpenVulkano::Math
|
||||
Set(Math::Vector4<TYPE>(vec4));
|
||||
}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_unsigned_v<T> || std::is_signed_v<TYPE>>>
|
||||
template<typename T, typename = std::enable_if_t<std::is_integral_v<TYPE>>>
|
||||
void const SetUnchecked(Vector3<T>& vec3)
|
||||
{
|
||||
value = vec3.r | vec3.g << 10 | vec3.b << 20 | MAX_ALPHA_VALUE << 30;
|
||||
}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_unsigned_v<T> || std::is_signed_v<TYPE>>>
|
||||
template<typename T, typename = std::enable_if_t<std::is_integral_v<TYPE>>>
|
||||
void SetUnchecked(const Vector3_SIMD<T>& vec3)
|
||||
{
|
||||
value = vec3.r | vec3.g << 10 | vec3.b << 20 | MAX_ALPHA_VALUE << 30;
|
||||
}
|
||||
|
||||
template<typename T, typename = std::enable_if_t<std::is_unsigned_v<T> || std::is_signed_v<TYPE>>>
|
||||
template<typename T, typename = std::enable_if_t<std::is_integral_v<TYPE>>>
|
||||
void SetUnchecked(const Vector4<T>& vec4)
|
||||
{
|
||||
value = vec4.r | vec4.g << 10 | vec4.b << 20 | vec4.a << 30;
|
||||
|
||||
@@ -18,79 +18,61 @@ namespace OpenVulkano::Math
|
||||
uint64_t timestamp;
|
||||
|
||||
public:
|
||||
explicit Timestamp(uint64_t nanos = 0) : timestamp(nanos) {}
|
||||
explicit Timestamp(double seconds) : timestamp(static_cast<uint64_t>(seconds * SECONDS_TO_NANOS)) {}
|
||||
explicit constexpr Timestamp(uint64_t nanos = 0) : timestamp(nanos) {}
|
||||
explicit constexpr Timestamp(double seconds) : timestamp(static_cast<uint64_t>(seconds * SECONDS_TO_NANOS)) {}
|
||||
|
||||
[[nodiscard]] uint64_t GetNanos() const { return timestamp; }
|
||||
[[nodiscard]] double GetSeconds() const { return timestamp * NANOS_TO_SECONDS; }
|
||||
[[nodiscard]] constexpr uint64_t GetNanos() const { return timestamp; }
|
||||
[[nodiscard]] constexpr double GetSeconds() const { return timestamp * NANOS_TO_SECONDS; }
|
||||
|
||||
Timestamp& operator+=(const Timestamp& rhs)
|
||||
constexpr Timestamp& operator+=(const Timestamp& rhs)
|
||||
{
|
||||
timestamp += rhs.timestamp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Timestamp& operator-=(const Timestamp& rhs)
|
||||
constexpr Timestamp& operator-=(const Timestamp& rhs)
|
||||
{
|
||||
timestamp -= rhs.timestamp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Timestamp& operator =(double time)
|
||||
constexpr Timestamp& operator =(double time)
|
||||
{
|
||||
timestamp = Timestamp(time).timestamp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Timestamp& operator =(uint64_t time)
|
||||
constexpr Timestamp& operator =(uint64_t time)
|
||||
{
|
||||
timestamp = time;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr inline bool operator==(const Timestamp& rhs) const { return GetNanos() == rhs.GetNanos(); }
|
||||
|
||||
constexpr inline bool operator!=(const Timestamp& rhs) const { return !(*this == rhs); }
|
||||
|
||||
constexpr inline bool operator<(const Timestamp& rhs) const { return GetNanos() < rhs.GetNanos(); }
|
||||
|
||||
constexpr inline bool operator>(const Timestamp& rhs) const { return rhs < *this; }
|
||||
|
||||
constexpr inline bool operator>=(const Timestamp& rhs) const { return !(*this < rhs); }
|
||||
|
||||
constexpr inline bool operator<=(const Timestamp& rhs) const { return !(rhs < *this); }
|
||||
|
||||
constexpr inline Timestamp operator-(const Timestamp& rhs) const
|
||||
{
|
||||
return Timestamp(GetNanos() - rhs.GetNanos());
|
||||
}
|
||||
|
||||
constexpr inline Timestamp operator+(const Timestamp& rhs) const
|
||||
{
|
||||
return Timestamp(GetNanos() + rhs.GetNanos());
|
||||
}
|
||||
|
||||
constexpr inline double operator/(const Timestamp& rhs) const
|
||||
{
|
||||
return GetNanos() / static_cast<double>(rhs.GetNanos());
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator==(const Timestamp& lhs, const Timestamp& rhs)
|
||||
{
|
||||
return lhs.GetNanos() == rhs.GetNanos();
|
||||
}
|
||||
|
||||
inline bool operator!=(const Timestamp& lhs, const Timestamp& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(const Timestamp& lhs, const Timestamp& rhs)
|
||||
{
|
||||
return lhs.GetNanos() < rhs.GetNanos();
|
||||
}
|
||||
|
||||
inline bool operator>(const Timestamp& lhs, const Timestamp& rhs)
|
||||
{
|
||||
return rhs < lhs;
|
||||
}
|
||||
|
||||
inline bool operator>=(const Timestamp& lhs, const Timestamp& rhs)
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
inline bool operator<=(const Timestamp& lhs, const Timestamp& rhs)
|
||||
{
|
||||
return !(rhs < lhs);
|
||||
}
|
||||
|
||||
inline Timestamp operator-(const Timestamp& lhs, const Timestamp& rhs)
|
||||
{
|
||||
return Timestamp(lhs.GetNanos() - rhs.GetNanos());
|
||||
}
|
||||
|
||||
inline Timestamp operator+(const Timestamp& lhs, const Timestamp& rhs)
|
||||
{
|
||||
return Timestamp(lhs.GetNanos() + rhs.GetNanos());
|
||||
}
|
||||
|
||||
inline double operator/(const Timestamp& lhs, const Timestamp& rhs)
|
||||
{
|
||||
return lhs.GetNanos() / static_cast<double>(rhs.GetNanos());
|
||||
}
|
||||
}
|
||||
156
tests/Math/AABB.cpp
Normal file
156
tests/Math/AABB.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "Math/Math.hpp"
|
||||
#include "Math/AABB.hpp"
|
||||
|
||||
using namespace OpenVulkano::Math;
|
||||
|
||||
TEST_CASE("Default Constructor", "[AABB]")
|
||||
{
|
||||
AABB aabb;
|
||||
REQUIRE(aabb.GetMin() == Vector3f(INFINITY));
|
||||
REQUIRE(aabb.GetMax() == Vector3f(-INFINITY));
|
||||
}
|
||||
|
||||
TEST_CASE("Constructor with min and max", "[AABB]")
|
||||
{
|
||||
Vector3f min(1.0f, 2.0f, 3.0f);
|
||||
Vector3f max(4.0f, 5.0f, 6.0f);
|
||||
AABB aabb(min, max);
|
||||
REQUIRE(aabb.GetMin() == min);
|
||||
REQUIRE(aabb.GetMax() == max);
|
||||
}
|
||||
|
||||
TEST_CASE("Constructor with single point", "[AABB]")
|
||||
{
|
||||
Vector3f point(1.0f, 2.0f, 3.0f);
|
||||
AABB aabb(point);
|
||||
REQUIRE(aabb.GetMin() == point);
|
||||
REQUIRE(aabb.GetMax() == point);
|
||||
}
|
||||
|
||||
TEST_CASE("Constructor with point and radius", "[AABB]")
|
||||
{
|
||||
Vector3f point(1.0f, 2.0f, 3.0f);
|
||||
float radius = 1.0f;
|
||||
AABB aabb(point, radius);
|
||||
REQUIRE(aabb.GetMin() == (point - radius));
|
||||
REQUIRE(aabb.GetMax() == (point + radius));
|
||||
}
|
||||
|
||||
TEST_CASE("Init with single point", "[AABB]")
|
||||
{
|
||||
AABB aabb;
|
||||
Vector3f point(1.0f, 2.0f, 3.0f);
|
||||
aabb.Init(point);
|
||||
REQUIRE(aabb.GetMin() == point);
|
||||
REQUIRE(aabb.GetMax() == point);
|
||||
}
|
||||
|
||||
TEST_CASE("Init with min and max", "[AABB]")
|
||||
{
|
||||
AABB aabb;
|
||||
Vector3f min(1.0f, 2.0f, 3.0f);
|
||||
Vector3f max(4.0f, 5.0f, 6.0f);
|
||||
aabb.Init(min, max);
|
||||
REQUIRE(aabb.GetMin() == min);
|
||||
REQUIRE(aabb.GetMax() == max);
|
||||
}
|
||||
|
||||
TEST_CASE("Init with point and radius", "[AABB]")
|
||||
{
|
||||
AABB aabb;
|
||||
Vector3f point(1.0f, 2.0f, 3.0f);
|
||||
float radius = 1.0f;
|
||||
aabb.Init(point, radius);
|
||||
REQUIRE(aabb.GetMin() == (point - radius));
|
||||
REQUIRE(aabb.GetMax() == (point + radius));
|
||||
}
|
||||
|
||||
TEST_CASE("Grow with point", "[AABB]")
|
||||
{
|
||||
AABB aabb(Vector3f(0.0f), Vector3f(1.0f));
|
||||
Vector3f point(2.0f, 3.0f, 4.0f);
|
||||
aabb.Grow(point);
|
||||
REQUIRE(aabb.GetMin() == Vector3f(0.0f, 0.0f, 0.0f));
|
||||
REQUIRE(aabb.GetMax() == point);
|
||||
}
|
||||
|
||||
TEST_CASE("Grow with AABB", "[AABB]")
|
||||
{
|
||||
AABB aabb1(Vector3f(0.0f), Vector3f(1.0f));
|
||||
AABB aabb2(Vector3f(-1.0f), Vector3f(2.0f));
|
||||
aabb1.Grow(aabb2);
|
||||
REQUIRE(aabb1.GetMin() == Vector3f(-1.0f));
|
||||
REQUIRE(aabb1.GetMax() == Vector3f(2.0f));
|
||||
}
|
||||
|
||||
TEST_CASE("GetDiagonal", "[AABB]")
|
||||
{
|
||||
AABB aabb(Vector3f(0.0f), Vector3f(1.0f));
|
||||
REQUIRE(aabb.GetDiagonal() == Vector3f(1.0f));
|
||||
}
|
||||
|
||||
TEST_CASE("GetCenter", "[AABB]")
|
||||
{
|
||||
AABB aabb(Vector3f(0.0f), Vector3f(2.0f));
|
||||
REQUIRE(aabb.GetCenter() == Vector3f(1.0f));
|
||||
}
|
||||
|
||||
TEST_CASE("IsOverlapping", "[AABB]")
|
||||
{
|
||||
AABB aabb1(Vector3f(0.0f), Vector3f(1.0f));
|
||||
AABB aabb2(Vector3f(0.5f), Vector3f(1.5f));
|
||||
REQUIRE(aabb1.IsOverlapping(aabb2));
|
||||
|
||||
AABB aabb3(Vector3f(2.0f), Vector3f(3.0f));
|
||||
REQUIRE_FALSE(aabb1.IsOverlapping(aabb3));
|
||||
}
|
||||
|
||||
TEST_CASE("InBounds", "[AABB]")
|
||||
{
|
||||
AABB aabb(Vector3f(0.0f), Vector3f(1.0f));
|
||||
|
||||
REQUIRE(aabb.InBounds(Vector3f(0.5f)));
|
||||
REQUIRE(aabb.InBounds(Vector3f(0.0f)));
|
||||
REQUIRE(aabb.InBounds(Vector3f(1.0f)));
|
||||
|
||||
REQUIRE_FALSE(aabb.InBounds(Vector3f(1.1f)));
|
||||
REQUIRE_FALSE(aabb.InBounds(Vector3f(-0.1f)));
|
||||
REQUIRE_FALSE(aabb.InBounds(Vector3f(2.0f)));
|
||||
}
|
||||
|
||||
TEST_CASE("Inside", "[AABB]")
|
||||
{
|
||||
AABB aabb(Vector3f(0.0f), Vector3f(1.0f));
|
||||
|
||||
REQUIRE(aabb.Inside(Vector3f(0.5f)));
|
||||
|
||||
REQUIRE_FALSE(aabb.Inside(Vector3f(0.0f)));
|
||||
REQUIRE_FALSE(aabb.Inside(Vector3f(1.0f)));
|
||||
REQUIRE_FALSE(aabb.Inside(Vector3f(1.1f)));
|
||||
REQUIRE_FALSE(aabb.Inside(Vector3f(-0.1f)));
|
||||
REQUIRE_FALSE(aabb.Inside(Vector3f(1.0f)));
|
||||
}
|
||||
|
||||
TEST_CASE("IsEmpty", "[AABB]")
|
||||
{
|
||||
AABB aabb;
|
||||
REQUIRE(aabb.IsEmpty());
|
||||
|
||||
aabb.Init(Vector3f(0.0f), Vector3f(1.0f));
|
||||
REQUIRE_FALSE(aabb.IsEmpty());
|
||||
}
|
||||
|
||||
TEST_CASE("Reset", "[AABB]")
|
||||
{
|
||||
AABB aabb(Vector3f(0.0f), Vector3f(1.0f));
|
||||
aabb.Reset();
|
||||
REQUIRE(aabb.IsEmpty());
|
||||
}
|
||||
131
tests/Math/ByteSize.cpp
Normal file
131
tests/Math/ByteSize.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <catch2/catch_all.hpp>
|
||||
#include <cmath>
|
||||
|
||||
#include "Math/ByteSize.hpp"
|
||||
|
||||
using namespace OpenVulkano;
|
||||
|
||||
namespace
|
||||
{
|
||||
bool almostEqual(float a, float b, float epsilon = 0.001f) { return std::fabs(a - b) < epsilon; }
|
||||
}
|
||||
|
||||
TEST_CASE("BuildFactors and BuildDivisors", "[ByteSize]")
|
||||
{
|
||||
constexpr auto factors = ByteSizeUnitHelper::BuildFactors();
|
||||
constexpr auto divisors = ByteSizeUnitHelper::BuildDivisors();
|
||||
|
||||
REQUIRE(factors.size() == 13);
|
||||
REQUIRE(factors[0] == 1);
|
||||
REQUIRE(factors[1] == (1uLL << 10)); // KiB
|
||||
REQUIRE(factors[6] == (1uLL << 60)); // EiB
|
||||
REQUIRE(factors[7] == 1000); // kB
|
||||
REQUIRE(factors[12] == 1'000'000'000'000'000'000); // EB
|
||||
|
||||
REQUIRE(divisors.size() == 13);
|
||||
REQUIRE(almostEqual(divisors[0], 1.0));
|
||||
REQUIRE(almostEqual(divisors[1], 1.0 / (1uLL << 10))); // KiB
|
||||
REQUIRE(almostEqual(divisors[12], 1.0 / 1'000'000'000'000'000'000)); // EB
|
||||
}
|
||||
|
||||
TEST_CASE("GetFactor, GetDivisor, and GetName", "[ByteSize]")
|
||||
{
|
||||
ByteSizeUnit kib(ByteSizeUnit::kiB);
|
||||
ByteSizeUnit gb(ByteSizeUnit::GB);
|
||||
|
||||
REQUIRE(kib.GetFactor() == (1uLL << 10)); // KiB
|
||||
REQUIRE(almostEqual(kib.GetDivisor(), 1.0 / (1uLL << 10)));
|
||||
REQUIRE(kib.GetName() == "kiB");
|
||||
|
||||
REQUIRE(gb.GetFactor() == 1'000'000'000); // GB
|
||||
REQUIRE(almostEqual(gb.GetDivisor(), 1.0 / 1'000'000'000));
|
||||
REQUIRE(gb.GetName() == "GB");
|
||||
}
|
||||
|
||||
TEST_CASE("FromName and GetClosestUnit", "[ByteSize]")
|
||||
{
|
||||
auto kib = ByteSizeUnit::FromName("kiB");
|
||||
auto tb = ByteSizeUnit::FromName("TB");
|
||||
|
||||
REQUIRE(kib.GetFactor() == (1uLL << 10));
|
||||
REQUIRE(tb.GetFactor() == 1'000'000'000'000);
|
||||
|
||||
uint64_t size1 = 2 * 1'000'000'000;
|
||||
uint64_t size2 = 3 * (1uLL << 40);
|
||||
ByteSizeUnit unit1 = ByteSizeUnit::GetClosestUnit(size1, true); // SI
|
||||
ByteSizeUnit unit2 = ByteSizeUnit::GetClosestUnit(size2, false); // Binary
|
||||
|
||||
REQUIRE(unit1.GetName() == "GB");
|
||||
REQUIRE(unit2.GetName() == "TiB");
|
||||
}
|
||||
|
||||
TEST_CASE("Constructors and parsing from string", "[ByteSize]")
|
||||
{
|
||||
ByteSize size1(1'024, ByteSizeUnit(ByteSizeUnit::kiB));
|
||||
ByteSize size2("1.5 MiB");
|
||||
|
||||
REQUIRE(static_cast<uint64_t>(size1) == 1'024 * (1uLL << 10));
|
||||
REQUIRE(almostEqual(static_cast<uint64_t>(size2), 1.5 * (1uLL << 20)));
|
||||
|
||||
REQUIRE_THROWS_AS(ByteSize("invalid size"), std::runtime_error);
|
||||
}
|
||||
|
||||
TEST_CASE("Formatting", "[ByteSize]")
|
||||
{
|
||||
ByteSize size2(1'024 + 512, ByteSizeUnit(ByteSizeUnit::kiB)); // This is 1.5 MiB
|
||||
|
||||
REQUIRE(size2.Format(true) == "1.57 MB");
|
||||
REQUIRE(size2.Format(false) == "1.5 MiB");
|
||||
}
|
||||
|
||||
TEST_CASE("Operator overloads", "[ByteSize]")
|
||||
{
|
||||
ByteSize size1(1'024, ByteSizeUnit(ByteSizeUnit::kiB));
|
||||
ByteSize size2(512, ByteSizeUnit(ByteSizeUnit::kiB));
|
||||
|
||||
ByteSize result = size1 + size2;
|
||||
REQUIRE(static_cast<uint64_t>(result) == (1'024 + 512) * (1uLL << 10));
|
||||
|
||||
result = size1 - size2;
|
||||
REQUIRE(static_cast<uint64_t>(result) == (1'024 - 512) * (1uLL << 10));
|
||||
|
||||
size1 += size2;
|
||||
REQUIRE(static_cast<uint64_t>(size1) == (1'024 + 512) * (1uLL << 10));
|
||||
}
|
||||
|
||||
TEST_CASE("Literals", "[ByteSize]")
|
||||
{
|
||||
REQUIRE(static_cast<uint64_t>(1.0_kiB) == 1uLL << 10);
|
||||
REQUIRE(static_cast<uint64_t>(1.0_MiB) == 1uLL << 20);
|
||||
REQUIRE(static_cast<uint64_t>(1.0_GiB) == 1uLL << 30);
|
||||
REQUIRE(static_cast<uint64_t>(1.0_TiB) == 1uLL << 40);
|
||||
REQUIRE(static_cast<uint64_t>(1.0_PiB) == 1uLL << 50);
|
||||
REQUIRE(static_cast<uint64_t>(1.0_EiB) == 1uLL << 60);
|
||||
|
||||
REQUIRE(static_cast<uint64_t>(1.0_kB) == 1'000);
|
||||
REQUIRE(static_cast<uint64_t>(1.0_MB) == 1'000'000);
|
||||
REQUIRE(static_cast<uint64_t>(1.0_GB) == 1'000'000'000);
|
||||
REQUIRE(static_cast<uint64_t>(1.0_TB) == 1'000'000'000'000);
|
||||
REQUIRE(static_cast<uint64_t>(1.0_PB) == 1'000'000'000'000'000);
|
||||
REQUIRE(static_cast<uint64_t>(1.0_EB) == 1'000'000'000'000'000'000);
|
||||
|
||||
REQUIRE(static_cast<uint64_t>(1_kiB) == 1uLL << 10);
|
||||
REQUIRE(static_cast<uint64_t>(1_MiB) == 1uLL << 20);
|
||||
REQUIRE(static_cast<uint64_t>(1_GiB) == 1uLL << 30);
|
||||
REQUIRE(static_cast<uint64_t>(1_TiB) == 1uLL << 40);
|
||||
REQUIRE(static_cast<uint64_t>(1_PiB) == 1uLL << 50);
|
||||
REQUIRE(static_cast<uint64_t>(1_EiB) == 1uLL << 60);
|
||||
|
||||
REQUIRE(static_cast<uint64_t>(1_kB) == 1'000);
|
||||
REQUIRE(static_cast<uint64_t>(1_MB) == 1'000'000);
|
||||
REQUIRE(static_cast<uint64_t>(1_GB) == 1'000'000'000);
|
||||
REQUIRE(static_cast<uint64_t>(1_TB) == 1'000'000'000'000);
|
||||
REQUIRE(static_cast<uint64_t>(1_PB) == 1'000'000'000'000'000);
|
||||
REQUIRE(static_cast<uint64_t>(1_EB) == 1'000'000'000'000'000'000);
|
||||
}
|
||||
80
tests/Math/DenseVector3i.cpp
Normal file
80
tests/Math/DenseVector3i.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "Math/DenseVector3i.hpp"
|
||||
|
||||
using namespace OpenVulkano::Math;
|
||||
|
||||
TEST_CASE("Constructor and Accessors", "[DenseVector3i]")
|
||||
{
|
||||
Vector3i vec3 { 10, 20, 30 };
|
||||
DenseVector3i<int32_t> denseVec(vec3);
|
||||
|
||||
REQUIRE(denseVec.X() == 10);
|
||||
REQUIRE(denseVec.Y() == 20);
|
||||
REQUIRE(denseVec.Z() == 30);
|
||||
|
||||
auto data = denseVec.Data();
|
||||
REQUIRE(data != 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Setters", "[DenseVector3i]")
|
||||
{
|
||||
DenseVector3i<int32_t> denseVec(10, 20, 30);
|
||||
|
||||
denseVec.SetX(40);
|
||||
REQUIRE(denseVec.X() == 40);
|
||||
|
||||
denseVec.SetY(50);
|
||||
REQUIRE(denseVec.Y() == 50);
|
||||
|
||||
denseVec.SetZ(60);
|
||||
REQUIRE(denseVec.Z() == 60);
|
||||
}
|
||||
|
||||
TEST_CASE("Comparison Operators", "[DenseVector3i]")
|
||||
{
|
||||
DenseVector3i<int32_t> denseVec1(10, 20, 30);
|
||||
DenseVector3i<int32_t> denseVec2(10, 20, 30);
|
||||
DenseVector3i<int32_t> denseVec3(40, 50, 60);
|
||||
|
||||
REQUIRE(denseVec1 == denseVec2);
|
||||
REQUIRE(denseVec1 != denseVec3);
|
||||
|
||||
REQUIRE(denseVec1 < denseVec3);
|
||||
|
||||
REQUIRE(denseVec3 > denseVec1);
|
||||
|
||||
REQUIRE(denseVec1 <= denseVec2);
|
||||
REQUIRE(denseVec1 <= denseVec3);
|
||||
|
||||
REQUIRE(denseVec1 >= denseVec2);
|
||||
REQUIRE(denseVec3 >= denseVec1);
|
||||
}
|
||||
|
||||
TEST_CASE("ToString method", "[DenseVector3i]")
|
||||
{
|
||||
DenseVector3i<int32_t> denseVec(10, 20, 30);
|
||||
REQUIRE(denseVec.ToString() == fmt::format("{},{},{}", 10, 20, 30));
|
||||
REQUIRE(denseVec.ToString(" ") == "10 20 30");
|
||||
}
|
||||
|
||||
TEST_CASE("Type Conversion", "[DenseVector3i]")
|
||||
{
|
||||
DenseVector3i<int32_t> denseVec(10, 20, 30);
|
||||
|
||||
Vector3i vec3 = static_cast<Vector3i>(denseVec);
|
||||
REQUIRE(vec3.x == 10);
|
||||
REQUIRE(vec3.y == 20);
|
||||
REQUIRE(vec3.z == 30);
|
||||
|
||||
Vector3i_SIMD vec3_simd = static_cast<Vector3i_SIMD>(denseVec);
|
||||
REQUIRE(vec3_simd.x == 10);
|
||||
REQUIRE(vec3_simd.y == 20);
|
||||
REQUIRE(vec3_simd.z == 30);
|
||||
}
|
||||
110
tests/Math/Int24.cpp
Normal file
110
tests/Math/Int24.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "Math/Int24.hpp"
|
||||
|
||||
using namespace OpenVulkano;
|
||||
|
||||
TEST_CASE("Default constructor", "[Int24]")
|
||||
{
|
||||
int24 a;
|
||||
REQUIRE(static_cast<int>(a) == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Integer constructor", "[Int24]")
|
||||
{
|
||||
int24 a(0x123456);
|
||||
REQUIRE(static_cast<int>(a) == 0x123456);
|
||||
|
||||
int24 b(-1);
|
||||
REQUIRE(static_cast<int>(b) == -1);
|
||||
}
|
||||
|
||||
TEST_CASE("Copy constructor", "[Int24]")
|
||||
{
|
||||
int24 a(0x123456);
|
||||
int24 b(a);
|
||||
REQUIRE(static_cast<int>(b) == 0x123456);
|
||||
}
|
||||
|
||||
TEST_CASE("Assignment operator", "[Int24]")
|
||||
{
|
||||
int24 a;
|
||||
a = 0x123456;
|
||||
REQUIRE(static_cast<int>(a) == 0x123456);
|
||||
|
||||
int24 b;
|
||||
b = a;
|
||||
REQUIRE(static_cast<int>(b) == 0x123456);
|
||||
}
|
||||
|
||||
TEST_CASE("Arithmetic operators", "[Int24]")
|
||||
{
|
||||
int24 a(0x10);
|
||||
int24 b(0x20);
|
||||
|
||||
REQUIRE(static_cast<int>(a + b) == 0x30);
|
||||
REQUIRE(static_cast<int>(b - a) == 0x10);
|
||||
REQUIRE(static_cast<int>(a * b) == 0x200);
|
||||
REQUIRE(static_cast<int>(b / a) == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("Compound assignment operators", "[Int24]")
|
||||
{
|
||||
int24 a(0x10);
|
||||
int24 b(0x20);
|
||||
|
||||
a += b;
|
||||
REQUIRE(static_cast<int>(a) == 0x30);
|
||||
|
||||
a -= b;
|
||||
REQUIRE(static_cast<int>(a) == 0x10);
|
||||
|
||||
a *= b;
|
||||
REQUIRE(static_cast<int>(a) == 0x200);
|
||||
|
||||
a /= b;
|
||||
REQUIRE(static_cast<int>(a) == 0x10);
|
||||
}
|
||||
|
||||
TEST_CASE("Comparison operators", "[Int24]")
|
||||
{
|
||||
int24 a(0x100000);
|
||||
int24 b(0x200000);
|
||||
|
||||
REQUIRE(a < b);
|
||||
REQUIRE(b > a);
|
||||
REQUIRE(a <= b);
|
||||
REQUIRE(b >= a);
|
||||
REQUIRE(a != b);
|
||||
|
||||
int24 c(0x100000);
|
||||
REQUIRE(a == c);
|
||||
}
|
||||
|
||||
TEST_CASE("Shift operators", "[Int24]")
|
||||
{
|
||||
int24 a(0x123456);
|
||||
REQUIRE(static_cast<int>(a << 1) == 0x2468ac);
|
||||
REQUIRE(static_cast<int>(a >> 1) == 0x91a2b);
|
||||
}
|
||||
|
||||
TEST_CASE("Boolean operators", "[Int24]")
|
||||
{
|
||||
int24 a(0);
|
||||
int24 b(1);
|
||||
|
||||
REQUIRE(!a);
|
||||
REQUIRE(b);
|
||||
}
|
||||
|
||||
TEST_CASE("Negation", "[Int24]")
|
||||
{
|
||||
int24 a(0x123456);
|
||||
REQUIRE(static_cast<int>(-a) == -0x123456);
|
||||
}
|
||||
134
tests/Math/RGB10A2.cpp
Normal file
134
tests/Math/RGB10A2.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "Math/RGB10A2.hpp"
|
||||
|
||||
using namespace OpenVulkano::Math;
|
||||
|
||||
namespace
|
||||
{
|
||||
bool almostEqual(float a, float b, float epsilon = 0.001f) { return std::fabs(a - b) < epsilon; }
|
||||
}
|
||||
|
||||
TEST_CASE("Default Constructor", "[RGB10A2U]")
|
||||
{
|
||||
RGB10A2U color;
|
||||
REQUIRE(color.value == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Set Method with Vector3", "[RGB10A2U]")
|
||||
{
|
||||
RGB10A2U color;
|
||||
Vector3<uint32_t> vec3 { 1000, 500, 250 };
|
||||
color.Set(vec3);
|
||||
REQUIRE(color.r == 1000);
|
||||
REQUIRE(color.g == 500);
|
||||
REQUIRE(color.b == 250);
|
||||
REQUIRE(color.a == 3);
|
||||
}
|
||||
|
||||
TEST_CASE("Set Method with Vector4", "[RGB10A2U]")
|
||||
{
|
||||
RGB10A2U color;
|
||||
Vector4<uint32_t> vec4 { 1000, 500, 250, 1 };
|
||||
color.Set(vec4);
|
||||
REQUIRE(color.r == 1000);
|
||||
REQUIRE(color.g == 500);
|
||||
REQUIRE(color.b == 250);
|
||||
REQUIRE(color.a == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("SetNormalized Method with Vector3", "[RGB10A2U]")
|
||||
{
|
||||
RGB10A2U color;
|
||||
Vector3<float> vec3 { 0.5f, 0.25f, 0.125f };
|
||||
color.SetNormalized(vec3);
|
||||
REQUIRE(color.r == int(0.5 * 1023));
|
||||
REQUIRE(color.g == int(0.25 * 1023));
|
||||
REQUIRE(color.b == int(0.125 * 1023));
|
||||
REQUIRE(color.a == 3);
|
||||
}
|
||||
|
||||
TEST_CASE("Equality Operators", "[RGB10A2U]")
|
||||
{
|
||||
RGB10A2U color;
|
||||
RGB10A2U color2 { color };
|
||||
REQUIRE(color == color2);
|
||||
color2.r = 1;
|
||||
REQUIRE(color != color2);
|
||||
}
|
||||
|
||||
TEST_CASE("Conversion to Vector4", "[RGB10A2U]")
|
||||
{
|
||||
RGB10A2U color;
|
||||
color.Set(Vector4<uint32_t> { 1000, 500, 250, 2 });
|
||||
Vector4f vec4 = color;
|
||||
REQUIRE(almostEqual(vec4.x, 1000.0f / 1023.0f));
|
||||
REQUIRE(almostEqual(vec4.y, 500.0f / 1023.0f));
|
||||
REQUIRE(almostEqual(vec4.z, 250.0f / 1023.0f));
|
||||
REQUIRE(almostEqual(vec4.w, 2.0f / 3.0f));
|
||||
}
|
||||
|
||||
TEST_CASE("Default Constructor", "[RGB10A2S]")
|
||||
{
|
||||
RGB10A2S color;
|
||||
REQUIRE(color.value == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Set Method with Vector3", "[RGB10A2S]")
|
||||
{
|
||||
RGB10A2S color;
|
||||
Vector3<int32_t> vec3 { 1000, 500, 250 };
|
||||
color.Set(vec3);
|
||||
REQUIRE(color.r == -24);
|
||||
REQUIRE(color.g == 500);
|
||||
REQUIRE(color.b == 250);
|
||||
REQUIRE(color.a == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("Set Method with Vector4", "[RGB10A2S]")
|
||||
{
|
||||
RGB10A2S color;
|
||||
Vector4<int32_t> vec4 { 1000, 500, 250, 1 };
|
||||
color.Set(vec4);
|
||||
REQUIRE(color.r == -24); // because it is RGB10A2S
|
||||
REQUIRE(color.g == 500);
|
||||
REQUIRE(color.b == 250);
|
||||
REQUIRE(color.a == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("SetNormalized Method with Vector3", "[RGB10A2S]")
|
||||
{
|
||||
RGB10A2S color;
|
||||
Vector3<float> vec3 { 0.5f, 0.25f, 0.125f };
|
||||
color.SetNormalized(vec3);
|
||||
REQUIRE(color.r == 255); // because it is RGB10A2S
|
||||
REQUIRE(color.g == 127); // because it is RGB10A2S
|
||||
REQUIRE(color.b == 63); // because it is RGB10A2S
|
||||
REQUIRE(color.a == 1); // because it is RGB10A2S
|
||||
}
|
||||
|
||||
TEST_CASE("Equality Operators", "[RGB10A2S]")
|
||||
{
|
||||
RGB10A2S color;
|
||||
RGB10A2S color2 { color };
|
||||
REQUIRE(color == color2);
|
||||
color2.r = 1;
|
||||
REQUIRE(color != color2);
|
||||
}
|
||||
|
||||
TEST_CASE("Conversion to Vector4", "[RGB10A2S]")
|
||||
{
|
||||
RGB10A2S color;
|
||||
color.Set(Vector4<int32_t> { 1000, 500, 250, 2 });
|
||||
Vector4f vec4 = color;
|
||||
REQUIRE(almostEqual(vec4.x, -0.0469667315)); // because the type is Signed. Ugh!
|
||||
REQUIRE(almostEqual(vec4.y, 0.978474)); // because the type is Signed. Ugh!
|
||||
REQUIRE(almostEqual(vec4.z, 0.489237)); // because the type is Signed. Ugh!
|
||||
REQUIRE(almostEqual(vec4.w, -2.0f)); // because the type is Signed. Ugh!
|
||||
}
|
||||
57
tests/Math/Range.cpp
Normal file
57
tests/Math/Range.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "Math/Range.hpp"
|
||||
|
||||
using namespace OpenVulkano::Math;
|
||||
using RangeType = Range<int>;
|
||||
|
||||
// The class does not have a default constructor... So rely on warnings about unitialized members
|
||||
|
||||
TEST_CASE("Parameterized constructor", "[Range]")
|
||||
{
|
||||
int min = 10;
|
||||
int max = 20;
|
||||
RangeType range(min, max);
|
||||
REQUIRE(range.GetMin() == min);
|
||||
REQUIRE(range.GetMax() == max);
|
||||
}
|
||||
|
||||
TEST_CASE("GetMin and GetMax", "[Range]")
|
||||
{
|
||||
int min = 10;
|
||||
int max = 20;
|
||||
RangeType range(min, max);
|
||||
|
||||
// Test const-qualified access
|
||||
const RangeType& constRange = range;
|
||||
REQUIRE(constRange.GetMin() == min);
|
||||
REQUIRE(constRange.GetMax() == max);
|
||||
|
||||
// Test non-const access
|
||||
range.GetMin() = 30;
|
||||
range.GetMax() = 40;
|
||||
REQUIRE(range.GetMin() == 30);
|
||||
REQUIRE(range.GetMax() == 40);
|
||||
}
|
||||
|
||||
TEST_CASE("GetSize", "[Range]")
|
||||
{
|
||||
int min = 10;
|
||||
int max = 20;
|
||||
RangeType range(min, max);
|
||||
REQUIRE(range.GetSize() == 10);
|
||||
}
|
||||
|
||||
TEST_CASE("GetSize with negative", "[Range]")
|
||||
{
|
||||
int min = -10;
|
||||
int max = 10;
|
||||
RangeType range(min, max);
|
||||
REQUIRE(range.GetSize() == 20);
|
||||
}
|
||||
79
tests/Math/Timestamp.cpp
Normal file
79
tests/Math/Timestamp.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include <catch2/catch_all.hpp>
|
||||
|
||||
#include "Math/Timestamp.hpp"
|
||||
|
||||
using namespace OpenVulkano::Math;
|
||||
|
||||
TEST_CASE("Constructors", "[Timestamp]")
|
||||
{
|
||||
Timestamp ts;
|
||||
REQUIRE(ts.GetNanos() == 0);
|
||||
REQUIRE(ts.GetSeconds() == 0.0);
|
||||
|
||||
ts = Timestamp((uint64_t)1'000'000'000ull); // 1 second
|
||||
REQUIRE(ts.GetNanos() == 1'000'000'000ull);
|
||||
REQUIRE(ts.GetSeconds() == 1.0);
|
||||
|
||||
ts = Timestamp(2.5); // 2.5 seconds
|
||||
REQUIRE(ts.GetNanos() == 2'500'000'000ull);
|
||||
REQUIRE(ts.GetSeconds() == 2.5);
|
||||
}
|
||||
|
||||
TEST_CASE("Arithmetic operations", "[Timestamp]")
|
||||
{
|
||||
Timestamp ts1((uint64_t)1'000'000'000ull); // 1 second
|
||||
Timestamp ts2((uint64_t)2'000'000'000ull); // 2 seconds
|
||||
Timestamp result;
|
||||
|
||||
result = ts1 + ts2;
|
||||
REQUIRE(result.GetNanos() == 3'000'000'000ull);
|
||||
|
||||
result = ts2 - ts1;
|
||||
REQUIRE(result.GetNanos() == 1'000'000'000ull);
|
||||
|
||||
ts1 += ts2;
|
||||
REQUIRE(ts1.GetNanos() == 3'000'000'000ull);
|
||||
|
||||
ts1 -= ts2;
|
||||
ts1 -= ts2; // Wraps around
|
||||
REQUIRE(ts1.GetNanos() > 0);
|
||||
}
|
||||
|
||||
TEST_CASE("Comparison operators", "[Timestamp]")
|
||||
{
|
||||
Timestamp ts1((uint64_t)1'000'000'000ull); // 1 second
|
||||
Timestamp ts2((uint64_t)2'000'000'000ull); // 2 seconds
|
||||
Timestamp ts3((uint64_t)1'000'000'000ull);
|
||||
|
||||
REQUIRE(ts1 == ts3);
|
||||
REQUIRE(ts1 != ts2);
|
||||
REQUIRE(ts1 < ts2);
|
||||
REQUIRE(ts2 > ts1);
|
||||
REQUIRE(ts1 <= ts3);
|
||||
REQUIRE(ts2 >= ts1);
|
||||
}
|
||||
|
||||
TEST_CASE("Assignment operators", "[Timestamp]")
|
||||
{
|
||||
Timestamp ts;
|
||||
ts = (uint64_t)1'000'000'000ull;
|
||||
REQUIRE(ts.GetNanos() == 1'000'000'000ull);
|
||||
|
||||
ts = 2.0;
|
||||
REQUIRE(ts.GetNanos() == 2'000'000'000ull);
|
||||
}
|
||||
|
||||
TEST_CASE("Division operator", "[Timestamp]")
|
||||
{
|
||||
Timestamp ts1(2.0);
|
||||
Timestamp ts2(1.0);
|
||||
|
||||
double result = ts1 / ts2;
|
||||
REQUIRE(result == 2.0);
|
||||
}
|
||||
Reference in New Issue
Block a user