From 428182f45797de73b0bc2335916d25762b0d719b Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Sun, 10 Nov 2024 19:49:10 +0100 Subject: created colliders --- src/crepe/api/BoxCollider.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/crepe/api/BoxCollider.h (limited to 'src/crepe/api/BoxCollider.h') diff --git a/src/crepe/api/BoxCollider.h b/src/crepe/api/BoxCollider.h new file mode 100644 index 0000000..2461636 --- /dev/null +++ b/src/crepe/api/BoxCollider.h @@ -0,0 +1,15 @@ +#pragma once + +#include "Vector2.h" +#include "../Collider.h" + +namespace crepe { + +class BoxCollider : public Collider { +public: + BoxCollider(game_object_id_t game_object_id,Vector2 offset, int width, int height); + double width; + double height; +}; + +} // namespace crepe -- cgit v1.2.3 From 47dd27c42f375b65ee53f8b1e8c1b25327315a92 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Sun, 10 Nov 2024 21:38:58 +0100 Subject: box-box collision --- src/crepe/api/BoxCollider.cpp | 5 +-- src/crepe/api/BoxCollider.h | 2 +- src/crepe/api/CMakeLists.txt | 4 ++ src/crepe/api/CircleCollider.cpp | 2 - src/crepe/api/CircleCollider.h | 1 + src/crepe/api/Rigidbody.h | 2 + src/crepe/system/CollisionSystem.cpp | 82 +++++++++++++++++++++++++++++++++++- src/crepe/system/CollisionSystem.h | 14 ++++++ src/example/CMakeLists.txt | 1 + src/example/collision.cpp | 42 ++++++++++++++++++ 10 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 src/example/collision.cpp (limited to 'src/crepe/api/BoxCollider.h') diff --git a/src/crepe/api/BoxCollider.cpp b/src/crepe/api/BoxCollider.cpp index c3cb60c..eafbdb2 100644 --- a/src/crepe/api/BoxCollider.cpp +++ b/src/crepe/api/BoxCollider.cpp @@ -1,8 +1,7 @@ -#pragma once - #include "BoxCollider.h" +#include "../Collider.h" using namespace crepe; -BoxCollider::BoxCollider(game_object_id_t game_object_id,Vector2 offset, int width, int height) : Collider(game_object_id,offset), width(width), height(height) {} +BoxCollider::BoxCollider(game_object_id_t game_object_id,Vector2 offset, double width, double 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 2461636..357c979 100644 --- a/src/crepe/api/BoxCollider.h +++ b/src/crepe/api/BoxCollider.h @@ -7,7 +7,7 @@ namespace crepe { class BoxCollider : public Collider { public: - BoxCollider(game_object_id_t game_object_id,Vector2 offset, int width, int height); + BoxCollider(game_object_id_t game_object_id,Vector2 offset, double width, double height); double width; double height; }; diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index 87cbb09..6915074 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -18,6 +18,8 @@ target_sources(crepe PUBLIC Vector2.cpp Camera.cpp Animator.cpp + BoxCollider.cpp + CircleCollider.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -42,4 +44,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES SceneManager.hpp Camera.h Animator.h + BoxCollider.h + CircleCollider.h ) diff --git a/src/crepe/api/CircleCollider.cpp b/src/crepe/api/CircleCollider.cpp index 9365793..04a4995 100644 --- a/src/crepe/api/CircleCollider.cpp +++ b/src/crepe/api/CircleCollider.cpp @@ -1,5 +1,3 @@ -#pragma once - #include "CircleCollider.h" using namespace crepe; diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h index 3a66355..29a9c1e 100644 --- a/src/crepe/api/CircleCollider.h +++ b/src/crepe/api/CircleCollider.h @@ -1,6 +1,7 @@ #pragma once #include "Vector2.h" + #include "../Collider.h" namespace crepe { diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 68481f4..b9edec2 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -75,6 +75,8 @@ public: bool use_gravity = true; //! if object bounces bool bounce = false; + //! offset of all colliders + Vector2 offset; }; public: diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 55e0fdc..75d5c58 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -1,7 +1,87 @@ +#include + #include "CollisionSystem.h" +#include "../ComponentManager.h" +#include "../api/BoxCollider.h" +#include "../api/CircleCollider.h" +#include "../api/Vector2.h" +#include "../api/Rigidbody.h" +#include "../api/Transform.h" + +#include "Collider.h" +#include "iostream" + using namespace crepe; CollisionSystem::CollisionSystem() {} -void CollisionSystem::update() {} +void CollisionSystem::update() { + ComponentManager & mgr = ComponentManager::get_instance(); + std::vector> boxcolliders = mgr.get_components_by_type(); + + Transform & transform1 = mgr.get_components_by_id(boxcolliders[0].get().game_object_id).front().get(); + Rigidbody & rigidbody1 = mgr.get_components_by_id(boxcolliders[0].get().game_object_id).front().get(); + Transform & transform2 = mgr.get_components_by_id(boxcolliders[1].get().game_object_id).front().get(); + Rigidbody & rigidbody2 = mgr.get_components_by_id(boxcolliders[1].get().game_object_id).front().get(); + BoxCollider & collider1 = boxcolliders[0].get(); + BoxCollider & collider2 = boxcolliders[1].get(); + bool test = check_box_box_collision(collider1, collider2, transform1, transform2, rigidbody1, rigidbody2); + std::cout << "collided? " << test << std::endl; +} + + + +bool CollisionSystem::check_collisions(const std::vector& colliders1, const std::vector& colliders2) {} +bool CollisionSystem::check_box_box_collision(const BoxCollider& box1, const BoxCollider& box2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) +{ + // Function to convert degrees to radians + auto degrees_to_radians = [](double degrees) { + return degrees * (M_PI / 180.0); + }; + + // Get the rotation in radians + double radians1 = degrees_to_radians(transform1.rotation); + double radians2 = degrees_to_radians(transform2.rotation); + + // Calculate the scale factor (for both rigidbody and box offsets) + double scale1 = transform1.scale; + double scale2 = transform2.scale; + + Vector2 total_offset1 = (rigidbody1.data.offset + box1.offset) * transform1.scale; + Vector2 total_offset2 = (rigidbody2.data.offset + box2.offset) * transform2.scale; + + // Rotate + double rotated_total_offset_x1 = total_offset1.x * cos(radians1) - total_offset1.y * sin(radians1); + double rotated_total_offset_y1 = total_offset1.x * sin(radians1) + total_offset1.y * cos(radians1); + + double rotated_total_offset_x2 = total_offset2.x * cos(radians2) - total_offset2.y * sin(radians2); + double rotated_total_offset_y2 = total_offset2.x * sin(radians2) + total_offset2.y * cos(radians2); + + // Final positions considering scaling and rotation + Vector2 final_position1 = transform1.position + Vector2(rotated_total_offset_x1, rotated_total_offset_y1); + Vector2 final_position2 = transform2.position + Vector2(rotated_total_offset_x2, rotated_total_offset_y2); + + // Log final positions for debugging purposes + std::cout << "Final Position of Box 1: (" << final_position1.x << ", " << final_position1.y << ")" << std::endl; + std::cout << "Final Position of Box 2: (" << final_position2.x << ", " << final_position2.y << ")" << std::endl; + + // Log rotation values for debugging + std::cout << "Rotation of Box 1: " << transform1.rotation << " degrees" << std::endl; + std::cout << "Rotation of Box 2: " << transform2.rotation << " degrees" << std::endl; + + + // Calculate half-extents (half width and half height) + double half_width1 = box1.width / 2.0; + double half_height1 = box1.height / 2.0; + double half_width2 = box2.width / 2.0; + double half_height2 = box2.height / 2.0; + + // Check if the boxes overlap along the X and Y axes + return !(final_position1.x + half_width1 < final_position2.x - half_width2 || // box1 is left of box2 + final_position1.x - half_width1 > final_position2.x + half_width2 || // box1 is right of box2 + final_position1.y + half_height1 < final_position2.y - half_height2 || // box1 is above box2 + final_position1.y - half_height1 > final_position2.y + half_height2); // box1 is below box2 +} +bool CollisionSystem::check_box_circle_collision(const BoxCollider& box, const CircleCollider& circle) {} +bool CollisionSystem::check_circle_circle_collision(const CircleCollider& circle1, const CircleCollider& circle2) {} diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 1e9f1aa..402ba64 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -1,11 +1,25 @@ #pragma once +#include "Collider.h" +#include + namespace crepe { +class Collider; +class BoxCollider; +class CircleCollider; +class Transform; +class Rigidbody; + class CollisionSystem { public: CollisionSystem(); void update(); +private: + bool check_collisions(const std::vector& colliders1, const std::vector& colliders2); + bool check_box_box_collision(const BoxCollider& box1, const BoxCollider& box2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2); + bool check_box_circle_collision(const BoxCollider& box, const CircleCollider& circle); + bool check_circle_circle_collision(const CircleCollider& circle1, const CircleCollider& circle2); }; } // namespace crepe diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index 36f9d4d..d43d56c 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -28,4 +28,5 @@ add_example(proxy) add_example(db) add_example(ecs) add_example(scene_manager) +add_example(collision) diff --git a/src/example/collision.cpp b/src/example/collision.cpp new file mode 100644 index 0000000..9faac69 --- /dev/null +++ b/src/example/collision.cpp @@ -0,0 +1,42 @@ +#include "api/BoxCollider.h" +#include "system/CollisionSystem.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace crepe; +using namespace std; + +int main(int argc, char * argv[]) { + + GameObject game_object1(0, "Name", "Tag", Vector2{1, 1}, 90, 1); + game_object1.add_component(Rigidbody::Data{ + .mass = 1, + .gravity_scale = 1, + .body_type = Rigidbody::BodyType::DYNAMIC, + .constraints = {0, 0, 0}, + .use_gravity = true, + .bounce = false, + .offset = {3,3} + }); + game_object1.add_component(Vector2{5, 5}, 100, 50); + + GameObject game_object2(1, "Name", "Tag", Vector2{20, 2}, 90, 1); + game_object2.add_component(Rigidbody::Data{ + .mass = 1, + .gravity_scale = 1, + .body_type = Rigidbody::BodyType::DYNAMIC, + .constraints = {0, 0, 0}, + .use_gravity = true, + .bounce = false, + .offset = {4,4} + }); + game_object2.add_component(Vector2{6, 6}, 100, 50); + CollisionSystem coltest; + coltest.update(); + return 0; +} -- cgit v1.2.3 From 3b615d87f421b576227ef6d0f7e3c5d66c545da2 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Tue, 19 Nov 2024 20:42:02 +0100 Subject: doxygen comment colliders --- src/crepe/api/BoxCollider.h | 9 +++++++++ src/crepe/api/CircleCollider.h | 8 ++++++++ 2 files changed, 17 insertions(+) (limited to 'src/crepe/api/BoxCollider.h') diff --git a/src/crepe/api/BoxCollider.h b/src/crepe/api/BoxCollider.h index 357c979..7f51cba 100644 --- a/src/crepe/api/BoxCollider.h +++ b/src/crepe/api/BoxCollider.h @@ -5,10 +5,19 @@ 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 { public: BoxCollider(game_object_id_t game_object_id,Vector2 offset, double width, double height); + + //! Width of box collider double width; + + //! Height of box collider double height; }; diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h index 29a9c1e..4e04fa4 100644 --- a/src/crepe/api/CircleCollider.h +++ b/src/crepe/api/CircleCollider.h @@ -6,9 +6,17 @@ 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 { public: + CircleCollider(game_object_id_t game_object_id,Vector2 offset, int radius); + + //! Radius of the circle collider. double radius; }; -- cgit v1.2.3 From 3f63143b4005936da446fb2cdbbd1072b47fc8c1 Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Fri, 22 Nov 2024 15:36:14 +0100 Subject: merge with master --- src/crepe/Collider.cpp | 2 +- src/crepe/Collider.h | 5 ++- 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/LoopManager.cpp | 1 + src/crepe/api/Rigidbody.h | 2 +- src/crepe/system/CollisionSystem.cpp | 79 ++++++++++++++++++------------------ src/crepe/system/CollisionSystem.h | 8 ++-- src/example/CMakeLists.txt | 1 + src/example/game.cpp | 30 +++++++------- 12 files changed, 71 insertions(+), 65 deletions(-) (limited to 'src/crepe/api/BoxCollider.h') diff --git a/src/crepe/Collider.cpp b/src/crepe/Collider.cpp index 0706371..80a944d 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, Vector2 offset) : Component(id), offset(offset) {} +Collider::Collider(game_object_id_t id, vec2 offset) : Component(id), offset(offset) {} diff --git a/src/crepe/Collider.h b/src/crepe/Collider.h index 0157324..5b26af5 100644 --- a/src/crepe/Collider.h +++ b/src/crepe/Collider.h @@ -3,16 +3,17 @@ #include "api/Vector2.h" #include "Component.h" +#include "types.h" namespace crepe { class Collider : public Component { public: - Collider(game_object_id_t id, Vector2 offset); + Collider(game_object_id_t id, vec2 offset); public: //! Offset of the collider relative to rigidbody position - Vector2 offset; + vec2 offset; }; } // namespace crepe diff --git a/src/crepe/api/BoxCollider.cpp b/src/crepe/api/BoxCollider.cpp index eafbdb2..83fb632 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,Vector2 offset, double width, double height) : Collider(game_object_id,offset), width(width), height(height) {} +BoxCollider::BoxCollider(game_object_id_t game_object_id,vec2 offset, double width, double 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 7f51cba..6135954 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,Vector2 offset, double width, double height); + BoxCollider(game_object_id_t game_object_id,vec2 offset, double width, double height); //! Width of box collider double width; diff --git a/src/crepe/api/CircleCollider.cpp b/src/crepe/api/CircleCollider.cpp index 04a4995..43de991 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,Vector2 offset, int radius) : Collider(game_object_id,offset), radius(radius) {} +CircleCollider::CircleCollider(game_object_id_t game_object_id,vec2 offset, int radius) : Collider(game_object_id,offset), radius(radius) {} diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h index 4e04fa4..843547f 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,Vector2 offset, int radius); + CircleCollider(game_object_id_t game_object_id,vec2 offset, int radius); //! Radius of the circle collider. double radius; diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index 586919d..10b59c8 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -63,6 +63,7 @@ void LoopManager::setup() { this->game_running = true; LoopTimer::get_instance().start(); LoopTimer::get_instance().set_fps(60); + this->scene_manager.load_next_scene(); } void LoopManager::render() { diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index b96b463..7939563 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -78,7 +78,7 @@ public: //! bounce factor of material double elastisity = 0.0; //! offset of all colliders relative to transform position - Vector2 offset; + vec2 offset; }; public: diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 9ca8b3a..8d9b356 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -15,6 +15,7 @@ #include "ComponentManager.h" #include "CollisionSystem.h" #include "Collider.h" +#include "types.h" using namespace crepe; @@ -39,7 +40,7 @@ void CollisionSystem::collision_handler(CollidedInfoStor& data1,CollidedInfoStor // Data needed for collision handler info const Collider* collider1 = nullptr; const Collider* collider2 = nullptr; - Vector2 move_back; + vec2 move_back; // Check collision type and get values for handler if (std::holds_alternative>(data1.collider)) { @@ -53,8 +54,8 @@ void CollisionSystem::collision_handler(CollidedInfoStor& data1,CollidedInfoStor // TODO: send with the collider info to this function because this is calculated previously // Get the current position of the collider - Vector2 final_position1 = current_position(box_collider1,data1.transform,data1.rigidbody); - Vector2 final_position2 = current_position(box_collider2,data2.transform,data2.rigidbody); + vec2 final_position1 = current_position(box_collider1,data1.transform,data1.rigidbody); + vec2 final_position2 = current_position(box_collider2,data2.transform,data2.rigidbody); // Determine move_back value for smallest overlap (x or y) move_back = box_box_collision_move_back(box_collider1,box_collider2,final_position1,final_position2); @@ -112,20 +113,20 @@ void CollisionSystem::collision_handler(CollidedInfoStor& data1,CollidedInfoStor } -Vector2 CollisionSystem::box_box_collision_move_back(const BoxCollider& box_collider1,const BoxCollider& box_collider2,Vector2 final_position1,Vector2 final_position2) +vec2 CollisionSystem::box_box_collision_move_back(const BoxCollider& box_collider1,const BoxCollider& box_collider2,vec2 final_position1,vec2 final_position2) { - Vector2 resolution; // Default resolution vector - Vector2 delta = final_position2 - final_position1; + vec2 resolution; // Default resolution vector + vec2 delta = final_position2 - final_position1; // Compute half-dimensions of the boxes - double half_width1 = box_collider1.width / 2.0; - double half_height1 = box_collider1.height / 2.0; - double half_width2 = box_collider2.width / 2.0; - double half_height2 = box_collider2.height / 2.0; + 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; // Calculate overlaps along X and Y axes - double overlap_x = (half_width1 + half_width2) - std::abs(delta.x); - double overlap_y = (half_height1 + half_height2) - std::abs(delta.y); + float overlap_x = (half_width1 + half_width2) - std::abs(delta.x); + float overlap_y = (half_height1 + half_height2) - std::abs(delta.y); // Check if there is a collision if (overlap_x > 0 && overlap_y > 0) {//should always be true check if this can be removed @@ -288,14 +289,14 @@ std::vector(oncollision, this->get_game_object_id()); + EventManager::get_instance().subscribe(oncollision, 0); } void update() { // Retrieve component from the same GameObject this script is on } }; + class ConcreteScene1 : public Scene { public: using Scene::Scene; @@ -37,11 +38,11 @@ public: ComponentManager & mgr = this->component_manager; Color color(0, 0, 0, 0); - double screen_size_width = 640; - double screen_size_height = 480; - double world_collider = 1000; + float screen_size_width = 640; + float screen_size_height = 480; + float world_collider = 1000; //define playable world - GameObject world = mgr.new_object("Name", "Tag", Vector2{screen_size_width/2, screen_size_height/2}, 0, 1); + 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, @@ -51,13 +52,13 @@ public: .bounce = false, .offset = {0,0} }); - world.add_component(Vector2{0, 0-(screen_size_height/2+world_collider/2)}, world_collider, world_collider);; // Top - world.add_component(Vector2{0, screen_size_height/2+world_collider/2}, world_collider, world_collider); // Bottom - world.add_component(Vector2{0-(screen_size_width/2+world_collider/2), 0}, world_collider, world_collider); // Left - world.add_component(Vector2{screen_size_width/2+world_collider/2, 0}, world_collider, world_collider); // right + world.add_component(vec2{0, 0-(screen_size_height/2+world_collider/2)}, world_collider, world_collider);; // Top + world.add_component(vec2{0, screen_size_height/2+world_collider/2}, world_collider, world_collider); // Bottom + world.add_component(vec2{0-(screen_size_width/2+world_collider/2), 0}, world_collider, world_collider); // Left + world.add_component(vec2{screen_size_width/2+world_collider/2, 0}, world_collider, world_collider); // right - GameObject game_object1 = mgr.new_object("Name", "Tag", Vector2{screen_size_width/2, screen_size_height/2}, 0, 1); + 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, @@ -69,20 +70,21 @@ public: .elastisity = 1, .offset = {0,0}, }); - game_object1.add_component(Vector2{0, 0}, 20, 20); + 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); } + + string get_name() const { return "scene1"; } }; int main(int argc, char * argv[]) { LoopManager gameloop; - gameloop.scene_manager.add_scene("scene1"); - gameloop.scene_manager.load_next_scene(); + gameloop.add_scene(); gameloop.start(); return 0; } -- cgit v1.2.3 From ad504dbf5152b663c3b503b04012efe092120b6d Mon Sep 17 00:00:00 2001 From: JAROWMR Date: Mon, 2 Dec 2024 13:18:36 +0100 Subject: added some comments and const --- src/crepe/api/BoxCollider.cpp | 2 +- src/crepe/api/BoxCollider.h | 6 +++--- src/crepe/api/CircleCollider.cpp | 2 +- src/crepe/api/CircleCollider.h | 4 ++-- src/crepe/system/CollisionSystem.cpp | 12 ++++++++++-- src/crepe/system/CollisionSystem.h | 2 +- 6 files changed, 18 insertions(+), 10 deletions(-) (limited to 'src/crepe/api/BoxCollider.h') diff --git a/src/crepe/api/BoxCollider.cpp b/src/crepe/api/BoxCollider.cpp index 4c767c8..6034837 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, double width, double height) : Collider(game_object_id,offset), width(width), height(height) {} +BoxCollider::BoxCollider(game_object_id_t game_object_id,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 6135954..2ce1ee8 100644 --- a/src/crepe/api/BoxCollider.h +++ b/src/crepe/api/BoxCollider.h @@ -12,13 +12,13 @@ namespace crepe { */ class BoxCollider : public Collider { public: - BoxCollider(game_object_id_t game_object_id,vec2 offset, double width, double height); + BoxCollider(game_object_id_t game_object_id,vec2 offset, float width, float height); //! Width of box collider - double width; + float width; //! Height of box collider - double height; + float height; }; } // namespace crepe diff --git a/src/crepe/api/CircleCollider.cpp b/src/crepe/api/CircleCollider.cpp index 43de991..497ebba 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, int radius) : Collider(game_object_id,offset), radius(radius) {} +CircleCollider::CircleCollider(game_object_id_t game_object_id,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 843547f..c61f027 100644 --- a/src/crepe/api/CircleCollider.h +++ b/src/crepe/api/CircleCollider.h @@ -14,10 +14,10 @@ namespace crepe { class CircleCollider : public Collider { public: - CircleCollider(game_object_id_t game_object_id,vec2 offset, int radius); + CircleCollider(game_object_id_t game_object_id,vec2 offset, float radius); //! Radius of the circle collider. - double radius; + float radius; }; } // namespace crepe diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 0b83bce..70fe855 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -105,6 +105,7 @@ std::pair CollisionSystem::collision_handler(Co vec2 collider_pos1 = current_position(collider1.offset, data1.transform, data1.rigidbody); vec2 collider_pos2 = current_position(collider2.offset, data2.transform, data2.rigidbody); resolution = box_box_resolution(collider1,collider2,collider_pos1,collider_pos2); + break; } case CollisionInternalType::BOX_CIRCLE: { const BoxCollider & collider1 = std::get>(data1.collider); @@ -112,7 +113,7 @@ std::pair CollisionSystem::collision_handler(Co vec2 collider_pos1 = current_position(collider1.offset, data1.transform, data1.rigidbody); vec2 collider_pos2 = current_position(collider2.offset, data2.transform, data2.rigidbody); resolution = circle_box_resolution(collider2,collider1,collider_pos2,collider_pos1); - + break; } case CollisionInternalType::CIRCLE_CIRCLE: { const CircleCollider & collider1 = std::get>(data1.collider); @@ -120,6 +121,7 @@ std::pair CollisionSystem::collision_handler(Co vec2 collider_pos1 = current_position(collider1.offset, data1.transform, data1.rigidbody); vec2 collider_pos2 = current_position(collider2.offset, data2.transform, data2.rigidbody); resolution = circle_circle_resolution(collider1,collider2,collider_pos1,collider_pos2); + break; } case CollisionInternalType::CIRCLE_BOX: { const CircleCollider & collider1 = std::get>(data1.collider); @@ -127,6 +129,7 @@ std::pair CollisionSystem::collision_handler(Co vec2 collider_pos1 = current_position(collider1.offset, data1.transform, data1.rigidbody); vec2 collider_pos2 = current_position(collider2.offset, data2.transform, data2.rigidbody); resolution = circle_box_resolution(collider1,collider2,collider_pos1,collider_pos2); + break; } } @@ -282,18 +285,23 @@ 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) { std::visit([&](auto& inner_collider_ref) { + // Return from visit if collider or components are not active if (!inner_collider_ref.get().active) return; auto inner_components = get_active_transform_and_rigidbody(inner_collider_ref.get().game_object_id); if (!inner_components) return; for (size_t j = i + 1; j < colliders.size(); ++j) { std::visit([&](auto& outer_collider_ref) { + // Return from visit if collider or components are not active and if they have the same id. if (!outer_collider_ref.get().active) return; if (inner_collider_ref.get().game_object_id == outer_collider_ref.get().game_object_id) return; auto outer_components = get_active_transform_and_rigidbody(outer_collider_ref.get().game_object_id); if (!outer_components) return; + // Get collision type form variant colliders CollisionInternalType type = check_collider_type(colliders[i],colliders[j]); if(!check_collision({ .collider = colliders[i], @@ -336,7 +344,7 @@ CollisionSystem::get_active_transform_and_rigidbody(game_object_id_t game_object return std::make_pair(std::ref(transform), std::ref(rigidbody)); } -CollisionSystem::CollisionInternalType CollisionSystem::check_collider_type(const collider_variant& collider1,const collider_variant& collider2){ +CollisionSystem::CollisionInternalType CollisionSystem::check_collider_type(const collider_variant& collider1,const collider_variant& collider2) const{ if(std::holds_alternative>(collider1)){ if(std::holds_alternative>(collider2)) { diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 86b8b7a..fc91603 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -92,7 +92,7 @@ private: * \param collider2 Second collider variant (BoxCollider or CircleCollider). * \return The combined type of the two colliders. */ - CollisionInternalType check_collider_type(const collider_variant& collider1,const collider_variant& collider2); + CollisionInternalType check_collider_type(const collider_variant& collider1,const collider_variant& collider2) const; /** * \brief Calculates the current position of a collider. -- 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/crepe/api/BoxCollider.h') 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 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/crepe/api/BoxCollider.h') 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/crepe/api/BoxCollider.h') 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 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/crepe/api/BoxCollider.h') 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