diff --git a/Makefile b/Makefile index e4dd01c..152bb89 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC=g++ SRCDIR=./src outputDir=./build -CFLAGS=-fPIC -O2 -g +CFLAGS=-fPIC -O2 -g -std=c++11 WarningFlags=-Wpedantic -pedantic -Wall -Wextra SDL_FLAGS=-lSDL2 -lSDL2main -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lSDL2_gfx INCLUDES=-I./include @@ -12,9 +12,9 @@ all: test engine_lib docs: doxygen ./doxygen_config -test: tests.o logger.o renderwindow.o values.o timestep.o utils.o math.o +test: entity.o logger.o math.o renderwindow.o timer.o timestep.o utils.o values.o tests.o mkdir -p build - $(CC) $^ $(SDL_FLAGS) $(WarningFlags) -o $(outputDir)/test + $(CC) $^ $(CFLAGS) $(SDL_FLAGS) $(WarningFlags) -o $(outputDir)/test run_tests: test ./build/test diff --git a/include/Math.hpp b/include/Math.hpp index 33c1570..0069eb2 100644 --- a/include/Math.hpp +++ b/include/Math.hpp @@ -4,6 +4,7 @@ namespace Birb { + /// Point in 2D space with floating point accuracy struct Vector2f { Vector2f() @@ -24,9 +25,36 @@ namespace Birb return "(" + std::to_string(x) + ", " + std::to_string(y) + ")"; } + /* Operator overloads */ + Vector2f operator+(const Vector2f& other) const + { + return Vector2f(x + other.x, y + other.y); + } + + Vector2f operator-(const Vector2f& other) const + { + return Vector2f(x - other.x, y - other.y); + } + + Vector2f operator*(const Vector2f& other) const + { + return Vector2f(x * other.x, y * other.y); + } + + Vector2f operator/(const Vector2f& other) const + { + return Vector2f(x / other.x, y / other.y); + } + + bool operator==(const Vector2f& other) const + { + return (x == other.x && y == other.y); + } + float x, y; }; + /// Point in 2D space with integer accuracy struct Vector2int { Vector2int() @@ -53,9 +81,36 @@ namespace Birb return "(" + std::to_string(x) + ", " + std::to_string(y) + ")"; } + /* Operator overloads */ + Vector2int operator+(const Vector2int& other) const + { + return Vector2int(x + other.x, y + other.y); + } + + Vector2int operator-(const Vector2int& other) const + { + return Vector2int(x - other.x, y - other.y); + } + + Vector2int operator*(const Vector2int& other) const + { + return Vector2int(x * other.x, y * other.y); + } + + Vector2int operator/(const Vector2int& other) const + { + return Vector2int((int)std::round((float)x / other.x), (int)std::round((float)y / other.y)); + } + + bool operator==(const Vector2int& other) const + { + return (x == other.x && y == other.y); + } + int x, y; }; + /// Point in 3D space with floating point accuracy struct Vector3f { Vector3f() @@ -76,9 +131,36 @@ namespace Birb return "(" + std::to_string(x) + ", " + std::to_string(y) + ", " + std::to_string(z) + ")"; } + /* Operator overloads */ + Vector3f operator+(const Vector3f& other) const + { + return Vector3f(x + other.x, y + other.y, z + other.z); + } + + Vector3f operator-(const Vector3f& other) const + { + return Vector3f(x - other.x, y - other.y, z - other.z); + } + + Vector3f operator*(const Vector3f& other) const + { + return Vector3f(x * other.x, y * other.y, z * other.z); + } + + Vector3f operator/(const Vector3f& other) const + { + return Vector3f(x / other.x, y / other.y, z / other.z); + } + + bool operator==(const Vector3f& other) const + { + return (x == other.x && y == other.y && z == other.z); + } + float x, y, z; }; + /// Point in 3D space with integer accuracy struct Vector3int { Vector3int() @@ -106,6 +188,46 @@ namespace Birb return "(" + std::to_string(x) + ", " + std::to_string(y) + ", " + std::to_string(z) + ")"; } + /* Operator overloads */ + Vector3int operator+(const Vector3int& other) const + { + return Vector3int(x + other.x, y + other.y, z + other.z); + } + + Vector3int operator-(const Vector3int& other) const + { + return Vector3int(x - other.x, y - other.y, z - other.z); + } + + Vector3int operator*(const Vector3int& other) const + { + return Vector3int(x * other.x, y * other.y, z * other.z); + } + + Vector3int operator/(const Vector3int& other) const + { + return Vector3int((int)std::round((float)x / other.x), (int)std::round((float)y / other.y), (int)std::round((float)z / other.z)); + } + + bool operator==(const Vector3int& other) const + { + return (x == other.x && y == other.y && z == other.z); + } + int x, y, z; }; + + /// Misc math functions + struct Math + { + static float VectorDistance(Vector2f a, Vector2f b); ///< Calculate the distance between two 2D floating point vectors + static float VectorDistance(Vector2int a, Vector2int b); ///< Calculate the distance between two 2D integer vectors + static float VectorDistance(Vector3f a, Vector3f b); ///< Calculate the distance between two 3D floating point vectors + static float VectorDistance(Vector3int a, Vector3int b); ///< Calculate the distance between two 3D integer vectors + + static Vector2f CenterPoint(Vector2f a, Vector2f b); ///< Calculate the center point between two 2D floating point vectors + static Vector2f CenterPoint(Vector2int a, Vector2int b); ///< Calculate the center point between two 2D integer vectors + static Vector3f CenterPoint(Vector3f a, Vector3f b); ///< Calculate the center point between two 3D floating point vectors + static Vector3f CenterPoint(Vector3int a, Vector3int b); ///< Calculate the center point between two 3D integer vectors + }; } diff --git a/src/math.cpp b/src/math.cpp index e69de29..81ec0c7 100644 --- a/src/math.cpp +++ b/src/math.cpp @@ -0,0 +1,44 @@ +#include "Math.hpp" + +namespace Birb +{ + float Math::VectorDistance(Vector2f a, Vector2f b) + { + return std::sqrt(std::pow(b.x - a.x, 2) + std::pow(b.y - a.y, 2)); + } + + float Math::VectorDistance(Vector2int a, Vector2int b) + { + return std::sqrt(std::pow(b.x - a.x, 2) + std::pow(b.y - a.y, 2)); + } + + float Math::VectorDistance(Vector3f a, Vector3f b) + { + return std::sqrt(std::pow(b.x - a.x, 2) + std::pow(b.y - a.y, 2) + std::pow(b.z - a.z, 2)); + } + + float Math::VectorDistance(Vector3int a, Vector3int b) + { + return std::sqrt(std::pow(b.x - a.x, 2) + std::pow(b.y - a.y, 2) + std::pow(b.z - a.z, 2)); + } + + Vector2f Math::CenterPoint(Vector2f a, Vector2f b) + { + return Vector2f((a.x + b.x) / 2, (a.y + b.y) / 2); + } + + Vector2f Math::CenterPoint(Vector2int a, Vector2int b) + { + return Vector2f((a.x + b.x) / 2.0f, (a.y + b.y) / 2.0f); + } + + Vector3f Math::CenterPoint(Vector3f a, Vector3f b) + { + return Vector3f((a.x + b.x) / 2, (a.y + b.y) / 2, (a.z + b.z) / 2); + } + + Vector3f Math::CenterPoint(Vector3int a, Vector3int b) + { + return Vector3f((a.x + b.x) / 2.0f, (a.y + b.y) / 2.0f, (a.z + b.z) / 2.0f); + } +} diff --git a/src/tests.cpp b/src/tests.cpp index a6ea1fe..bf4d783 100644 --- a/src/tests.cpp +++ b/src/tests.cpp @@ -109,6 +109,106 @@ TEST_CASE("Vector3int with arguments") CHECK(Birb::Vector3int(1.53f, 5.21f, 2.45f).z == 2); } +TEST_CASE("Distance calculation with 2D vectors") +{ + Birb::Vector2f pointAf(1.0f, 1.0f); + Birb::Vector2f pointBf(8.0f, 3.0f); + + Birb::Vector2int pointAint(1, 1); + Birb::Vector2int pointBint(8, 3); + + CHECK(Birb::Math::VectorDistance(pointAf, pointBf) == 7.2801098892805f); + CHECK(Birb::Math::VectorDistance(pointAint, pointBint) == 7.2801098892805f); +} + +TEST_CASE("Distance calculation with 3D vectors") +{ + Birb::Vector3f pointAf(1.0f, 1.0f, 1.0f); + Birb::Vector3f pointBf(8.0f, 3.0f, 2.0f); + + Birb::Vector3int pointAint(1, 1, 1); + Birb::Vector3int pointBint(8, 3, 2); + + CHECK(std::roundf(Birb::Math::VectorDistance(pointAf, pointBf)) == std::roundf(7.3484792283495)); + CHECK(std::roundf(Birb::Math::VectorDistance(pointAint, pointBint)) == std::roundf(7.3484692283495)); +} + +TEST_CASE("Calculate the centerpoint between two 2D vectors") +{ + Birb::Vector2f pointAf(1.0f, 1.0f); + Birb::Vector2f pointBf(8.0f, 3.0f); + + Birb::Vector2int pointAint(1, 1); + Birb::Vector2int pointBint(8, 3); + + Birb::Vector2f resultf = Birb::Math::CenterPoint(pointAf, pointBf); + Birb::Vector2f resultint = Birb::Math::CenterPoint(pointAint, pointBint); + Birb::Vector2f expectedResult(4.5f, 2.0f); + + CHECK(resultf == expectedResult); + CHECK(resultint == expectedResult); +} + +TEST_CASE("Calculate the centerpoint between two 3D vectors") +{ + Birb::Vector3f pointAf(1.0f, 1.0f, 1.0f); + Birb::Vector3f pointBf(8.0f, 3.0f, 2.0f); + + Birb::Vector3int pointAint(1, 1, 1); + Birb::Vector3int pointBint(8, 3, 2); + + Birb::Vector3f resultf = Birb::Math::CenterPoint(pointAf, pointBf); + Birb::Vector3f resultint = Birb::Math::CenterPoint(pointAint, pointBint); + Birb::Vector3f expectedResult(4.5f, 2.0f, 1.5f); + + CHECK(resultf == expectedResult); + CHECK(resultint == expectedResult); +} + +TEST_CASE("Vector2f operator overloads") +{ + Birb::Vector2f vecA(1.0f, 1.5f); + Birb::Vector2f vecB(2.0f, 3.2f); + + CHECK(vecA + vecB == Birb::Vector2f(3.0f, 4.7f)); + CHECK(vecA - vecB == Birb::Vector2f(-1.0f, -1.7f)); + CHECK(vecA * vecB == Birb::Vector2f(2.0f, 4.8f)); + CHECK(vecA / vecB == Birb::Vector2f(0.5f, 0.46875f)); +} + +TEST_CASE("Vector2int operator overloads") +{ + Birb::Vector2int vecA(4, 2); + Birb::Vector2int vecB(2, 3); + + CHECK(vecA + vecB == Birb::Vector2int(6, 5)); + CHECK(vecA - vecB == Birb::Vector2int(2, -1)); + CHECK(vecA * vecB == Birb::Vector2int(8, 6)); + CHECK(vecA / vecB == Birb::Vector2int(2, 1)); +} + +TEST_CASE("Vector3f operator overloads") +{ + Birb::Vector3f vecA(1.0f, 1.5f, 0.2f); + Birb::Vector3f vecB(2.0f, 3.2f, 2.0f); + + CHECK(vecA + vecB == Birb::Vector3f(3.0f, 4.7f, 2.2f)); + CHECK(vecA - vecB == Birb::Vector3f(-1.0f, -1.7f, -1.8f)); + CHECK(vecA * vecB == Birb::Vector3f(2.0f, 4.8f, 0.4f)); + CHECK(vecA / vecB == Birb::Vector3f(0.5f, 0.468750f, 0.1f)); +} + +TEST_CASE("Vector3int operator overloads") +{ + Birb::Vector3int vecA(4, 6, 5); + Birb::Vector3int vecB(2, 3, 2); + + CHECK(vecA + vecB == Birb::Vector3int(6, 9, 7)); + CHECK(vecA - vecB == Birb::Vector3int(2, 3, 3)); + CHECK(vecA * vecB == Birb::Vector3int(8, 18, 10)); + CHECK(vecA / vecB == Birb::Vector3int(2, 2, 3)); +} + TEST_CASE("Default Rect") { Birb::Rect defaultRect;