diff options
| author | JAROWMR <jarorutjes07@gmail.com> | 2024-12-04 20:11:02 +0100 | 
|---|---|---|
| committer | JAROWMR <jarorutjes07@gmail.com> | 2024-12-04 20:11:02 +0100 | 
| commit | d76ab0bf77d0a61712dc25bbe1760995be4c4782 (patch) | |
| tree | f71073322d52d6341ed46068e2c63fab8bb6f942 /src | |
| parent | 322e9a8ceaa8b2ce5d3e6056be4a9739817d47cf (diff) | |
make format
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/Collider.cpp | 2 | ||||
| -rw-r--r-- | src/crepe/Collider.h | 2 | ||||
| -rw-r--r-- | src/crepe/api/BoxCollider.cpp | 7 | ||||
| -rw-r--r-- | src/crepe/api/BoxCollider.h | 6 | ||||
| -rw-r--r-- | src/crepe/api/CircleCollider.cpp | 6 | ||||
| -rw-r--r-- | src/crepe/api/CircleCollider.h | 3 | ||||
| -rw-r--r-- | src/crepe/api/Event.h | 4 | ||||
| -rw-r--r-- | src/crepe/api/LoopManager.cpp | 3 | ||||
| -rw-r--r-- | src/crepe/api/Rigidbody.cpp | 4 | ||||
| -rw-r--r-- | src/crepe/api/Rigidbody.h | 4 | ||||
| -rw-r--r-- | src/crepe/system/CollisionSystem.cpp | 514 | ||||
| -rw-r--r-- | src/crepe/system/CollisionSystem.h | 121 | ||||
| -rw-r--r-- | src/crepe/system/PhysicsSystem.cpp | 9 | ||||
| -rw-r--r-- | src/example/game.cpp | 97 | ||||
| -rw-r--r-- | src/test/CollisionTest.cpp | 122 | ||||
| -rw-r--r-- | src/test/Profiling.cpp | 121 | 
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);  |