From c341f6a44699d71b8b20e6b814274b30e43514c8 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Sat, 23 Nov 2024 22:07:15 +0100 Subject: added profiling test --- src/test/Profiling.cpp | 128 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/test/Profiling.cpp (limited to 'src/test/Profiling.cpp') diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp new file mode 100644 index 0000000..9929288 --- /dev/null +++ b/src/test/Profiling.cpp @@ -0,0 +1,128 @@ +#include "system/ParticleSystem.h" +#include "system/PhysicsSystem.h" +#include "system/RenderSystem.h" +#include +#include +#include + +#define private public +#define protected public + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace std::chrono_literals; +using namespace crepe; +using namespace testing; + +class CollisionHandler : public Script { +public: + int box_id; + + CollisionHandler(int box_id) { + this->box_id = box_id; + } + + bool on_collision(const CollisionEvent& ev) { + // test load? + return true; + } + + void init() { + subscribe([this](const CollisionEvent& ev) -> bool { + return this->on_collision(ev); + }); + } + void update() { + // Retrieve component from the same GameObject this script is on + } +}; + +class Profiling : public Test { +public: + ComponentManager mgr; + // Add system used for profling tests + CollisionSystem collision_sys{mgr}; + PhysicsSystem physics_sys{mgr}; + ParticleSystem particle_sys{mgr}; + RenderSystem render_sys{mgr}; + ScriptSystem script_sys{mgr}; + + // Store individual function timings + std::map timings; + + // Min and max gameobject that should and can be created + int min_gameobject_count = 100; + int max_gameobject_count = 100; + + void SetUp() override { + + GameObject do_not_use = mgr.new_object("DO_NOT_USE","",{0,0}); + do_not_use.add_component(Color::WHITE); + // initialize systems here: + //calls init + script_sys.update(); + //creates window + render_sys.update(); + } + + // Helper function to time an update call and store its duration + template + long long time_function(const std::string& name, Func&& func) { + auto start = std::chrono::steady_clock::now(); + func(); + auto end = std::chrono::steady_clock::now(); + auto duration = std::chrono::duration_cast(end - start).count(); + timings[name] = duration; // Store the duration in microseconds + return duration; // Return the duration in microseconds + } + + // Run and profile all systems, return the total time in milliseconds + long long run_all_systems() { + long long total_microseconds = 0; + total_microseconds += time_function("PhysicsSystem", [&]() { physics_sys.update(); }); + total_microseconds += time_function("CollisionSystem", [&]() { collision_sys.update(); }); + total_microseconds += time_function("ParticleSystem", [&]() { particle_sys.update(); }); + total_microseconds += time_function("RenderSystem", [&]() { render_sys.update(); }); + return total_microseconds; + } + + // Print timings of all functions + void log_timings(long long total_time,int game_object_count) const { + std::stringstream ss; + ss << std::endl <<"Function timings:\n"; // Starting with a header + for (const auto& [name, duration] : timings) { + ss << name << " took " << duration / 1000.0 << " ms (" << duration << " µs). " << std::endl; + } + ss << "Total time: " << total_time / 1000.0 << "ms (" << total_time << " µs)" << std::endl; + ss << "Amount of gameobjects: " << game_object_count << std::endl; + // Use GTest INFO macro to print the accumulated log without extra newlines + GTEST_LOG_(INFO) << ss.str(); + } +}; + +TEST_F(Profiling, Profiling_example) { + int game_object_count = 0; + long long total_time = 0; + while (total_time < 16000) { + game_object_count++; + { + //define gameobject used for testing + GameObject gameobject = mgr.new_object("gameobject","",{0,0}); + } + total_time = run_all_systems(); + if(game_object_count >= max_gameobject_count) break; + } + log_timings(total_time,game_object_count); + EXPECT_GE(game_object_count, min_gameobject_count); +} -- cgit v1.2.3 From 86b1f2208214fdb207e7d0541a293625990016c4 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Sat, 23 Nov 2024 22:16:45 +0100 Subject: Added simple profling test --- src/test/Profiling.cpp | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 9929288..518d1c5 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -25,22 +25,14 @@ using namespace std::chrono_literals; using namespace crepe; using namespace testing; -class CollisionHandler : public Script { -public: - int box_id; - - CollisionHandler(int box_id) { - this->box_id = box_id; - } - - bool on_collision(const CollisionEvent& ev) { - // test load? +class TestScript : public Script { + bool oncollision(const CollisionEvent& test) { + Log::logf("Box {} script on_collision()", test.info.first.collider.game_object_id); return true; } - void init() { subscribe([this](const CollisionEvent& ev) -> bool { - return this->on_collision(ev); + return this->oncollision(ev); }); } void update() { @@ -115,11 +107,41 @@ TEST_F(Profiling, Profiling_example) { int game_object_count = 0; long long total_time = 0; while (total_time < 16000) { - game_object_count++; + { //define gameobject used for testing GameObject gameobject = mgr.new_object("gameobject","",{0,0}); } + + game_object_count++; + total_time = run_all_systems(); + if(game_object_count >= max_gameobject_count) break; + } + log_timings(total_time,game_object_count); + EXPECT_GE(game_object_count, min_gameobject_count); +} + +TEST_F(Profiling, Profiling_small_object_no_collision) { + int game_object_count = 0; + long long total_time = 0; + while (total_time < 16000) { + + { + //define gameobject used for testing + GameObject gameobject = mgr.new_object("gameobject","",{static_cast(game_object_count*2),0}); + gameobject.add_component(Rigidbody::Data{ + .body_type = Rigidbody::BodyType::STATIC, + .use_gravity = false, + }); + gameobject.add_component(vec2{0, 0}, 1, 1); + gameobject.add_component().set_script(); + Color color(0, 0, 0, 0); + gameobject.add_component( + make_shared("/home/jaro/crepe/asset/texture/green_square.png"), color, + FlipSettings{true, true}); + } + render_sys.update(); + game_object_count++; total_time = run_all_systems(); if(game_object_count >= max_gameobject_count) break; } -- cgit v1.2.3 From 08a3171b6bcc9a36ad89f04d2cdae406eb366a96 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Sat, 23 Nov 2024 22:19:34 +0100 Subject: change test data --- src/test/Profiling.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 518d1c5..d7a4f2e 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -55,7 +55,7 @@ public: // Min and max gameobject that should and can be created int min_gameobject_count = 100; - int max_gameobject_count = 100; + int max_gameobject_count = 1000; void SetUp() override { @@ -140,6 +140,7 @@ TEST_F(Profiling, Profiling_small_object_no_collision) { make_shared("/home/jaro/crepe/asset/texture/green_square.png"), color, FlipSettings{true, true}); } + render_sys.update(); game_object_count++; total_time = run_all_systems(); -- cgit v1.2.3 From 0b677b12d959e6320dc560edd093603ac7fbc55b Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Sat, 23 Nov 2024 22:26:06 +0100 Subject: added particle test --- src/test/Profiling.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index d7a4f2e..5cc70a4 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -121,7 +122,7 @@ TEST_F(Profiling, Profiling_example) { EXPECT_GE(game_object_count, min_gameobject_count); } -TEST_F(Profiling, Profiling_small_object_no_collision) { +TEST_F(Profiling, Profiling_small_object) { int game_object_count = 0; long long total_time = 0; while (total_time < 16000) { @@ -140,7 +141,49 @@ TEST_F(Profiling, Profiling_small_object_no_collision) { make_shared("/home/jaro/crepe/asset/texture/green_square.png"), color, FlipSettings{true, true}); } - + + render_sys.update(); + game_object_count++; + total_time = run_all_systems(); + if(game_object_count >= max_gameobject_count) break; + } + log_timings(total_time,game_object_count); + EXPECT_GE(game_object_count, min_gameobject_count); +} + +TEST_F(Profiling, Profiling_small_object_Particle_emitter) { + int game_object_count = 0; + long long total_time = 0; + while (total_time < 16000) { + + { + //define gameobject used for testing + GameObject gameobject = mgr.new_object("gameobject","",{static_cast(game_object_count*2),0}); + gameobject.add_component(Rigidbody::Data{ + .body_type = Rigidbody::BodyType::STATIC, + .use_gravity = false, + }); + gameobject.add_component(vec2{0, 0}, 1, 1); + gameobject.add_component().set_script(); + Color color(0, 0, 0, 0); + gameobject.add_component( + make_shared("/home/jaro/crepe/asset/texture/green_square.png"), color, + FlipSettings{true, true}); + Sprite & test_sprite = gameobject.add_component( + make_shared("/home/jaro/crepe/asset/texture/img.png"), color, FlipSettings{false, false}); + auto & test = gameobject.add_component(ParticleEmitter::Data{ + .max_particles = 100, + .emission_rate = 100, + .end_lifespan = 100000, + .boundary{ + .width = 1000, + .height = 1000, + .offset = vec2{0, 0}, + .reset_on_exit = false, + }, + .sprite = test_sprite, + }); + } render_sys.update(); game_object_count++; total_time = run_all_systems(); -- cgit v1.2.3 From ca03e1fc7f0dd3e97f319529b9f00e48860f6d94 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 25 Nov 2024 20:49:47 +0100 Subject: improved test --- src/test/Profiling.cpp | 104 +++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 50 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 5cc70a4..8283bba 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -26,6 +26,14 @@ using namespace std::chrono_literals; using namespace crepe; using namespace testing; + +/* +List of test cases with component settings/details +1. Minimal test creates gameobject without additonal components +2. Minimal 'Complex' gameobject. Has dynamic body without bounce and no collision handler +3. Minimal 'Complex' gameobject. Same as test 2 but with particle emitter +*/ + class TestScript : public Script { bool oncollision(const CollisionEvent& test) { Log::logf("Box {} script on_collision()", test.info.first.collider.game_object_id); @@ -43,6 +51,11 @@ class TestScript : public Script { class Profiling : public Test { public: + // config for test + const int min_gameobject_count = 100; + const int max_gameobject_count = 1000; + const std::chrono::microseconds duration = 16000us; + ComponentManager mgr; // Add system used for profling tests CollisionSystem collision_sys{mgr}; @@ -51,12 +64,11 @@ public: RenderSystem render_sys{mgr}; ScriptSystem script_sys{mgr}; - // Store individual function timings - std::map timings; + // Test data + std::map timings; + int game_object_count = 0; + std::chrono::microseconds total_time = 0us; - // Min and max gameobject that should and can be created - int min_gameobject_count = 100; - int max_gameobject_count = 1000; void SetUp() override { @@ -71,18 +83,18 @@ public: // Helper function to time an update call and store its duration template - long long time_function(const std::string& name, Func&& func) { + std::chrono::microseconds time_function(const std::string& name, Func&& func) { auto start = std::chrono::steady_clock::now(); func(); auto end = std::chrono::steady_clock::now(); - auto duration = std::chrono::duration_cast(end - start).count(); - timings[name] = duration; // Store the duration in microseconds - return duration; // Return the duration in microseconds + std::chrono::microseconds duration = std::chrono::duration_cast(end - start); + timings[name] = duration; + return duration; } // Run and profile all systems, return the total time in milliseconds - long long run_all_systems() { - long long total_microseconds = 0; + std::chrono::microseconds run_all_systems() { + std::chrono::microseconds total_microseconds = 0us; total_microseconds += time_function("PhysicsSystem", [&]() { physics_sys.update(); }); total_microseconds += time_function("CollisionSystem", [&]() { collision_sys.update(); }); total_microseconds += time_function("ParticleSystem", [&]() { particle_sys.update(); }); @@ -91,41 +103,36 @@ public: } // Print timings of all functions - void log_timings(long long total_time,int game_object_count) const { + void log_timings() const { std::stringstream ss; - ss << std::endl <<"Function timings:\n"; // Starting with a header - for (const auto& [name, duration] : timings) { - ss << name << " took " << duration / 1000.0 << " ms (" << duration << " µs). " << std::endl; - } - ss << "Total time: " << total_time / 1000.0 << "ms (" << total_time << " µs)" << std::endl; - ss << "Amount of gameobjects: " << game_object_count << std::endl; - // Use GTest INFO macro to print the accumulated log without extra newlines - GTEST_LOG_(INFO) << ss.str(); + ss << "\nFunction timings:\n"; + for (const auto& [name, duration] : timings) { + ss << name << " took " << duration.count() / 1000.0 << " ms (" << duration.count() << " µs).\n"; + } + ss << "Total time: " << this->total_time.count() / 1000.0 << " ms (" << this->total_time.count() << " µs)\n"; + ss << "Amount of gameobjects: " << game_object_count << "\n"; + GTEST_LOG_(INFO) << ss.str(); } }; -TEST_F(Profiling, Profiling_example) { - int game_object_count = 0; - long long total_time = 0; - while (total_time < 16000) { - +TEST_F(Profiling, Profiling_1) { + while (this->total_time < this->duration) { + { //define gameobject used for testing GameObject gameobject = mgr.new_object("gameobject","",{0,0}); } - game_object_count++; - total_time = run_all_systems(); - if(game_object_count >= max_gameobject_count) break; + this->game_object_count++; + this->total_time = run_all_systems(); + if(this->game_object_count >= this->max_gameobject_count) break; } - log_timings(total_time,game_object_count); - EXPECT_GE(game_object_count, min_gameobject_count); + log_timings(); + EXPECT_GE(this->game_object_count, this->min_gameobject_count); } -TEST_F(Profiling, Profiling_small_object) { - int game_object_count = 0; - long long total_time = 0; - while (total_time < 16000) { +TEST_F(Profiling, Profiling_2) { + while (this->total_time < this->duration) { { //define gameobject used for testing @@ -142,19 +149,16 @@ TEST_F(Profiling, Profiling_small_object) { FlipSettings{true, true}); } - render_sys.update(); - game_object_count++; - total_time = run_all_systems(); - if(game_object_count >= max_gameobject_count) break; + this->game_object_count++; + this->total_time = run_all_systems(); + if(this->game_object_count >= this->max_gameobject_count) break; } - log_timings(total_time,game_object_count); - EXPECT_GE(game_object_count, min_gameobject_count); + log_timings(); + EXPECT_GE(this->game_object_count, this->min_gameobject_count); } -TEST_F(Profiling, Profiling_small_object_Particle_emitter) { - int game_object_count = 0; - long long total_time = 0; - while (total_time < 16000) { +TEST_F(Profiling, Profiling_3) { + while (this->total_time < this->duration) { { //define gameobject used for testing @@ -172,7 +176,7 @@ TEST_F(Profiling, Profiling_small_object_Particle_emitter) { Sprite & test_sprite = gameobject.add_component( make_shared("/home/jaro/crepe/asset/texture/img.png"), color, FlipSettings{false, false}); auto & test = gameobject.add_component(ParticleEmitter::Data{ - .max_particles = 100, + .max_particles = 10, .emission_rate = 100, .end_lifespan = 100000, .boundary{ @@ -185,10 +189,10 @@ TEST_F(Profiling, Profiling_small_object_Particle_emitter) { }); } render_sys.update(); - game_object_count++; - total_time = run_all_systems(); - if(game_object_count >= max_gameobject_count) break; + this->game_object_count++; + this->total_time = run_all_systems(); + if(this->game_object_count >= this->max_gameobject_count) break; } - log_timings(total_time,game_object_count); - EXPECT_GE(game_object_count, min_gameobject_count); + log_timings(); + EXPECT_GE(this->game_object_count, this->min_gameobject_count); } -- cgit v1.2.3 From b6c69952a1747b1181c9b684f40cf3a3f8c79def Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 25 Nov 2024 21:45:52 +0100 Subject: added average --- src/test/Profiling.cpp | 54 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 11 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 8283bba..6b32805 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -51,10 +51,16 @@ class TestScript : public Script { class Profiling : public Test { public: - // config for test + // Config for test + // Minimum amount to let test pass const int min_gameobject_count = 100; - const int max_gameobject_count = 1000; + // Maximum amount to stop test + const int max_gameobject_count = 200; + // Amount of times a test runs to calculate average + const int average = 10; + // Maximum duration to stop test const std::chrono::microseconds duration = 16000us; + ComponentManager mgr; // Add system used for profling tests @@ -88,7 +94,7 @@ public: func(); auto end = std::chrono::steady_clock::now(); std::chrono::microseconds duration = std::chrono::duration_cast(end - start); - timings[name] = duration; + timings[name] += duration; return duration; } @@ -107,16 +113,23 @@ public: std::stringstream ss; ss << "\nFunction timings:\n"; for (const auto& [name, duration] : timings) { - ss << name << " took " << duration.count() / 1000.0 << " ms (" << duration.count() << " µs).\n"; + ss << name << " took " << duration.count() / 1000.0 / average << " ms (" << duration.count() / average << " µs).\n"; } - ss << "Total time: " << this->total_time.count() / 1000.0 << " ms (" << this->total_time.count() << " µs)\n"; + ss << "Total time: " << this->total_time.count() / 1000.0 / average << " ms (" << this->total_time.count() / average << " µs)\n"; ss << "Amount of gameobjects: " << game_object_count << "\n"; GTEST_LOG_(INFO) << ss.str(); } + + void clear_timings() { + for (auto& [key, value] : timings) { + value = std::chrono::microseconds(0); + } + } }; TEST_F(Profiling, Profiling_1) { - while (this->total_time < this->duration) { + while (this->total_time/this->average < this->duration) { + { //define gameobject used for testing @@ -124,7 +137,14 @@ TEST_F(Profiling, Profiling_1) { } this->game_object_count++; - this->total_time = run_all_systems(); + + this->total_time = 0us; + clear_timings(); + + for (int amount = 0; amount < this->average; amount++) { + this->total_time += run_all_systems(); + } + if(this->game_object_count >= this->max_gameobject_count) break; } log_timings(); @@ -132,7 +152,7 @@ TEST_F(Profiling, Profiling_1) { } TEST_F(Profiling, Profiling_2) { - while (this->total_time < this->duration) { + while (this->total_time/this->average < this->duration) { { //define gameobject used for testing @@ -150,7 +170,13 @@ TEST_F(Profiling, Profiling_2) { } this->game_object_count++; - this->total_time = run_all_systems(); + + this->total_time = 0us; + clear_timings(); + for (int amount = 0; amount < this->average; amount++) { + this->total_time += run_all_systems(); + } + if(this->game_object_count >= this->max_gameobject_count) break; } log_timings(); @@ -158,7 +184,7 @@ TEST_F(Profiling, Profiling_2) { } TEST_F(Profiling, Profiling_3) { - while (this->total_time < this->duration) { + while (this->total_time/this->average < this->duration) { { //define gameobject used for testing @@ -190,7 +216,13 @@ TEST_F(Profiling, Profiling_3) { } render_sys.update(); this->game_object_count++; - this->total_time = run_all_systems(); + + this->total_time = 0us; + clear_timings(); + for (int amount = 0; amount < this->average; amount++) { + this->total_time += run_all_systems(); + } + if(this->game_object_count >= this->max_gameobject_count) break; } log_timings(); -- cgit v1.2.3 From 15498a9b2b1c0052bcde6b367c1726b1d883cdd2 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Tue, 26 Nov 2024 19:38:26 +0100 Subject: added average --- src/test/Profiling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 6b32805..59d9ed6 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -57,7 +57,7 @@ public: // Maximum amount to stop test const int max_gameobject_count = 200; // Amount of times a test runs to calculate average - const int average = 10; + const int average = 5; // Maximum duration to stop test const std::chrono::microseconds duration = 16000us; -- cgit v1.2.3 From 8f2d0a5a7edb6120c85cb7250e14e2055831a7cb Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Tue, 26 Nov 2024 19:42:09 +0100 Subject: fixed path --- src/test/Profiling.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 59d9ed6..2b03102 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -165,7 +165,7 @@ TEST_F(Profiling, Profiling_2) { gameobject.add_component().set_script(); Color color(0, 0, 0, 0); gameobject.add_component( - make_shared("/home/jaro/crepe/asset/texture/green_square.png"), color, + make_shared("asset/texture/green_square.png"), color, FlipSettings{true, true}); } @@ -197,10 +197,10 @@ TEST_F(Profiling, Profiling_3) { gameobject.add_component().set_script(); Color color(0, 0, 0, 0); gameobject.add_component( - make_shared("/home/jaro/crepe/asset/texture/green_square.png"), color, + make_shared("asset/texture/green_square.png"), color, FlipSettings{true, true}); Sprite & test_sprite = gameobject.add_component( - make_shared("/home/jaro/crepe/asset/texture/img.png"), color, FlipSettings{false, false}); + make_shared("asset/texture/img.png"), color, FlipSettings{false, false}); auto & test = gameobject.add_component(ParticleEmitter::Data{ .max_particles = 10, .emission_rate = 100, -- cgit v1.2.3 From 7566fa3d50093935315598aabcb0dc0a9e7cca57 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Sun, 1 Dec 2024 22:07:05 +0100 Subject: removed struct and renamed structs --- src/crepe/system/CollisionSystem.cpp | 100 ++++++++++++++-------------- src/crepe/system/CollisionSystem.h | 41 +++++------- src/test/CMakeLists.txt | 4 +- src/test/CollisionTest.cpp | 124 +++++++++++++++++------------------ src/test/Profiling.cpp | 2 +- 5 files changed, 134 insertions(+), 137 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 6f2c39d..362378d 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -28,19 +28,19 @@ void CollisionSystem::update() { std::vector> boxcolliders = mgr.get_components_by_type(); std::vector> circlecolliders = mgr.get_components_by_type(); - std::vector all_colliders; + std::vector all_colliders; // Add BoxCollider references for (auto& box : boxcolliders) { - all_colliders.push_back(collider_stor{box}); + all_colliders.push_back(collider_variant{box}); } // Add CircleCollider references for (auto& circle : circlecolliders) { - all_colliders.push_back(collider_stor{circle}); + all_colliders.push_back(collider_variant{circle}); } // Check between all colliders if there is a collision - std::vector> collided = check_collisions(all_colliders); + std::vector> collided = check_collisions(all_colliders); // For both objects call the collision handler for (auto& collision_pair : collided) { @@ -49,30 +49,30 @@ void CollisionSystem::update() { } } -void CollisionSystem::collision_handler_request(CollidedInfoStor& data1,CollidedInfoStor& data2){ +void CollisionSystem::collision_handler_request(CollisionInternal& data1,CollisionInternal& data2){ - ColliderStorType type = check_collider_type(data1.collider,data2.collider); - std::pair move_back_data = collision_handler(data1,data2,type); + CollisionInternalType type = check_collider_type(data1.collider,data2.collider); + std::pair resolution_data = collision_handler(data1,data2,type); OptionalRef collider1; OptionalRef collider2; switch (type) { - case ColliderStorType::BOX_BOX:{ + case CollisionInternalType::BOX_BOX:{ collider1 = std::get>(data1.collider); collider2 = std::get>(data2.collider); break; } - case ColliderStorType::BOX_CIRCLE:{ + case CollisionInternalType::BOX_CIRCLE:{ collider1 = std::get>(data1.collider); collider2 = std::get>(data2.collider); break; } - case ColliderStorType::CIRCLE_BOX:{ + case CollisionInternalType::CIRCLE_BOX:{ collider1 = std::get>(data1.collider); collider2 = std::get>(data2.collider); break; } - case ColliderStorType::CIRCLE_CIRCLE:{ + case CollisionInternalType::CIRCLE_CIRCLE:{ collider1 = std::get>(data1.collider); collider2 = std::get>(data2.collider); break; @@ -81,10 +81,14 @@ void CollisionSystem::collision_handler_request(CollidedInfoStor& data1,Collided // collision info crepe::CollisionSystem::CollisionInfo collision_info{ - .first={ collider1, data1.transform, data1.rigidbody }, - .second={ collider2, data2.transform, data2.rigidbody }, - .move_back_value = move_back_data.first, - .move_back_direction = move_back_data.second, + .first_collider = collider1, + .first_transform = data1.transform, + .first_rigidbody = data1.rigidbody, + .second_collider = collider2, + .second_transform = data2.transform, + .second_rigidbody = data2.rigidbody, + .resolution = resolution_data.first, + .resolution_direction = resolution_data.second, }; // Determine if static needs to be called @@ -92,23 +96,23 @@ void CollisionSystem::collision_handler_request(CollidedInfoStor& data1,Collided } -std::pair CollisionSystem::collision_handler(CollidedInfoStor& data1,CollidedInfoStor& data2,ColliderStorType type) { +std::pair CollisionSystem::collision_handler(CollisionInternal& data1,CollisionInternal& data2,CollisionInternalType type) { vec2 move_back; switch (type) { - case ColliderStorType::BOX_BOX: { + case CollisionInternalType::BOX_BOX: { const BoxCollider & collider1 = std::get>(data1.collider); const BoxCollider & collider2 = std::get>(data2.collider); vec2 collider_pos1 = current_position(collider1.offset, data1.transform, data1.rigidbody); vec2 collider_pos2 = current_position(collider2.offset, data2.transform, data2.rigidbody); move_back = box_box_move_back(collider1,collider2,collider_pos1,collider_pos2); } - case ColliderStorType::BOX_CIRCLE: { + case CollisionInternalType::BOX_CIRCLE: { } - case ColliderStorType::CIRCLE_CIRCLE: { + case CollisionInternalType::CIRCLE_CIRCLE: { } - case ColliderStorType::CIRCLE_BOX: { + case CollisionInternalType::CIRCLE_BOX: { } } @@ -165,43 +169,43 @@ vec2 CollisionSystem::box_box_move_back(const BoxCollider& box_collider1,const B void CollisionSystem::determine_collision_handler(CollisionInfo& info){ // Check rigidbody type for static - if(info.first.rigidbody.data.body_type != Rigidbody::BodyType::STATIC) + if(info.first_rigidbody.data.body_type != Rigidbody::BodyType::STATIC) { // If second body is static perform the static collision handler in this system - if(info.second.rigidbody.data.body_type == Rigidbody::BodyType::STATIC){ + if(info.second_rigidbody.data.body_type == Rigidbody::BodyType::STATIC){ static_collision_handler(info); }; // Call collision event for user CollisionEvent data(info); - EventManager::get_instance().trigger_event(data, info.first.collider.game_object_id); + EventManager::get_instance().trigger_event(data, info.first_collider.game_object_id); } } void CollisionSystem::static_collision_handler(CollisionInfo& info){ // Move object back using calculate move back value - info.first.transform.position += info.move_back_value; + info.first_transform.position += info.resolution; // If bounce is enabled mirror velocity - if(info.first.rigidbody.data.bounce) { - if(info.move_back_direction == Direction::BOTH) + if(info.first_rigidbody.data.bounce) { + if(info.resolution_direction == Direction::BOTH) { - info.first.rigidbody.data.linear_velocity.y = -info.first.rigidbody.data.linear_velocity.y * info.first.rigidbody.data.elastisity; - info.first.rigidbody.data.linear_velocity.x = -info.first.rigidbody.data.linear_velocity.x * info.first.rigidbody.data.elastisity; + info.first_rigidbody.data.linear_velocity.y = -info.first_rigidbody.data.linear_velocity.y * info.first_rigidbody.data.elastisity; + info.first_rigidbody.data.linear_velocity.x = -info.first_rigidbody.data.linear_velocity.x * info.first_rigidbody.data.elastisity; } - else if(info.move_back_direction == Direction::Y_DIRECTION) { - info.first.rigidbody.data.linear_velocity.y = -info.first.rigidbody.data.linear_velocity.y * info.first.rigidbody.data.elastisity; + else if(info.resolution_direction == Direction::Y_DIRECTION) { + info.first_rigidbody.data.linear_velocity.y = -info.first_rigidbody.data.linear_velocity.y * info.first_rigidbody.data.elastisity; } - else if(info.move_back_direction == Direction::X_DIRECTION){ - info.first.rigidbody.data.linear_velocity.x = -info.first.rigidbody.data.linear_velocity.x * info.first.rigidbody.data.elastisity; + else if(info.resolution_direction == Direction::X_DIRECTION){ + info.first_rigidbody.data.linear_velocity.x = -info.first_rigidbody.data.linear_velocity.x * info.first_rigidbody.data.elastisity; } } // Stop movement if bounce is disabled else { - info.first.rigidbody.data.linear_velocity = {0,0}; + info.first_rigidbody.data.linear_velocity = {0,0}; } } -std::vector> CollisionSystem::check_collisions(std::vector & colliders) { +std::vector> CollisionSystem::check_collisions(std::vector & colliders) { // TODO: @@ -233,7 +237,7 @@ std::vector> collisions_ret; + std::vector> collisions_ret; for (size_t i = 0; i < colliders.size(); ++i) { std::visit([&](auto& inner_collider_ref) { if (!inner_collider_ref.get().active) return; @@ -245,11 +249,11 @@ std::vectorfirst.get(), inner_components->second.get()}, - CollidedInfoStor{colliders[j], outer_components->first.get(), outer_components->second.get()} + CollisionInternal{colliders[i], inner_components->first.get(), inner_components->second.get()}, + CollisionInternal{colliders[j], outer_components->first.get(), outer_components->second.get()} ); }, colliders[j]); } @@ -259,45 +263,45 @@ std::vector>(collider1)){ if(std::holds_alternative>(collider2)) { - return ColliderStorType::CIRCLE_CIRCLE; + return CollisionInternalType::CIRCLE_CIRCLE; } else { - return ColliderStorType::CIRCLE_BOX; + return CollisionInternalType::CIRCLE_BOX; } } else { if(std::holds_alternative>(collider2)) { - return ColliderStorType::BOX_CIRCLE; + return CollisionInternalType::BOX_CIRCLE; } else { - return ColliderStorType::BOX_BOX; + return CollisionInternalType::BOX_BOX; } } } -bool CollisionSystem::check_collision(const collider_stor& collider1,std::pair, std::reference_wrapper> components1,const collider_stor& collider2,std::pair, std::reference_wrapper> components2, ColliderStorType type){ +bool CollisionSystem::check_collision(const collider_variant& collider1,std::pair, std::reference_wrapper> components1,const collider_variant& collider2,std::pair, std::reference_wrapper> components2, CollisionInternalType type){ switch (type) { - case ColliderStorType::BOX_BOX: { + case CollisionInternalType::BOX_BOX: { const BoxCollider & box_collider1 = std::get>(collider1); const BoxCollider & box_collider2 = std::get>(collider2); return check_box_box_collision(box_collider1,box_collider2,components1.first.get(),components2.first.get(),components1.second.get(),components2.second.get()); } - case ColliderStorType::BOX_CIRCLE: { + case CollisionInternalType::BOX_CIRCLE: { const BoxCollider & box_collider = std::get>(collider1); const CircleCollider & circle_collider = std::get>(collider2); return check_box_circle_collision(box_collider,circle_collider,components1.first.get(),components2.first.get(),components1.second.get(),components2.second.get()); } - case ColliderStorType::CIRCLE_CIRCLE: { + case CollisionInternalType::CIRCLE_CIRCLE: { const CircleCollider & circle_collider1 = std::get>(collider1); const CircleCollider & circle_collider2 = std::get>(collider2); return check_circle_circle_collision(circle_collider1,circle_collider2,components1.first.get(),components2.first.get(),components1.second.get(),components2.second.get()); } - case ColliderStorType::CIRCLE_BOX: { + case CollisionInternalType::CIRCLE_BOX: { const CircleCollider & circle_collider = std::get>(collider1); const BoxCollider & box_collider = std::get>(collider2); return check_box_circle_collision(box_collider,circle_collider,components1.first.get(),components2.first.get(),components1.second.get(),components2.second.get()); diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 6334ba1..f8c7633 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -23,10 +23,10 @@ private: //! A variant type that can hold either a BoxCollider or a CircleCollider. // using collider_stor = std::variant; - using collider_stor = std::variant, std::reference_wrapper>; + using collider_variant = std::variant, std::reference_wrapper>; //! A enum that is used to tell the pair of the collider stor in a std::pair. - enum class ColliderStorType { + enum class CollisionInternalType { BOX_BOX, CIRCLE_CIRCLE, BOX_CIRCLE, @@ -38,9 +38,9 @@ private: * * This structure stores the collider type, its associated transform, and its rigidbody. */ - struct CollidedInfoStor { + struct CollisionInternal { //! Store either BoxCollider or CircleCollider - collider_stor& collider; + collider_variant& collider; Transform& transform; Rigidbody& rigidbody; }; @@ -54,27 +54,20 @@ private: }; public: - /** - * \brief A structure representing the collision information between two colliders. - * - * This structure contains both colliders, their associated transforms and rigidbodies, - * as well as the movement vector to resolve the collision. - */ - struct ColliderInfo { - const Collider& collider; - Transform& transform; - Rigidbody& rigidbody; - }; /** * \brief A structure representing detailed collision information between two colliders. * * This includes the movement data required to resolve the collision. */ struct CollisionInfo{ - ColliderInfo first; - ColliderInfo second; - vec2 move_back_value; - Direction move_back_direction = Direction::NONE; + Collider& first_collider; + Transform& first_transform; + Rigidbody& first_rigidbody; + Collider& second_collider; + Transform& second_transform; + Rigidbody& second_rigidbody; + vec2 resolution; + Direction resolution_direction = Direction::NONE; }; public: @@ -94,7 +87,7 @@ private: //generic * * \return collider pair type. */ - ColliderStorType check_collider_type(const collider_stor& collider1,const collider_stor& collider2); + CollisionInternalType check_collider_type(const collider_variant& collider1,const collider_variant& collider2); /** * \brief Calculates the position of the Collider @@ -122,7 +115,7 @@ private:// handeling * * \return Postion of collider. */ - void collision_handler_request(CollidedInfoStor& data1,CollidedInfoStor& data2); + void collision_handler_request(CollisionInternal& data1,CollisionInternal& data2); /** * \brief Calculates the move back value and direction of the Collision @@ -135,7 +128,7 @@ private:// handeling * * \return Move back value and direction for first gameobject */ - std::pair collision_handler(CollidedInfoStor& data1,CollidedInfoStor& data2 ,ColliderStorType type); + std::pair collision_handler(CollisionInternal& data1,CollisionInternal& data2 ,CollisionInternalType type); /** * \brief Calculates the move back value for box box collision @@ -183,7 +176,7 @@ private: // detection * * \return Move back value and direction for first gameobject */ - std::vector> check_collisions(std::vector & colliders); + std::vector> check_collisions(std::vector & colliders); /** * \brief Calls the correct check collision function. @@ -198,7 +191,7 @@ private: // detection * * \return status of collision */ - bool check_collision(const collider_stor& collider1,std::pair, std::reference_wrapper> components1,const collider_stor& collider2,std::pair, std::reference_wrapper> components2,CollisionSystem::ColliderStorType type); + bool check_collision(const collider_variant& collider1,std::pair, std::reference_wrapper> components1,const collider_variant& collider2,std::pair, std::reference_wrapper> components2,CollisionSystem::CollisionInternalType type); /** * \brief Check collision for box on box collider diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 68fa01c..616e238 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,5 +1,5 @@ target_sources(test_main PUBLIC - # CollisionTest.cpp + CollisionTest.cpp main.cpp # PhysicsTest.cpp # ScriptTest.cpp @@ -13,5 +13,5 @@ target_sources(test_main PUBLIC # ValueBrokerTest.cpp # DBTest.cpp # Vector2Test.cpp - Profiling.cpp + # Profiling.cpp ) diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index 245cced..8daf77f 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -114,11 +114,11 @@ TEST_F(CollisionTest, collision_example) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 1); + EXPECT_EQ(ev.info.first_collider.game_object_id, 1); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 2); + EXPECT_EQ(ev.info.first_collider.game_object_id, 2); }; EXPECT_FALSE(collision_happend); collision_sys.update(); @@ -129,17 +129,17 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both_no_velocity) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 1); - EXPECT_EQ(ev.info.move_back_value.x, 10); - EXPECT_EQ(ev.info.move_back_value.y, 10); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::BOTH); + EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.resolution.x, 10); + EXPECT_EQ(ev.info.resolution.y, 10); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 2); - EXPECT_EQ(ev.info.move_back_value.x, 10); - EXPECT_EQ(ev.info.move_back_value.y, 10); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::BOTH); + EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.resolution.x, 10); + EXPECT_EQ(ev.info.resolution.y, 10); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); @@ -152,17 +152,17 @@ TEST_F(CollisionTest, collision_box_box_dynamic_x_direction_no_velocity) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 1); - EXPECT_EQ(ev.info.move_back_value.x, -5); - EXPECT_EQ(ev.info.move_back_value.y, 0); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::X_DIRECTION); + EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.resolution.x, -5); + EXPECT_EQ(ev.info.resolution.y, 0); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 2); - EXPECT_EQ(ev.info.move_back_value.x, 5); - EXPECT_EQ(ev.info.move_back_value.y, 0); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::X_DIRECTION); + EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.resolution.x, 5); + EXPECT_EQ(ev.info.resolution.y, 0); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); @@ -175,17 +175,17 @@ TEST_F(CollisionTest, collision_box_box_dynamic_y_direction_no_velocity) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 1); - EXPECT_EQ(ev.info.move_back_value.x, 0); - EXPECT_EQ(ev.info.move_back_value.y, -5); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); + EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.resolution.x, 0); + EXPECT_EQ(ev.info.resolution.y, -5); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 2); - EXPECT_EQ(ev.info.move_back_value.x, 0); - EXPECT_EQ(ev.info.move_back_value.y, 5); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); + EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.resolution.x, 0); + EXPECT_EQ(ev.info.resolution.y, 5); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); @@ -198,17 +198,17 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 1); - EXPECT_EQ(ev.info.move_back_value.x, 10); - EXPECT_EQ(ev.info.move_back_value.y, 10); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::BOTH); + EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.resolution.x, 10); + EXPECT_EQ(ev.info.resolution.y, 10); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 2); - EXPECT_EQ(ev.info.move_back_value.x, 10); - EXPECT_EQ(ev.info.move_back_value.y, 10); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::BOTH); + EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.resolution.x, 10); + EXPECT_EQ(ev.info.resolution.y, 10); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); @@ -225,17 +225,17 @@ TEST_F(CollisionTest, collision_box_box_dynamic_x_direction) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 1); - EXPECT_EQ(ev.info.move_back_value.x, -5); - EXPECT_EQ(ev.info.move_back_value.y, -5); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::X_DIRECTION); + EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.resolution.x, -5); + EXPECT_EQ(ev.info.resolution.y, -5); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 2); - EXPECT_EQ(ev.info.move_back_value.x, 5); - EXPECT_EQ(ev.info.move_back_value.y, 5); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::X_DIRECTION); + EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.resolution.x, 5); + EXPECT_EQ(ev.info.resolution.y, 5); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); @@ -252,17 +252,17 @@ TEST_F(CollisionTest, collision_box_box_dynamic_y_direction) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 1); - EXPECT_EQ(ev.info.move_back_value.x, -5); - EXPECT_EQ(ev.info.move_back_value.y, -5); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); + EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.resolution.x, -5); + EXPECT_EQ(ev.info.resolution.y, -5); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 2); - EXPECT_EQ(ev.info.move_back_value.x, 5); - EXPECT_EQ(ev.info.move_back_value.y, 5); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); + EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.resolution.x, 5); + EXPECT_EQ(ev.info.resolution.y, 5); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); @@ -280,10 +280,10 @@ TEST_F(CollisionTest, collision_box_box_static_both) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 1); - EXPECT_EQ(ev.info.move_back_value.x, 10); - EXPECT_EQ(ev.info.move_back_value.y, 10); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::BOTH); + EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.resolution.x, 10); + EXPECT_EQ(ev.info.resolution.y, 10); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { // is static should not be called @@ -302,10 +302,10 @@ TEST_F(CollisionTest, collision_box_box_static_x_direction) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 1); - EXPECT_EQ(ev.info.move_back_value.x, -5); - EXPECT_EQ(ev.info.move_back_value.y, -5); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::X_DIRECTION); + EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.resolution.x, -5); + EXPECT_EQ(ev.info.resolution.y, -5); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { // is static should not be called @@ -326,10 +326,10 @@ TEST_F(CollisionTest, collision_box_box_static_y_direction) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first.collider.game_object_id, 1); - EXPECT_EQ(ev.info.move_back_value.x, -5); - EXPECT_EQ(ev.info.move_back_value.y, -5); - EXPECT_EQ(ev.info.move_back_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); + EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.resolution.x, -5); + EXPECT_EQ(ev.info.resolution.y, -5); + EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { // is static should not be called diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 2b03102..2549c57 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -36,7 +36,7 @@ List of test cases with component settings/details class TestScript : public Script { bool oncollision(const CollisionEvent& test) { - Log::logf("Box {} script on_collision()", test.info.first.collider.game_object_id); + Log::logf("Box {} script on_collision()", test.info.first_collider.game_object_id); return true; } void init() { -- cgit v1.2.3 From eeb66130e2cb94c94e1748576f98f78ce0f1ee86 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 2 Dec 2024 17:17:21 +0100 Subject: changed some values because of feedback and merged from master --- src/crepe/Collider.cpp | 2 +- src/crepe/Collider.h | 2 +- src/crepe/api/BoxCollider.cpp | 2 +- src/crepe/api/BoxCollider.h | 2 +- src/crepe/api/CircleCollider.cpp | 2 +- src/crepe/api/CircleCollider.h | 2 +- src/crepe/api/Rigidbody.h | 14 +++++------- src/crepe/system/CollisionSystem.cpp | 18 ++++++++-------- src/crepe/system/CollisionSystem.h | 8 +++---- src/crepe/system/PhysicsSystem.cpp | 10 ++++----- src/test/CMakeLists.txt | 2 +- src/test/CollisionTest.cpp | 5 ----- src/test/Profiling.cpp | 42 +++++++++++++++++++----------------- 13 files changed, 52 insertions(+), 59 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/crepe/Collider.cpp b/src/crepe/Collider.cpp index 80a944d..9d94152 100644 --- a/src/crepe/Collider.cpp +++ b/src/crepe/Collider.cpp @@ -2,4 +2,4 @@ using namespace crepe; -Collider::Collider(game_object_id_t id, vec2 offset) : Component(id), offset(offset) {} +Collider::Collider(game_object_id_t id, const vec2& offset) : Component(id), offset(offset) {} diff --git a/src/crepe/Collider.h b/src/crepe/Collider.h index e1624b4..15d3a24 100644 --- a/src/crepe/Collider.h +++ b/src/crepe/Collider.h @@ -7,7 +7,7 @@ namespace crepe { class Collider : public Component { public: - Collider(game_object_id_t id, vec2 offset); + Collider(game_object_id_t id, const vec2& offset); public: //! Offset of the collider relative to rigidbody position diff --git a/src/crepe/api/BoxCollider.cpp b/src/crepe/api/BoxCollider.cpp index 6034837..1069e90 100644 --- a/src/crepe/api/BoxCollider.cpp +++ b/src/crepe/api/BoxCollider.cpp @@ -4,4 +4,4 @@ using namespace crepe; -BoxCollider::BoxCollider(game_object_id_t game_object_id,vec2 offset, float width, float height) : Collider(game_object_id,offset), width(width), height(height) {} +BoxCollider::BoxCollider(game_object_id_t game_object_id,const vec2& offset, float width, float height) : Collider(game_object_id,offset), width(width), height(height) {} diff --git a/src/crepe/api/BoxCollider.h b/src/crepe/api/BoxCollider.h index 2ce1ee8..c83d54a 100644 --- a/src/crepe/api/BoxCollider.h +++ b/src/crepe/api/BoxCollider.h @@ -12,7 +12,7 @@ namespace crepe { */ class BoxCollider : public Collider { public: - BoxCollider(game_object_id_t game_object_id,vec2 offset, float width, float height); + BoxCollider(game_object_id_t game_object_id,const vec2& offset, float width, float height); //! Width of box collider float width; diff --git a/src/crepe/api/CircleCollider.cpp b/src/crepe/api/CircleCollider.cpp index 497ebba..473734e 100644 --- a/src/crepe/api/CircleCollider.cpp +++ b/src/crepe/api/CircleCollider.cpp @@ -3,4 +3,4 @@ using namespace crepe; -CircleCollider::CircleCollider(game_object_id_t game_object_id,vec2 offset, float radius) : Collider(game_object_id,offset), radius(radius) {} +CircleCollider::CircleCollider(game_object_id_t game_object_id,const vec2& offset, float radius) : Collider(game_object_id,offset), radius(radius) {} diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h index c61f027..bbcc330 100644 --- a/src/crepe/api/CircleCollider.h +++ b/src/crepe/api/CircleCollider.h @@ -14,7 +14,7 @@ namespace crepe { class CircleCollider : public Collider { public: - CircleCollider(game_object_id_t game_object_id,vec2 offset, float radius); + CircleCollider(game_object_id_t game_object_id,const vec2& offset, float radius); //! Radius of the circle collider. float radius; diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 446c5dd..63b1b51 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -54,7 +54,7 @@ public: //! objects mass float mass = 0.0; //! gravtiy scale - float gravity_scale = 0.0; + float gravity_scale = 0; //! Changes if physics apply BodyType body_type = BodyType::DYNAMIC; //! linear velocity of object @@ -62,20 +62,16 @@ public: //! maximum linear velocity of object vec2 max_linear_velocity = {INFINITY ,INFINITY}; //! linear damping of object - vec2 linear_damping; + vec2 linear_velocity_factor; //! angular velocity of object - float angular_velocity = 0.0; + float angular_velocity = 1; //! max angular velocity of object float max_angular_velocity = INFINITY; //! angular damping of object - float angular_damping = 0.0; + float angular_velocity_factor = 1; //! movements constraints of object PhysicsConstraints constraints; - //! if gravity applies - bool use_gravity = true; - //! if object bounces - bool bounce = false; - //! bounce factor of material + //! bounce factor of material. 0.0 <= means all velocity is lost, 1.0 means it gets the same momentum but the mirrored direction. 0.5 is half of the velocity is saved. float elastisity = 0.0; //! offset of all colliders relative to transform position vec2 offset; diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 2fe3621..fbb16e8 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -146,10 +146,10 @@ std::pair CollisionSystem::collision_handler(Co resolution.x = data1.rigidbody.data.linear_velocity.x * (resolution.y/data1.rigidbody.data.linear_velocity.y); } - return {resolution,resolution_direction}; + return std::make_pair(resolution,resolution_direction); } -vec2 CollisionSystem::get_box_box_resolution(const BoxCollider& box_collider1,const BoxCollider& box_collider2,vec2 final_position1,vec2 final_position2) const +vec2 CollisionSystem::get_box_box_resolution(const BoxCollider& box_collider1,const BoxCollider& box_collider2,const vec2& final_position1,const vec2& final_position2) const { vec2 resolution; // Default resolution vector vec2 delta = final_position2 - final_position1; @@ -183,7 +183,7 @@ vec2 CollisionSystem::get_box_box_resolution(const BoxCollider& box_collider1,co return resolution; } -vec2 CollisionSystem::get_circle_circle_resolution(const CircleCollider& circle_collider1, const CircleCollider& circle_collider2, vec2 final_position1, vec2 final_position2) const +vec2 CollisionSystem::get_circle_circle_resolution(const CircleCollider& circle_collider1, const CircleCollider& circle_collider2, const vec2& final_position1, const vec2& final_position2) const { vec2 delta = final_position2 - final_position1; @@ -205,7 +205,7 @@ vec2 CollisionSystem::get_circle_circle_resolution(const CircleCollider& circle_ return resolution; } -vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider& circle_collider, const BoxCollider& box_collider, vec2 circle_position, vec2 box_position) const +vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider& circle_collider, const BoxCollider& box_collider, const vec2& circle_position, const vec2& box_position) const { vec2 delta = circle_position - box_position; @@ -252,7 +252,7 @@ void CollisionSystem::static_collision_handler(CollisionInfo& info){ info.first_transform.position += info.resolution; // If bounce is enabled mirror velocity - if(info.first_rigidbody.data.bounce) { + if(info.first_rigidbody.data.elastisity > 0) { if(info.resolution_direction == Direction::BOTH) { info.first_rigidbody.data.linear_velocity.y = -info.first_rigidbody.data.linear_velocity.y * info.first_rigidbody.data.elastisity; @@ -335,12 +335,12 @@ CollisionSystem::get_active_transform_and_rigidbody(game_object_id_t game_object RefVector transforms = this->component_manager.get_components_by_id(game_object_id); if (transforms.empty()) return std::nullopt; + Transform& transform = transforms.front().get(); + if (!transform.active) return std::nullopt; + RefVector rigidbodies = this->component_manager.get_components_by_id(game_object_id); if (rigidbodies.empty()) return std::nullopt; - Transform& transform = transforms.front().get(); - if (!transform.active) return std::nullopt; - Rigidbody& rigidbody = rigidbodies.front().get(); if (!rigidbody.active) return std::nullopt; @@ -453,7 +453,7 @@ bool CollisionSystem::get_circle_circle_collision(const CircleCollider& circle1, return distance_squared <= radius_sum * radius_sum; } -vec2 CollisionSystem::get_current_position(vec2 collider_offset, const Transform& transform, const Rigidbody& rigidbody) const { +vec2 CollisionSystem::get_current_position(const vec2& collider_offset, const Transform& transform, const Rigidbody& rigidbody) const { // Get the rotation in radians float radians1 = transform.rotation * (M_PI / 180.0); diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 3f24db1..34c03ae 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -104,7 +104,7 @@ private: * \param rigidbody The Rigidbody of the associated game object. * \return The calculated position of the collider. */ - vec2 get_current_position(vec2 collider_offset, const Transform& transform, const Rigidbody& rigidbody) const; + vec2 get_current_position(const vec2& collider_offset, const Transform& transform, const Rigidbody& rigidbody) const; private: @@ -141,7 +141,7 @@ private: * \param position2 The position of the second BoxCollider. * \return The resolution vector for the collision. */ - vec2 get_box_box_resolution(const BoxCollider& box_collider1,const BoxCollider& box_collider2,vec2 position1,vec2 position2) const; + vec2 get_box_box_resolution(const BoxCollider& box_collider1,const BoxCollider& box_collider2,const vec2& position1,const vec2& position2) const; /** * \brief Calculates the resolution vector for two CircleCollider. @@ -154,7 +154,7 @@ private: * \param position2 The position of the second CircleCollider. * \return The resolution vector for the collision. */ - vec2 get_circle_circle_resolution(const CircleCollider& circle_collider1, const CircleCollider& circle_collider2, vec2 final_position1, vec2 final_position2) const; + vec2 get_circle_circle_resolution(const CircleCollider& circle_collider1, const CircleCollider& circle_collider2, const vec2& final_position1, const vec2& final_position2) const; /** * \brief Calculates the resolution vector for two CircleCollider. @@ -167,7 +167,7 @@ private: * \param box_position The position of the BocCollider. * \return The resolution vector for the collision. */ - vec2 get_circle_box_resolution(const CircleCollider& circle_collider, const BoxCollider& box_collider, vec2 circle_position, vec2 box_position) const; + vec2 get_circle_box_resolution(const CircleCollider& circle_collider, const BoxCollider& box_collider, const vec2& circle_position, const vec2& box_position) const; /** * \brief Determines the appropriate collision handler for a collision. diff --git a/src/crepe/system/PhysicsSystem.cpp b/src/crepe/system/PhysicsSystem.cpp index 514a4b3..8f21727 100644 --- a/src/crepe/system/PhysicsSystem.cpp +++ b/src/crepe/system/PhysicsSystem.cpp @@ -25,17 +25,17 @@ void PhysicsSystem::update() { if (transform.game_object_id == rigidbody.game_object_id) { // Add gravity - if (rigidbody.data.use_gravity) { + if (rigidbody.data.gravity_scale > 0) { rigidbody.data.linear_velocity.y += (rigidbody.data.mass * rigidbody.data.gravity_scale * gravity); } // Add damping - if (rigidbody.data.angular_damping != 0) { - rigidbody.data.angular_velocity *= rigidbody.data.angular_damping; + if (rigidbody.data.angular_velocity_factor != 1 && rigidbody.data.angular_velocity_factor > 0) { + rigidbody.data.angular_velocity *= rigidbody.data.angular_velocity_factor; } - if (rigidbody.data.linear_damping != vec2{0, 0}) { - rigidbody.data.linear_velocity *= rigidbody.data.linear_damping; + if (rigidbody.data.linear_velocity_factor != vec2{1, 1} && rigidbody.data.linear_velocity_factor.x > 0 && rigidbody.data.linear_velocity_factor.y > 0) { + rigidbody.data.linear_velocity *= rigidbody.data.linear_velocity_factor; } // Max velocity check diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 616e238..4555c0b 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -13,5 +13,5 @@ target_sources(test_main PUBLIC # ValueBrokerTest.cpp # DBTest.cpp # Vector2Test.cpp - # Profiling.cpp + Profiling.cpp ) diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index ed40b1b..92ff7ba 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -65,7 +65,6 @@ public: world.add_component(Rigidbody::Data{ // TODO: remove unrelated properties: .body_type = Rigidbody::BodyType::STATIC, - .bounce = false, .offset = {0,0}, }); // Create a box with an inner size of 10x10 units @@ -80,8 +79,6 @@ public: .body_type = Rigidbody::BodyType::DYNAMIC, .linear_velocity = {0,0}, .constraints = {0, 0, 0}, - .use_gravity = true, - .bounce = true, .elastisity = 1, .offset = {0,0}, }); @@ -96,8 +93,6 @@ public: .body_type = Rigidbody::BodyType::DYNAMIC, .linear_velocity = {0,0}, .constraints = {0, 0, 0}, - .use_gravity = true, - .bounce = true, .elastisity = 1, .offset = {0,0}, }); diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 2549c57..a88bf85 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -79,7 +79,8 @@ public: void SetUp() override { GameObject do_not_use = mgr.new_object("DO_NOT_USE","",{0,0}); - do_not_use.add_component(Color::WHITE); + do_not_use.add_component(Color::WHITE, ivec2{1080, 720}, + vec2{2000, 2000}, 1.0f); // initialize systems here: //calls init script_sys.update(); @@ -110,14 +111,19 @@ public: // Print timings of all functions void log_timings() const { - std::stringstream ss; - ss << "\nFunction timings:\n"; - for (const auto& [name, duration] : timings) { - ss << name << " took " << duration.count() / 1000.0 / average << " ms (" << duration.count() / average << " µs).\n"; - } - ss << "Total time: " << this->total_time.count() / 1000.0 / average << " ms (" << this->total_time.count() / average << " µs)\n"; - ss << "Amount of gameobjects: " << game_object_count << "\n"; - GTEST_LOG_(INFO) << ss.str(); + std::string result = "\nFunction timings:\n"; + + for (const auto& [name, duration] : timings) { + result += name + " took " + std::to_string(duration.count() / 1000.0 / average) + " ms (" + + std::to_string(duration.count() / average) + " µs).\n"; + } + + result += "Total time: " + std::to_string(this->total_time.count() / 1000.0 / average) + " ms (" + + std::to_string(this->total_time.count() / average) + " µs)\n"; + + result += "Amount of gameobjects: " + std::to_string(game_object_count) + "\n"; + + GTEST_LOG_(INFO) << result; } void clear_timings() { @@ -158,15 +164,14 @@ TEST_F(Profiling, Profiling_2) { //define gameobject used for testing GameObject gameobject = mgr.new_object("gameobject","",{static_cast(game_object_count*2),0}); gameobject.add_component(Rigidbody::Data{ - .body_type = Rigidbody::BodyType::STATIC, - .use_gravity = false, + .gravity_scale = 0.0, + .body_type = Rigidbody::BodyType::STATIC, }); gameobject.add_component(vec2{0, 0}, 1, 1); gameobject.add_component().set_script(); Color color(0, 0, 0, 0); - gameobject.add_component( - make_shared("asset/texture/green_square.png"), color, - FlipSettings{true, true}); + auto img = Texture("asset/texture/green_square.png"); + Sprite & test_sprite = gameobject.add_component(img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); } this->game_object_count++; @@ -190,17 +195,14 @@ TEST_F(Profiling, Profiling_3) { //define gameobject used for testing GameObject gameobject = mgr.new_object("gameobject","",{static_cast(game_object_count*2),0}); gameobject.add_component(Rigidbody::Data{ + .gravity_scale = 0, .body_type = Rigidbody::BodyType::STATIC, - .use_gravity = false, }); gameobject.add_component(vec2{0, 0}, 1, 1); gameobject.add_component().set_script(); Color color(0, 0, 0, 0); - gameobject.add_component( - make_shared("asset/texture/green_square.png"), color, - FlipSettings{true, true}); - Sprite & test_sprite = gameobject.add_component( - make_shared("asset/texture/img.png"), color, FlipSettings{false, false}); + auto img = Texture("asset/texture/green_square.png"); + Sprite & test_sprite = gameobject.add_component(img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); auto & test = gameobject.add_component(ParticleEmitter::Data{ .max_particles = 10, .emission_rate = 100, -- cgit v1.2.3 From 4bbc27098d5a8907ab0500ad3ccc82283cf95ddf Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 2 Dec 2024 20:34:00 +0100 Subject: merge fix and review fix --- src/example/game.cpp | 13 ++++--------- src/test/CMakeLists.txt | 24 ++++++++++++------------ src/test/PhysicsTest.cpp | 10 ++++------ src/test/Profiling.cpp | 10 +--------- 4 files changed, 21 insertions(+), 36 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/example/game.cpp b/src/example/game.cpp index e851526..c439f5d 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -18,7 +18,7 @@ using namespace std; class MyScript : public Script { bool oncollision(const CollisionEvent& test) { - Log::logf("Box {} script on_collision()", test.info.first.collider.game_object_id); + Log::logf("Box {} script on_collision()", test.info.first_collider.game_object_id); return true; } void init() { @@ -50,8 +50,6 @@ public: .gravity_scale = 0, .body_type = Rigidbody::BodyType::STATIC, .constraints = {0, 0, 0}, - .use_gravity = false, - .bounce = false, .offset = {0,0} }); world.add_component(vec2{0, 0-(screen_size_height/2+world_collider/2)}, world_collider, world_collider);; // Top @@ -67,17 +65,14 @@ public: .body_type = Rigidbody::BodyType::DYNAMIC, .linear_velocity = {1,1}, .constraints = {0, 0, 0}, - .use_gravity = true, - .bounce = true, .elastisity = 1, .offset = {0,0}, }); game_object1.add_component(vec2{0, 0}, 20, 20); game_object1.add_component().set_script(); - game_object1.add_component( - make_shared("/home/jaro/crepe/asset/texture/green_square.png"), color, - FlipSettings{true, true}); - game_object1.add_component(Color::WHITE); + auto img = Texture("asset/texture/green_square.png"); + game_object1.add_component(img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); + game_object1.add_component(Color::WHITE, ivec2{1080, 720},vec2{2000, 2000}, 1.0f); } string get_name() const { return "scene1"; } diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 4555c0b..cd61fb7 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -1,17 +1,17 @@ target_sources(test_main PUBLIC CollisionTest.cpp main.cpp - # PhysicsTest.cpp - # ScriptTest.cpp - # ParticleTest.cpp - # AssetTest.cpp - # OptionalRefTest.cpp - # RenderSystemTest.cpp - # EventTest.cpp - # ECSTest.cpp - # SceneManagerTest.cpp - # ValueBrokerTest.cpp - # DBTest.cpp - # Vector2Test.cpp + PhysicsTest.cpp + ScriptTest.cpp + ParticleTest.cpp + AssetTest.cpp + OptionalRefTest.cpp + RenderSystemTest.cpp + EventTest.cpp + ECSTest.cpp + SceneManagerTest.cpp + ValueBrokerTest.cpp + DBTest.cpp + Vector2Test.cpp Profiling.cpp ) diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp index 33b6020..5dd448f 100644 --- a/src/test/PhysicsTest.cpp +++ b/src/test/PhysicsTest.cpp @@ -28,8 +28,6 @@ public: .max_linear_velocity = vec2{10, 10}, .max_angular_velocity = 10, .constraints = {0, 0}, - .use_gravity = true, - .bounce = false, }); } transforms = mgr.get_components_by_id(0); @@ -105,16 +103,16 @@ TEST_F(PhysicsTest, movement) { EXPECT_EQ(transform.position.y, 1); EXPECT_EQ(transform.rotation, 1); - rigidbody.data.linear_damping.x = 0.5; - rigidbody.data.linear_damping.y = 0.5; - rigidbody.data.angular_damping = 0.5; + rigidbody.data.linear_velocity_factor.x = 0.5; + rigidbody.data.linear_velocity_factor.y = 0.5; + rigidbody.data.angular_velocity_factor = 0.5; system.update(); EXPECT_EQ(rigidbody.data.linear_velocity.x, 0.5); EXPECT_EQ(rigidbody.data.linear_velocity.y, 0.5); EXPECT_EQ(rigidbody.data.angular_velocity, 0.5); rigidbody.data.constraints = {1, 1, 0}; - rigidbody.data.angular_damping = 0; + rigidbody.data.angular_velocity_factor = 0; rigidbody.data.max_angular_velocity = 1000; rigidbody.data.angular_velocity = 360; system.update(); diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index a88bf85..e46d5ff 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -26,14 +26,6 @@ using namespace std::chrono_literals; using namespace crepe; using namespace testing; - -/* -List of test cases with component settings/details -1. Minimal test creates gameobject without additonal components -2. Minimal 'Complex' gameobject. Has dynamic body without bounce and no collision handler -3. Minimal 'Complex' gameobject. Same as test 2 but with particle emitter -*/ - class TestScript : public Script { bool oncollision(const CollisionEvent& test) { Log::logf("Box {} script on_collision()", test.info.first_collider.game_object_id); @@ -55,7 +47,7 @@ public: // Minimum amount to let test pass const int min_gameobject_count = 100; // Maximum amount to stop test - const int max_gameobject_count = 200; + const int max_gameobject_count = 150; // Amount of times a test runs to calculate average const int average = 5; // Maximum duration to stop test -- cgit v1.2.3 From ff618da3f97237796042fa3664da59ed147bc1da Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Tue, 3 Dec 2024 19:32:15 +0100 Subject: improved comments --- src/crepe/Collider.h | 18 +++- src/crepe/api/BoxCollider.cpp | 2 +- src/crepe/api/BoxCollider.h | 10 +-- src/crepe/api/Rigidbody.h | 128 +++++++++++++++++++++++---- src/crepe/system/CollisionSystem.cpp | 167 ++++++++++++++++------------------- src/crepe/system/CollisionSystem.h | 32 ++----- src/crepe/system/PhysicsSystem.cpp | 8 +- src/example/game.cpp | 4 +- src/test/CollisionTest.cpp | 56 ++++++------ src/test/PhysicsTest.cpp | 8 +- src/test/Profiling.cpp | 2 +- 11 files changed, 257 insertions(+), 178 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/crepe/Collider.h b/src/crepe/Collider.h index 15d3a24..f5f53d2 100644 --- a/src/crepe/Collider.h +++ b/src/crepe/Collider.h @@ -10,7 +10,23 @@ public: Collider(game_object_id_t id, const vec2& offset); public: - //! Offset of the collider relative to rigidbody position + /** + * \brief Offset of the collider relative to the rigidbody position. + * + * The `offset` defines the positional shift applied to the collider relative to the position of the rigidbody it is attached to. + * This allows the collider to be placed at a different position than the rigidbody, which can be useful for scenarios + * where the collider's position needs to differ from the rigidbody's center, such as in non-centered colliders. + * + * - The `offset` is typically used when the collider is not meant to be centered exactly on the rigidbody's position. + * - For example, the collider might need to be shifted to account for an object with an asymmetrical shape or for objects + * where the pivot point of the rigidbody is different from the collider's center. + * + * When multiple colliders are added to the same object (e.g., a character with separate body parts or a vehicle with multiple zones), + * the offset is important for properly positioning each collider relative to the rigidbody, allowing accurate collision detection. + * + * - Multiple colliders can be used on the same object, and each can have its own unique offset. + * - Overlap between colliders is allowed and does not impact performance. + */ vec2 offset; }; diff --git a/src/crepe/api/BoxCollider.cpp b/src/crepe/api/BoxCollider.cpp index 1069e90..f94ced7 100644 --- a/src/crepe/api/BoxCollider.cpp +++ b/src/crepe/api/BoxCollider.cpp @@ -4,4 +4,4 @@ using namespace crepe; -BoxCollider::BoxCollider(game_object_id_t game_object_id,const vec2& offset, float width, float height) : Collider(game_object_id,offset), width(width), height(height) {} +BoxCollider::BoxCollider(game_object_id_t game_object_id,const vec2& offset, const vec2& dimensions) : Collider(game_object_id,offset), dimensions(dimensions) {} diff --git a/src/crepe/api/BoxCollider.h b/src/crepe/api/BoxCollider.h index c83d54a..1f5f1c1 100644 --- a/src/crepe/api/BoxCollider.h +++ b/src/crepe/api/BoxCollider.h @@ -2,6 +2,7 @@ #include "Vector2.h" #include "../Collider.h" +#include "types.h" namespace crepe { @@ -12,13 +13,10 @@ namespace crepe { */ class BoxCollider : public Collider { public: - BoxCollider(game_object_id_t game_object_id,const vec2& offset, float width, float height); + BoxCollider(game_object_id_t game_object_id,const vec2& offset, const vec2& dimensions); - //! Width of box collider - float width; - - //! Height of box collider - float height; + //! Width and height of the box collider + vec2 dimensions; }; } // namespace crepe diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 63b1b51..9cdf3f5 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -36,11 +36,11 @@ public: * the systems will not move the object. */ struct PhysicsConstraints { - //! X constraint + //! Prevent movement along X axis bool x = false; - //! Y constraint + //! Prevent movement along Y axis bool y = false; - //! rotation constraint + //! Prevent rotation bool rotation = false; }; @@ -53,27 +53,112 @@ public: struct Data { //! objects mass float mass = 0.0; - //! gravtiy scale + /** + * \brief Gravity scale factor. + * + * The `gravity_scale` controls how much gravity affects the object. It is a multiplier applied to the default + * gravity force, allowing for fine-grained control over how the object responds to gravity. + * + * - A value of `0.0` means that gravity has **no effect** on the object (i.e., the object is completely immune to gravity). + * - A value of `1.0` means that gravity is applied at its **normal intensity** (the default behavior). + * - A value greater than `1.0` means the object is affected by gravity more strongly than normal. + * - A value less than `1.0` (but greater than `0.0`) reduces the effect of gravity on the object. + * + * This is useful in cases where you need objects to behave differently under gravity, such as lighter objects (like feathers), + * objects that float in water, or heavier objects that fall faster. + */ float gravity_scale = 0; - //! Changes if physics apply + /** + * \brief Defines the type of the physics body, which determines how the physics system interacts with the object. + * + * - **Static**: The object does not move and is not affected by forces. It is used for immovable objects like walls or terrain. Does not have collision detection. + * - **Dynamic**: The object is fully affected by physics forces, including gravity, collisions, and other physical interactions. It can move and be moved by forces. + * - **Kinematic**: The object does not move and is not affected by forces. It is typically controlled by external factors (e.g., animations or user input), and collision detection is handled without affecting its velocity. + * + * The `body_type` defines the behavior of the object in the physics system. + * + * \default BodyType::DYNAMIC + */ BodyType body_type = BodyType::DYNAMIC; - //! linear velocity of object + + /** + * \name Linear (positional) motion + * + * These variables define the linear motion (movement along the position) of an object. + * The linear velocity is applied to the object's position in each update of the PhysicsSystem. + * The motion is affected by the object's linear velocity, its maximum velocity, and a coefficient + * that can scale the velocity over time. + * + * \{ + */ + //! Linear velocity of the object (speed and direction). vec2 linear_velocity; - //! maximum linear velocity of object + //! Maximum linear velocity of the object. This limits the object's speed. vec2 max_linear_velocity = {INFINITY ,INFINITY}; - //! linear damping of object - vec2 linear_velocity_factor; - //! angular velocity of object + //! Linear velocity coefficient. This scales the object's velocity for adjustment or damping. + vec2 linear_velocity_coefficient = {1,1}; + //! \} + + /** + * \name Angular (rotational) motion + * + * These variables define the angular motion (rotation) of an object. + * The angular velocity determines how quickly the object rotates, while the maximum angular velocity + * sets a limit on the rotation speed. The angular velocity coefficient applies damping or scaling + * to the angular velocity, which can be used to simulate friction or other effects that slow down rotation. + * + * \{ + */ + //! Angular velocity of the object, representing the rate of rotation (in radians per second). float angular_velocity = 1; - //! max angular velocity of object + //! Maximum angular velocity of the object. This limits the maximum rate of rotation. float max_angular_velocity = INFINITY; - //! angular damping of object - float angular_velocity_factor = 1; - //! movements constraints of object + //! Angular velocity coefficient. This scales the object's angular velocity, typically used for damping. + float angular_velocity_coefficient = 1; + //! \} + + /** + * \brief Movement constraints for an object. + * + * The `PhysicsConstraints` struct defines the constraints that restrict an object's movement + * in certain directions or prevent rotation. These constraints effect only the physics system + * to prevent the object from moving or rotating in specified ways. + * + * - **X Constraint**: If enabled, the object cannot move along the X-axis. + * - **Y Constraint**: If enabled, the object cannot move along the Y-axis. + * - **Rotation Constraint**: If enabled, the object cannot rotate. + * + * These constraints allow you to restrict movement for specific scenarios (e.g., a platform that shouldn't move + * or a character that should only move horizontally). + */ PhysicsConstraints constraints; - //! bounce factor of material. 0.0 <= means all velocity is lost, 1.0 means it gets the same momentum but the mirrored direction. 0.5 is half of the velocity is saved. - float elastisity = 0.0; - //! offset of all colliders relative to transform position + + /** + * \brief Elasticity factor of the material (bounce factor). + * + * The `elasticity_coefficient` controls how much of the object's velocity is retained after a collision. + * It represents the material's ability to bounce or recover velocity upon impact. The coefficient is a value + * between 0.0 and 1.0, where: + * + * - **0.0** means no velocity is retained after the collision (all velocity is lost, and the object does not bounce). + * - **1.0** means the object retains its full velocity but in the opposite direction (perfect elastic bounce). + * - **0.5** means the object retains half of its velocity, resulting in a bounce with reduced speed. + * + * This factor can be used to simulate different materials, such as rubber (high elasticity) or concrete (low elasticity). + */ + float elastisity_coefficient = 0.0; + + /** + * \brief Offset of all colliders relative to the object's transform position. + * + * The `offset` defines a positional shift applied to all colliders associated with the object, relative to the object's + * transform position. This allows for the colliders to be placed at a different position than the object's actual + * position, without modifying the object's transform itself. + * + * - The `offset` is typically used to adjust the collider's position in cases where all colluders should be moved. + * - For example, if a character has a animation where all colliders should be moved this offset can be used to + * achieve this. + */ vec2 offset; }; @@ -99,6 +184,15 @@ public: * \param force Vector2 that is added to the angular force. */ void add_force_angular(float force); + +protected: + /** + * Ensures there is at most one Rigidbody component per entity. + * \return Always returns 1, indicating this constraint. + */ + virtual int get_instances_max() const { return 1; } + //! ComponentManager instantiates all components + friend class ComponentManager; }; } // namespace crepe diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 380cc3d..2d5ce9d 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -10,6 +10,7 @@ #include "api/EventManager.h" #include "api/BoxCollider.h" #include "api/CircleCollider.h" +#include "api/Metadata.h" #include "api/Vector2.h" #include "api/Rigidbody.h" #include "api/Transform.h" @@ -23,18 +24,16 @@ using namespace crepe; void CollisionSystem::update() { - std::vector all_colliders; - ComponentManager & mgr = this->component_manager; game_object_id_t id = 0; - RefVector rigidbodies = mgr.get_components_by_type(); + RefVector rigidbodies = this->component_manager.get_components_by_type(); // Collisions can only happen on object with a rigidbody for(Rigidbody& rigidbody : rigidbodies) { if (!rigidbody.active) continue; id = rigidbody.game_object_id; Transform& transform = this->component_manager.get_components_by_id(id).front().get(); // Check if the boxcollider is active and has the same id as the rigidbody. - RefVector boxcolliders = mgr.get_components_by_type(); + RefVector boxcolliders = this->component_manager.get_components_by_type(); for (BoxCollider& boxcollider : boxcolliders) { if(boxcollider.game_object_id != id) continue; if(!boxcollider.active) continue; @@ -48,7 +47,7 @@ void CollisionSystem::update() { ); } // Check if the circlecollider is active and has the same id as the rigidbody. - RefVector circlecolliders = mgr.get_components_by_type(); + RefVector circlecolliders = this->component_manager.get_components_by_type(); for (CircleCollider& circlecollider : circlecolliders) { if(circlecollider.game_object_id != id) continue; if(!circlecollider.active) continue; @@ -64,59 +63,63 @@ void CollisionSystem::update() { } // Check between all colliders if there is a collision - std::vector> collided = gather_collisions(all_colliders); + std::vector> collided = this->gather_collisions(all_colliders); // For both objects call the collision handler for (auto& collision_pair : collided) { - collision_handler_request(collision_pair.first,collision_pair.second); - collision_handler_request(collision_pair.second,collision_pair.first); + this->collision_handler_request(collision_pair.first,collision_pair.second); + this->collision_handler_request(collision_pair.second,collision_pair.first); } } -void CollisionSystem::collision_handler_request(CollisionInternal& data1,CollisionInternal& data2){ +void CollisionSystem::collision_handler_request(CollisionInternal& this_data,CollisionInternal& other_data){ - CollisionInternalType type = get_collider_type(data1.collider,data2.collider); - std::pair resolution_data = collision_handler(data1,data2,type); + CollisionInternalType type = this->get_collider_type(this_data.collider,other_data.collider); + std::pair resolution_data = this->collision_handler(this_data,other_data,type); - OptionalRef collider1; - OptionalRef collider2; + OptionalRef this_metadata = this->component_manager.get_components_by_id(this_data.id).front().get(); + OptionalRef other_metadata = this->component_manager.get_components_by_id(other_data.id).front().get(); + OptionalRef this_collider; + OptionalRef other_collider; switch (type) { case CollisionInternalType::BOX_BOX:{ - collider1 = std::get>(data1.collider); - collider2 = std::get>(data2.collider); + this_collider = std::get>(this_data.collider); + other_collider = std::get>(other_data.collider); break; } case CollisionInternalType::BOX_CIRCLE:{ - collider1 = std::get>(data1.collider); - collider2 = std::get>(data2.collider); + this_collider = std::get>(this_data.collider); + other_collider = std::get>(other_data.collider); break; } case CollisionInternalType::CIRCLE_BOX:{ - collider1 = std::get>(data1.collider); - collider2 = std::get>(data2.collider); + this_collider = std::get>(this_data.collider); + other_collider = std::get>(other_data.collider); break; } case CollisionInternalType::CIRCLE_CIRCLE:{ - collider1 = std::get>(data1.collider); - collider2 = std::get>(data2.collider); + this_collider = std::get>(this_data.collider); + other_collider = std::get>(other_data.collider); break; } } - + // collision info crepe::CollisionSystem::CollisionInfo collision_info{ - .first_collider = collider1, - .first_transform = data1.transform, - .first_rigidbody = data1.rigidbody, - .second_collider = collider2, - .second_transform = data2.transform, - .second_rigidbody = data2.rigidbody, + .this_collider = this_collider, + .this_transform = this_data.transform, + .this_rigidbody = this_data.rigidbody, + .this_metadata = this_metadata, + .other_collider = other_collider, + .other_transform = other_data.transform, + .other_rigidbody = other_data.rigidbody, + .other_metadata = other_metadata, .resolution = resolution_data.first, .resolution_direction = resolution_data.second, }; // Determine if static needs to be called - determine_collision_handler(collision_info); + this->determine_collision_handler(collision_info); } @@ -126,33 +129,33 @@ std::pair CollisionSystem::collision_handler(Co case CollisionInternalType::BOX_BOX: { const BoxCollider & collider1 = std::get>(data1.collider); const BoxCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = get_current_position(collider1.offset, data1.transform, data1.rigidbody); - vec2 collider_pos2 = get_current_position(collider2.offset, data2.transform, data2.rigidbody); - resolution = get_box_box_resolution(collider1,collider2,collider_pos1,collider_pos2); + vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, data1.rigidbody); + vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); + resolution = this->get_box_box_resolution(collider1,collider2,collider_pos1,collider_pos2); break; } case CollisionInternalType::BOX_CIRCLE: { const BoxCollider & collider1 = std::get>(data1.collider); const CircleCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = get_current_position(collider1.offset, data1.transform, data1.rigidbody); - vec2 collider_pos2 = get_current_position(collider2.offset, data2.transform, data2.rigidbody); - resolution = get_circle_box_resolution(collider2,collider1,collider_pos2,collider_pos1); + vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, data1.rigidbody); + vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); + resolution = this->get_circle_box_resolution(collider2,collider1,collider_pos2,collider_pos1); break; } case CollisionInternalType::CIRCLE_CIRCLE: { const CircleCollider & collider1 = std::get>(data1.collider); const CircleCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = get_current_position(collider1.offset, data1.transform, data1.rigidbody); - vec2 collider_pos2 = get_current_position(collider2.offset, data2.transform, data2.rigidbody); - resolution = get_circle_circle_resolution(collider1,collider2,collider_pos1,collider_pos2); + vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, data1.rigidbody); + vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); + resolution = this->get_circle_circle_resolution(collider1,collider2,collider_pos1,collider_pos2); break; } case CollisionInternalType::CIRCLE_BOX: { const CircleCollider & collider1 = std::get>(data1.collider); const BoxCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = get_current_position(collider1.offset, data1.transform, data1.rigidbody); - vec2 collider_pos2 = get_current_position(collider2.offset, data2.transform, data2.rigidbody); - resolution = get_circle_box_resolution(collider1,collider2,collider_pos1,collider_pos2); + vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, data1.rigidbody); + vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); + resolution = this->get_circle_box_resolution(collider1,collider2,collider_pos1,collider_pos2); break; } } @@ -179,10 +182,10 @@ vec2 CollisionSystem::get_box_box_resolution(const BoxCollider& box_collider1,co vec2 delta = final_position2 - final_position1; // Compute half-dimensions of the boxes - float half_width1 = box_collider1.width / 2.0; - float half_height1 = box_collider1.height / 2.0; - float half_width2 = box_collider2.width / 2.0; - float half_height2 = box_collider2.height / 2.0; + float half_width1 = box_collider1.dimensions.x / 2.0; + float half_height1 = box_collider1.dimensions.y / 2.0; + float half_width2 = box_collider2.dimensions.x / 2.0; + float half_height2 = box_collider2.dimensions.y / 2.0; // Calculate overlaps along X and Y axes float overlap_x = (half_width1 + half_width2) - std::abs(delta.x); @@ -234,8 +237,8 @@ vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider& circle_col vec2 delta = circle_position - box_position; // Compute half-dimensions of the box - float half_width = box_collider.width / 2.0f; - float half_height = box_collider.height / 2.0f; + float half_width = box_collider.dimensions.x / 2.0f; + float half_height = box_collider.dimensions.y / 2.0f; // Clamp circle center to the nearest point on the box vec2 closest_point; @@ -261,37 +264,37 @@ vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider& circle_col void CollisionSystem::determine_collision_handler(CollisionInfo& info){ // Check rigidbody type for static - if(info.first_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; + if(info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; // If second body is static perform the static collision handler in this system - if(info.second_rigidbody.data.body_type == Rigidbody::BodyType::STATIC){ + if(info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC){ static_collision_handler(info); }; // Call collision event for user CollisionEvent data(info); - EventManager::get_instance().trigger_event(data, info.first_collider.game_object_id); + EventManager::get_instance().trigger_event(data, info.this_collider.game_object_id); } void CollisionSystem::static_collision_handler(CollisionInfo& info){ // Move object back using calculate move back value - info.first_transform.position += info.resolution; + info.this_transform.position += info.resolution; // If bounce is enabled mirror velocity - if(info.first_rigidbody.data.elastisity > 0) { + if(info.this_rigidbody.data.elastisity_coefficient > 0) { if(info.resolution_direction == Direction::BOTH) { - info.first_rigidbody.data.linear_velocity.y = -info.first_rigidbody.data.linear_velocity.y * info.first_rigidbody.data.elastisity; - info.first_rigidbody.data.linear_velocity.x = -info.first_rigidbody.data.linear_velocity.x * info.first_rigidbody.data.elastisity; + info.this_rigidbody.data.linear_velocity.y = -info.this_rigidbody.data.linear_velocity.y * info.this_rigidbody.data.elastisity_coefficient; + info.this_rigidbody.data.linear_velocity.x = -info.this_rigidbody.data.linear_velocity.x * info.this_rigidbody.data.elastisity_coefficient; } else if(info.resolution_direction == Direction::Y_DIRECTION) { - info.first_rigidbody.data.linear_velocity.y = -info.first_rigidbody.data.linear_velocity.y * info.first_rigidbody.data.elastisity; + info.this_rigidbody.data.linear_velocity.y = -info.this_rigidbody.data.linear_velocity.y * info.this_rigidbody.data.elastisity_coefficient; } else if(info.resolution_direction == Direction::X_DIRECTION){ - info.first_rigidbody.data.linear_velocity.x = -info.first_rigidbody.data.linear_velocity.x * info.first_rigidbody.data.elastisity; + info.this_rigidbody.data.linear_velocity.x = -info.this_rigidbody.data.linear_velocity.x * info.this_rigidbody.data.elastisity_coefficient; } } // Stop movement if bounce is disabled else { - info.first_rigidbody.data.linear_velocity = {0,0}; + info.this_rigidbody.data.linear_velocity = {0,0}; } } @@ -332,24 +335,6 @@ std::vector, std::reference_wrapper>> -CollisionSystem::get_active_transform_and_rigidbody(game_object_id_t game_object_id) const{ - RefVector transforms = this->component_manager.get_components_by_id(game_object_id); - if (transforms.empty()) return std::nullopt; - - Transform& transform = transforms.front().get(); - if (!transform.active) return std::nullopt; - - RefVector rigidbodies = this->component_manager.get_components_by_id(game_object_id); - if (rigidbodies.empty()) return std::nullopt; - - Rigidbody& rigidbody = rigidbodies.front().get(); - if (!rigidbody.active) return std::nullopt; - - // Return the active components - return std::make_pair(std::ref(transform), std::ref(rigidbody)); -} - CollisionSystem::CollisionInternalType CollisionSystem::get_collider_type(const collider_variant& collider1,const collider_variant& collider2) const{ if(std::holds_alternative>(collider1)){ if(std::holds_alternative>(collider2)) @@ -376,22 +361,22 @@ bool CollisionSystem::get_collision(const CollisionInternal& first_info,const Co case CollisionInternalType::BOX_BOX: { const BoxCollider & box_collider1 = std::get>(first_info.collider); const BoxCollider & box_collider2 = std::get>(second_info.collider); - return get_box_box_collision(box_collider1,box_collider2,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); + return this->get_box_box_collision(box_collider1,box_collider2,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); } case CollisionInternalType::BOX_CIRCLE: { const BoxCollider & box_collider = std::get>(first_info.collider); const CircleCollider & circle_collider = std::get>(second_info.collider); - return get_box_circle_collision(box_collider,circle_collider,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); + return this->get_box_circle_collision(box_collider,circle_collider,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); } case CollisionInternalType::CIRCLE_CIRCLE: { const CircleCollider & circle_collider1 = std::get>(first_info.collider); const CircleCollider & circle_collider2 = std::get>(second_info.collider); - return get_circle_circle_collision(circle_collider1,circle_collider2,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); + return this->get_circle_circle_collision(circle_collider1,circle_collider2,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); } case CollisionInternalType::CIRCLE_BOX: { const CircleCollider & circle_collider = std::get>(first_info.collider); const BoxCollider & box_collider = std::get>(second_info.collider); - return get_box_circle_collision(box_collider,circle_collider,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); + return this->get_box_circle_collision(box_collider,circle_collider,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); } } return false; @@ -401,14 +386,14 @@ bool CollisionSystem::get_collision(const CollisionInternal& first_info,const Co bool CollisionSystem::get_box_box_collision(const BoxCollider& box1, const BoxCollider& box2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = get_current_position(box1.offset,transform1,rigidbody1); - vec2 final_position2 = get_current_position(box2.offset,transform2,rigidbody2); + vec2 final_position1 = this->get_current_position(box1.offset,transform1,rigidbody1); + vec2 final_position2 = this->get_current_position(box2.offset,transform2,rigidbody2); // Calculate half-extents (half width and half height) - float half_width1 = box1.width / 2.0; - float half_height1 = box1.height / 2.0; - float half_width2 = box2.width / 2.0; - float half_height2 = box2.height / 2.0; + float half_width1 = box1.dimensions.x / 2.0; + float half_height1 = box1.dimensions.y / 2.0; + float half_width2 = box2.dimensions.x / 2.0; + float half_height2 = box2.dimensions.y / 2.0; // Check if the boxes overlap along the X and Y axes return (final_position1.x + half_width1 > final_position2.x - half_width2 && @@ -419,12 +404,12 @@ bool CollisionSystem::get_box_box_collision(const BoxCollider& box1, const BoxCo bool CollisionSystem::get_box_circle_collision(const BoxCollider& box1, const CircleCollider& circle2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = get_current_position(box1.offset, transform1, rigidbody1); - vec2 final_position2 = get_current_position(circle2.offset, transform2, rigidbody2); + vec2 final_position1 = this->get_current_position(box1.offset, transform1, rigidbody1); + vec2 final_position2 = this->get_current_position(circle2.offset, transform2, rigidbody2); // Calculate box half-extents - float half_width = box1.width / 2.0; - float half_height = box1.height / 2.0; + float half_width = box1.dimensions.x / 2.0; + float half_height = box1.dimensions.y / 2.0; // Find the closest point on the box to the circle's center float closest_x = std::max(final_position1.x - half_width, std::min(final_position2.x, final_position1.x + half_width)); @@ -441,8 +426,8 @@ bool CollisionSystem::get_box_circle_collision(const BoxCollider& box1, const Ci bool CollisionSystem::get_circle_circle_collision(const CircleCollider& circle1, const CircleCollider& circle2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = get_current_position(circle1.offset,transform1,rigidbody1); - vec2 final_position2 = get_current_position(circle2.offset,transform2,rigidbody2); + vec2 final_position1 = this->get_current_position(circle1.offset,transform1,rigidbody1); + vec2 final_position2 = this->get_current_position(circle2.offset,transform2,rigidbody2); float distance_x = final_position1.x - final_position2.x; float distance_y = final_position1.y - final_position2.y; diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 7fb8b45..85ae5ad 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -8,6 +8,7 @@ #include "api/Transform.h" #include "api/BoxCollider.h" #include "api/CircleCollider.h" +#include "api/Metadata.h" #include "api/Vector2.h" #include "Collider.h" @@ -68,12 +69,14 @@ public: * Includes information about the colliding objects and the resolution data for handling the collision. */ struct CollisionInfo{ - Collider& first_collider; - Transform& first_transform; - Rigidbody& first_rigidbody; - Collider& second_collider; - Transform& second_transform; - Rigidbody& second_rigidbody; + Collider& this_collider; + Transform& this_transform; + Rigidbody& this_rigidbody; + Metadata& this_metadata; + Collider& other_collider; + Transform& other_transform; + Rigidbody& other_rigidbody; + Metadata& other_metadata; //! The resolution vector for the collision. vec2 resolution; //! The direction of movement for resolving the collision. @@ -213,23 +216,6 @@ private: */ bool get_collision(const CollisionInternal& first_info,const CollisionInternal& second_info, CollisionInternalType type) const; - /** - * \brief Retrieves the active Transform and Rigidbody components for a given game object. - * - * This function looks up the Transform and Rigidbody components associated with the specified - * game object ID. It checks if both components are present and active. If both are found - * to be active, they are returned wrapped in reference wrappers; otherwise, an empty - * optional is returned. - * - * \param game_object_id The ID of the game object for which to retrieve the components. - * - * \return A std::optional containing a pair of reference wrappers to the active Transform - * and Rigidbody components, or std::nullopt if either component is not found - * or not active. - */ - std::optional, std::reference_wrapper>> get_active_transform_and_rigidbody(game_object_id_t game_object_id) const; - - /** * \brief Detects collisions between two BoxColliders. * diff --git a/src/crepe/system/PhysicsSystem.cpp b/src/crepe/system/PhysicsSystem.cpp index 8f21727..f3833cb 100644 --- a/src/crepe/system/PhysicsSystem.cpp +++ b/src/crepe/system/PhysicsSystem.cpp @@ -31,11 +31,11 @@ void PhysicsSystem::update() { * gravity); } // Add damping - if (rigidbody.data.angular_velocity_factor != 1 && rigidbody.data.angular_velocity_factor > 0) { - rigidbody.data.angular_velocity *= rigidbody.data.angular_velocity_factor; + if (rigidbody.data.angular_velocity_coefficient != 1 && rigidbody.data.angular_velocity_coefficient > 0) { + rigidbody.data.angular_velocity *= rigidbody.data.angular_velocity_coefficient; } - if (rigidbody.data.linear_velocity_factor != vec2{1, 1} && rigidbody.data.linear_velocity_factor.x > 0 && rigidbody.data.linear_velocity_factor.y > 0) { - rigidbody.data.linear_velocity *= rigidbody.data.linear_velocity_factor; + if (rigidbody.data.linear_velocity_coefficient != vec2{1, 1} && rigidbody.data.linear_velocity_coefficient.x > 0 && rigidbody.data.linear_velocity_coefficient.y > 0) { + rigidbody.data.linear_velocity *= rigidbody.data.linear_velocity_coefficient; } // Max velocity check diff --git a/src/example/game.cpp b/src/example/game.cpp index c439f5d..4e16d4a 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -18,7 +18,7 @@ using namespace std; class MyScript : public Script { bool oncollision(const CollisionEvent& test) { - Log::logf("Box {} script on_collision()", test.info.first_collider.game_object_id); + Log::logf("Box {} script on_collision()", test.info.this_collider.game_object_id); return true; } void init() { @@ -65,7 +65,7 @@ public: .body_type = Rigidbody::BodyType::DYNAMIC, .linear_velocity = {1,1}, .constraints = {0, 0, 0}, - .elastisity = 1, + .elastisity_coefficient = 1, .offset = {0,0}, }); game_object1.add_component(vec2{0, 0}, 20, 20); diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index 92ff7ba..fec42f3 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -68,10 +68,10 @@ public: .offset = {0,0}, }); // Create a box with an inner size of 10x10 units - world.add_component(vec2{0, -100}, 100, 100); // Top - world.add_component(vec2{0, 100}, 100, 100); // Bottom - world.add_component(vec2{-100, 0}, 100, 100); // Left - world.add_component(vec2{100, 0}, 100, 100); // right + world.add_component(vec2{0, -100}, vec2{100, 100}); // Top + world.add_component(vec2{0, 100}, vec2{100, 100}); // Bottom + world.add_component(vec2{-100, 0}, vec2{100, 100}); // Left + world.add_component(vec2{100, 0}, vec2{100, 100}); // right game_object1.add_component(Rigidbody::Data{ .mass = 1, @@ -79,10 +79,10 @@ public: .body_type = Rigidbody::BodyType::DYNAMIC, .linear_velocity = {0,0}, .constraints = {0, 0, 0}, - .elastisity = 1, + .elastisity_coefficient = 1, .offset = {0,0}, }); - game_object1.add_component(vec2{0, 0}, 10, 10); + game_object1.add_component(vec2{0, 0}, vec2{10, 10}); BehaviorScript & script_object1 = game_object1.add_component().set_script(1); script_object1_ref = static_cast(script_object1.script.get()); ASSERT_NE(script_object1_ref, nullptr); @@ -93,10 +93,10 @@ public: .body_type = Rigidbody::BodyType::DYNAMIC, .linear_velocity = {0,0}, .constraints = {0, 0, 0}, - .elastisity = 1, + .elastisity_coefficient = 1, .offset = {0,0}, }); - game_object2.add_component(vec2{0, 0}, 10, 10); + game_object2.add_component(vec2{0, 0}, vec2{10, 10}); BehaviorScript & script_object2 = game_object2.add_component().set_script(2); script_object2_ref = static_cast(script_object2.script.get()); ASSERT_NE(script_object2_ref, nullptr); @@ -110,11 +110,11 @@ TEST_F(CollisionTest, collision_example) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.this_collider.game_object_id, 2); }; EXPECT_FALSE(collision_happend); collision_sys.update(); @@ -125,14 +125,14 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both_no_velocity) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, 10); EXPECT_EQ(ev.info.resolution.y, 10); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.this_collider.game_object_id, 2); EXPECT_EQ(ev.info.resolution.x, 10); EXPECT_EQ(ev.info.resolution.y, 10); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); @@ -148,14 +148,14 @@ TEST_F(CollisionTest, collision_box_box_dynamic_x_direction_no_velocity) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, -5); EXPECT_EQ(ev.info.resolution.y, 0); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.this_collider.game_object_id, 2); EXPECT_EQ(ev.info.resolution.x, 5); EXPECT_EQ(ev.info.resolution.y, 0); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); @@ -171,14 +171,14 @@ TEST_F(CollisionTest, collision_box_box_dynamic_y_direction_no_velocity) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, 0); EXPECT_EQ(ev.info.resolution.y, -5); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.this_collider.game_object_id, 2); EXPECT_EQ(ev.info.resolution.x, 0); EXPECT_EQ(ev.info.resolution.y, 5); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); @@ -194,14 +194,14 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, 10); EXPECT_EQ(ev.info.resolution.y, 10); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.this_collider.game_object_id, 2); EXPECT_EQ(ev.info.resolution.x, 10); EXPECT_EQ(ev.info.resolution.y, 10); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); @@ -221,14 +221,14 @@ TEST_F(CollisionTest, collision_box_box_dynamic_x_direction) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, -5); EXPECT_EQ(ev.info.resolution.y, -5); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.this_collider.game_object_id, 2); EXPECT_EQ(ev.info.resolution.x, 5); EXPECT_EQ(ev.info.resolution.y, 5); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); @@ -248,14 +248,14 @@ TEST_F(CollisionTest, collision_box_box_dynamic_y_direction) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, -5); EXPECT_EQ(ev.info.resolution.y, -5); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 2); + EXPECT_EQ(ev.info.this_collider.game_object_id, 2); EXPECT_EQ(ev.info.resolution.x, 5); EXPECT_EQ(ev.info.resolution.y, 5); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); @@ -276,7 +276,7 @@ TEST_F(CollisionTest, collision_box_box_static_both) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, 10); EXPECT_EQ(ev.info.resolution.y, 10); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH); @@ -298,7 +298,7 @@ TEST_F(CollisionTest, collision_box_box_static_x_direction) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, -5); EXPECT_EQ(ev.info.resolution.y, -5); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); @@ -322,7 +322,7 @@ TEST_F(CollisionTest, collision_box_box_static_y_direction) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, -5); EXPECT_EQ(ev.info.resolution.y, -5); EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); @@ -348,8 +348,8 @@ TEST_F(CollisionTest, collision_box_box_static_multiple) {//todo check visually float resolution = 0; script_object1_ref->test_fn = [&](const CollisionEvent & ev) { collision_happend = true; - EXPECT_EQ(ev.info.first_collider.game_object_id, 1); - EXPECT_EQ(ev.info.first_collider.offset.x , offset_value); + EXPECT_EQ(ev.info.this_collider.game_object_id, 1); + EXPECT_EQ(ev.info.this_collider.offset.x , offset_value); EXPECT_EQ(ev.info.resolution.x , resolution); }; script_object2_ref->test_fn = [&](const CollisionEvent & ev) { @@ -365,7 +365,7 @@ TEST_F(CollisionTest, collision_box_box_static_multiple) {//todo check visually rg2.data.body_type = crepe::Rigidbody::BodyType::STATIC; BoxCollider & bxc = this->mgr.get_components_by_id(1).front().get(); bxc.offset = {5,0}; - this->game_object1.add_component(vec2{-5, 0}, 10, 10); + this->game_object1.add_component(vec2{-5, 0}, vec2{10, 10}); offset_value = 5; resolution = 10; collision_sys.update(); diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp index 5dd448f..ad7cb03 100644 --- a/src/test/PhysicsTest.cpp +++ b/src/test/PhysicsTest.cpp @@ -103,16 +103,16 @@ TEST_F(PhysicsTest, movement) { EXPECT_EQ(transform.position.y, 1); EXPECT_EQ(transform.rotation, 1); - rigidbody.data.linear_velocity_factor.x = 0.5; - rigidbody.data.linear_velocity_factor.y = 0.5; - rigidbody.data.angular_velocity_factor = 0.5; + rigidbody.data.linear_velocity_coefficient.x = 0.5; + rigidbody.data.linear_velocity_coefficient.y = 0.5; + rigidbody.data.angular_velocity_coefficient = 0.5; system.update(); EXPECT_EQ(rigidbody.data.linear_velocity.x, 0.5); EXPECT_EQ(rigidbody.data.linear_velocity.y, 0.5); EXPECT_EQ(rigidbody.data.angular_velocity, 0.5); rigidbody.data.constraints = {1, 1, 0}; - rigidbody.data.angular_velocity_factor = 0; + rigidbody.data.angular_velocity_coefficient = 0; rigidbody.data.max_angular_velocity = 1000; rigidbody.data.angular_velocity = 360; system.update(); diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index e46d5ff..fa0f5f3 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -28,7 +28,7 @@ using namespace testing; class TestScript : public Script { bool oncollision(const CollisionEvent& test) { - Log::logf("Box {} script on_collision()", test.info.first_collider.game_object_id); + Log::logf("Box {} script on_collision()", test.info.this_collider.game_object_id); return true; } void init() { -- cgit v1.2.3 From d76ab0bf77d0a61712dc25bbe1760995be4c4782 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Wed, 4 Dec 2024 20:11:02 +0100 Subject: make format --- src/crepe/Collider.cpp | 2 +- src/crepe/Collider.h | 2 +- src/crepe/api/BoxCollider.cpp | 7 +- src/crepe/api/BoxCollider.h | 6 +- src/crepe/api/CircleCollider.cpp | 6 +- src/crepe/api/CircleCollider.h | 3 +- src/crepe/api/Event.h | 4 +- src/crepe/api/LoopManager.cpp | 3 +- src/crepe/api/Rigidbody.cpp | 4 +- src/crepe/api/Rigidbody.h | 4 +- src/crepe/system/CollisionSystem.cpp | 514 ++++++++++++++++++++--------------- src/crepe/system/CollisionSystem.h | 121 +++++---- src/crepe/system/PhysicsSystem.cpp | 9 +- src/example/game.cpp | 97 ++++--- src/test/CollisionTest.cpp | 122 +++++---- src/test/Profiling.cpp | 121 +++++---- 16 files changed, 574 insertions(+), 451 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/crepe/Collider.cpp b/src/crepe/Collider.cpp index 9d94152..77e11c8 100644 --- a/src/crepe/Collider.cpp +++ b/src/crepe/Collider.cpp @@ -2,4 +2,4 @@ using namespace crepe; -Collider::Collider(game_object_id_t id, const vec2& offset) : Component(id), offset(offset) {} +Collider::Collider(game_object_id_t id, const vec2 & offset) : Component(id), offset(offset) {} diff --git a/src/crepe/Collider.h b/src/crepe/Collider.h index b3a09fb..a08a68e 100644 --- a/src/crepe/Collider.h +++ b/src/crepe/Collider.h @@ -7,7 +7,7 @@ namespace crepe { class Collider : public Component { public: - Collider(game_object_id_t id, const vec2& offset); + Collider(game_object_id_t id, const vec2 & offset); public: /** diff --git a/src/crepe/api/BoxCollider.cpp b/src/crepe/api/BoxCollider.cpp index f94ced7..c097a24 100644 --- a/src/crepe/api/BoxCollider.cpp +++ b/src/crepe/api/BoxCollider.cpp @@ -1,7 +1,10 @@ #include "BoxCollider.h" -#include "../Collider.h" +#include "../Collider.h" using namespace crepe; -BoxCollider::BoxCollider(game_object_id_t game_object_id,const vec2& offset, const vec2& dimensions) : Collider(game_object_id,offset), dimensions(dimensions) {} +BoxCollider::BoxCollider(game_object_id_t game_object_id, const vec2 & offset, + const vec2 & dimensions) + : Collider(game_object_id, offset), + dimensions(dimensions) {} diff --git a/src/crepe/api/BoxCollider.h b/src/crepe/api/BoxCollider.h index 1f5f1c1..89e43d8 100644 --- a/src/crepe/api/BoxCollider.h +++ b/src/crepe/api/BoxCollider.h @@ -1,7 +1,7 @@ #pragma once -#include "Vector2.h" #include "../Collider.h" +#include "Vector2.h" #include "types.h" namespace crepe { @@ -13,9 +13,9 @@ namespace crepe { */ class BoxCollider : public Collider { public: - BoxCollider(game_object_id_t game_object_id,const vec2& offset, const vec2& dimensions); + BoxCollider(game_object_id_t game_object_id, const vec2 & offset, const vec2 & dimensions); - //! Width and height of the box collider + //! Width and height of the box collider vec2 dimensions; }; diff --git a/src/crepe/api/CircleCollider.cpp b/src/crepe/api/CircleCollider.cpp index 473734e..a4271e9 100644 --- a/src/crepe/api/CircleCollider.cpp +++ b/src/crepe/api/CircleCollider.cpp @@ -2,5 +2,7 @@ using namespace crepe; - -CircleCollider::CircleCollider(game_object_id_t game_object_id,const vec2& offset, float radius) : Collider(game_object_id,offset), radius(radius) {} +CircleCollider::CircleCollider(game_object_id_t game_object_id, const vec2 & offset, + float radius) + : Collider(game_object_id, offset), + radius(radius) {} diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h index bbcc330..ebd1cb2 100644 --- a/src/crepe/api/CircleCollider.h +++ b/src/crepe/api/CircleCollider.h @@ -13,8 +13,7 @@ namespace crepe { */ class CircleCollider : public Collider { public: - - CircleCollider(game_object_id_t game_object_id,const vec2& offset, float radius); + CircleCollider(game_object_id_t game_object_id, const vec2 & offset, float radius); //! Radius of the circle collider. float radius; diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h index 259acba..152bc2c 100644 --- a/src/crepe/api/Event.h +++ b/src/crepe/api/Event.h @@ -98,8 +98,8 @@ public: class CollisionEvent : public Event { public: crepe::CollisionSystem::CollisionInfo info; - CollisionEvent(const crepe::CollisionSystem::CollisionInfo& collisionInfo) - : info(collisionInfo) {} + CollisionEvent(const crepe::CollisionSystem::CollisionInfo & collisionInfo) + : info(collisionInfo) {} }; /** diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index feb1338..d4819ea 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -1,13 +1,12 @@ #include "../facade/SDLContext.h" +#include "../system/PhysicsSystem.h" #include "../system/AnimatorSystem.h" #include "../system/CollisionSystem.h" #include "../system/ParticleSystem.h" #include "../system/PhysicsSystem.h" #include "../system/RenderSystem.h" #include "../system/ScriptSystem.h" -#include "..//system/PhysicsSystem.h" -#include "../system/CollisionSystem.h" #include "LoopManager.h" #include "LoopTimer.h" diff --git a/src/crepe/api/Rigidbody.cpp b/src/crepe/api/Rigidbody.cpp index c4b1d6f..8213afb 100644 --- a/src/crepe/api/Rigidbody.cpp +++ b/src/crepe/api/Rigidbody.cpp @@ -10,6 +10,4 @@ void crepe::Rigidbody::add_force_linear(const vec2 & force) { this->data.linear_velocity += force; } -void crepe::Rigidbody::add_force_angular(float force) { - this->data.angular_velocity += force; -} +void crepe::Rigidbody::add_force_angular(float force) { this->data.angular_velocity += force; } diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 431e000..756cc28 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -78,9 +78,9 @@ public: //! Linear velocity of the object (speed and direction). vec2 linear_velocity; //! Maximum linear velocity of the object. This limits the object's speed. - vec2 max_linear_velocity = {INFINITY ,INFINITY}; + vec2 max_linear_velocity = {INFINITY, INFINITY}; //! Linear velocity coefficient. This scales the object's velocity for adjustment or damping. - vec2 linear_velocity_coefficient = {1,1}; + vec2 linear_velocity_coefficient = {1, 1}; //! \} /** diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 2d5ce9d..34cd125 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -1,23 +1,23 @@ -#include #include +#include #include #include +#include #include #include -#include -#include "api/Event.h" -#include "api/EventManager.h" #include "api/BoxCollider.h" #include "api/CircleCollider.h" +#include "api/Event.h" +#include "api/EventManager.h" #include "api/Metadata.h" -#include "api/Vector2.h" #include "api/Rigidbody.h" #include "api/Transform.h" +#include "api/Vector2.h" -#include "ComponentManager.h" -#include "CollisionSystem.h" #include "Collider.h" +#include "CollisionSystem.h" +#include "ComponentManager.h" #include "types.h" #include "util/OptionalRef.h" @@ -26,158 +26,191 @@ using namespace crepe; void CollisionSystem::update() { std::vector all_colliders; game_object_id_t id = 0; - RefVector rigidbodies = this->component_manager.get_components_by_type(); + RefVector rigidbodies + = this->component_manager.get_components_by_type(); // Collisions can only happen on object with a rigidbody - for(Rigidbody& rigidbody : rigidbodies) { + for (Rigidbody & rigidbody : rigidbodies) { if (!rigidbody.active) continue; id = rigidbody.game_object_id; - Transform& transform = this->component_manager.get_components_by_id(id).front().get(); + Transform & transform + = this->component_manager.get_components_by_id(id).front().get(); // Check if the boxcollider is active and has the same id as the rigidbody. - RefVector boxcolliders = this->component_manager.get_components_by_type(); - for (BoxCollider& boxcollider : boxcolliders) { - if(boxcollider.game_object_id != id) continue; - if(!boxcollider.active) continue; - all_colliders.push_back( - { - .id = id, - .collider = collider_variant{boxcollider}, - .transform = transform, - .rigidbody = rigidbody - } - ); + RefVector boxcolliders + = this->component_manager.get_components_by_type(); + for (BoxCollider & boxcollider : boxcolliders) { + if (boxcollider.game_object_id != id) continue; + if (!boxcollider.active) continue; + all_colliders.push_back({.id = id, + .collider = collider_variant{boxcollider}, + .transform = transform, + .rigidbody = rigidbody}); } // Check if the circlecollider is active and has the same id as the rigidbody. - RefVector circlecolliders = this->component_manager.get_components_by_type(); - for (CircleCollider& circlecollider : circlecolliders) { - if(circlecollider.game_object_id != id) continue; - if(!circlecollider.active) continue; - all_colliders.push_back( - { - .id = id, - .collider = collider_variant{circlecollider}, - .transform = transform, - .rigidbody = rigidbody - } - ); + RefVector circlecolliders + = this->component_manager.get_components_by_type(); + for (CircleCollider & circlecollider : circlecolliders) { + if (circlecollider.game_object_id != id) continue; + if (!circlecollider.active) continue; + all_colliders.push_back({.id = id, + .collider = collider_variant{circlecollider}, + .transform = transform, + .rigidbody = rigidbody}); } } // Check between all colliders if there is a collision - std::vector> collided = this->gather_collisions(all_colliders); + std::vector> collided + = this->gather_collisions(all_colliders); - // For both objects call the collision handler - for (auto& collision_pair : collided) { - this->collision_handler_request(collision_pair.first,collision_pair.second); - this->collision_handler_request(collision_pair.second,collision_pair.first); + // For both objects call the collision handler + for (auto & collision_pair : collided) { + this->collision_handler_request(collision_pair.first, collision_pair.second); + this->collision_handler_request(collision_pair.second, collision_pair.first); } } -void CollisionSystem::collision_handler_request(CollisionInternal& this_data,CollisionInternal& other_data){ +void CollisionSystem::collision_handler_request(CollisionInternal & this_data, + CollisionInternal & other_data) { - CollisionInternalType type = this->get_collider_type(this_data.collider,other_data.collider); - std::pair resolution_data = this->collision_handler(this_data,other_data,type); + CollisionInternalType type + = this->get_collider_type(this_data.collider, other_data.collider); + std::pair resolution_data + = this->collision_handler(this_data, other_data, type); - OptionalRef this_metadata = this->component_manager.get_components_by_id(this_data.id).front().get(); - OptionalRef other_metadata = this->component_manager.get_components_by_id(other_data.id).front().get(); + OptionalRef this_metadata + = this->component_manager.get_components_by_id(this_data.id).front().get(); + OptionalRef other_metadata + = this->component_manager.get_components_by_id(other_data.id).front().get(); OptionalRef this_collider; OptionalRef other_collider; switch (type) { - case CollisionInternalType::BOX_BOX:{ + case CollisionInternalType::BOX_BOX: { this_collider = std::get>(this_data.collider); - other_collider = std::get>(other_data.collider); + other_collider + = std::get>(other_data.collider); break; } - case CollisionInternalType::BOX_CIRCLE:{ + case CollisionInternalType::BOX_CIRCLE: { this_collider = std::get>(this_data.collider); - other_collider = std::get>(other_data.collider); + other_collider + = std::get>(other_data.collider); break; } - case CollisionInternalType::CIRCLE_BOX:{ - this_collider = std::get>(this_data.collider); - other_collider = std::get>(other_data.collider); + case CollisionInternalType::CIRCLE_BOX: { + this_collider + = std::get>(this_data.collider); + other_collider + = std::get>(other_data.collider); break; } - case CollisionInternalType::CIRCLE_CIRCLE:{ - this_collider = std::get>(this_data.collider); - other_collider = std::get>(other_data.collider); + case CollisionInternalType::CIRCLE_CIRCLE: { + this_collider + = std::get>(this_data.collider); + other_collider + = std::get>(other_data.collider); break; } } // collision info crepe::CollisionSystem::CollisionInfo collision_info{ - .this_collider = this_collider, - .this_transform = this_data.transform, - .this_rigidbody = this_data.rigidbody, - .this_metadata = this_metadata, - .other_collider = other_collider, - .other_transform = other_data.transform, - .other_rigidbody = other_data.rigidbody, - .other_metadata = other_metadata, - .resolution = resolution_data.first, - .resolution_direction = resolution_data.second, - }; + .this_collider = this_collider, + .this_transform = this_data.transform, + .this_rigidbody = this_data.rigidbody, + .this_metadata = this_metadata, + .other_collider = other_collider, + .other_transform = other_data.transform, + .other_rigidbody = other_data.rigidbody, + .other_metadata = other_metadata, + .resolution = resolution_data.first, + .resolution_direction = resolution_data.second, + }; // Determine if static needs to be called - this->determine_collision_handler(collision_info); + this->determine_collision_handler(collision_info); } - -std::pair CollisionSystem::collision_handler(CollisionInternal& data1,CollisionInternal& data2,CollisionInternalType type) { +std::pair +CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal & data2, + CollisionInternalType type) { vec2 resolution; switch (type) { - case CollisionInternalType::BOX_BOX: { - const BoxCollider & collider1 = std::get>(data1.collider); - const BoxCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, data1.rigidbody); - vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); - resolution = this->get_box_box_resolution(collider1,collider2,collider_pos1,collider_pos2); + case CollisionInternalType::BOX_BOX: { + const BoxCollider & collider1 + = std::get>(data1.collider); + const BoxCollider & collider2 + = std::get>(data2.collider); + vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, + data1.rigidbody); + vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, + data2.rigidbody); + resolution = this->get_box_box_resolution(collider1, collider2, collider_pos1, + collider_pos2); break; } case CollisionInternalType::BOX_CIRCLE: { - const BoxCollider & collider1 = std::get>(data1.collider); - const CircleCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, data1.rigidbody); - vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); - resolution = this->get_circle_box_resolution(collider2,collider1,collider_pos2,collider_pos1); + const BoxCollider & collider1 + = std::get>(data1.collider); + const CircleCollider & collider2 + = std::get>(data2.collider); + vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, + data1.rigidbody); + vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, + data2.rigidbody); + resolution = this->get_circle_box_resolution(collider2, collider1, collider_pos2, + collider_pos1); break; } - case CollisionInternalType::CIRCLE_CIRCLE: { - const CircleCollider & collider1 = std::get>(data1.collider); - const CircleCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, data1.rigidbody); - vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); - resolution = this->get_circle_circle_resolution(collider1,collider2,collider_pos1,collider_pos2); + case CollisionInternalType::CIRCLE_CIRCLE: { + const CircleCollider & collider1 + = std::get>(data1.collider); + const CircleCollider & collider2 + = std::get>(data2.collider); + vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, + data1.rigidbody); + vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, + data2.rigidbody); + resolution = this->get_circle_circle_resolution(collider1, collider2, + collider_pos1, collider_pos2); break; } - case CollisionInternalType::CIRCLE_BOX: { - const CircleCollider & collider1 = std::get>(data1.collider); - const BoxCollider & collider2 = std::get>(data2.collider); - vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, data1.rigidbody); - vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); - resolution = this->get_circle_box_resolution(collider1,collider2,collider_pos1,collider_pos2); + case CollisionInternalType::CIRCLE_BOX: { + const CircleCollider & collider1 + = std::get>(data1.collider); + const BoxCollider & collider2 + = std::get>(data2.collider); + vec2 collider_pos1 = this->get_current_position(collider1.offset, data1.transform, + data1.rigidbody); + vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, + data2.rigidbody); + resolution = this->get_circle_box_resolution(collider1, collider2, collider_pos1, + collider_pos2); break; } } Direction resolution_direction = Direction::NONE; - if(resolution.x != 0 && resolution.y > 0) { + if (resolution.x != 0 && resolution.y > 0) { resolution_direction = Direction::BOTH; } else if (resolution.x != 0) { resolution_direction = Direction::X_DIRECTION; - if(data1.rigidbody.data.linear_velocity.y != 0) - resolution.y = data1.rigidbody.data.linear_velocity.y * (resolution.x/data1.rigidbody.data.linear_velocity.x); + if (data1.rigidbody.data.linear_velocity.y != 0) + resolution.y = data1.rigidbody.data.linear_velocity.y + * (resolution.x / data1.rigidbody.data.linear_velocity.x); } else if (resolution.y != 0) { resolution_direction = Direction::Y_DIRECTION; - if(data1.rigidbody.data.linear_velocity.x != 0) - resolution.x = data1.rigidbody.data.linear_velocity.x * (resolution.y/data1.rigidbody.data.linear_velocity.y); + if (data1.rigidbody.data.linear_velocity.x != 0) + resolution.x = data1.rigidbody.data.linear_velocity.x + * (resolution.y / data1.rigidbody.data.linear_velocity.y); } - return std::make_pair(resolution,resolution_direction); + return std::make_pair(resolution, resolution_direction); } -vec2 CollisionSystem::get_box_box_resolution(const BoxCollider& box_collider1,const BoxCollider& box_collider2,const vec2& final_position1,const vec2& final_position2) const -{ +vec2 CollisionSystem::get_box_box_resolution(const BoxCollider & box_collider1, + const BoxCollider & box_collider2, + const vec2 & final_position1, + const vec2 & final_position2) const { vec2 resolution; // Default resolution vector vec2 delta = final_position2 - final_position1; @@ -210,97 +243,107 @@ vec2 CollisionSystem::get_box_box_resolution(const BoxCollider& box_collider1,co return resolution; } -vec2 CollisionSystem::get_circle_circle_resolution(const CircleCollider& circle_collider1, const CircleCollider& circle_collider2, const vec2& final_position1, const vec2& final_position2) const -{ - vec2 delta = final_position2 - final_position1; +vec2 CollisionSystem::get_circle_circle_resolution(const CircleCollider & circle_collider1, + const CircleCollider & circle_collider2, + const vec2 & final_position1, + const vec2 & final_position2) const { + vec2 delta = final_position2 - final_position1; - // Compute the distance between the two circle centers - float distance = std::sqrt(delta.x * delta.x + delta.y * delta.y); + // Compute the distance between the two circle centers + float distance = std::sqrt(delta.x * delta.x + delta.y * delta.y); - // Compute the combined radii of the two circles - float combined_radius = circle_collider1.radius + circle_collider2.radius; + // Compute the combined radii of the two circles + float combined_radius = circle_collider1.radius + circle_collider2.radius; - // Compute the penetration depth - float penetration_depth = combined_radius - distance; + // Compute the penetration depth + float penetration_depth = combined_radius - distance; - // Normalize the delta vector to get the collision direction - vec2 collision_normal = delta / distance; + // Normalize the delta vector to get the collision direction + vec2 collision_normal = delta / distance; - // Compute the resolution vector - vec2 resolution = collision_normal * penetration_depth; + // Compute the resolution vector + vec2 resolution = collision_normal * penetration_depth; - return resolution; + return resolution; } -vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider& circle_collider, const BoxCollider& box_collider, const vec2& circle_position, const vec2& box_position) const -{ - vec2 delta = circle_position - box_position; +vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_collider, + const BoxCollider & box_collider, + const vec2 & circle_position, + const vec2 & box_position) const { + vec2 delta = circle_position - box_position; - // Compute half-dimensions of the box - float half_width = box_collider.dimensions.x / 2.0f; - float half_height = box_collider.dimensions.y / 2.0f; + // Compute half-dimensions of the box + float half_width = box_collider.dimensions.x / 2.0f; + float half_height = box_collider.dimensions.y / 2.0f; - // Clamp circle center to the nearest point on the box - vec2 closest_point; - closest_point.x = std::clamp(delta.x, -half_width, half_width); - closest_point.y = std::clamp(delta.y, -half_height, half_height); + // Clamp circle center to the nearest point on the box + vec2 closest_point; + closest_point.x = std::clamp(delta.x, -half_width, half_width); + closest_point.y = std::clamp(delta.y, -half_height, half_height); - // Find the vector from the circle center to the closest point - vec2 closest_delta = delta - closest_point; + // Find the vector from the circle center to the closest point + vec2 closest_delta = delta - closest_point; - // Normalize the delta to get the collision direction - float distance = std::sqrt(closest_delta.x * closest_delta.x + closest_delta.y * closest_delta.y); - vec2 collision_normal = closest_delta / distance; + // Normalize the delta to get the collision direction + float distance + = std::sqrt(closest_delta.x * closest_delta.x + closest_delta.y * closest_delta.y); + vec2 collision_normal = closest_delta / distance; - // Compute penetration depth - float penetration_depth = circle_collider.radius - distance; + // Compute penetration depth + float penetration_depth = circle_collider.radius - distance; - // Compute the resolution vector - vec2 resolution = collision_normal * penetration_depth; + // Compute the resolution vector + vec2 resolution = collision_normal * penetration_depth; - return resolution; + return resolution; } - -void CollisionSystem::determine_collision_handler(CollisionInfo& info){ +void CollisionSystem::determine_collision_handler(CollisionInfo & info) { // Check rigidbody type for static - if(info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; + if (info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; // If second body is static perform the static collision handler in this system - if(info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC){ + if (info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) { static_collision_handler(info); - }; + }; // Call collision event for user CollisionEvent data(info); - EventManager::get_instance().trigger_event(data, info.this_collider.game_object_id); + EventManager::get_instance().trigger_event( + data, info.this_collider.game_object_id); } -void CollisionSystem::static_collision_handler(CollisionInfo& info){ - // Move object back using calculate move back value +void CollisionSystem::static_collision_handler(CollisionInfo & info) { + // Move object back using calculate move back value info.this_transform.position += info.resolution; // If bounce is enabled mirror velocity - if(info.this_rigidbody.data.elastisity_coefficient > 0) { - if(info.resolution_direction == Direction::BOTH) - { - info.this_rigidbody.data.linear_velocity.y = -info.this_rigidbody.data.linear_velocity.y * info.this_rigidbody.data.elastisity_coefficient; - info.this_rigidbody.data.linear_velocity.x = -info.this_rigidbody.data.linear_velocity.x * info.this_rigidbody.data.elastisity_coefficient; - } - else if(info.resolution_direction == Direction::Y_DIRECTION) { - info.this_rigidbody.data.linear_velocity.y = -info.this_rigidbody.data.linear_velocity.y * info.this_rigidbody.data.elastisity_coefficient; - } - else if(info.resolution_direction == Direction::X_DIRECTION){ - info.this_rigidbody.data.linear_velocity.x = -info.this_rigidbody.data.linear_velocity.x * info.this_rigidbody.data.elastisity_coefficient; + if (info.this_rigidbody.data.elastisity_coefficient > 0) { + if (info.resolution_direction == Direction::BOTH) { + info.this_rigidbody.data.linear_velocity.y + = -info.this_rigidbody.data.linear_velocity.y + * info.this_rigidbody.data.elastisity_coefficient; + info.this_rigidbody.data.linear_velocity.x + = -info.this_rigidbody.data.linear_velocity.x + * info.this_rigidbody.data.elastisity_coefficient; + } else if (info.resolution_direction == Direction::Y_DIRECTION) { + info.this_rigidbody.data.linear_velocity.y + = -info.this_rigidbody.data.linear_velocity.y + * info.this_rigidbody.data.elastisity_coefficient; + } else if (info.resolution_direction == Direction::X_DIRECTION) { + info.this_rigidbody.data.linear_velocity.x + = -info.this_rigidbody.data.linear_velocity.x + * info.this_rigidbody.data.elastisity_coefficient; } } // Stop movement if bounce is disabled else { - info.this_rigidbody.data.linear_velocity = {0,0}; + info.this_rigidbody.data.linear_velocity = {0, 0}; } } -std::vector> CollisionSystem::gather_collisions(std::vector & colliders) { - - +std::vector> +CollisionSystem::gather_collisions(std::vector & colliders) { + // TODO: // If no colliders skip // Check if colliders has rigidbody if not skip @@ -311,83 +354,103 @@ std::vector> collisions_ret; - //using visit to visit the variant to access the active and id. + std::vector> collisions_ret; + //using visit to visit the variant to access the active and id. for (size_t i = 0; i < colliders.size(); ++i) { for (size_t j = i + 1; j < colliders.size(); ++j) { - if(colliders[i].id == colliders[j].id) continue; - CollisionInternalType type = get_collider_type(colliders[i].collider,colliders[j].collider); - if(!get_collision({ - .collider = colliders[i].collider, - .transform = colliders[i].transform, - .rigidbody = colliders[i].rigidbody, + if (colliders[i].id == colliders[j].id) continue; + CollisionInternalType type + = get_collider_type(colliders[i].collider, colliders[j].collider); + if (!get_collision( + { + .collider = colliders[i].collider, + .transform = colliders[i].transform, + .rigidbody = colliders[i].rigidbody, }, { - .collider = colliders[j].collider, - .transform = colliders[j].transform, - .rigidbody = colliders[j].rigidbody, + .collider = colliders[j].collider, + .transform = colliders[j].transform, + .rigidbody = colliders[j].rigidbody, }, - type)) continue; - collisions_ret.emplace_back(colliders[i],colliders[j]); + type)) + continue; + collisions_ret.emplace_back(colliders[i], colliders[j]); } } - + return collisions_ret; } -CollisionSystem::CollisionInternalType CollisionSystem::get_collider_type(const collider_variant& collider1,const collider_variant& collider2) const{ - if(std::holds_alternative>(collider1)){ - if(std::holds_alternative>(collider2)) - { +CollisionSystem::CollisionInternalType +CollisionSystem::get_collider_type(const collider_variant & collider1, + const collider_variant & collider2) const { + if (std::holds_alternative>(collider1)) { + if (std::holds_alternative>(collider2)) { return CollisionInternalType::CIRCLE_CIRCLE; - } - else { + } else { return CollisionInternalType::CIRCLE_BOX; } - } - else { - if(std::holds_alternative>(collider2)) - { + } else { + if (std::holds_alternative>(collider2)) { return CollisionInternalType::BOX_CIRCLE; - } - else { + } else { return CollisionInternalType::BOX_BOX; } } } -bool CollisionSystem::get_collision(const CollisionInternal& first_info,const CollisionInternal& second_info, CollisionInternalType type) const{ +bool CollisionSystem::get_collision(const CollisionInternal & first_info, + const CollisionInternal & second_info, + CollisionInternalType type) const { switch (type) { - case CollisionInternalType::BOX_BOX: { - const BoxCollider & box_collider1 = std::get>(first_info.collider); - const BoxCollider & box_collider2 = std::get>(second_info.collider); - return this->get_box_box_collision(box_collider1,box_collider2,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); + case CollisionInternalType::BOX_BOX: { + const BoxCollider & box_collider1 + = std::get>(first_info.collider); + const BoxCollider & box_collider2 + = std::get>(second_info.collider); + return this->get_box_box_collision(box_collider1, box_collider2, + first_info.transform, second_info.transform, + second_info.rigidbody, second_info.rigidbody); } case CollisionInternalType::BOX_CIRCLE: { - const BoxCollider & box_collider = std::get>(first_info.collider); - const CircleCollider & circle_collider = std::get>(second_info.collider); - return this->get_box_circle_collision(box_collider,circle_collider,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); + const BoxCollider & box_collider + = std::get>(first_info.collider); + const CircleCollider & circle_collider + = std::get>(second_info.collider); + return this->get_box_circle_collision( + box_collider, circle_collider, first_info.transform, second_info.transform, + second_info.rigidbody, second_info.rigidbody); } - case CollisionInternalType::CIRCLE_CIRCLE: { - const CircleCollider & circle_collider1 = std::get>(first_info.collider); - const CircleCollider & circle_collider2 = std::get>(second_info.collider); - return this->get_circle_circle_collision(circle_collider1,circle_collider2,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); + case CollisionInternalType::CIRCLE_CIRCLE: { + const CircleCollider & circle_collider1 + = std::get>(first_info.collider); + const CircleCollider & circle_collider2 + = std::get>(second_info.collider); + return this->get_circle_circle_collision( + circle_collider1, circle_collider2, first_info.transform, + second_info.transform, second_info.rigidbody, second_info.rigidbody); } - case CollisionInternalType::CIRCLE_BOX: { - const CircleCollider & circle_collider = std::get>(first_info.collider); - const BoxCollider & box_collider = std::get>(second_info.collider); - return this->get_box_circle_collision(box_collider,circle_collider,first_info.transform,second_info.transform,second_info.rigidbody,second_info.rigidbody); + case CollisionInternalType::CIRCLE_BOX: { + const CircleCollider & circle_collider + = std::get>(first_info.collider); + const BoxCollider & box_collider + = std::get>(second_info.collider); + return this->get_box_circle_collision( + box_collider, circle_collider, first_info.transform, second_info.transform, + second_info.rigidbody, second_info.rigidbody); } } return false; } - -bool CollisionSystem::get_box_box_collision(const BoxCollider& box1, const BoxCollider& box2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) const -{ +bool CollisionSystem::get_box_box_collision(const BoxCollider & box1, const BoxCollider & box2, + const Transform & transform1, + const Transform & transform2, + const Rigidbody & rigidbody1, + const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = this->get_current_position(box1.offset,transform1,rigidbody1); - vec2 final_position2 = this->get_current_position(box2.offset,transform2,rigidbody2); + vec2 final_position1 = this->get_current_position(box1.offset, transform1, rigidbody1); + vec2 final_position2 = this->get_current_position(box2.offset, transform2, rigidbody2); // Calculate half-extents (half width and half height) float half_width1 = box1.dimensions.x / 2.0; @@ -396,13 +459,18 @@ bool CollisionSystem::get_box_box_collision(const BoxCollider& box1, const BoxCo float half_height2 = box2.dimensions.y / 2.0; // Check if the boxes overlap along the X and Y axes - return (final_position1.x + half_width1 > final_position2.x - half_width2 && - final_position1.x - half_width1 < final_position2.x + half_width2 && - final_position1.y + half_height1 > final_position2.y - half_height2 && - final_position1.y - half_height1 < final_position2.y + half_height2); + return (final_position1.x + half_width1 > final_position2.x - half_width2 + && final_position1.x - half_width1 < final_position2.x + half_width2 + && final_position1.y + half_height1 > final_position2.y - half_height2 + && final_position1.y - half_height1 < final_position2.y + half_height2); } -bool CollisionSystem::get_box_circle_collision(const BoxCollider& box1, const CircleCollider& circle2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) const { +bool CollisionSystem::get_box_circle_collision(const BoxCollider & box1, + const CircleCollider & circle2, + const Transform & transform1, + const Transform & transform2, + const Rigidbody & rigidbody1, + const Rigidbody & rigidbody2) const { // Get current positions of colliders vec2 final_position1 = this->get_current_position(box1.offset, transform1, rigidbody1); vec2 final_position2 = this->get_current_position(circle2.offset, transform2, rigidbody2); @@ -412,8 +480,10 @@ bool CollisionSystem::get_box_circle_collision(const BoxCollider& box1, const Ci float half_height = box1.dimensions.y / 2.0; // Find the closest point on the box to the circle's center - float closest_x = std::max(final_position1.x - half_width, std::min(final_position2.x, final_position1.x + half_width)); - float closest_y = std::max(final_position1.y - half_height, std::min(final_position2.y, final_position1.y + half_height)); + float closest_x = std::max(final_position1.x - half_width, + std::min(final_position2.x, final_position1.x + half_width)); + float closest_y = std::max(final_position1.y - half_height, + std::min(final_position2.y, final_position1.y + half_height)); // Calculate the distance squared between the circle's center and the closest point on the box float distance_x = final_position2.x - closest_x; @@ -424,10 +494,15 @@ bool CollisionSystem::get_box_circle_collision(const BoxCollider& box1, const Ci return distance_squared <= circle2.radius * circle2.radius; } -bool CollisionSystem::get_circle_circle_collision(const CircleCollider& circle1, const CircleCollider& circle2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) const { +bool CollisionSystem::get_circle_circle_collision(const CircleCollider & circle1, + const CircleCollider & circle2, + const Transform & transform1, + const Transform & transform2, + const Rigidbody & rigidbody1, + const Rigidbody & rigidbody2) const { // Get current positions of colliders - vec2 final_position1 = this->get_current_position(circle1.offset,transform1,rigidbody1); - vec2 final_position2 = this->get_current_position(circle2.offset,transform2,rigidbody2); + vec2 final_position1 = this->get_current_position(circle1.offset, transform1, rigidbody1); + vec2 final_position2 = this->get_current_position(circle2.offset, transform2, rigidbody2); float distance_x = final_position1.x - final_position2.x; float distance_y = final_position1.y - final_position2.y; @@ -440,7 +515,9 @@ bool CollisionSystem::get_circle_circle_collision(const CircleCollider& circle1, return distance_squared <= radius_sum * radius_sum; } -vec2 CollisionSystem::get_current_position(const vec2& collider_offset, const Transform& transform, const Rigidbody& rigidbody) const { +vec2 CollisionSystem::get_current_position(const vec2 & collider_offset, + const Transform & transform, + const Rigidbody & rigidbody) const { // Get the rotation in radians float radians1 = transform.rotation * (M_PI / 180.0); @@ -448,10 +525,11 @@ vec2 CollisionSystem::get_current_position(const vec2& collider_offset, const Tr vec2 total_offset = (rigidbody.data.offset + collider_offset) * transform.scale; // Rotate - float rotated_total_offset_x1 = total_offset.x * cos(radians1) - total_offset.y * sin(radians1); - float rotated_total_offset_y1 = total_offset.x * sin(radians1) + total_offset.y * cos(radians1); + float rotated_total_offset_x1 + = total_offset.x * cos(radians1) - total_offset.y * sin(radians1); + float rotated_total_offset_y1 + = total_offset.x * sin(radians1) + total_offset.y * cos(radians1); // Final positions considering scaling and rotation - return(transform.position + vec2(rotated_total_offset_x1, rotated_total_offset_y1)); - + return (transform.position + vec2(rotated_total_offset_x1, rotated_total_offset_y1)); } diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 85ae5ad..6b5a4bb 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -1,38 +1,37 @@ #pragma once -#include -#include #include +#include +#include -#include "api/Rigidbody.h" -#include "api/Transform.h" #include "api/BoxCollider.h" #include "api/CircleCollider.h" #include "api/Metadata.h" +#include "api/Rigidbody.h" +#include "api/Transform.h" #include "api/Vector2.h" #include "Collider.h" #include "System.h" - namespace crepe { - //! A system responsible for detecting and handling collisions between colliders. class CollisionSystem : public System { public: using System::System; + private: - //! A variant type that can hold either a BoxCollider or a CircleCollider. - using collider_variant = std::variant, std::reference_wrapper>; + using collider_variant = std::variant, + std::reference_wrapper>; //! Enum representing the types of collider pairs for collision detection. enum class CollisionInternalType { - BOX_BOX, - CIRCLE_CIRCLE, - BOX_CIRCLE, - CIRCLE_BOX, + BOX_BOX, + CIRCLE_CIRCLE, + BOX_CIRCLE, + CIRCLE_BOX, }; /** @@ -45,21 +44,21 @@ private: */ struct CollisionInternal { game_object_id_t id = 0; - collider_variant collider; - Transform& transform; - Rigidbody& rigidbody; + collider_variant collider; + Transform & transform; + Rigidbody & rigidbody; }; - + //! Enum representing movement directions during collision resolution. enum class Direction { //! No movement required. - NONE, + NONE, //! Movement in the X direction. - X_DIRECTION, + X_DIRECTION, //! Movement in the Y direction. - Y_DIRECTION, + Y_DIRECTION, //! Movement in both X and Y directions. - BOTH + BOTH }; public: @@ -68,15 +67,15 @@ public: * * Includes information about the colliding objects and the resolution data for handling the collision. */ - struct CollisionInfo{ - Collider& this_collider; - Transform& this_transform; - Rigidbody& this_rigidbody; - Metadata& this_metadata; - Collider& other_collider; - Transform& other_transform; - Rigidbody& other_rigidbody; - Metadata& other_metadata; + struct CollisionInfo { + Collider & this_collider; + Transform & this_transform; + Rigidbody & this_rigidbody; + Metadata & this_metadata; + Collider & other_collider; + Transform & other_transform; + Rigidbody & other_rigidbody; + Metadata & other_metadata; //! The resolution vector for the collision. vec2 resolution; //! The direction of movement for resolving the collision. @@ -84,11 +83,10 @@ public: }; public: - //! Updates the collision system by checking for collisions between colliders and handling them. void update() override; -private: +private: /** * \brief Determines the type of collider pair from two colliders. * @@ -98,7 +96,8 @@ private: * \param collider2 Second collider variant (BoxCollider or CircleCollider). * \return The combined type of the two colliders. */ - CollisionInternalType get_collider_type(const collider_variant& collider1,const collider_variant& collider2) const; + CollisionInternalType get_collider_type(const collider_variant & collider1, + const collider_variant & collider2) const; /** * \brief Calculates the current position of a collider. @@ -110,10 +109,10 @@ private: * \param rigidbody The Rigidbody of the associated game object. * \return The calculated position of the collider. */ - vec2 get_current_position(const vec2& collider_offset, const Transform& transform, const Rigidbody& rigidbody) const; + vec2 get_current_position(const vec2 & collider_offset, const Transform & transform, + const Rigidbody & rigidbody) const; private: - /** * \brief Handles collision resolution between two colliders. * @@ -122,7 +121,7 @@ private: * \param data1 Collision data for the first collider. * \param data2 Collision data for the second collider. */ - void collision_handler_request(CollisionInternal& data1,CollisionInternal& data2); + void collision_handler_request(CollisionInternal & data1, CollisionInternal & data2); /** * \brief Resolves collision between two colliders and calculates the movement required. @@ -134,7 +133,9 @@ private: * \param type The type of collider pair. * \return A pair containing the resolution vector and direction for the first collider. */ - std::pair collision_handler(CollisionInternal& data1,CollisionInternal& data2 ,CollisionInternalType type); + std::pair collision_handler(CollisionInternal & data1, + CollisionInternal & data2, + CollisionInternalType type); /** * \brief Calculates the resolution vector for two BoxColliders. @@ -147,7 +148,9 @@ private: * \param position2 The position of the second BoxCollider. * \return The resolution vector for the collision. */ - vec2 get_box_box_resolution(const BoxCollider& box_collider1,const BoxCollider& box_collider2,const vec2& position1,const vec2& position2) const; + vec2 get_box_box_resolution(const BoxCollider & box_collider1, + const BoxCollider & box_collider2, const vec2 & position1, + const vec2 & position2) const; /** * \brief Calculates the resolution vector for two CircleCollider. @@ -160,7 +163,10 @@ private: * \param position2 The position of the second CircleCollider. * \return The resolution vector for the collision. */ - vec2 get_circle_circle_resolution(const CircleCollider& circle_collider1, const CircleCollider& circle_collider2, const vec2& final_position1, const vec2& final_position2) const; + vec2 get_circle_circle_resolution(const CircleCollider & circle_collider1, + const CircleCollider & circle_collider2, + const vec2 & final_position1, + const vec2 & final_position2) const; /** * \brief Calculates the resolution vector for two CircleCollider. @@ -173,7 +179,10 @@ private: * \param box_position The position of the BocCollider. * \return The resolution vector for the collision. */ - vec2 get_circle_box_resolution(const CircleCollider& circle_collider, const BoxCollider& box_collider, const vec2& circle_position, const vec2& box_position) const; + vec2 get_circle_box_resolution(const CircleCollider & circle_collider, + const BoxCollider & box_collider, + const vec2 & circle_position, + const vec2 & box_position) const; /** * \brief Determines the appropriate collision handler for a collision. @@ -182,7 +191,7 @@ private: * * \param info Collision information containing data about both colliders. */ - void determine_collision_handler(CollisionInfo& info); + void determine_collision_handler(CollisionInfo & info); /** * \brief Handles collisions involving static objects. @@ -191,9 +200,9 @@ private: * * \param info Collision information containing data about both colliders. */ - void static_collision_handler(CollisionInfo& info); + void static_collision_handler(CollisionInfo & info); + private: - /** * \brief Checks for collisions between colliders. * @@ -202,7 +211,8 @@ private: * \param colliders A collection of all active colliders. * \return A list of collision pairs with their associated data. */ - std::vector> gather_collisions(std::vector & colliders); + std::vector> + gather_collisions(std::vector & colliders); /** * \brief Checks for collision between two colliders. @@ -214,8 +224,10 @@ private: * \param type The type of collider pair. * \return True if a collision is detected, otherwise false. */ - bool get_collision(const CollisionInternal& first_info,const CollisionInternal& second_info, CollisionInternalType type) const; - + bool get_collision(const CollisionInternal & first_info, + const CollisionInternal & second_info, + CollisionInternalType type) const; + /** * \brief Detects collisions between two BoxColliders. * @@ -227,8 +239,11 @@ private: * \param rigidbody2 Rigidbody of the second object. * \return True if a collision is detected, otherwise false. */ - bool get_box_box_collision(const BoxCollider& box1, const BoxCollider& box2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) const; - + bool get_box_box_collision(const BoxCollider & box1, const BoxCollider & box2, + const Transform & transform1, const Transform & transform2, + const Rigidbody & rigidbody1, + const Rigidbody & rigidbody2) const; + /** * \brief Check collision for box on circle collider * @@ -240,7 +255,10 @@ private: * \param rigidbody2 Rigidbody of the second object. * \return True if a collision is detected, otherwise false. */ - bool get_box_circle_collision(const BoxCollider& box1, const CircleCollider& circle2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) const; + bool get_box_circle_collision(const BoxCollider & box1, const CircleCollider & circle2, + const Transform & transform1, const Transform & transform2, + const Rigidbody & rigidbody1, + const Rigidbody & rigidbody2) const; /** * \brief Check collision for circle on circle collider @@ -255,7 +273,12 @@ private: * * \return status of collision */ - bool get_circle_circle_collision(const CircleCollider& circle1, const CircleCollider& circle2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) const; + bool get_circle_circle_collision(const CircleCollider & circle1, + const CircleCollider & circle2, + const Transform & transform1, + const Transform & transform2, + const Rigidbody & rigidbody1, + const Rigidbody & rigidbody2) const; }; } // namespace crepe diff --git a/src/crepe/system/PhysicsSystem.cpp b/src/crepe/system/PhysicsSystem.cpp index b5da042..b3adfa1 100644 --- a/src/crepe/system/PhysicsSystem.cpp +++ b/src/crepe/system/PhysicsSystem.cpp @@ -32,10 +32,13 @@ void PhysicsSystem::update() { } // Add damping if (rigidbody.data.angular_velocity_coefficient > 0) { - rigidbody.data.angular_velocity *= rigidbody.data.angular_velocity_coefficient; + rigidbody.data.angular_velocity + *= rigidbody.data.angular_velocity_coefficient; } - if (rigidbody.data.linear_velocity_coefficient.x > 0 && rigidbody.data.linear_velocity_coefficient.y > 0) { - rigidbody.data.linear_velocity *= rigidbody.data.linear_velocity_coefficient; + if (rigidbody.data.linear_velocity_coefficient.x > 0 + && rigidbody.data.linear_velocity_coefficient.y > 0) { + rigidbody.data.linear_velocity + *= rigidbody.data.linear_velocity_coefficient; } // Max velocity check diff --git a/src/example/game.cpp b/src/example/game.cpp index de08a22..70c562e 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -1,77 +1,84 @@ -#include -#include -#include #include #include -#include #include -#include -#include -#include #include #include +#include #include +#include +#include +#include +#include +#include +#include using namespace crepe; using namespace std; class MyScript : public Script { - bool oncollision(const CollisionEvent& test) { + bool oncollision(const CollisionEvent & test) { Log::logf("Box {} script on_collision()", test.info.this_collider.game_object_id); return true; } void init() { - subscribe([this](const CollisionEvent& ev) -> bool { - return this->oncollision(ev); - }); + subscribe( + [this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); }); } void update() { // Retrieve component from the same GameObject this script is on } }; - class ConcreteScene1 : public Scene { public: using Scene::Scene; void load_scene() { - ComponentManager & mgr = this->component_manager; - Color color(0, 0, 0, 255); + ComponentManager & mgr = this->component_manager; + Color color(0, 0, 0, 255); - float screen_size_width = 640; - float screen_size_height = 480; - float world_collider = 1000; - //define playable world - GameObject world = mgr.new_object("Name", "Tag", vec2{screen_size_width/2, screen_size_height/2}, 0, 1); - world.add_component(Rigidbody::Data{ - .mass = 0, - .gravity_scale = 0, - .body_type = Rigidbody::BodyType::STATIC, - .constraints = {0, 0, 0}, - .offset = {0,0} - }); - world.add_component(vec2{0, 0-(screen_size_height/2+world_collider/2)}, vec2{world_collider, world_collider});; // Top - world.add_component(vec2{0, screen_size_height/2+world_collider/2}, vec2{world_collider, world_collider}); // Bottom - world.add_component(vec2{0-(screen_size_width/2+world_collider/2), 0}, vec2{world_collider, world_collider}); // Left - world.add_component(vec2{screen_size_width/2+world_collider/2, 0}, vec2{world_collider, world_collider}); // right - world.add_component(Color::WHITE, ivec2{640, 480},vec2{640, 480}, 1.0f); + float screen_size_width = 640; + float screen_size_height = 480; + float world_collider = 1000; + //define playable world + GameObject world = mgr.new_object( + "Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1); + world.add_component( + Rigidbody::Data{.mass = 0, + .gravity_scale = 0, + .body_type = Rigidbody::BodyType::STATIC, + .constraints = {0, 0, 0}, + .offset = {0, 0}}); + world.add_component( + vec2{0, 0 - (screen_size_height / 2 + world_collider / 2)}, + vec2{world_collider, world_collider}); + ; // Top + world.add_component(vec2{0, screen_size_height / 2 + world_collider / 2}, + vec2{world_collider, world_collider}); // Bottom + world.add_component( + vec2{0 - (screen_size_width / 2 + world_collider / 2), 0}, + vec2{world_collider, world_collider}); // Left + world.add_component(vec2{screen_size_width / 2 + world_collider / 2, 0}, + vec2{world_collider, world_collider}); // right + world.add_component(Color::WHITE, ivec2{640, 480}, vec2{640, 480}, 1.0f); - GameObject game_object1 = mgr.new_object("Name", "Tag", vec2{screen_size_width/2, screen_size_height/2}, 0, 1); - game_object1.add_component(Rigidbody::Data{ - .mass = 1, - .gravity_scale = 0.01, - .body_type = Rigidbody::BodyType::DYNAMIC, - .linear_velocity = {1,1}, - .constraints = {0, 0, 0}, - .elastisity_coefficient = 1, - .offset = {0,0}, - }); - game_object1.add_component(vec2{0, 0}, vec2{20, 20}); - game_object1.add_component().set_script(); - auto img = Texture("asset/texture/green_square.png"); - game_object1.add_component(img, color, Sprite::FlipSettings{false, false}, 1, 1, 20); + GameObject game_object1 = mgr.new_object( + "Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1); + game_object1.add_component(Rigidbody::Data{ + .mass = 1, + .gravity_scale = 0.01, + .body_type = Rigidbody::BodyType::DYNAMIC, + .linear_velocity = {1, 1}, + .constraints = {0, 0, 0}, + .elastisity_coefficient = 1, + .offset = {0, 0}, + }); + game_object1.add_component(vec2{0, 0}, vec2{20, 20}); + game_object1.add_component().set_script(); + auto img = Texture("asset/texture/green_square.png"); + game_object1.add_component(img, color, Sprite::FlipSettings{false, false}, 1, + 1, 20); } string get_name() const { return "scene1"; } diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index fec42f3..74edaf7 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -26,22 +26,19 @@ using namespace testing; class CollisionHandler : public Script { public: int box_id; - function test_fn = [](const CollisionEvent & ev) { }; + function test_fn = [](const CollisionEvent & ev) {}; - CollisionHandler(int box_id) { - this->box_id = box_id; - } + CollisionHandler(int box_id) { this->box_id = box_id; } - bool on_collision(const CollisionEvent& ev) { + bool on_collision(const CollisionEvent & ev) { //Log::logf("Box {} script on_collision()", box_id); test_fn(ev); return true; } void init() { - subscribe([this](const CollisionEvent& ev) -> bool { - return this->on_collision(ev); - }); + subscribe( + [this](const CollisionEvent & ev) -> bool { return this->on_collision(ev); }); } void update() { // Retrieve component from the same GameObject this script is on @@ -54,18 +51,18 @@ public: CollisionSystem collision_sys{mgr}; ScriptSystem script_sys{mgr}; - GameObject world = mgr.new_object("world","",{50,50}); - GameObject game_object1 = mgr.new_object("object1", "", { 50, 50}); - GameObject game_object2 = mgr.new_object("object2", "", { 50, 30}); + GameObject world = mgr.new_object("world", "", {50, 50}); + GameObject game_object1 = mgr.new_object("object1", "", {50, 50}); + GameObject game_object2 = mgr.new_object("object2", "", {50, 30}); CollisionHandler * script_object1_ref = nullptr; CollisionHandler * script_object2_ref = nullptr; - + void SetUp() override { world.add_component(Rigidbody::Data{ // TODO: remove unrelated properties: .body_type = Rigidbody::BodyType::STATIC, - .offset = {0,0}, + .offset = {0, 0}, }); // Create a box with an inner size of 10x10 units world.add_component(vec2{0, -100}, vec2{100, 100}); // Top @@ -77,28 +74,30 @@ public: .mass = 1, .gravity_scale = 0.01, .body_type = Rigidbody::BodyType::DYNAMIC, - .linear_velocity = {0,0}, + .linear_velocity = {0, 0}, .constraints = {0, 0, 0}, .elastisity_coefficient = 1, - .offset = {0,0}, + .offset = {0, 0}, }); game_object1.add_component(vec2{0, 0}, vec2{10, 10}); - BehaviorScript & script_object1 = game_object1.add_component().set_script(1); - script_object1_ref = static_cast(script_object1.script.get()); + BehaviorScript & script_object1 + = game_object1.add_component().set_script(1); + script_object1_ref = static_cast(script_object1.script.get()); ASSERT_NE(script_object1_ref, nullptr); - + game_object2.add_component(Rigidbody::Data{ .mass = 1, .gravity_scale = 0.01, .body_type = Rigidbody::BodyType::DYNAMIC, - .linear_velocity = {0,0}, + .linear_velocity = {0, 0}, .constraints = {0, 0, 0}, .elastisity_coefficient = 1, - .offset = {0,0}, + .offset = {0, 0}, }); game_object2.add_component(vec2{0, 0}, vec2{10, 10}); - BehaviorScript & script_object2 = game_object2.add_component().set_script(2); - script_object2_ref = static_cast(script_object2.script.get()); + BehaviorScript & script_object2 + = game_object2.add_component().set_script(2); + script_object2_ref = static_cast(script_object2.script.get()); ASSERT_NE(script_object2_ref, nullptr); // Ensure Script::init() is called on all BehaviorScript instances @@ -139,7 +138,7 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both_no_velocity) { }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); - tf.position = {50,30}; + tf.position = {50, 30}; collision_sys.update(); EXPECT_TRUE(collision_happend); } @@ -151,18 +150,20 @@ TEST_F(CollisionTest, collision_box_box_dynamic_x_direction_no_velocity) { EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, -5); EXPECT_EQ(ev.info.resolution.y, 0); - EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); + EXPECT_EQ(ev.info.resolution_direction, + crepe::CollisionSystem::Direction::X_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; EXPECT_EQ(ev.info.this_collider.game_object_id, 2); EXPECT_EQ(ev.info.resolution.x, 5); EXPECT_EQ(ev.info.resolution.y, 0); - EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); + EXPECT_EQ(ev.info.resolution_direction, + crepe::CollisionSystem::Direction::X_DIRECTION); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); - tf.position = {45,30}; + tf.position = {45, 30}; collision_sys.update(); EXPECT_TRUE(collision_happend); } @@ -174,18 +175,20 @@ TEST_F(CollisionTest, collision_box_box_dynamic_y_direction_no_velocity) { EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, 0); EXPECT_EQ(ev.info.resolution.y, -5); - EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); + EXPECT_EQ(ev.info.resolution_direction, + crepe::CollisionSystem::Direction::Y_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; EXPECT_EQ(ev.info.this_collider.game_object_id, 2); EXPECT_EQ(ev.info.resolution.x, 0); EXPECT_EQ(ev.info.resolution.y, 5); - EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); + EXPECT_EQ(ev.info.resolution_direction, + crepe::CollisionSystem::Direction::Y_DIRECTION); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); - tf.position = {50,25}; + tf.position = {50, 25}; collision_sys.update(); EXPECT_TRUE(collision_happend); } @@ -208,11 +211,11 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both) { }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); - tf.position = {50,30}; + tf.position = {50, 30}; Rigidbody & rg1 = this->mgr.get_components_by_id(1).front().get(); - rg1.data.linear_velocity = {10,10}; + rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); - rg2.data.linear_velocity = {10,10}; + rg2.data.linear_velocity = {10, 10}; collision_sys.update(); EXPECT_TRUE(collision_happend); } @@ -224,22 +227,24 @@ TEST_F(CollisionTest, collision_box_box_dynamic_x_direction) { EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, -5); EXPECT_EQ(ev.info.resolution.y, -5); - EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); + EXPECT_EQ(ev.info.resolution_direction, + crepe::CollisionSystem::Direction::X_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; EXPECT_EQ(ev.info.this_collider.game_object_id, 2); EXPECT_EQ(ev.info.resolution.x, 5); EXPECT_EQ(ev.info.resolution.y, 5); - EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); + EXPECT_EQ(ev.info.resolution_direction, + crepe::CollisionSystem::Direction::X_DIRECTION); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); - tf.position = {45,30}; + tf.position = {45, 30}; Rigidbody & rg1 = this->mgr.get_components_by_id(1).front().get(); - rg1.data.linear_velocity = {10,10}; + rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); - rg2.data.linear_velocity = {10,10}; + rg2.data.linear_velocity = {10, 10}; collision_sys.update(); EXPECT_TRUE(collision_happend); } @@ -251,27 +256,28 @@ TEST_F(CollisionTest, collision_box_box_dynamic_y_direction) { EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, -5); EXPECT_EQ(ev.info.resolution.y, -5); - EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); + EXPECT_EQ(ev.info.resolution_direction, + crepe::CollisionSystem::Direction::Y_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { collision_happend = true; EXPECT_EQ(ev.info.this_collider.game_object_id, 2); EXPECT_EQ(ev.info.resolution.x, 5); EXPECT_EQ(ev.info.resolution.y, 5); - EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); + EXPECT_EQ(ev.info.resolution_direction, + crepe::CollisionSystem::Direction::Y_DIRECTION); }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); - tf.position = {50,25}; + tf.position = {50, 25}; Rigidbody & rg1 = this->mgr.get_components_by_id(1).front().get(); - rg1.data.linear_velocity = {10,10}; + rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); - rg2.data.linear_velocity = {10,10}; + rg2.data.linear_velocity = {10, 10}; collision_sys.update(); EXPECT_TRUE(collision_happend); } - TEST_F(CollisionTest, collision_box_box_static_both) { bool collision_happend = false; script_object1_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { @@ -287,7 +293,7 @@ TEST_F(CollisionTest, collision_box_box_static_both) { }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); - tf.position = {50,30}; + tf.position = {50, 30}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); rg2.data.body_type = crepe::Rigidbody::BodyType::STATIC; collision_sys.update(); @@ -301,7 +307,8 @@ TEST_F(CollisionTest, collision_box_box_static_x_direction) { EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, -5); EXPECT_EQ(ev.info.resolution.y, -5); - EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::X_DIRECTION); + EXPECT_EQ(ev.info.resolution_direction, + crepe::CollisionSystem::Direction::X_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { // is static should not be called @@ -309,9 +316,9 @@ TEST_F(CollisionTest, collision_box_box_static_x_direction) { }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); - tf.position = {45,30}; + tf.position = {45, 30}; Rigidbody & rg1 = this->mgr.get_components_by_id(1).front().get(); - rg1.data.linear_velocity = {10,10}; + rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); rg2.data.body_type = crepe::Rigidbody::BodyType::STATIC; collision_sys.update(); @@ -325,7 +332,8 @@ TEST_F(CollisionTest, collision_box_box_static_y_direction) { EXPECT_EQ(ev.info.this_collider.game_object_id, 1); EXPECT_EQ(ev.info.resolution.x, -5); EXPECT_EQ(ev.info.resolution.y, -5); - EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::Y_DIRECTION); + EXPECT_EQ(ev.info.resolution_direction, + crepe::CollisionSystem::Direction::Y_DIRECTION); }; script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { // is static should not be called @@ -333,24 +341,24 @@ TEST_F(CollisionTest, collision_box_box_static_y_direction) { }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); - tf.position = {50,25}; + tf.position = {50, 25}; Rigidbody & rg1 = this->mgr.get_components_by_id(1).front().get(); - rg1.data.linear_velocity = {10,10}; + rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); rg2.data.body_type = crepe::Rigidbody::BodyType::STATIC; collision_sys.update(); EXPECT_TRUE(collision_happend); } -TEST_F(CollisionTest, collision_box_box_static_multiple) {//todo check visually +TEST_F(CollisionTest, collision_box_box_static_multiple) { //todo check visually bool collision_happend = false; float offset_value = 0; float resolution = 0; script_object1_ref->test_fn = [&](const CollisionEvent & ev) { collision_happend = true; EXPECT_EQ(ev.info.this_collider.game_object_id, 1); - EXPECT_EQ(ev.info.this_collider.offset.x , offset_value); - EXPECT_EQ(ev.info.resolution.x , resolution); + EXPECT_EQ(ev.info.this_collider.offset.x, offset_value); + EXPECT_EQ(ev.info.resolution.x, resolution); }; script_object2_ref->test_fn = [&](const CollisionEvent & ev) { // is static should not be called @@ -358,20 +366,20 @@ TEST_F(CollisionTest, collision_box_box_static_multiple) {//todo check visually }; EXPECT_FALSE(collision_happend); Transform & tf = this->mgr.get_components_by_id(1).front().get(); - tf.position = {45,30}; + tf.position = {45, 30}; Rigidbody & rg1 = this->mgr.get_components_by_id(1).front().get(); - rg1.data.linear_velocity = {10,10}; + rg1.data.linear_velocity = {10, 10}; Rigidbody & rg2 = this->mgr.get_components_by_id(2).front().get(); rg2.data.body_type = crepe::Rigidbody::BodyType::STATIC; BoxCollider & bxc = this->mgr.get_components_by_id(1).front().get(); - bxc.offset = {5,0}; + bxc.offset = {5, 0}; this->game_object1.add_component(vec2{-5, 0}, vec2{10, 10}); offset_value = 5; resolution = 10; collision_sys.update(); offset_value = -5; resolution = 10; - tf.position = {55,30}; + tf.position = {55, 30}; collision_sys.update(); EXPECT_TRUE(collision_happend); } diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index fa0f5f3..d2f219e 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -1,8 +1,8 @@ #include "system/ParticleSystem.h" #include "system/PhysicsSystem.h" #include "system/RenderSystem.h" -#include #include +#include #include #define private public @@ -12,10 +12,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -27,14 +27,13 @@ using namespace crepe; using namespace testing; class TestScript : public Script { - bool oncollision(const CollisionEvent& test) { + bool oncollision(const CollisionEvent & test) { Log::logf("Box {} script on_collision()", test.info.this_collider.game_object_id); return true; } void init() { - subscribe([this](const CollisionEvent& ev) -> bool { - return this->oncollision(ev); - }); + subscribe( + [this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); }); } void update() { // Retrieve component from the same GameObject this script is on @@ -52,10 +51,9 @@ public: const int average = 5; // Maximum duration to stop test const std::chrono::microseconds duration = 16000us; - ComponentManager mgr; - // Add system used for profling tests + // Add system used for profling tests CollisionSystem collision_sys{mgr}; PhysicsSystem physics_sys{mgr}; ParticleSystem particle_sys{mgr}; @@ -67,12 +65,11 @@ public: int game_object_count = 0; std::chrono::microseconds total_time = 0us; - void SetUp() override { - - GameObject do_not_use = mgr.new_object("DO_NOT_USE","",{0,0}); - do_not_use.add_component(Color::WHITE, ivec2{1080, 720}, - vec2{2000, 2000}, 1.0f); + + GameObject do_not_use = mgr.new_object("DO_NOT_USE", "", {0, 0}); + do_not_use.add_component(Color::WHITE, ivec2{1080, 720}, vec2{2000, 2000}, + 1.0f); // initialize systems here: //calls init script_sys.update(); @@ -82,11 +79,12 @@ public: // Helper function to time an update call and store its duration template - std::chrono::microseconds time_function(const std::string& name, Func&& func) { + std::chrono::microseconds time_function(const std::string & name, Func && func) { auto start = std::chrono::steady_clock::now(); func(); auto end = std::chrono::steady_clock::now(); - std::chrono::microseconds duration = std::chrono::duration_cast(end - start); + std::chrono::microseconds duration + = std::chrono::duration_cast(end - start); timings[name] += duration; return duration; } @@ -95,8 +93,10 @@ public: std::chrono::microseconds run_all_systems() { std::chrono::microseconds total_microseconds = 0us; total_microseconds += time_function("PhysicsSystem", [&]() { physics_sys.update(); }); - total_microseconds += time_function("CollisionSystem", [&]() { collision_sys.update(); }); - total_microseconds += time_function("ParticleSystem", [&]() { particle_sys.update(); }); + total_microseconds + += time_function("CollisionSystem", [&]() { collision_sys.update(); }); + total_microseconds + += time_function("ParticleSystem", [&]() { particle_sys.update(); }); total_microseconds += time_function("RenderSystem", [&]() { render_sys.update(); }); return total_microseconds; } @@ -104,34 +104,33 @@ public: // Print timings of all functions void log_timings() const { std::string result = "\nFunction timings:\n"; - - for (const auto& [name, duration] : timings) { - result += name + " took " + std::to_string(duration.count() / 1000.0 / average) + " ms (" + - std::to_string(duration.count() / average) + " µs).\n"; - } - - result += "Total time: " + std::to_string(this->total_time.count() / 1000.0 / average) + " ms (" + - std::to_string(this->total_time.count() / average) + " µs)\n"; - - result += "Amount of gameobjects: " + std::to_string(game_object_count) + "\n"; - - GTEST_LOG_(INFO) << result; + + for (const auto & [name, duration] : timings) { + result += name + " took " + std::to_string(duration.count() / 1000.0 / average) + + " ms (" + std::to_string(duration.count() / average) + " µs).\n"; + } + + result += "Total time: " + std::to_string(this->total_time.count() / 1000.0 / average) + + " ms (" + std::to_string(this->total_time.count() / average) + " µs)\n"; + + result += "Amount of gameobjects: " + std::to_string(game_object_count) + "\n"; + + GTEST_LOG_(INFO) << result; } void clear_timings() { - for (auto& [key, value] : timings) { - value = std::chrono::microseconds(0); + for (auto & [key, value] : timings) { + value = std::chrono::microseconds(0); } } }; TEST_F(Profiling, Profiling_1) { - while (this->total_time/this->average < this->duration) { - + while (this->total_time / this->average < this->duration) { { //define gameobject used for testing - GameObject gameobject = mgr.new_object("gameobject","",{0,0}); + GameObject gameobject = mgr.new_object("gameobject", "", {0, 0}); } this->game_object_count++; @@ -143,18 +142,19 @@ TEST_F(Profiling, Profiling_1) { this->total_time += run_all_systems(); } - if(this->game_object_count >= this->max_gameobject_count) break; + if (this->game_object_count >= this->max_gameobject_count) break; } log_timings(); EXPECT_GE(this->game_object_count, this->min_gameobject_count); } TEST_F(Profiling, Profiling_2) { - while (this->total_time/this->average < this->duration) { - + while (this->total_time / this->average < this->duration) { + { //define gameobject used for testing - GameObject gameobject = mgr.new_object("gameobject","",{static_cast(game_object_count*2),0}); + GameObject gameobject = mgr.new_object( + "gameobject", "", {static_cast(game_object_count * 2), 0}); gameobject.add_component(Rigidbody::Data{ .gravity_scale = 0.0, .body_type = Rigidbody::BodyType::STATIC, @@ -163,7 +163,8 @@ TEST_F(Profiling, Profiling_2) { gameobject.add_component().set_script(); Color color(0, 0, 0, 0); auto img = Texture("asset/texture/green_square.png"); - Sprite & test_sprite = gameobject.add_component(img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); + Sprite & test_sprite = gameobject.add_component( + img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); } this->game_object_count++; @@ -174,50 +175,52 @@ TEST_F(Profiling, Profiling_2) { this->total_time += run_all_systems(); } - if(this->game_object_count >= this->max_gameobject_count) break; + if (this->game_object_count >= this->max_gameobject_count) break; } log_timings(); EXPECT_GE(this->game_object_count, this->min_gameobject_count); } TEST_F(Profiling, Profiling_3) { - while (this->total_time/this->average < this->duration) { - + while (this->total_time / this->average < this->duration) { + { //define gameobject used for testing - GameObject gameobject = mgr.new_object("gameobject","",{static_cast(game_object_count*2),0}); + GameObject gameobject = mgr.new_object( + "gameobject", "", {static_cast(game_object_count * 2), 0}); gameobject.add_component(Rigidbody::Data{ - .gravity_scale = 0, - .body_type = Rigidbody::BodyType::STATIC, + .gravity_scale = 0, + .body_type = Rigidbody::BodyType::STATIC, }); gameobject.add_component(vec2{0, 0}, 1, 1); gameobject.add_component().set_script(); Color color(0, 0, 0, 0); auto img = Texture("asset/texture/green_square.png"); - Sprite & test_sprite = gameobject.add_component(img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); + Sprite & test_sprite = gameobject.add_component( + img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); auto & test = gameobject.add_component(ParticleEmitter::Data{ - .max_particles = 10, - .emission_rate = 100, - .end_lifespan = 100000, - .boundary{ - .width = 1000, - .height = 1000, - .offset = vec2{0, 0}, - .reset_on_exit = false, - }, - .sprite = test_sprite, - }); + .max_particles = 10, + .emission_rate = 100, + .end_lifespan = 100000, + .boundary{ + .width = 1000, + .height = 1000, + .offset = vec2{0, 0}, + .reset_on_exit = false, + }, + .sprite = test_sprite, + }); } render_sys.update(); this->game_object_count++; - + this->total_time = 0us; clear_timings(); for (int amount = 0; amount < this->average; amount++) { this->total_time += run_all_systems(); } - if(this->game_object_count >= this->max_gameobject_count) break; + if (this->game_object_count >= this->max_gameobject_count) break; } log_timings(); EXPECT_GE(this->game_object_count, this->min_gameobject_count); -- cgit v1.2.3 From 27a5332ee8e905d346a088ac7f4d1d1bb30025c4 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Fri, 6 Dec 2024 15:32:31 +0100 Subject: review feedback --- src/crepe/api/LoopManager.cpp | 1 + src/crepe/api/Rigidbody.h | 4 ++-- src/crepe/api/Script.h | 2 +- src/crepe/system/CollisionSystem.cpp | 10 +++++----- src/crepe/system/CollisionSystem.h | 12 ++++++------ src/test/Profiling.cpp | 4 ++-- 6 files changed, 17 insertions(+), 16 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index b9e91dd..2c12895 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -34,6 +34,7 @@ void LoopManager::start() { void LoopManager::set_running(bool running) { this->game_running = running; } void LoopManager::fixed_update() { + // TODO: retrieve EventManager from direct member after singleton refactor EventManager & ev = this->mediator.event_manager; ev.dispatch_events(); this->get_system().update(); diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index b0a24f7..a6aab26 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -136,8 +136,8 @@ public: /** * \brief Defines the collision layers of a GameObject. * - * The `collision_layers` vector specifies the layers that the GameObject will collide with. - * Each element in the vector represents a layer ID, and the GameObject will only detect + * The `collision_layers` specifies the layers that the GameObject will collide with. + * Each element represents a layer ID, and the GameObject will only detect * collisions with other GameObjects that belong to these layers. */ std::set collision_layers; diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index 1474a09..3d416a1 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -3,7 +3,7 @@ #include #include "../manager/EventManager.h" -#include "system/CollisionSystem.h" +#include "../system/CollisionSystem.h" #include "../manager/Mediator.h" #include "../types.h" #include "../util/OptionalRef.h" diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 44ea7ee..e196e10 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -158,8 +158,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal data1.rigidbody); vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); - resolution = this->get_circle_box_resolution(collider2, collider1, collider_pos2, - collider_pos1,true); + resolution = -this->get_circle_box_resolution(collider2, collider1, collider_pos2, + collider_pos1); break; } case CollisionInternalType::CIRCLE_CIRCLE: { @@ -185,7 +185,7 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); resolution = this->get_circle_box_resolution(collider1, collider2, collider_pos1, - collider_pos2,false); + collider_pos2); break; } } @@ -272,7 +272,7 @@ vec2 CollisionSystem::get_circle_circle_resolution(const CircleCollider & circle vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_collider, const BoxCollider & box_collider, const vec2 & circle_position, - const vec2 & box_position,bool inverse) const { + const vec2 & box_position) const { vec2 delta = circle_position - box_position; // Compute half-dimensions of the box @@ -294,7 +294,7 @@ vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_co // Compute penetration depth float penetration_depth = circle_collider.radius - distance; - if(inverse) collision_normal = -collision_normal; + // Compute the resolution vector vec2 resolution = collision_normal * penetration_depth; diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index b978dbb..6216af9 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -184,7 +184,7 @@ private: vec2 get_circle_box_resolution(const CircleCollider & circle_collider, const BoxCollider & box_collider, const vec2 & circle_position, - const vec2 & box_position,bool inverse) const; + const vec2 & box_position) const; /** * \brief Determines the appropriate collision handler for a collision. @@ -219,14 +219,14 @@ private: /** * \brief Checks if two collision layers have at least one common layer. * - * This function checks if there is any overlapping layer between the two input - * collision layer vectors. It compares each layer from the first vector to see - * if it exists in the second vector. If at least one common layer is found, + * This function checks if there is any overlapping layer between the two inputs. + * It compares each layer from the first input to see + * if it exists in the second input. If at least one common layer is found, * the function returns true, indicating that the two colliders share a common * collision layer. * - * \param layers1 A vector of collision layers for the first collider. - * \param layers2 A vector of collision layers for the second collider. + * \param layers1 all collision layers for the first collider. + * \param layers2 all collision layers for the second collider. * \return Returns true if there is at least one common layer, false otherwise. */ diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 91be769..6a6c29f 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -165,7 +165,7 @@ TEST_F(Profiling, Profiling_2) { gameobject.add_component().set_script(); Color color(0, 0, 0, 0); - auto img = Texture("asset/texture/green_square.png"); + auto img = Texture("asset/texture/square.png"); Sprite & test_sprite = gameobject.add_component( img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); } @@ -198,7 +198,7 @@ TEST_F(Profiling, Profiling_3) { gameobject.add_component(vec2{0, 0}, vec2{1, 1}); gameobject.add_component().set_script(); Color color(0, 0, 0, 0); - auto img = Texture("asset/texture/green_square.png"); + auto img = Texture("asset/texture/square.png"); Sprite & test_sprite = gameobject.add_component( img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); auto & test = gameobject.add_component(ParticleEmitter::Data{ -- cgit v1.2.3 From 70c1cd14ec4c4aca185d5a7e4a3749169f6425f4 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Fri, 6 Dec 2024 15:42:52 +0100 Subject: make format --- src/crepe/api/LoopManager.cpp | 4 +- src/crepe/api/Rigidbody.h | 1 - src/crepe/api/Script.h | 2 +- src/crepe/system/CollisionSystem.cpp | 33 +++++-------- src/crepe/system/CollisionSystem.h | 2 +- src/example/game.cpp | 94 +++++++++++++++++------------------- src/test/CollisionTest.cpp | 6 +-- src/test/Profiling.cpp | 6 +-- 8 files changed, 66 insertions(+), 82 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index 2c12895..a76c167 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -48,13 +48,13 @@ void LoopManager::loop() { while (game_running) { timer.update(); - + while (timer.get_lag() >= timer.get_fixed_delta_time()) { this->process_input(); this->fixed_update(); timer.advance_fixed_update(); } - + this->update(); this->render(); diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index a6aab26..8265ba5 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -7,7 +7,6 @@ #include "types.h" - namespace crepe { /** diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index 3d416a1..d1be1dc 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -3,8 +3,8 @@ #include #include "../manager/EventManager.h" -#include "../system/CollisionSystem.h" #include "../manager/Mediator.h" +#include "../system/CollisionSystem.h" #include "../types.h" #include "../util/OptionalRef.h" diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index e196e10..44a0431 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -6,6 +6,8 @@ #include #include +#include "../manager/ComponentManager.h" +#include "../manager/EventManager.h" #include "api/BoxCollider.h" #include "api/CircleCollider.h" #include "api/Event.h" @@ -13,8 +15,6 @@ #include "api/Rigidbody.h" #include "api/Transform.h" #include "api/Vector2.h" -#include "../manager/ComponentManager.h" -#include "../manager/EventManager.h" #include "Collider.h" #include "CollisionSystem.h" @@ -27,17 +27,14 @@ void CollisionSystem::update() { std::vector all_colliders; game_object_id_t id = 0; ComponentManager & mgr = this->mediator.component_manager; - RefVector rigidbodies - = mgr.get_components_by_type(); + RefVector rigidbodies = mgr.get_components_by_type(); // Collisions can only happen on object with a rigidbody for (Rigidbody & rigidbody : rigidbodies) { if (!rigidbody.active) continue; id = rigidbody.game_object_id; - Transform & transform - = mgr.get_components_by_id(id).front().get(); + Transform & transform = mgr.get_components_by_id(id).front().get(); // Check if the boxcollider is active and has the same id as the rigidbody. - RefVector boxcolliders - = mgr.get_components_by_type(); + RefVector boxcolliders = mgr.get_components_by_type(); for (BoxCollider & boxcollider : boxcolliders) { if (boxcollider.game_object_id != id) continue; if (!boxcollider.active) continue; @@ -159,7 +156,7 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal vec2 collider_pos2 = this->get_current_position(collider2.offset, data2.transform, data2.rigidbody); resolution = -this->get_circle_box_resolution(collider2, collider1, collider_pos2, - collider_pos1); + collider_pos1); break; } case CollisionInternalType::CIRCLE_CIRCLE: { @@ -261,7 +258,6 @@ vec2 CollisionSystem::get_circle_circle_resolution(const CircleCollider & circle // Normalize the delta vector to get the collision direction vec2 collision_normal = delta / distance; - // Compute the resolution vector vec2 resolution = -collision_normal * penetration_depth; @@ -311,8 +307,7 @@ void CollisionSystem::determine_collision_handler(CollisionInfo & info) { // Call collision event for user CollisionEvent data(info); EventManager & emgr = this->mediator.event_manager; - emgr.trigger_event( - data, info.this_collider.game_object_id); + emgr.trigger_event(data, info.this_collider.game_object_id); } void CollisionSystem::static_collision_handler(CollisionInfo & info) { @@ -389,14 +384,14 @@ CollisionSystem::gather_collisions(std::vector & colliders) { bool CollisionSystem::have_common_layer(const std::set & layers1, const std::set & layers2) { - + // Check if any number is equal in the layers for (int num : layers1) { - if (layers2.contains(num)) { - // Common layer found - return true; - break; - } + if (layers2.contains(num)) { + // Common layer found + return true; + break; + } } // No common layer found return false; @@ -554,5 +549,3 @@ vec2 CollisionSystem::get_current_position(const vec2 & collider_offset, // Final positions considering scaling and rotation return (transform.position + vec2(rotated_total_offset_x1, rotated_total_offset_y1)); } - - diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 6216af9..7e893c8 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -6,11 +6,11 @@ #include "api/BoxCollider.h" #include "api/CircleCollider.h" +#include "api/Event.h" #include "api/Metadata.h" #include "api/Rigidbody.h" #include "api/Transform.h" #include "api/Vector2.h" -#include "api/Event.h" #include "Collider.h" #include "System.h" diff --git a/src/example/game.cpp b/src/example/game.cpp index be756bd..4239c15 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -1,6 +1,6 @@ #include "api/CircleCollider.h" -#include "manager/ComponentManager.h" #include "api/Scene.h" +#include "manager/ComponentManager.h" #include "manager/Mediator.h" #include #include @@ -28,66 +28,60 @@ class MyScript1 : public Script { bool keypressed(const KeyPressEvent & test) { Log::logf("Box script keypressed()"); switch (test.key) { - case Keycode::A: - { + case Keycode::A: { Transform & tf = this->get_component(); tf.position.x -= 1; break; } - case Keycode::W: - { + case Keycode::W: { Transform & tf = this->get_component(); tf.position.y -= 1; break; } - case Keycode::S: - { + case Keycode::S: { Transform & tf = this->get_component(); tf.position.y += 1; break; } - case Keycode::D: - { + case Keycode::D: { Transform & tf = this->get_component(); tf.position.x += 1; break; } - case Keycode::E: - { - if(flip){ + case Keycode::E: { + if (flip) { flip = false; this->get_component().active = true; this->get_components()[0].get().active = true; this->get_component().active = false; this->get_components()[1].get().active = false; - } - else { + } else { flip = true; this->get_component().active = false; this->get_components()[0].get().active = false; this->get_component().active = true; this->get_components()[1].get().active = true; } - - + //add collider switch break; } default: - break; + break; } return false; - } + } void init() { Log::logf("init"); - subscribe([this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); }); - subscribe([this](const KeyPressEvent & ev) -> bool { return this->keypressed(ev); }); + subscribe( + [this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); }); + subscribe( + [this](const KeyPressEvent & ev) -> bool { return this->keypressed(ev); }); } void update() { // Retrieve component from the same GameObject this script is on } - }; class MyScript2 : public Script { @@ -99,74 +93,68 @@ class MyScript2 : public Script { bool keypressed(const KeyPressEvent & test) { Log::logf("Box script keypressed()"); switch (test.key) { - case Keycode::LEFT: - { + case Keycode::LEFT: { Transform & tf = this->get_component(); tf.position.x -= 1; break; } - case Keycode::UP: - { + case Keycode::UP: { Transform & tf = this->get_component(); tf.position.y -= 1; break; } - case Keycode::DOWN: - { + case Keycode::DOWN: { Transform & tf = this->get_component(); tf.position.y += 1; break; } - case Keycode::RIGHT: - { + case Keycode::RIGHT: { Transform & tf = this->get_component(); tf.position.x += 1; break; } - case Keycode::PAUSE: - { - if(flip){ + case Keycode::PAUSE: { + if (flip) { flip = false; this->get_component().active = true; this->get_components()[0].get().active = true; this->get_component().active = false; this->get_components()[1].get().active = false; - } - else { + } else { flip = true; this->get_component().active = false; this->get_components()[0].get().active = false; this->get_component().active = true; this->get_components()[1].get().active = true; } - - + //add collider switch break; } default: - break; + break; } return false; - } + } void init() { Log::logf("init"); - subscribe([this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); }); - subscribe([this](const KeyPressEvent & ev) -> bool { return this->keypressed(ev); }); + subscribe( + [this](const CollisionEvent & ev) -> bool { return this->oncollision(ev); }); + subscribe( + [this](const KeyPressEvent & ev) -> bool { return this->keypressed(ev); }); } void update() { // Retrieve component from the same GameObject this script is on } - }; class ConcreteScene1 : public Scene { public: using Scene::Scene; - + void load_scene() { - + Mediator & m = this->mediator; ComponentManager & mgr = m.component_manager; Color color(0, 0, 0, 255); @@ -195,7 +183,10 @@ public: vec2{world_collider, world_collider}); // Left world.add_component(vec2{screen_size_width / 2 + world_collider / 2, 0}, vec2{world_collider, world_collider}); // right - world.add_component(Color::WHITE, ivec2{static_cast(screen_size_width), static_cast(screen_size_height)}, vec2{screen_size_width, screen_size_height}, 1.0f); + world.add_component( + Color::WHITE, + ivec2{static_cast(screen_size_width), static_cast(screen_size_height)}, + vec2{screen_size_width, screen_size_height}, 1.0f); GameObject game_object1 = mgr.new_object( "Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1); @@ -219,10 +210,10 @@ public: //add circle with cirlcecollider deactiveated game_object1.add_component(vec2{0, 0}, 10).active = false; auto img2 = Texture("asset/texture/circle.png"); - game_object1.add_component(img2, color, Sprite::FlipSettings{false, false}, 1, - 1, 20).active = false; - - + game_object1 + .add_component(img2, color, Sprite::FlipSettings{false, false}, 1, 1, 20) + .active + = false; GameObject game_object2 = mgr.new_object( "Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1); @@ -246,9 +237,10 @@ public: //add circle with cirlcecollider deactiveated game_object2.add_component(vec2{0, 0}, 10).active = false; auto img4 = Texture("asset/texture/circle.png"); - game_object2.add_component(img4, color, Sprite::FlipSettings{false, false}, 1, - 1, 20).active = false; - + game_object2 + .add_component(img4, color, Sprite::FlipSettings{false, false}, 1, 1, 20) + .active + = false; } string get_name() const { return "scene1"; } diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index a683b1f..dd45eb6 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -7,14 +7,14 @@ #define private public #define protected public -#include -#include #include -#include #include #include #include #include +#include +#include +#include #include #include #include diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 6a6c29f..24ac494 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -9,14 +9,14 @@ #define private public #define protected public -#include #include -#include #include #include #include #include #include +#include +#include #include #include #include @@ -162,7 +162,7 @@ TEST_F(Profiling, Profiling_2) { .body_type = Rigidbody::BodyType::STATIC, }); gameobject.add_component(vec2{0, 0}, vec2{1, 1}); - + gameobject.add_component().set_script(); Color color(0, 0, 0, 0); auto img = Texture("asset/texture/square.png"); -- cgit v1.2.3 From cfd578dd0b7d5894ff0b0a0796d85cd5e9ae6e56 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Fri, 6 Dec 2024 19:24:15 +0100 Subject: merge #53 --- src/test/CMakeLists.txt | 2 +- src/test/Profiling.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 9a4dfe7..c9cbac5 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -16,5 +16,5 @@ target_sources(test_main PUBLIC InputTest.cpp ScriptEventTest.cpp ScriptSceneTest.cpp - # Profiling.cpp #disabled for saving time + Profiling.cpp ) diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index 24ac494..bd99614 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -41,7 +41,7 @@ class TestScript : public Script { } }; -class Profiling : public Test { +class DISABLED_ProfilingTest : public Test { public: // Config for test // Minimum amount to let test pass @@ -127,7 +127,7 @@ public: } }; -TEST_F(Profiling, Profiling_1) { +TEST_F(DISABLED_ProfilingTest, Profiling_1) { while (this->total_time / this->average < this->duration) { { @@ -150,7 +150,7 @@ TEST_F(Profiling, Profiling_1) { EXPECT_GE(this->game_object_count, this->min_gameobject_count); } -TEST_F(Profiling, Profiling_2) { +TEST_F(DISABLED_ProfilingTest, Profiling_2) { while (this->total_time / this->average < this->duration) { { @@ -184,7 +184,7 @@ TEST_F(Profiling, Profiling_2) { EXPECT_GE(this->game_object_count, this->min_gameobject_count); } -TEST_F(Profiling, Profiling_3) { +TEST_F(DISABLED_ProfilingTest, Profiling_3) { while (this->total_time / this->average < this->duration) { { -- cgit v1.2.3 From fdb4c99e139a264d4e15e6913a3756fc6cccb2f2 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Fri, 6 Dec 2024 20:07:24 +0100 Subject: nitpick #59 --- src/crepe/Collider.h | 2 +- src/crepe/Component.h | 2 +- src/crepe/api/Animator.cpp | 6 ++-- src/crepe/api/Animator.h | 58 ++++++++------------------------ src/crepe/api/AssetManager.h | 6 ++-- src/crepe/api/BoxCollider.h | 2 +- src/crepe/api/Button.h | 6 ++-- src/crepe/api/CMakeLists.txt | 4 +-- src/crepe/api/CircleCollider.h | 2 +- src/crepe/api/Config.h | 5 +-- src/crepe/api/EventHandler.h | 34 +++++++++---------- src/crepe/api/GameObject.h | 12 +++---- src/crepe/api/Metadata.h | 2 +- src/crepe/api/Rigidbody.h | 28 ++++++++-------- src/crepe/api/Scene.h | 4 +-- src/crepe/api/Script.h | 2 +- src/crepe/api/Sprite.h | 38 ++++++++++----------- src/crepe/api/Transform.h | 2 +- src/crepe/facade/SDLContext.h | 28 ++++++++-------- src/crepe/facade/Sound.h | 2 +- src/crepe/manager/ComponentManager.h | 30 ++++++++--------- src/crepe/manager/EventManager.h | 28 ++++++++-------- src/crepe/system/CollisionSystem.h | 65 ++++++++++++++++++------------------ src/crepe/system/ParticleSystem.h | 10 +++--- src/crepe/system/PhysicsSystem.h | 4 +-- src/crepe/system/RenderSystem.cpp | 3 +- src/crepe/system/RenderSystem.h | 8 ++--- src/crepe/system/ScriptSystem.h | 2 +- src/test/Profiling.cpp | 25 ++++++++++---- 29 files changed, 200 insertions(+), 220 deletions(-) (limited to 'src/test/Profiling.cpp') diff --git a/src/crepe/Collider.h b/src/crepe/Collider.h index a08a68e..42ccfd4 100644 --- a/src/crepe/Collider.h +++ b/src/crepe/Collider.h @@ -15,7 +15,7 @@ public: * * The `offset` defines the positional shift applied to the collider relative to the position of the rigidbody it is attached to. * This allows the collider to be placed at a different position than the rigidbody. - * + * */ vec2 offset; }; diff --git a/src/crepe/Component.h b/src/crepe/Component.h index dc17721..c30419d 100644 --- a/src/crepe/Component.h +++ b/src/crepe/Component.h @@ -8,7 +8,7 @@ class ComponentManager; /** * \brief Base class for all components - * + * * This class is the base class for all components. It provides a common interface for all * components. */ diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp index 154135f..b8a91dc 100644 --- a/src/crepe/api/Animator.cpp +++ b/src/crepe/api/Animator.cpp @@ -7,10 +7,10 @@ using namespace crepe; -Animator::Animator(uint32_t id, Sprite & ss, unsigned int max_row, unsigned int max_col, - const Animator::Data & data) +Animator::Animator(game_object_id_t id, Sprite & spritesheet, unsigned int max_row, + unsigned int max_col, const Animator::Data & data) : Component(id), - spritesheet(ss), + spritesheet(spritesheet), max_rows(max_row), max_columns(max_col), data(data) { diff --git a/src/crepe/api/Animator.h b/src/crepe/api/Animator.h index 23d29f6..7c850b8 100644 --- a/src/crepe/api/Animator.h +++ b/src/crepe/api/Animator.h @@ -1,10 +1,9 @@ #pragma once -#include +#include "../types.h" #include "Component.h" #include "Sprite.h" -#include "types.h" namespace crepe { @@ -21,55 +20,31 @@ class SDLContext; class Animator : public Component { public: struct Data { - //! frames per second for animation unsigned int fps = 1; - //! The current col being animated. unsigned int col = 0; - //! The current row being animated. unsigned int row = 0; - //! should the animation loop bool looping = false; - //! starting frame for cycling unsigned int cycle_start = 0; - - //! end frame for cycling (-1 --> use last frame) + //! end frame for cycling (-1 = use last frame) int cycle_end = -1; - - //! offset in pixels. - // TODO implement - unsigned int white_space = 0; }; public: - /** - * \brief Animator will repeat the animation - * - */ + //! Animator will repeat the animation void loop(); - - /** - * \brief starts the animation - * - */ + //! starts the animation void play(); - /** - * \brief pauses the animation - * - * sets the active false - * - */ + //! pauses the animation void pause(); - /** * \brief stops the animation * * sets the active on false and resets all the current rows and columns - * */ void stop(); /** @@ -81,8 +56,8 @@ public: /** * \brief set the range in the row * - * \param start of row animation - * \param end of row animation + * \param start of row animation + * \param end of row animation */ void set_cycle_range(int start, int end); /** @@ -91,11 +66,7 @@ public: * \param col animation column */ void set_anim(int col); - - /** - * \brief will go to the next animaiton of current row - * - */ + //! will go to the next animaiton of current row void next_anim(); public: @@ -103,7 +74,7 @@ public: * \brief Constructs an Animator object that will control animations for a sprite sheet. * * \param id The unique identifier for the component, typically assigned automatically. - * \param ss the reference to the spritesheet + * \param spritesheet the reference to the spritesheet * \param max_row maximum of rows inside the given spritesheet * \param max_col maximum of columns inside the given spritesheet * \param data extra animation data for more control @@ -111,25 +82,22 @@ public: * This constructor sets up the Animator with the given parameters, and initializes the * animation system. */ - Animator(game_object_id_t id, Sprite & ss, unsigned int max_row, unsigned int max_col, - const Animator::Data & data); + Animator(game_object_id_t id, Sprite & spritesheet, unsigned int max_row, + unsigned int max_col, const Animator::Data & data); ~Animator(); // dbg_trace public: //! The maximum number of columns in the sprite sheet. const unsigned int max_columns; - //! The maximum number of rows in the sprite sheet. const unsigned int max_rows; - Animator::Data data; private: //! A reference to the Sprite sheet containing. Sprite & spritesheet; - - // uses the spritesheet + //! Uses the spritesheet friend AnimatorSystem; }; + } // namespace crepe -// diff --git a/src/crepe/api/AssetManager.h b/src/crepe/api/AssetManager.h index fee6780..3b1cc4b 100644 --- a/src/crepe/api/AssetManager.h +++ b/src/crepe/api/AssetManager.h @@ -9,7 +9,7 @@ namespace crepe { /** * \brief The AssetManager is responsible for storing and managing assets over multiple scenes. - * + * * The AssetManager ensures that assets are loaded once and can be accessed across different * scenes. It caches assets to avoid reloading them every time a scene is loaded. Assets are * retained in memory until the AssetManager is destroyed, at which point the cached assets are @@ -46,9 +46,9 @@ public: * \param reload If true, the asset will be reloaded from the file, even if it is already * cached. * \tparam T The type of asset to cache (e.g., texture, sound, etc.). - * + * * \return A shared pointer to the cached asset. - * + * * This template function caches the asset at the given file path. If the asset is already * cached and `reload` is false, the existing cached version will be returned. Otherwise, the * asset will be reloaded and added to the cache. diff --git a/src/crepe/api/BoxCollider.h b/src/crepe/api/BoxCollider.h index 89e43d8..1ac4d46 100644 --- a/src/crepe/api/BoxCollider.h +++ b/src/crepe/api/BoxCollider.h @@ -8,7 +8,7 @@ namespace crepe { /** * \brief A class representing a box-shaped collider. - * + * * This class is used for collision detection with other colliders (e.g., CircleCollider). */ class BoxCollider : public Collider { diff --git a/src/crepe/api/Button.h b/src/crepe/api/Button.h index 26e7526..61b18d7 100644 --- a/src/crepe/api/Button.h +++ b/src/crepe/api/Button.h @@ -11,7 +11,7 @@ class Button : public UIObject { public: /** * \brief Constructs a Button with the specified game object ID and dimensions. - * + * * \param id The unique ID of the game object associated with this button. * \param dimensions The width and height of the UIObject * \param offset The offset relative this GameObjects Transform @@ -23,7 +23,7 @@ public: /** * \brief Indicates if the button is a toggle button (can be pressed and released). - * + * * A toggle button allows for a pressed/released state, whereas a regular button * typically only has an on-click state. */ @@ -31,7 +31,7 @@ public: // TODO: create separate toggle button class /** * \brief The callback function to be executed when the button is clicked. - * + * * This function is invoked whenever the button is clicked. It can be set to any * function that matches the signature `void()`. */ diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index b2e3df8..593c4e6 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -39,8 +39,8 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES Vector2.h Vector2.hpp Color.h - Texture.h - AssetManager.h + Texture.h + AssetManager.h AssetManager.hpp Scene.h Metadata.h diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h index ebd1cb2..c7bf66e 100644 --- a/src/crepe/api/CircleCollider.h +++ b/src/crepe/api/CircleCollider.h @@ -8,7 +8,7 @@ namespace crepe { /** * \brief A class representing a circle-shaped collider. - * + * * This class is used for collision detection with other colliders (e.g., BoxCollider). */ class CircleCollider : public Collider { diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h index f1bca62..a9745c3 100644 --- a/src/crepe/api/Config.h +++ b/src/crepe/api/Config.h @@ -1,8 +1,10 @@ #pragma once +#include + #include "../util/Log.h" + #include "types.h" -#include namespace crepe { @@ -69,7 +71,6 @@ public: //! default screen size in pixels ivec2 default_size = {1280, 720}; std::string window_title = "Jetpack joyride clone"; - } window_settings; //! Asset loading options diff --git a/src/crepe/api/EventHandler.h b/src/crepe/api/EventHandler.h index 7bdd9a3..7bb501b 100644 --- a/src/crepe/api/EventHandler.h +++ b/src/crepe/api/EventHandler.h @@ -8,12 +8,12 @@ namespace crepe { /** * \brief A type alias for an event handler function. - * - * The EventHandler is a std::function that takes an EventType reference and returns a boolean value + * + * The EventHandler is a std::function that takes an EventType reference and returns a boolean value * indicating whether the event is handled. - * + * * \tparam EventType The type of event this handler will handle. - * + * * Returning \c false from an event handler results in the event being propogated to other listeners for the same event type, while returning \c true stops propogation altogether. */ template @@ -22,7 +22,7 @@ using EventHandler = std::function; /** * \class IEventHandlerWrapper * \brief An abstract base class for event handler wrappers. - * + * * This class provides the interface for handling events. Derived classes must implement the * `call()` method to process events */ @@ -35,9 +35,9 @@ public: /** * \brief Executes the handler with the given event. - * + * * This method calls the `call()` method of the derived class, passing the event to the handler. - * + * * \param e The event to be processed. * \return A boolean value indicating whether the event is handled. */ @@ -46,9 +46,9 @@ public: private: /** * \brief The method responsible for handling the event. - * + * * This method is implemented by derived classes to process the event. - * + * * \param e The event to be processed. * \return A boolean value indicating whether the event is handled. */ @@ -58,11 +58,11 @@ private: /** * \class EventHandlerWrapper * \brief A wrapper for event handler functions. - * - * This class wraps an event handler function of a specific event type. It implements the - * `call()` and `get_type()` methods to allow the handler to be executed and its type to be + * + * This class wraps an event handler function of a specific event type. It implements the + * `call()` and `get_type()` methods to allow the handler to be executed and its type to be * queried. - * + * * \tparam EventType The type of event this handler will handle. */ template @@ -70,9 +70,9 @@ class EventHandlerWrapper : public IEventHandlerWrapper { public: /** * \brief Constructs an EventHandlerWrapper with a given handler. - * + * * The constructor takes an event handler function and stores it in the wrapper. - * + * * \param handler The event handler function. */ explicit EventHandlerWrapper(const EventHandler & handler); @@ -80,9 +80,9 @@ public: private: /** * \brief Calls the stored event handler with the event. - * + * * This method casts the event to the appropriate type and calls the handler. - * + * * \param e The event to be handled. * \return A boolean value indicating whether the event is handled. */ diff --git a/src/crepe/api/GameObject.h b/src/crepe/api/GameObject.h index 4cd2bc0..ff80f49 100644 --- a/src/crepe/api/GameObject.h +++ b/src/crepe/api/GameObject.h @@ -10,7 +10,7 @@ class ComponentManager; /** * \brief Represents a GameObject - * + * * This class represents a GameObject. The GameObject class is only used as an interface for * the game programmer. The actual implementation is done in the ComponentManager. */ @@ -19,7 +19,7 @@ private: /** * This constructor creates a new GameObject. It creates a new Transform and Metadata * component and adds them to the ComponentManager. - * + * * \param component_manager Reference to component_manager * \param id The id of the GameObject * \param name The name of the GameObject @@ -37,20 +37,20 @@ private: public: /** * \brief Set the parent of this GameObject - * + * * This method sets the parent of this GameObject. It sets the parent in the Metadata * component of this GameObject and adds this GameObject to the children list of the parent * GameObject. - * + * * \param parent The parent GameObject */ void set_parent(const GameObject & parent); /** * \brief Add a component to the GameObject - * + * * This method adds a component to the GameObject. It forwards the arguments to the * ComponentManager. - * + * * \tparam T The type of the component * \tparam Args The types of the arguments * \param args The arguments to create the component diff --git a/src/crepe/api/Metadata.h b/src/crepe/api/Metadata.h index 235d42f..f404703 100644 --- a/src/crepe/api/Metadata.h +++ b/src/crepe/api/Metadata.h @@ -9,7 +9,7 @@ namespace crepe { /** * \brief Metadata component - * + * * This class represents the Metadata component. It stores the name, tag, parent and children * of a GameObject. */ diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 8265ba5..40c6bf1 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -11,7 +11,7 @@ namespace crepe { /** * \brief Rigidbody class - * + * * This class is used by the physics sytem and collision system. It configures how to system * interact with the gameobject for movement and collisions. */ @@ -19,7 +19,7 @@ class Rigidbody : public Component { public: /** * \brief BodyType enum - * + * * This enum provides three bodytypes the physics sytem and collision system use. */ enum class BodyType { @@ -32,7 +32,7 @@ public: }; /** * \brief PhysicsConstraints to constrain movement - * + * * This struct configures the movement constraint for this object. If a constraint is enabled * the systems will not move the object. */ @@ -46,9 +46,9 @@ public: }; public: - /** + /** * \brief struct for Rigidbody data - * + * * This struct holds the data for the Rigidbody. */ struct Data { @@ -59,7 +59,7 @@ public: * * The `gravity_scale` controls how much gravity affects the object. It is a multiplier applied to the default * gravity force, allowing for fine-grained control over how the object responds to gravity. - * + * */ float gravity_scale = 0; @@ -108,7 +108,7 @@ public: * The `PhysicsConstraints` struct defines the constraints that restrict an object's movement * in certain directions or prevent rotation. These constraints effect only the physics system * to prevent the object from moving or rotating in specified ways. - * + * */ PhysicsConstraints constraints; @@ -128,7 +128,7 @@ public: * The `offset` defines a positional shift applied to all colliders associated with the object, relative to the object's * transform position. This allows for the colliders to be placed at a different position than the object's actual * position, without modifying the object's transform itself. - * + * */ vec2 offset; @@ -136,14 +136,14 @@ public: * \brief Defines the collision layers of a GameObject. * * The `collision_layers` specifies the layers that the GameObject will collide with. - * Each element represents a layer ID, and the GameObject will only detect + * Each element represents a layer ID, and the GameObject will only detect * collisions with other GameObjects that belong to these layers. */ std::set collision_layers; }; public: - /** + /** * \param game_object_id id of the gameobject the rigibody is added to. * \param data struct to configure the rigidbody. */ @@ -152,15 +152,15 @@ public: Data data; public: - /** + /** * \brief add a linear force to the Rigidbody. - * + * * \param force Vector2 that is added to the linear force. */ void add_force_linear(const vec2 & force); - /** + /** * \brief add a angular force to the Rigidbody. - * + * * \param force Vector2 that is added to the angular force. */ void add_force_angular(float force); diff --git a/src/crepe/api/Scene.h b/src/crepe/api/Scene.h index 9f1e8ce..ba9bb76 100644 --- a/src/crepe/api/Scene.h +++ b/src/crepe/api/Scene.h @@ -12,7 +12,7 @@ class ComponentManager; /** * \brief Represents a Scene - * + * * This class represents a Scene. The Scene class is only used as an interface for the game * programmer. */ @@ -41,7 +41,7 @@ public: protected: /** * \name Late references - * + * * These references are set by SceneManager immediately after calling the constructor of Scene. * * \note Scene must have a constructor without arguments so the game programmer doesn't need to diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index d1be1dc..d99ab0e 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -20,7 +20,7 @@ class ComponentManager; * This class is used as a base class for user-defined scripts that can be added to game * objects using the \c BehaviorScript component. * - * \info Additional *events* (like Unity's OnDisable and OnEnable) should be implemented as + * \note Additional *events* (like Unity's OnDisable and OnEnable) should be implemented as * member or lambda methods in derivative user script classes and registered in \c init(). * * \warning Concrete scripts are allowed do create a custom constructor, but the utility diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h index ea8104c..dbf41e4 100644 --- a/src/crepe/api/Sprite.h +++ b/src/crepe/api/Sprite.h @@ -31,11 +31,10 @@ public: //! Sprite data that does not have to be set in the constructor struct Data { /** - * \color tint of the sprite + * \brief Sprite tint (multiplied) * - * the default value is white because of the color multiplier. - * this means that the orginal image will be shown. if color is BLACK for example - * then it turns the image black because of the Color channels being 0. + * The sprite texture's pixels are multiplied by this color before being displayed + * (including alpha channel for transparency). */ Color color = Color::WHITE; @@ -49,15 +48,15 @@ public: const int order_in_layer = 0; /** - * \size width and height of the sprite in game units - * - * - if height is filled in and not width it will multiply width by aspect_ratio. - * - if width is filled in and not height it will multiply height by aspect_ratio. - * - if neither is filled it will not show sprite because size will be zero - * - if both are filled will it use the width and height without making sure the aspect_ratio - * is correct - */ - vec2 size; + * \brief width and height of the sprite in game units + * + * - if exclusively width is specified, the height is calculated using the texture's aspect + * ratio + * - if exclusively height is specified, the width is calculated using the texture's aspect + * ratio + * - if both are specified the texture is streched to fit the specified size + */ + vec2 size = {0, 0}; //! independent sprite angle. rotating clockwise direction in degrees float angle_offset = 0; @@ -71,7 +70,6 @@ public: public: /** - * \brief Constructs a Sprite with specified parameters. * \param game_id Unique identifier for the game object this sprite belongs to. * \param texture asset of the image * \param ctx all the sprite data @@ -86,12 +84,12 @@ public: private: /** - * \aspect_ratio ratio of the img - * - * - This will multiply one of \c size variable if it is 0. - * - Will be adjusted if \c Animator component is added to an GameObject - * that is why this value cannot be const. - */ + * \brief ratio of the img + * + * - This will multiply one of \c size variable if it is 0. + * - Will be adjusted if \c Animator component is added to an GameObject that is why this + * value cannot be const. + */ float aspect_ratio; //! Reads the mask of sprite diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h index 3ef0fb5..7ee6d65 100644 --- a/src/crepe/api/Transform.h +++ b/src/crepe/api/Transform.h @@ -7,7 +7,7 @@ namespace crepe { /** * \brief Transform component - * + * * This class represents the Transform component. It stores the position, rotation and scale of * a GameObject. */ diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 81a8a34..e232511 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -25,7 +25,7 @@ class InputSystem; /** * \class SDLContext * \brief Facade for the SDL library - * + * * SDLContext is a singleton that handles the SDL window and renderer, provides methods for * event handling, and rendering to the screen. It is never used directly by the user */ @@ -38,16 +38,16 @@ public: vec2 zoomed_viewport; /** - * \render_scale scaling factor + * \brief scaling factor * * depending on the black bars type will the scaling be different. - * - lettorboxing --> scaling on the y-as - * - pillarboxing --> scaling on the x-as + * - letterboxing --> scaling on the y-as + * - pillarboxing --> scaling on the x-as */ vec2 render_scale; /** - * \bar_size size of calculated black bars + * \brief size of calculated black bars * * depending on the black bars type will the size be different * - lettorboxing --> {0, bar_height} @@ -108,21 +108,21 @@ private: friend class InputSystem; /** * \brief Retrieves a list of all events from the SDL context. - * + * * This method retrieves all the events from the SDL context that are currently * available. It is primarily used by the InputSystem to process various * input events such as mouse clicks, mouse movements, and keyboard presses. - * + * * \return Events that occurred since last call to `get_events()` */ std::vector get_events(); /** * \brief Converts an SDL key code to the custom Keycode type. - * + * * This method maps an SDL key code to the corresponding `Keycode` enum value, * which is used internally by the system to identify the keys. - * + * * \param sdl_key The SDL key code to convert. * \return The corresponding `Keycode` value or `Keycode::NONE` if the key is unrecognized. */ @@ -130,10 +130,10 @@ private: /** * \brief Converts an SDL mouse button code to the custom MouseButton type. - * - * This method maps an SDL mouse button code to the corresponding `MouseButton` + * + * This method maps an SDL mouse button code to the corresponding `MouseButton` * enum value, which is used internally by the system to identify mouse buttons. - * + * * \param sdl_button The SDL mouse button code to convert. * \return The corresponding `MouseButton` value or `MouseButton::NONE` if the key is unrecognized */ @@ -233,14 +233,14 @@ private: * \param pos the pos in world units * \param cam the camera of the current scene * \param cam_pos the current postion of the camera - * \param img_scale the image multiplier for increasing img size + * \param img_scale the image multiplier for increasing img size * \return sdl rectangle to draw a dst image to draw on the screen */ SDL_FRect get_dst_rect(const DestinationRectangleData & data) const; /** * \brief Set an additional color value multiplied into render copy operations. * - * \param texture the given texture to adjust + * \param texture the given texture to adjust * \param color the color data for the texture */ void set_color_texture(const Texture & texture, const Color & color); diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h index 4c68f32..ee43d94 100644 --- a/src/crepe/facade/Sound.h +++ b/src/crepe/facade/Sound.h @@ -35,7 +35,7 @@ public: void play(); /** * \brief Reset playhead position - * + * * Resets the playhead position so that calling \c play() after this function makes it play * from the start of the sample. If the sound is not paused before calling this function, * this function will stop playback. diff --git a/src/crepe/manager/ComponentManager.h b/src/crepe/manager/ComponentManager.h index ad37586..44429d9 100644 --- a/src/crepe/manager/ComponentManager.h +++ b/src/crepe/manager/ComponentManager.h @@ -16,7 +16,7 @@ class GameObject; /** * \brief Manages all components - * + * * This class manages all components. It provides methods to add, delete and get components. */ class ComponentManager : public Manager { @@ -56,10 +56,10 @@ protected: friend class GameObject; /** * \brief Add a component to the ComponentManager - * + * * This method adds a component to the ComponentManager. The component is created with the * given arguments and added to the ComponentManager. - * + * * \tparam T The type of the component * \tparam Args The types of the arguments * \param id The id of the GameObject this component belongs to @@ -70,9 +70,9 @@ protected: T & add_component(game_object_id_t id, Args &&... args); /** * \brief Delete all components of a specific type and id - * + * * This method deletes all components of a specific type and id. - * + * * \tparam T The type of the component * \param id The id of the GameObject this component belongs to */ @@ -80,24 +80,24 @@ protected: void delete_components_by_id(game_object_id_t id); /** * \brief Delete all components of a specific type - * + * * This method deletes all components of a specific type. - * + * * \tparam T The type of the component */ template void delete_components(); /** * \brief Delete all components of a specific id - * + * * This method deletes all components of a specific id. - * + * * \param id The id of the GameObject this component belongs to */ void delete_all_components_of_id(game_object_id_t id); /** * \brief Delete all components - * + * * This method deletes all components. */ void delete_all_components(); @@ -115,9 +115,9 @@ protected: public: /** * \brief Get all components of a specific type and id - * + * * This method gets all components of a specific type and id. - * + * * \tparam T The type of the component * \param id The id of the GameObject this component belongs to * \return A vector of all components of the specific type and id @@ -126,9 +126,9 @@ public: RefVector get_components_by_id(game_object_id_t id) const; /** * \brief Get all components of a specific type - * + * * This method gets all components of a specific type. - * + * * \tparam T The type of the component * \return A vector of all components of the specific type */ @@ -138,7 +138,7 @@ public: private: /** * \brief The components - * + * * This unordered_map stores all components. The key is the type of the component and the * value is a vector of vectors of unique pointers to the components. * diff --git a/src/crepe/manager/EventManager.h b/src/crepe/manager/EventManager.h index d634f54..ba5e98b 100644 --- a/src/crepe/manager/EventManager.h +++ b/src/crepe/manager/EventManager.h @@ -24,7 +24,7 @@ typedef size_t event_channel_t; /** * \class EventManager * \brief Manages event subscriptions, triggers, and queues, enabling decoupled event handling. - * + * * The `EventManager` acts as a centralized event system. It allows for registering callbacks * for specific event types, triggering events synchronously, queueing events for later * processing, and managing subscriptions via unique identifiers. @@ -35,20 +35,20 @@ public: /** * \brief Get the singleton instance of the EventManager. - * + * * This method returns the unique instance of the EventManager, creating it if it * doesn't already exist. Ensures only one instance is active in the program. - * + * * \return Reference to the singleton instance of the EventManager. */ static EventManager & get_instance(); /** * \brief Subscribe to a specific event type. - * + * * Registers a callback for a given event type and optional channel. Each callback * is assigned a unique subscription ID that can be used for later unsubscription. - * + * * \tparam EventType The type of the event to subscribe to. * \param callback The callback function to be invoked when the event is triggered. * \param channel The channel number to subscribe to (default is CHANNEL_ALL, which listens to all channels). @@ -60,18 +60,18 @@ public: /** * \brief Unsubscribe a previously registered callback. - * + * * Removes a callback from the subscription list based on its unique subscription ID. - * + * * \param event_id The unique subscription ID of the callback to remove. */ void unsubscribe(subscription_t event_id); /** * \brief Trigger an event immediately. - * + * * Synchronously invokes all registered callbacks for the given event type on the specified channel. - * + * * \tparam EventType The type of the event to trigger. * \param event The event instance to pass to the callbacks. * \param channel The channel to trigger the event on (default is CHANNEL_ALL, which triggers on all channels). @@ -81,9 +81,9 @@ public: /** * \brief Queue an event for later processing. - * + * * Adds an event to the event queue to be processed during the next call to `dispatch_events`. - * + * * \tparam EventType The type of the event to queue. * \param event The event instance to queue. * \param channel The channel to associate with the event (default is CHANNEL_ALL). @@ -93,7 +93,7 @@ public: /** * \brief Process all queued events. - * + * * Iterates through the event queue and triggers callbacks for each queued event. * Events are removed from the queue once processed. */ @@ -101,7 +101,7 @@ public: /** * \brief Clear all subscriptions. - * + * * Removes all registered event handlers and clears the subscription list. */ void clear(); @@ -109,7 +109,7 @@ public: private: /** * \brief Default constructor for the EventManager. - * + * * Constructor is private to enforce the singleton pattern. */ EventManager() = default; diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 7e893c8..5b136c6 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -37,7 +37,7 @@ private: /** * \brief A structure to store the collision data of a single collider. - * + * * This structure all components and id that are for needed within this system when calculating or handeling collisions. * The transform and rigidbody are mostly needed for location and rotation. * In rigidbody additional info is written about what the body of the object is, @@ -65,7 +65,7 @@ private: public: /** * \brief Structure representing detailed collision information between two colliders. - * + * * Includes information about the colliding objects and the resolution data for handling the collision. */ struct CollisionInfo { @@ -90,9 +90,9 @@ public: private: /** * \brief Determines the type of collider pair from two colliders. - * + * * Uses std::holds_alternative to identify the types of the provided colliders. - * + * * \param collider1 First collider variant (BoxCollider or CircleCollider). * \param collider2 Second collider variant (BoxCollider or CircleCollider). * \return The combined type of the two colliders. @@ -102,9 +102,9 @@ private: /** * \brief Calculates the current position of a collider. - * + * * Combines the Collider offset, Transform position, and Rigidbody offset to compute the position of the collider. - * + * * \param collider_offset The offset of the collider. * \param transform The Transform of the associated game object. * \param rigidbody The Rigidbody of the associated game object. @@ -116,9 +116,9 @@ private: private: /** * \brief Handles collision resolution between two colliders. - * + * * Processes collision data and adjusts objects to resolve collisions and/or calls the user oncollision script function. - * + * * \param data1 Collision data for the first collider. * \param data2 Collision data for the second collider. */ @@ -126,9 +126,9 @@ private: /** * \brief Resolves collision between two colliders and calculates the movement required. - * + * * Determines the displacement and direction needed to separate colliders based on their types. - * + * * \param data1 Collision data for the first collider. * \param data2 Collision data for the second collider. * \param type The type of collider pair. @@ -140,9 +140,9 @@ private: /** * \brief Calculates the resolution vector for two BoxColliders. - * + * * Computes the displacement required to separate two overlapping BoxColliders. - * + * * \param box_collider1 The first BoxCollider. * \param box_collider2 The second BoxCollider. * \param position1 The position of the first BoxCollider. @@ -155,13 +155,13 @@ private: /** * \brief Calculates the resolution vector for two CircleCollider. - * + * * Computes the displacement required to separate two overlapping CircleCollider. - * + * * \param circle_collider1 The first CircleCollider. * \param circle_collider2 The second CircleCollider. - * \param position1 The position of the first CircleCollider. - * \param position2 The position of the second CircleCollider. + * \param final_position1 The position of the first CircleCollider. + * \param final_position2 The position of the second CircleCollider. * \return The resolution vector for the collision. */ vec2 get_circle_circle_resolution(const CircleCollider & circle_collider1, @@ -171,14 +171,13 @@ private: /** * \brief Calculates the resolution vector for two CircleCollider. - * + * * Computes the displacement required to separate two overlapping CircleCollider. - * + * * \param circle_collider The first CircleCollider. * \param box_collider The second CircleCollider. * \param circle_position The position of the CircleCollider. * \param box_position The position of the BoxCollider. - * \param inverse Inverted true if box circle collision, false if circle box collision (inverts the direction). * \return The resolution vector for the collision. */ vec2 get_circle_box_resolution(const CircleCollider & circle_collider, @@ -188,18 +187,18 @@ private: /** * \brief Determines the appropriate collision handler for a collision. - * + * * Decides the correct resolution process based on the dynamic or static nature of the colliders involved. - * + * * \param info Collision information containing data about both colliders. */ void determine_collision_handler(CollisionInfo & info); /** * \brief Handles collisions involving static objects. - * + * * Resolves collisions by adjusting positions and modifying velocities if bounce is enabled. - * + * * \param info Collision information containing data about both colliders. */ void static_collision_handler(CollisionInfo & info); @@ -207,9 +206,9 @@ private: private: /** * \brief Checks for collisions between colliders. - * + * * Identifies collisions and generates pairs of colliding objects for further processing. - * + * * \param colliders A collection of all active colliders. * \return A list of collision pairs with their associated data. */ @@ -218,13 +217,13 @@ private: /** * \brief Checks if two collision layers have at least one common layer. - * + * * This function checks if there is any overlapping layer between the two inputs. - * It compares each layer from the first input to see - * if it exists in the second input. If at least one common layer is found, - * the function returns true, indicating that the two colliders share a common + * It compares each layer from the first input to see + * if it exists in the second input. If at least one common layer is found, + * the function returns true, indicating that the two colliders share a common * collision layer. - * + * * \param layers1 all collision layers for the first collider. * \param layers2 all collision layers for the second collider. * \return Returns true if there is at least one common layer, false otherwise. @@ -234,9 +233,9 @@ private: /** * \brief Checks for collision between two colliders. - * + * * Calls the appropriate collision detection function based on the collider types. - * + * * \param first_info Collision data for the first collider. * \param second_info Collision data for the second collider. * \param type The type of collider pair. @@ -248,7 +247,7 @@ private: /** * \brief Detects collisions between two BoxColliders. - * + * * \param box1 The first BoxCollider. * \param box2 The second BoxCollider. * \param transform1 Transform of the first object. diff --git a/src/crepe/system/ParticleSystem.h b/src/crepe/system/ParticleSystem.h index c647284..068f01c 100644 --- a/src/crepe/system/ParticleSystem.h +++ b/src/crepe/system/ParticleSystem.h @@ -25,7 +25,7 @@ public: private: /** * \brief Emits a particle from the specified emitter based on its emission properties. - * + * * \param emitter Reference to the ParticleEmitter. * \param transform Const reference to the Transform component associated with the emitter. */ @@ -34,7 +34,7 @@ private: /** * \brief Calculates the number of times particles should be emitted based on emission rate * and update count. - * + * * \param count Current update count. * \param emission Emission rate. * \return The number of particles to emit. @@ -44,7 +44,7 @@ private: /** * \brief Checks whether particles are within the emitter’s boundary, resets or stops * particles if they exit. - * + * * \param emitter Reference to the ParticleEmitter. * \param transform Const reference to the Transform component associated with the emitter. */ @@ -52,7 +52,7 @@ private: /** * \brief Generates a random angle for particle emission within the specified range. - * + * * \param min_angle Minimum emission angle in degrees. * \param max_angle Maximum emission angle in degrees. * \return Random angle in degrees. @@ -61,7 +61,7 @@ private: /** * \brief Generates a random speed for particle emission within the specified range. - * + * * \param min_speed Minimum emission speed. * \param max_speed Maximum emission speed. * \return Random speed. diff --git a/src/crepe/system/PhysicsSystem.h b/src/crepe/system/PhysicsSystem.h index 227ab69..26152a5 100644 --- a/src/crepe/system/PhysicsSystem.h +++ b/src/crepe/system/PhysicsSystem.h @@ -6,7 +6,7 @@ namespace crepe { /** * \brief System that controls all physics - * + * * This class is a physics system that uses a rigidbody and transform to add physics to a game * object. */ @@ -15,7 +15,7 @@ public: using System::System; /** * \brief updates the physics system. - * + * * It calculates new velocties and changes the postion in the transform. */ void update() override; diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 830d380..26f2c85 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -46,7 +46,8 @@ SDLContext::CameraValues RenderSystem::update_camera() { } bool sorting_comparison(const Sprite & a, const Sprite & b) { - if (a.data.sorting_in_layer != b.data.sorting_in_layer) return a.data.sorting_in_layer < b.data.sorting_in_layer; + if (a.data.sorting_in_layer != b.data.sorting_in_layer) + return a.data.sorting_in_layer < b.data.sorting_in_layer; if (a.data.order_in_layer != b.data.order_in_layer) return a.data.order_in_layer < b.data.order_in_layer; diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index de76229..e270a6b 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -18,7 +18,7 @@ class Transform; * \brief Manages rendering operations for all game objects. * * RenderSystem is responsible for rendering, clearing and presenting the screen, and - * managing the active camera. + * managing the active camera. */ class RenderSystem : public System { public: @@ -56,10 +56,10 @@ private: const double & scale); /** - * \brief renders a sprite with a Transform component on the screen + * \brief renders a sprite with a Transform component on the screen * * \param sprite the sprite component that holds all the data - * \param tm the Transform component that holds the position,rotation and scale + * \param tm the Transform component that holds the position,rotation and scale */ void render_normal(const Sprite & sprite, const SDLContext::CameraValues & cam, const Transform & tm); @@ -67,7 +67,7 @@ private: /** * \brief sort a vector sprite objects with * - * \param objs the vector that will do a sorting algorithm on + * \param objs the vector that will do a sorting algorithm on * \return returns a sorted reference vector */ RefVector sort(RefVector & objs) const; diff --git a/src/crepe/system/ScriptSystem.h b/src/crepe/system/ScriptSystem.h index 936e9ca..3db1b1e 100644 --- a/src/crepe/system/ScriptSystem.h +++ b/src/crepe/system/ScriptSystem.h @@ -8,7 +8,7 @@ class Script; /** * \brief Script system - * + * * The script system is responsible for all \c BehaviorScript components, and * calls the methods on classes derived from \c Script. */ diff --git a/src/test/Profiling.cpp b/src/test/Profiling.cpp index bd99614..c753bca 100644 --- a/src/test/Profiling.cpp +++ b/src/test/Profiling.cpp @@ -70,8 +70,11 @@ public: void SetUp() override { GameObject do_not_use = mgr.new_object("DO_NOT_USE", "", {0, 0}); - do_not_use.add_component(Color::WHITE, ivec2{1080, 720}, vec2{2000, 2000}, - 1.0f); + do_not_use.add_component(ivec2{1080, 720}, vec2{2000, 2000}, + Camera::Data{ + .bg_color = Color::WHITE, + .zoom = 1.0f, + }); // initialize systems here: //calls init script_sys.update(); @@ -164,10 +167,15 @@ TEST_F(DISABLED_ProfilingTest, Profiling_2) { gameobject.add_component(vec2{0, 0}, vec2{1, 1}); gameobject.add_component().set_script(); - Color color(0, 0, 0, 0); auto img = Texture("asset/texture/square.png"); Sprite & test_sprite = gameobject.add_component( - img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); + img, Sprite::Data{ + .color = {0, 0, 0, 0}, + .flip = {.flip_x = false, .flip_y = false}, + .sorting_in_layer = 1, + .order_in_layer = 1, + .size = {.y = 500}, + }); } this->game_object_count++; @@ -197,10 +205,15 @@ TEST_F(DISABLED_ProfilingTest, Profiling_3) { }); gameobject.add_component(vec2{0, 0}, vec2{1, 1}); gameobject.add_component().set_script(); - Color color(0, 0, 0, 0); auto img = Texture("asset/texture/square.png"); Sprite & test_sprite = gameobject.add_component( - img, color, Sprite::FlipSettings{false, false}, 1, 1, 500); + img, Sprite::Data{ + .color = {0, 0, 0, 0}, + .flip = {.flip_x = false, .flip_y = false}, + .sorting_in_layer = 1, + .order_in_layer = 1, + .size = {.y = 500}, + }); auto & test = gameobject.add_component(ParticleEmitter::Data{ .max_particles = 10, .emission_rate = 100, -- cgit v1.2.3