aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/crepe/Collider.cpp2
-rw-r--r--src/crepe/Collider.h2
-rw-r--r--src/crepe/api/BoxCollider.cpp7
-rw-r--r--src/crepe/api/BoxCollider.h6
-rw-r--r--src/crepe/api/CircleCollider.cpp6
-rw-r--r--src/crepe/api/CircleCollider.h3
-rw-r--r--src/crepe/api/Event.h4
-rw-r--r--src/crepe/api/LoopManager.cpp3
-rw-r--r--src/crepe/api/Rigidbody.cpp4
-rw-r--r--src/crepe/api/Rigidbody.h4
-rw-r--r--src/crepe/system/CollisionSystem.cpp514
-rw-r--r--src/crepe/system/CollisionSystem.h121
-rw-r--r--src/crepe/system/PhysicsSystem.cpp9
-rw-r--r--src/example/game.cpp97
-rw-r--r--src/test/CollisionTest.cpp122
-rw-r--r--src/test/Profiling.cpp121
16 files changed, 574 insertions, 451 deletions
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 <cmath>
#include <algorithm>
+#include <cmath>
#include <cstddef>
#include <functional>
+#include <optional>
#include <utility>
#include <variant>
-#include <optional>
-#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<CollisionInternal> all_colliders;
game_object_id_t id = 0;
- RefVector<Rigidbody> rigidbodies = this->component_manager.get_components_by_type<Rigidbody>();
+ RefVector<Rigidbody> rigidbodies
+ = this->component_manager.get_components_by_type<Rigidbody>();
// 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<Transform>(id).front().get();
+ Transform & transform
+ = this->component_manager.get_components_by_id<Transform>(id).front().get();
// Check if the boxcollider is active and has the same id as the rigidbody.
- RefVector<BoxCollider> boxcolliders = this->component_manager.get_components_by_type<BoxCollider>();
- 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<BoxCollider> boxcolliders
+ = this->component_manager.get_components_by_type<BoxCollider>();
+ 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<CircleCollider> circlecolliders = this->component_manager.get_components_by_type<CircleCollider>();
- 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<CircleCollider> circlecolliders
+ = this->component_manager.get_components_by_type<CircleCollider>();
+ 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<std::pair<CollisionInternal,CollisionInternal>> collided = this->gather_collisions(all_colliders);
+ std::vector<std::pair<CollisionInternal, CollisionInternal>> 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<vec2,CollisionSystem::Direction> resolution_data = this->collision_handler(this_data,other_data,type);
+ CollisionInternalType type
+ = this->get_collider_type(this_data.collider, other_data.collider);
+ std::pair<vec2, CollisionSystem::Direction> resolution_data
+ = this->collision_handler(this_data, other_data, type);
- OptionalRef<Metadata> this_metadata = this->component_manager.get_components_by_id<Metadata>(this_data.id).front().get();
- OptionalRef<Metadata> other_metadata = this->component_manager.get_components_by_id<Metadata>(other_data.id).front().get();
+ OptionalRef<Metadata> this_metadata
+ = this->component_manager.get_components_by_id<Metadata>(this_data.id).front().get();
+ OptionalRef<Metadata> other_metadata
+ = this->component_manager.get_components_by_id<Metadata>(other_data.id).front().get();
OptionalRef<Collider> this_collider;
OptionalRef<Collider> other_collider;
switch (type) {
- case CollisionInternalType::BOX_BOX:{
+ case CollisionInternalType::BOX_BOX: {
this_collider = std::get<std::reference_wrapper<BoxCollider>>(this_data.collider);
- other_collider = std::get<std::reference_wrapper<BoxCollider>>(other_data.collider);
+ other_collider
+ = std::get<std::reference_wrapper<BoxCollider>>(other_data.collider);
break;
}
- case CollisionInternalType::BOX_CIRCLE:{
+ case CollisionInternalType::BOX_CIRCLE: {
this_collider = std::get<std::reference_wrapper<BoxCollider>>(this_data.collider);
- other_collider = std::get<std::reference_wrapper<CircleCollider>>(other_data.collider);
+ other_collider
+ = std::get<std::reference_wrapper<CircleCollider>>(other_data.collider);
break;
}
- case CollisionInternalType::CIRCLE_BOX:{
- this_collider = std::get<std::reference_wrapper<CircleCollider>>(this_data.collider);
- other_collider = std::get<std::reference_wrapper<BoxCollider>>(other_data.collider);
+ case CollisionInternalType::CIRCLE_BOX: {
+ this_collider
+ = std::get<std::reference_wrapper<CircleCollider>>(this_data.collider);
+ other_collider
+ = std::get<std::reference_wrapper<BoxCollider>>(other_data.collider);
break;
}
- case CollisionInternalType::CIRCLE_CIRCLE:{
- this_collider = std::get<std::reference_wrapper<CircleCollider>>(this_data.collider);
- other_collider = std::get<std::reference_wrapper<CircleCollider>>(other_data.collider);
+ case CollisionInternalType::CIRCLE_CIRCLE: {
+ this_collider
+ = std::get<std::reference_wrapper<CircleCollider>>(this_data.collider);
+ other_collider
+ = std::get<std::reference_wrapper<CircleCollider>>(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<vec2,CollisionSystem::Direction> CollisionSystem::collision_handler(CollisionInternal& data1,CollisionInternal& data2,CollisionInternalType type) {
+std::pair<vec2, CollisionSystem::Direction>
+CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal & data2,
+ CollisionInternalType type) {
vec2 resolution;
switch (type) {
- case CollisionInternalType::BOX_BOX: {
- const BoxCollider & collider1 = std::get<std::reference_wrapper<BoxCollider>>(data1.collider);
- const BoxCollider & collider2 = std::get<std::reference_wrapper<BoxCollider>>(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<std::reference_wrapper<BoxCollider>>(data1.collider);
+ const BoxCollider & collider2
+ = std::get<std::reference_wrapper<BoxCollider>>(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<std::reference_wrapper<BoxCollider>>(data1.collider);
- const CircleCollider & collider2 = std::get<std::reference_wrapper<CircleCollider>>(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<std::reference_wrapper<BoxCollider>>(data1.collider);
+ const CircleCollider & collider2
+ = std::get<std::reference_wrapper<CircleCollider>>(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<std::reference_wrapper<CircleCollider>>(data1.collider);
- const CircleCollider & collider2 = std::get<std::reference_wrapper<CircleCollider>>(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<std::reference_wrapper<CircleCollider>>(data1.collider);
+ const CircleCollider & collider2
+ = std::get<std::reference_wrapper<CircleCollider>>(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<std::reference_wrapper<CircleCollider>>(data1.collider);
- const BoxCollider & collider2 = std::get<std::reference_wrapper<BoxCollider>>(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<std::reference_wrapper<CircleCollider>>(data1.collider);
+ const BoxCollider & collider2
+ = std::get<std::reference_wrapper<BoxCollider>>(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<CollisionEvent>(data, info.this_collider.game_object_id);
+ EventManager::get_instance().trigger_event<CollisionEvent>(
+ 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<std::pair<CollisionSystem::CollisionInternal,CollisionSystem::CollisionInternal>> CollisionSystem::gather_collisions(std::vector<CollisionInternal> & colliders) {
-
-
+std::vector<std::pair<CollisionSystem::CollisionInternal, CollisionSystem::CollisionInternal>>
+CollisionSystem::gather_collisions(std::vector<CollisionInternal> & colliders) {
+
// TODO:
// If no colliders skip
// Check if colliders has rigidbody if not skip
@@ -311,83 +354,103 @@ std::vector<std::pair<CollisionSystem::CollisionInternal,CollisionSystem::Collis
// Quadtree is placed over the input vector
// Return data of collided colliders which are variants
- std::vector<std::pair<CollisionInternal,CollisionInternal>> collisions_ret;
- //using visit to visit the variant to access the active and id.
+ std::vector<std::pair<CollisionInternal, CollisionInternal>> 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<std::reference_wrapper<CircleCollider>>(collider1)){
- if(std::holds_alternative<std::reference_wrapper<CircleCollider>>(collider2))
- {
+CollisionSystem::CollisionInternalType
+CollisionSystem::get_collider_type(const collider_variant & collider1,
+ const collider_variant & collider2) const {
+ if (std::holds_alternative<std::reference_wrapper<CircleCollider>>(collider1)) {
+ if (std::holds_alternative<std::reference_wrapper<CircleCollider>>(collider2)) {
return CollisionInternalType::CIRCLE_CIRCLE;
- }
- else {
+ } else {
return CollisionInternalType::CIRCLE_BOX;
}
- }
- else {
- if(std::holds_alternative<std::reference_wrapper<CircleCollider>>(collider2))
- {
+ } else {
+ if (std::holds_alternative<std::reference_wrapper<CircleCollider>>(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<std::reference_wrapper<BoxCollider>>(first_info.collider);
- const BoxCollider & box_collider2 = std::get<std::reference_wrapper<BoxCollider>>(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<std::reference_wrapper<BoxCollider>>(first_info.collider);
+ const BoxCollider & box_collider2
+ = std::get<std::reference_wrapper<BoxCollider>>(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<std::reference_wrapper<BoxCollider>>(first_info.collider);
- const CircleCollider & circle_collider = std::get<std::reference_wrapper<CircleCollider>>(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<std::reference_wrapper<BoxCollider>>(first_info.collider);
+ const CircleCollider & circle_collider
+ = std::get<std::reference_wrapper<CircleCollider>>(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<std::reference_wrapper<CircleCollider>>(first_info.collider);
- const CircleCollider & circle_collider2 = std::get<std::reference_wrapper<CircleCollider>>(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<std::reference_wrapper<CircleCollider>>(first_info.collider);
+ const CircleCollider & circle_collider2
+ = std::get<std::reference_wrapper<CircleCollider>>(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<std::reference_wrapper<CircleCollider>>(first_info.collider);
- const BoxCollider & box_collider = std::get<std::reference_wrapper<BoxCollider>>(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<std::reference_wrapper<CircleCollider>>(first_info.collider);
+ const BoxCollider & box_collider
+ = std::get<std::reference_wrapper<BoxCollider>>(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 <vector>
-#include <variant>
#include <optional>
+#include <variant>
+#include <vector>
-#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<BoxCollider>, std::reference_wrapper<CircleCollider>>;
+ using collider_variant = std::variant<std::reference_wrapper<BoxCollider>,
+ std::reference_wrapper<CircleCollider>>;
//! 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<vec2,Direction> collision_handler(CollisionInternal& data1,CollisionInternal& data2 ,CollisionInternalType type);
+ std::pair<vec2, Direction> 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<std::pair<CollisionInternal,CollisionInternal>> gather_collisions(std::vector<CollisionInternal> & colliders);
+ std::vector<std::pair<CollisionInternal, CollisionInternal>>
+ gather_collisions(std::vector<CollisionInternal> & 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 <crepe/api/GameObject.h>
-#include <crepe/api/Transform.h>
-#include <crepe/api/Rigidbody.h>
#include <crepe/api/BoxCollider.h>
#include <crepe/api/Camera.h>
-#include <crepe/api/Script.h>
#include <crepe/api/Color.h>
-#include <crepe/api/Sprite.h>
-#include <crepe/api/Texture.h>
-#include <crepe/api/Vector2.h>
#include <crepe/api/Event.h>
#include <crepe/api/EventManager.h>
+#include <crepe/api/GameObject.h>
#include <crepe/api/LoopManager.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/Script.h>
+#include <crepe/api/Sprite.h>
+#include <crepe/api/Texture.h>
+#include <crepe/api/Transform.h>
+#include <crepe/api/Vector2.h>
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<CollisionEvent>([this](const CollisionEvent& ev) -> bool {
- return this->oncollision(ev);
- });
+ subscribe<CollisionEvent>(
+ [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>(Rigidbody::Data{
- .mass = 0,
- .gravity_scale = 0,
- .body_type = Rigidbody::BodyType::STATIC,
- .constraints = {0, 0, 0},
- .offset = {0,0}
- });
- world.add_component<BoxCollider>(vec2{0, 0-(screen_size_height/2+world_collider/2)}, vec2{world_collider, world_collider});; // Top
- world.add_component<BoxCollider>(vec2{0, screen_size_height/2+world_collider/2}, vec2{world_collider, world_collider}); // Bottom
- world.add_component<BoxCollider>(vec2{0-(screen_size_width/2+world_collider/2), 0}, vec2{world_collider, world_collider}); // Left
- world.add_component<BoxCollider>(vec2{screen_size_width/2+world_collider/2, 0}, vec2{world_collider, world_collider}); // right
- world.add_component<Camera>(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>(
+ Rigidbody::Data{.mass = 0,
+ .gravity_scale = 0,
+ .body_type = Rigidbody::BodyType::STATIC,
+ .constraints = {0, 0, 0},
+ .offset = {0, 0}});
+ world.add_component<BoxCollider>(
+ vec2{0, 0 - (screen_size_height / 2 + world_collider / 2)},
+ vec2{world_collider, world_collider});
+ ; // Top
+ world.add_component<BoxCollider>(vec2{0, screen_size_height / 2 + world_collider / 2},
+ vec2{world_collider, world_collider}); // Bottom
+ world.add_component<BoxCollider>(
+ vec2{0 - (screen_size_width / 2 + world_collider / 2), 0},
+ vec2{world_collider, world_collider}); // Left
+ world.add_component<BoxCollider>(vec2{screen_size_width / 2 + world_collider / 2, 0},
+ vec2{world_collider, world_collider}); // right
+ world.add_component<Camera>(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>(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<BoxCollider>(vec2{0, 0}, vec2{20, 20});
- game_object1.add_component<BehaviorScript>().set_script<MyScript>();
- auto img = Texture("asset/texture/green_square.png");
- game_object1.add_component<Sprite>(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>(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<BoxCollider>(vec2{0, 0}, vec2{20, 20});
+ game_object1.add_component<BehaviorScript>().set_script<MyScript>();
+ auto img = Texture("asset/texture/green_square.png");
+ game_object1.add_component<Sprite>(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<void(const CollisionEvent& ev)> test_fn = [](const CollisionEvent & ev) { };
+ function<void(const CollisionEvent & ev)> 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<CollisionEvent>([this](const CollisionEvent& ev) -> bool {
- return this->on_collision(ev);
- });
+ subscribe<CollisionEvent>(
+ [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>(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<BoxCollider>(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<BoxCollider>(vec2{0, 0}, vec2{10, 10});
- BehaviorScript & script_object1 = game_object1.add_component<BehaviorScript>().set_script<CollisionHandler>(1);
- script_object1_ref = static_cast<CollisionHandler*>(script_object1.script.get());
+ BehaviorScript & script_object1
+ = game_object1.add_component<BehaviorScript>().set_script<CollisionHandler>(1);
+ script_object1_ref = static_cast<CollisionHandler *>(script_object1.script.get());
ASSERT_NE(script_object1_ref, nullptr);
-
+
game_object2.add_component<Rigidbody>(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<BoxCollider>(vec2{0, 0}, vec2{10, 10});
- BehaviorScript & script_object2 = game_object2.add_component<BehaviorScript>().set_script<CollisionHandler>(2);
- script_object2_ref = static_cast<CollisionHandler*>(script_object2.script.get());
+ BehaviorScript & script_object2
+ = game_object2.add_component<BehaviorScript>().set_script<CollisionHandler>(2);
+ script_object2_ref = static_cast<CollisionHandler *>(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<Transform>(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<Transform>(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<Transform>(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<Transform>(1).front().get();
- tf.position = {50,30};
+ tf.position = {50, 30};
Rigidbody & rg1 = this->mgr.get_components_by_id<Rigidbody>(1).front().get();
- rg1.data.linear_velocity = {10,10};
+ rg1.data.linear_velocity = {10, 10};
Rigidbody & rg2 = this->mgr.get_components_by_id<Rigidbody>(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<Transform>(1).front().get();
- tf.position = {45,30};
+ tf.position = {45, 30};
Rigidbody & rg1 = this->mgr.get_components_by_id<Rigidbody>(1).front().get();
- rg1.data.linear_velocity = {10,10};
+ rg1.data.linear_velocity = {10, 10};
Rigidbody & rg2 = this->mgr.get_components_by_id<Rigidbody>(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<Transform>(1).front().get();
- tf.position = {50,25};
+ tf.position = {50, 25};
Rigidbody & rg1 = this->mgr.get_components_by_id<Rigidbody>(1).front().get();
- rg1.data.linear_velocity = {10,10};
+ rg1.data.linear_velocity = {10, 10};
Rigidbody & rg2 = this->mgr.get_components_by_id<Rigidbody>(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<Transform>(1).front().get();
- tf.position = {50,30};
+ tf.position = {50, 30};
Rigidbody & rg2 = this->mgr.get_components_by_id<Rigidbody>(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<Transform>(1).front().get();
- tf.position = {45,30};
+ tf.position = {45, 30};
Rigidbody & rg1 = this->mgr.get_components_by_id<Rigidbody>(1).front().get();
- rg1.data.linear_velocity = {10,10};
+ rg1.data.linear_velocity = {10, 10};
Rigidbody & rg2 = this->mgr.get_components_by_id<Rigidbody>(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<Transform>(1).front().get();
- tf.position = {50,25};
+ tf.position = {50, 25};
Rigidbody & rg1 = this->mgr.get_components_by_id<Rigidbody>(1).front().get();
- rg1.data.linear_velocity = {10,10};
+ rg1.data.linear_velocity = {10, 10};
Rigidbody & rg2 = this->mgr.get_components_by_id<Rigidbody>(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<Transform>(1).front().get();
- tf.position = {45,30};
+ tf.position = {45, 30};
Rigidbody & rg1 = this->mgr.get_components_by_id<Rigidbody>(1).front().get();
- rg1.data.linear_velocity = {10,10};
+ rg1.data.linear_velocity = {10, 10};
Rigidbody & rg2 = this->mgr.get_components_by_id<Rigidbody>(2).front().get();
rg2.data.body_type = crepe::Rigidbody::BodyType::STATIC;
BoxCollider & bxc = this->mgr.get_components_by_id<BoxCollider>(1).front().get();
- bxc.offset = {5,0};
+ bxc.offset = {5, 0};
this->game_object1.add_component<BoxCollider>(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 <cmath>
#include <chrono>
+#include <cmath>
#include <gtest/gtest.h>
#define private public
@@ -12,10 +12,10 @@
#include <crepe/api/Event.h>
#include <crepe/api/EventManager.h>
#include <crepe/api/GameObject.h>
+#include <crepe/api/ParticleEmitter.h>
#include <crepe/api/Rigidbody.h>
#include <crepe/api/Script.h>
#include <crepe/api/Transform.h>
-#include <crepe/api/ParticleEmitter.h>
#include <crepe/system/CollisionSystem.h>
#include <crepe/system/ScriptSystem.h>
#include <crepe/types.h>
@@ -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<CollisionEvent>([this](const CollisionEvent& ev) -> bool {
- return this->oncollision(ev);
- });
+ subscribe<CollisionEvent>(
+ [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<Camera>(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<Camera>(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 <typename Func>
- 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<std::chrono::microseconds>(end - start);
+ std::chrono::microseconds duration
+ = std::chrono::duration_cast<std::chrono::microseconds>(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<float>(game_object_count*2),0});
+ GameObject gameobject = mgr.new_object(
+ "gameobject", "", {static_cast<float>(game_object_count * 2), 0});
gameobject.add_component<Rigidbody>(Rigidbody::Data{
.gravity_scale = 0.0,
.body_type = Rigidbody::BodyType::STATIC,
@@ -163,7 +163,8 @@ TEST_F(Profiling, Profiling_2) {
gameobject.add_component<BehaviorScript>().set_script<TestScript>();
Color color(0, 0, 0, 0);
auto img = Texture("asset/texture/green_square.png");
- Sprite & test_sprite = gameobject.add_component<Sprite>(img, color, Sprite::FlipSettings{false, false}, 1, 1, 500);
+ Sprite & test_sprite = gameobject.add_component<Sprite>(
+ 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<float>(game_object_count*2),0});
+ GameObject gameobject = mgr.new_object(
+ "gameobject", "", {static_cast<float>(game_object_count * 2), 0});
gameobject.add_component<Rigidbody>(Rigidbody::Data{
- .gravity_scale = 0,
- .body_type = Rigidbody::BodyType::STATIC,
+ .gravity_scale = 0,
+ .body_type = Rigidbody::BodyType::STATIC,
});
gameobject.add_component<BoxCollider>(vec2{0, 0}, 1, 1);
gameobject.add_component<BehaviorScript>().set_script<TestScript>();
Color color(0, 0, 0, 0);
auto img = Texture("asset/texture/green_square.png");
- Sprite & test_sprite = gameobject.add_component<Sprite>(img, color, Sprite::FlipSettings{false, false}, 1, 1, 500);
+ Sprite & test_sprite = gameobject.add_component<Sprite>(
+ img, color, Sprite::FlipSettings{false, false}, 1, 1, 500);
auto & test = gameobject.add_component<ParticleEmitter>(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);