diff options
| -rw-r--r-- | src/crepe/facade/SDLContext.cpp | 2 | ||||
| -rw-r--r-- | src/crepe/system/CollisionSystem.cpp | 79 | ||||
| -rw-r--r-- | src/crepe/system/CollisionSystem.h | 2 | ||||
| -rw-r--r-- | src/crepe/system/RenderSystem.cpp | 5 | ||||
| -rw-r--r-- | src/crepe/util/AbsoluutPosition.cpp | 21 | ||||
| -rw-r--r-- | src/crepe/util/AbsoluutPosition.h | 17 | ||||
| -rw-r--r-- | src/crepe/util/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/example/game.cpp | 53 | ||||
| -rw-r--r-- | src/test/CollisionTest.cpp | 20 | 
9 files changed, 123 insertions, 78 deletions
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 20bb030..ee7d149 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -235,7 +235,7 @@ SDL_FRect SDLContext::get_dst_rect(const DestinationRectangleData & ctx) const {  	}  	size *= cam_aux_data.render_scale * ctx.img_scale * data.scale_offset; -	vec2 screen_pos = (ctx.pos + data.position_offset - cam_aux_data.cam_pos +	vec2 screen_pos = (ctx.pos - cam_aux_data.cam_pos  					   + (cam_aux_data.zoomed_viewport) / 2)  						  * cam_aux_data.render_scale  					  - size / 2 + cam_aux_data.bar_size; diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index fc8c430..294e7b3 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -15,31 +15,15 @@  #include "api/Rigidbody.h"  #include "api/Transform.h"  #include "api/Vector2.h" +#include "util/OptionalRef.h" +#include "util/AbsoluutPosition.h"  #include "Collider.h"  #include "CollisionSystem.h"  #include "types.h" -#include "util/OptionalRef.h"  using namespace crepe; -vec2 get_current_position(const Transform & transform,const vec2 & offset) { -	// Get the rotation in radians -	float radians1 = transform.rotation * (M_PI / 180.0); - -	// Calculate total offset with scale -	vec2 total_offset = 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); - -	// Final positions considering scaling and rotation -	return (transform.position + vec2(rotated_total_offset_x1, rotated_total_offset_y1)); -} -  void CollisionSystem::update() {  	std::vector<CollisionInternal> all_colliders;  	game_object_id_t id = 0; @@ -155,8 +139,9 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal  				= std::get<std::reference_wrapper<BoxCollider>>(data1.collider);  			const BoxCollider & collider2  				= std::get<std::reference_wrapper<BoxCollider>>(data2.collider); -			vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); -			vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); +			 +			vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); +			vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset);  			resolution = this->get_box_box_resolution(collider1, collider2, collider_pos1,  													  collider_pos2);  			break; @@ -166,8 +151,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal  				= std::get<std::reference_wrapper<BoxCollider>>(data1.collider);  			const CircleCollider & collider2  				= std::get<std::reference_wrapper<CircleCollider>>(data2.collider); -			vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); -			vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); +			vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); +			vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset);  			resolution = -this->get_circle_box_resolution(collider2, collider1, collider_pos2,  														  collider_pos1);  			break; @@ -177,8 +162,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal  				= std::get<std::reference_wrapper<CircleCollider>>(data1.collider);  			const CircleCollider & collider2  				= std::get<std::reference_wrapper<CircleCollider>>(data2.collider); -			vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); -			vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); +			vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); +			vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset);  			resolution = this->get_circle_circle_resolution(collider1, collider2,  															collider_pos1, collider_pos2);  			break; @@ -188,8 +173,8 @@ CollisionSystem::collision_handler(CollisionInternal & data1, CollisionInternal  				= std::get<std::reference_wrapper<CircleCollider>>(data1.collider);  			const BoxCollider & collider2  				= std::get<std::reference_wrapper<BoxCollider>>(data2.collider); -			vec2 collider_pos1 = get_current_position(data1.transform,collider1.offset); -			vec2 collider_pos2 = get_current_position(data2.transform,collider2.offset); +			vec2 collider_pos1 = AbsoluutPosition::get_position(data1.transform,collider1.offset); +			vec2 collider_pos2 = AbsoluutPosition::get_position(data2.transform,collider2.offset);  			resolution = this->get_circle_box_resolution(collider1, collider2, collider_pos1,  														 collider_pos2);  			break; @@ -311,15 +296,7 @@ vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_co  }  void CollisionSystem::determine_collision_handler(CollisionInfo & info) { -	// If both objects are static skip handle call collision script -	if(info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; - -	//	First body is not dynamic -	if(info.this_rigidbody.data.body_type != Rigidbody::BodyType::DYNAMIC) -	{ -		bool static_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC; -		bool kinematic_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC && info.this_rigidbody.data.kinematic_collision; -		// Inverted collision info +	// Inverted collision info  		CollisionInfo inverted = {  				.this_collider = info.other_collider,  				.this_transform = info.other_transform, @@ -332,13 +309,22 @@ void CollisionSystem::determine_collision_handler(CollisionInfo & info) {  				.resolution = -info.resolution,  				.resolution_direction = info.resolution_direction,  				}; +	// If both objects are static skip handle call collision script +	if(info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return; + +	//	First body is not dynamic +	if(info.this_rigidbody.data.body_type != Rigidbody::BodyType::DYNAMIC) +	{ +		bool static_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::STATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC; +		bool kinematic_collision = info.this_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC && info.other_rigidbody.data.body_type == Rigidbody::BodyType::DYNAMIC && info.this_rigidbody.data.kinematic_collision; +		  		if(static_collision || kinematic_collision){  			// Static collision  			this->static_collision_handler(inverted);  		};  		// Call scripts -		this->call_collision_events(inverted); +		this->call_collision_events(inverted,info);  		return;  	} @@ -348,20 +334,21 @@ void CollisionSystem::determine_collision_handler(CollisionInfo & info) {  		bool static_collision = info.other_rigidbody.data.body_type == Rigidbody::BodyType::STATIC;  		bool kinematic_collision = info.other_rigidbody.data.body_type == Rigidbody::BodyType::KINEMATIC && info.other_rigidbody.data.kinematic_collision;  		if(static_collision || kinematic_collision)	this->static_collision_handler(info); -		this->call_collision_events(info); +		this->call_collision_events(info,inverted);  		return;  	}  	//dynamic  	this->dynamic_collision_handler(info); -	this->call_collision_events(info); +	this->call_collision_events(info,inverted);  } -void CollisionSystem::call_collision_events(CollisionInfo & info){ +void CollisionSystem::call_collision_events(CollisionInfo & info,CollisionInfo & info_inverted){  	CollisionEvent data(info); +	CollisionEvent data_inverted(info_inverted);  	EventManager & emgr = this->mediator.event_manager;  	emgr.trigger_event<CollisionEvent>(data, info.this_collider.game_object_id); -	emgr.trigger_event<CollisionEvent>(data, info.other_collider.game_object_id); +	emgr.trigger_event<CollisionEvent>(data_inverted, info_inverted.this_collider.game_object_id);  }  void CollisionSystem::static_collision_handler(CollisionInfo & info) { @@ -615,8 +602,8 @@ bool CollisionSystem::get_box_box_collision(const BoxCollider & box1, const BoxC  											const Rigidbody & rigidbody1,  											const Rigidbody & rigidbody2) const {  	// Get current positions of colliders -	vec2 final_position1 = get_current_position(transform1,box1.offset); -	vec2 final_position2 = get_current_position(transform2,box2.offset); +	vec2 final_position1 = AbsoluutPosition::get_position(transform1,box1.offset); +	vec2 final_position2 = AbsoluutPosition::get_position(transform2,box2.offset);  	// Scale dimensions  	vec2 scaled_box1 = box1.dimensions * transform1.scale; @@ -642,8 +629,8 @@ bool CollisionSystem::get_box_circle_collision(const BoxCollider & box1,  											   const Rigidbody & rigidbody1,  											   const Rigidbody & rigidbody2) const {  	// Get current positions of colliders -	vec2 final_position1 = get_current_position(transform1,box1.offset); -	vec2 final_position2 = get_current_position(transform2,circle2.offset); +	vec2 final_position1 = AbsoluutPosition::get_position(transform1,box1.offset); +	vec2 final_position2 = AbsoluutPosition::get_position(transform2,circle2.offset);  	// Scale dimensions  	vec2 scaled_box = box1.dimensions * transform1.scale; @@ -675,8 +662,8 @@ bool CollisionSystem::get_circle_circle_collision(const CircleCollider & circle1  												  const Rigidbody & rigidbody1,  												  const Rigidbody & rigidbody2) const {  	// Get current positions of colliders -	vec2 final_position1 = get_current_position(transform1,circle1.offset); -	vec2 final_position2 = get_current_position(transform2,circle2.offset); +	vec2 final_position1 = AbsoluutPosition::get_position(transform1,circle1.offset); +	vec2 final_position2 = AbsoluutPosition::get_position(transform2,circle2.offset);  	// Scale dimensions  	float scaled_circle1 = circle1.radius * transform1.scale; diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 78fce46..b802426 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -188,7 +188,7 @@ private:  		*  		* \param info Collision information containing data about both colliders.  		*/ -	void call_collision_events(CollisionInfo & info); +	void call_collision_events(CollisionInfo & info,CollisionInfo & info_inverted);  	/**  		* \brief Handles collisions involving static objects. diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index afd9548..d14d78d 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -13,6 +13,7 @@  #include "../facade/Texture.h"  #include "../manager/ComponentManager.h"  #include "../manager/ResourceManager.h" +#include "util/AbsoluutPosition.h"  #include "RenderSystem.h"  #include "types.h" @@ -105,11 +106,11 @@ void RenderSystem::render_normal(const Sprite & sprite, const Transform & tm) {  	SDLContext & ctx = this->mediator.sdl_context;  	ResourceManager & resource_manager = this->mediator.resource_manager;  	const Texture & res = resource_manager.get<Texture>(sprite.source); - +	vec2 pos = AbsoluutPosition::get_position(tm,sprite.data.position_offset);  	ctx.draw(SDLContext::RenderContext{  		.sprite = sprite,  		.texture = res, -		.pos = tm.position, +		.pos = pos,  		.angle = tm.rotation,  		.scale = tm.scale,  	}); diff --git a/src/crepe/util/AbsoluutPosition.cpp b/src/crepe/util/AbsoluutPosition.cpp new file mode 100644 index 0000000..8be625e --- /dev/null +++ b/src/crepe/util/AbsoluutPosition.cpp @@ -0,0 +1,21 @@ +#include "AbsoluutPosition.h" + +using namespace crepe; + +vec2 AbsoluutPosition::get_position(const Transform & transform,const vec2 & offset) { +	// Get the rotation in radians +	float radians1 = transform.rotation * (M_PI / 180.0); + +	// Calculate total offset with scale +	vec2 total_offset = 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); + +	// Final positions considering scaling and rotation +	return (transform.position + vec2(rotated_total_offset_x1, rotated_total_offset_y1)); +} + diff --git a/src/crepe/util/AbsoluutPosition.h b/src/crepe/util/AbsoluutPosition.h new file mode 100644 index 0000000..4441f90 --- /dev/null +++ b/src/crepe/util/AbsoluutPosition.h @@ -0,0 +1,17 @@ +#pragma once + + +#include "api/Transform.h" + +#include "types.h" + +namespace crepe { + + +class AbsoluutPosition { +public: +	static vec2 get_position(const Transform & transform,const vec2 & offset); + +}; + +} // namespace crepe diff --git a/src/crepe/util/CMakeLists.txt b/src/crepe/util/CMakeLists.txt index 94ed906..b4b9221 100644 --- a/src/crepe/util/CMakeLists.txt +++ b/src/crepe/util/CMakeLists.txt @@ -1,6 +1,7 @@  target_sources(crepe PUBLIC  	LogColor.cpp  	Log.cpp +	AbsoluutPosition.cpp  )  target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -11,5 +12,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES  	Proxy.hpp  	OptionalRef.h  	OptionalRef.hpp +	AbsoluutPosition.h  ) diff --git a/src/example/game.cpp b/src/example/game.cpp index 8ea50ea..3ba15d2 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -3,6 +3,7 @@  #include "manager/ComponentManager.h"  #include "manager/Mediator.h"  #include "types.h" +#include <cmath>  #include <crepe/api/BoxCollider.h>  #include <crepe/api/Camera.h>  #include <crepe/api/Color.h> @@ -66,11 +67,6 @@ class MyScript1 : public Script {  				//add collider switch  				break;  			} -			case Keycode::Q: { -				Rigidbody & rg = this->get_component<Rigidbody>(); -				rg.data.angular_velocity = 1; -				break; -			}  			default:  				break;  		} @@ -139,6 +135,31 @@ class MyScript2 : public Script {  				//add collider switch  				break;  			} +			case Keycode::J: { +				Rigidbody & tf = this->get_component<Rigidbody>(); +				tf.data.linear_velocity.x = -10; +				break; +			} +			case Keycode::I: { +				Rigidbody & tf = this->get_component<Rigidbody>(); +				tf.data.linear_velocity.y -= 1; +				break; +			} +			case Keycode::K: { +				Rigidbody & tf = this->get_component<Rigidbody>(); +				tf.data.linear_velocity.y += 1; +				break; +			} +			case Keycode::L: { +				Rigidbody & tf = this->get_component<Rigidbody>(); +				tf.data.linear_velocity.x = 10; +				break; +			} +			case Keycode::O: { +				Rigidbody & tf = this->get_component<Rigidbody>(); +				tf.data.linear_velocity.x = 0; +				break; +			}  			default:  				break;  		} @@ -175,7 +196,6 @@ public:  			.mass = 0,  			.gravity_scale = 0,  			.body_type = Rigidbody::BodyType::STATIC, -			.offset = {0, 0},  			.collision_layers = {0},  		});  		world.add_component<BoxCollider>( @@ -198,24 +218,26 @@ public:  			});  		GameObject game_object1 = new_object( -			"Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1); +			"Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 45, 1);  		game_object1.add_component<Rigidbody>(Rigidbody::Data{  			.mass = 1, -			.gravity_scale = 1, -			.body_type = Rigidbody::BodyType::DYNAMIC, +			.gravity_scale = 0, +			.body_type = Rigidbody::BodyType::KINEMATIC,  			.linear_velocity = {0, 1},  			.constraints = {0, 0, 0},  			.elastisity_coefficient = 1, -			.offset = {0, 0},  			.collision_layers = {0},  		});  		// add box with boxcollider  		game_object1.add_component<BoxCollider>(vec2{0, 0}, vec2{20, 20});  		game_object1.add_component<BehaviorScript>().set_script<MyScript1>(); -		Asset img1{"asset/texture/square.png"}; +		Asset img1{"asset/texture/test_ap43.png"};  		game_object1.add_component<Sprite>(img1, Sprite::Data{ +													 .sorting_in_layer = 2, +													 .order_in_layer = 2,  													 .size = {20, 20}, +													 .position_offset = {0,-10},  												 });  		//add circle with cirlcecollider deactiveated @@ -233,16 +255,15 @@ public:  			"Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1);  		game_object2.add_component<Rigidbody>(Rigidbody::Data{  			.mass = 1, -			.gravity_scale = 0, -			.body_type = Rigidbody::BodyType::STATIC, +			.gravity_scale = 1, +			.body_type = Rigidbody::BodyType::KINEMATIC,  			.linear_velocity = {0, 0},  			.constraints = {0, 0, 0}, -			.elastisity_coefficient = 1, -			.offset = {0, 0}, +			.elastisity_coefficient = 0.66,  			.collision_layers = {0},  		});  		// add box with boxcollider -		game_object2.add_component<BoxCollider>(vec2{0, 0}, vec2{20, 20}); +		game_object2.add_component<BoxCollider>(vec2{0, 0}, vec2{INFINITY, 20});  		game_object2.add_component<BehaviorScript>().set_script<MyScript2>();  		game_object2.add_component<Sprite>(img1, Sprite::Data{ diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index 2ad65fa..43bf77d 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -66,7 +66,6 @@ public:  		world.add_component<Rigidbody>(Rigidbody::Data{  			// TODO: remove unrelated properties:  			.body_type = Rigidbody::BodyType::STATIC, -			.offset = {0, 0},  		});  		// Create a box with an inner size of 10x10 units  		world.add_component<BoxCollider>(vec2{0, -100}, vec2{100, 100}); // Top @@ -81,7 +80,6 @@ public:  			.linear_velocity = {0, 0},  			.constraints = {0, 0, 0},  			.elastisity_coefficient = 1, -			.offset = {0, 0},  			.collision_layers = {0},  		});  		game_object1.add_component<BoxCollider>(vec2{0, 0}, vec2{10, 10}); @@ -97,7 +95,6 @@ public:  			.linear_velocity = {0, 0},  			.constraints = {0, 0, 0},  			.elastisity_coefficient = 1, -			.offset = {0, 0},  			.collision_layers = {0},  		});  		game_object2.add_component<BoxCollider>(vec2{0, 0}, vec2{10, 10}); @@ -138,8 +135,8 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both_no_velocity) {  	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, 10); -		EXPECT_EQ(ev.info.resolution.y, 10); +		EXPECT_EQ(ev.info.resolution.x, -10); +		EXPECT_EQ(ev.info.resolution.y, -10);  		EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH);  	};  	EXPECT_FALSE(collision_happend); @@ -211,8 +208,8 @@ TEST_F(CollisionTest, collision_box_box_dynamic_both) {  	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, 10); -		EXPECT_EQ(ev.info.resolution.y, 10); +		EXPECT_EQ(ev.info.resolution.x, -10); +		EXPECT_EQ(ev.info.resolution.y, -10);  		EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH);  	};  	EXPECT_FALSE(collision_happend); @@ -294,8 +291,7 @@ TEST_F(CollisionTest, collision_box_box_static_both) {  		EXPECT_EQ(ev.info.resolution_direction, crepe::CollisionSystem::Direction::BOTH);  	};  	script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) { -		// is static should not be called -		FAIL(); +		collision_happend = true;  	};  	EXPECT_FALSE(collision_happend);  	Transform & tf = this->mgr.get_components_by_id<Transform>(1).front().get(); @@ -318,7 +314,7 @@ TEST_F(CollisionTest, collision_box_box_static_x_direction) {  	};  	script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) {  		// is static should not be called -		FAIL(); +		//FAIL();  	};  	EXPECT_FALSE(collision_happend);  	Transform & tf = this->mgr.get_components_by_id<Transform>(1).front().get(); @@ -343,7 +339,7 @@ TEST_F(CollisionTest, collision_box_box_static_y_direction) {  	};  	script_object2_ref->test_fn = [&collision_happend](const CollisionEvent & ev) {  		// is static should not be called -		FAIL(); +		//FAIL();  	};  	EXPECT_FALSE(collision_happend);  	Transform & tf = this->mgr.get_components_by_id<Transform>(1).front().get(); @@ -368,7 +364,7 @@ TEST_F(CollisionTest, collision_box_box_static_multiple) { //todo check visually  	};  	script_object2_ref->test_fn = [&](const CollisionEvent & ev) {  		// is static should not be called -		FAIL(); +		//FAIL();  	};  	EXPECT_FALSE(collision_happend);  	Transform & tf = this->mgr.get_components_by_id<Transform>(1).front().get();  |