diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/api/Config.h | 2 | ||||
| -rw-r--r-- | src/crepe/api/Rigidbody.h | 2 | ||||
| -rw-r--r-- | src/crepe/system/AISystem.cpp | 8 | ||||
| -rw-r--r-- | src/crepe/system/CollisionSystem.cpp | 4 | ||||
| -rw-r--r-- | src/crepe/system/PhysicsSystem.cpp | 53 | ||||
| -rw-r--r-- | src/example/AITest.cpp | 24 | ||||
| -rw-r--r-- | src/example/game.cpp | 45 | ||||
| -rw-r--r-- | src/test/PhysicsTest.cpp | 40 | 
8 files changed, 105 insertions, 73 deletions
| diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h index cd27343..ca2d3f1 100644 --- a/src/crepe/api/Config.h +++ b/src/crepe/api/Config.h @@ -53,7 +53,7 @@ struct Config final {  		 *  		 * Gravity value of game.  		 */ -		float gravity = 1; +		float gravity = 10;  	} physics;  	//! default window settings diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index f641fff..b08c8db 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -53,7 +53,7 @@ public:  	 */  	struct Data {  		//! objects mass -		float mass = 0.0; +		float mass = 1;  		/**  		* \brief Gravity scale factor.  		* diff --git a/src/crepe/system/AISystem.cpp b/src/crepe/system/AISystem.cpp index 1d8ffb9..6578ecb 100644 --- a/src/crepe/system/AISystem.cpp +++ b/src/crepe/system/AISystem.cpp @@ -13,12 +13,10 @@ using namespace std::chrono;  void AISystem::update() {  	const Mediator & mediator = this->mediator;  	ComponentManager & mgr = mediator.component_manager; -	LoopTimerManager & timer = mediator.loop_timer; -	RefVector<AI> ai_components = mgr.get_components_by_type<AI>();  	LoopTimerManager & loop_timer = mediator.loop_timer; +	RefVector<AI> ai_components = mgr.get_components_by_type<AI>(); -	//TODO: Use fixed loop dt (this is not available at master at the moment) -	duration_t dt = loop_timer.get_delta_time(); +	duration_t dt = loop_timer.get_scaled_fixed_delta_time();  	// Loop through all AI components  	for (AI & ai : ai_components) { @@ -45,7 +43,7 @@ void AISystem::update() {  		// Calculate the acceleration (using the above calculated force)  		vec2 acceleration = force / rigidbody.data.mass;  		// Finally, update Rigidbody's velocity -		rigidbody.data.linear_velocity += acceleration * duration_cast<seconds>(dt).count(); +		rigidbody.data.linear_velocity += acceleration * duration<float>(dt).count();  	}  } diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index dc5270e..0483693 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -290,10 +290,6 @@ vec2 CollisionSystem::get_circle_box_resolution(const CircleCollider & circle_co  	// Compute penetration depth  	float penetration_depth = circle_collider.radius - distance; -<<<<<<< HEAD -======= - ->>>>>>> 05a33d4793520fa84a93bc79882ef29d39cd08e5  	// Compute the resolution vector  	vec2 resolution = collision_normal * penetration_depth; diff --git a/src/crepe/system/PhysicsSystem.cpp b/src/crepe/system/PhysicsSystem.cpp index be768f9..a1d35bb 100644 --- a/src/crepe/system/PhysicsSystem.cpp +++ b/src/crepe/system/PhysicsSystem.cpp @@ -5,65 +5,78 @@  #include "../api/Transform.h"  #include "../api/Vector2.h"  #include "../manager/ComponentManager.h" +#include "../manager/LoopTimerManager.h" +#include "../manager/Mediator.h"  #include "PhysicsSystem.h"  using namespace crepe; +using namespace std::chrono;  void PhysicsSystem::update() { -	double dt = LoopTimer::get_instance().get_fixed_delta_time(); -	ComponentManager & mgr = this->mediator.component_manager; + +	const Mediator & mediator = this->mediator; +	ComponentManager & mgr = mediator.component_manager; +	LoopTimerManager & loop_timer = mediator.loop_timer;  	RefVector<Rigidbody> rigidbodies = mgr.get_components_by_type<Rigidbody>(); -	 + +	duration_t delta_time = loop_timer.get_scaled_fixed_delta_time(); +	float dt = duration<float>(delta_time).count();  	float gravity = Config::get_instance().physics.gravity;  	for (Rigidbody & rigidbody : rigidbodies) {  		if (!rigidbody.active) continue; -		Transform & transform = mgr.get_components_by_id<Transform>(rigidbody.game_object_id).front().get(); +		Transform & transform +			= mgr.get_components_by_id<Transform>(rigidbody.game_object_id).front().get();  		switch (rigidbody.data.body_type) {  			case Rigidbody::BodyType::DYNAMIC:  				if (transform.game_object_id == rigidbody.game_object_id) {  					// Add gravity + +					if (rigidbody.data.mass <= 0) { +						throw std::runtime_error("Mass must be greater than 0"); +					} + +					if (gravity <= 0) { +						throw std::runtime_error("Config Gravity must be greater than 0"); +					} +  					if (rigidbody.data.gravity_scale > 0) {  						rigidbody.data.linear_velocity.y -							+= (rigidbody.data.mass * rigidbody.data.gravity_scale -								* gravity * dt); +							+= (rigidbody.data.mass * rigidbody.data.gravity_scale * gravity +								* dt);  					}  					// Add coefficient rotation  					if (rigidbody.data.angular_velocity_coefficient > 0) {  						rigidbody.data.angular_velocity  							*= std::pow(rigidbody.data.angular_velocity_coefficient, dt); -							  					}  					// Add coefficient movement horizontal -					if (rigidbody.data.linear_velocity_coefficient.x > 0) -					{ +					if (rigidbody.data.linear_velocity_coefficient.x > 0) {  						rigidbody.data.linear_velocity.x -								*= std::pow(rigidbody.data.linear_velocity_coefficient.x, dt); +							*= std::pow(rigidbody.data.linear_velocity_coefficient.x, dt);  					}  					// Add coefficient movement horizontal -					if (rigidbody.data.linear_velocity_coefficient.y > 0) -					{ +					if (rigidbody.data.linear_velocity_coefficient.y > 0) {  						rigidbody.data.linear_velocity.y -								*= std::pow(rigidbody.data.linear_velocity_coefficient.y, dt); +							*= std::pow(rigidbody.data.linear_velocity_coefficient.y, dt);  					}  					// Max velocity check  					if (rigidbody.data.angular_velocity  						> rigidbody.data.max_angular_velocity) { -						rigidbody.data.angular_velocity -							= rigidbody.data.max_angular_velocity; +						rigidbody.data.angular_velocity = rigidbody.data.max_angular_velocity;  					} else if (rigidbody.data.angular_velocity -									< -rigidbody.data.max_angular_velocity) { -						rigidbody.data.angular_velocity -							= -rigidbody.data.max_angular_velocity; +							   < -rigidbody.data.max_angular_velocity) { +						rigidbody.data.angular_velocity = -rigidbody.data.max_angular_velocity;  					} -					 +  					// Set max velocity to maximum length -					if(rigidbody.data.linear_velocity.length() > rigidbody.data.max_linear_velocity) { +					if (rigidbody.data.linear_velocity.length() +						> rigidbody.data.max_linear_velocity) {  						rigidbody.data.linear_velocity.normalize();  						rigidbody.data.linear_velocity *= rigidbody.data.max_linear_velocity;  					} diff --git a/src/example/AITest.cpp b/src/example/AITest.cpp index f4efc9f..93ba500 100644 --- a/src/example/AITest.cpp +++ b/src/example/AITest.cpp @@ -8,7 +8,6 @@  #include <crepe/api/Scene.h>  #include <crepe/api/Script.h>  #include <crepe/api/Sprite.h> -#include <crepe/api/Texture.h>  #include <crepe/manager/Mediator.h>  #include <crepe/types.h> @@ -47,14 +46,19 @@ public:  		GameObject game_object1 = mgr.new_object("", "", vec2{0, 0}, 0, 1);  		GameObject game_object2 = mgr.new_object("", "", vec2{0, 0}, 0, 1); -		Texture img = Texture("asset/texture/test_ap43.png"); -		game_object1.add_component<Sprite>(img, Sprite::Data{ -													.color = Color::MAGENTA, -													.flip = Sprite::FlipSettings{false, false}, -													.sorting_in_layer = 1, -													.order_in_layer = 1, -													.size = {0, 195}, -												}); +		Asset img{"asset/texture/test_ap43.png"}; + +		Sprite & test_sprite = game_object1.add_component<Sprite>( +			img, Sprite::Data{ +					 .color = Color::MAGENTA, +					 .flip = Sprite::FlipSettings{false, false}, +					 .sorting_in_layer = 2, +					 .order_in_layer = 2, +					 .size = {0, 100}, +					 .angle_offset = 0, +					 .position_offset = {0, 0}, +				 }); +  		AI & ai = game_object1.add_component<AI>(3000);  		// ai.arrive_on();  		// ai.flee_on(); @@ -63,7 +67,7 @@ public:  		ai.make_oval_path(1000, 500, {0, 500}, 4.7124, false);  		game_object1.add_component<Rigidbody>(Rigidbody::Data{  			.mass = 0.1f, -			.max_linear_velocity = {40, 40}, +			.max_linear_velocity = 40,  		});  		game_object1.add_component<BehaviorScript>().set_script<Script1>(); diff --git a/src/example/game.cpp b/src/example/game.cpp index 4239c15..5361f3a 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -2,6 +2,7 @@  #include "api/Scene.h"  #include "manager/ComponentManager.h"  #include "manager/Mediator.h" +#include "types.h"  #include <crepe/api/BoxCollider.h>  #include <crepe/api/Camera.h>  #include <crepe/api/Color.h> @@ -11,7 +12,6 @@  #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> @@ -66,6 +66,11 @@ 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;  		} @@ -184,15 +189,18 @@ public:  		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{static_cast<int>(screen_size_width), static_cast<int>(screen_size_height)}, -			vec2{screen_size_width, screen_size_height}, 1.0f); +			vec2{screen_size_width, screen_size_height}, +			Camera::Data{ +				.bg_color = Color::WHITE, +				.zoom = 1, +			});  		GameObject game_object1 = mgr.new_object(  			"Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 0, 1);  		game_object1.add_component<Rigidbody>(Rigidbody::Data{  			.mass = 1, -			.gravity_scale = 0, +			.gravity_scale = 1,  			.body_type = Rigidbody::BodyType::DYNAMIC,  			.linear_velocity = {0, 0},  			.constraints = {0, 0, 0}, @@ -203,15 +211,20 @@ public:  		// add box with boxcollider  		game_object1.add_component<BoxCollider>(vec2{0, 0}, vec2{20, 20});  		game_object1.add_component<BehaviorScript>().set_script<MyScript1>(); -		auto img1 = Texture("asset/texture/square.png"); -		game_object1.add_component<Sprite>(img1, color, Sprite::FlipSettings{false, false}, 1, -										   1, 20); + +		Asset img1{"asset/texture/square.png"}; +		game_object1.add_component<Sprite>(img1, Sprite::Data{ +													 .size = {20, 20}, +												 });  		//add circle with cirlcecollider deactiveated  		game_object1.add_component<CircleCollider>(vec2{0, 0}, 10).active = false; -		auto img2 = Texture("asset/texture/circle.png"); +		Asset img2{"asset/texture/circle.png"};  		game_object1 -			.add_component<Sprite>(img2, color, Sprite::FlipSettings{false, false}, 1, 1, 20) +			.add_component<Sprite>(img2, +								   Sprite::Data{ +									   .size = {20, 20}, +								   })  			.active  			= false; @@ -230,15 +243,19 @@ public:  		// add box with boxcollider  		game_object2.add_component<BoxCollider>(vec2{0, 0}, vec2{20, 20});  		game_object2.add_component<BehaviorScript>().set_script<MyScript2>(); -		auto img3 = Texture("asset/texture/square.png"); -		game_object2.add_component<Sprite>(img3, color, Sprite::FlipSettings{false, false}, 1, -										   1, 20); + +		game_object2.add_component<Sprite>(img1, Sprite::Data{ +													 .size = {20, 20}, +												 });  		//add circle with cirlcecollider deactiveated  		game_object2.add_component<CircleCollider>(vec2{0, 0}, 10).active = false; -		auto img4 = Texture("asset/texture/circle.png"); +  		game_object2 -			.add_component<Sprite>(img4, color, Sprite::FlipSettings{false, false}, 1, 1, 20) +			.add_component<Sprite>(img2, +								   Sprite::Data{ +									   .size = {20, 20}, +								   })  			.active  			= false;  	} diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp index 4af34f5..c04e3ff 100644 --- a/src/test/PhysicsTest.cpp +++ b/src/test/PhysicsTest.cpp @@ -3,6 +3,8 @@  #include <crepe/api/Rigidbody.h>  #include <crepe/api/Transform.h>  #include <crepe/manager/ComponentManager.h> +#include <crepe/manager/LoopTimerManager.h> +#include <crepe/manager/Mediator.h>  #include <crepe/system/PhysicsSystem.h>  #include <gtest/gtest.h> @@ -16,6 +18,7 @@ class PhysicsTest : public ::testing::Test {  public:  	ComponentManager component_manager{m};  	PhysicsSystem system{m}; +	LoopTimerManager loop_timer{m};  	void SetUp() override {  		ComponentManager & mgr = this->component_manager; @@ -55,39 +58,40 @@ TEST_F(PhysicsTest, gravity) {  	EXPECT_EQ(transform.position.y, 0);  	system.update(); -	EXPECT_EQ(transform.position.y, 1); +	EXPECT_NEAR(transform.position.y, 0.0004, 0.0001);  	system.update(); -	EXPECT_EQ(transform.position.y, 3); +	EXPECT_NEAR(transform.position.y, 0.002, 0.001);  }  TEST_F(PhysicsTest, max_velocity) {  	ComponentManager & mgr = this->component_manager;  	vector<reference_wrapper<Rigidbody>> rigidbodies = mgr.get_components_by_id<Rigidbody>(0);  	Rigidbody & rigidbody = rigidbodies.front().get(); +	rigidbody.data.gravity_scale = 0;  	ASSERT_FALSE(rigidbodies.empty());  	EXPECT_EQ(rigidbody.data.linear_velocity.y, 0);  	rigidbody.add_force_linear({100, 100});  	rigidbody.add_force_angular(100);  	system.update(); -	EXPECT_EQ(rigidbody.data.linear_velocity.y, 10); -	EXPECT_EQ(rigidbody.data.linear_velocity.x, 10); +	EXPECT_NEAR(rigidbody.data.linear_velocity.y, 7.07, 0.01); +	EXPECT_NEAR(rigidbody.data.linear_velocity.x, 7.07, 0.01);  	EXPECT_EQ(rigidbody.data.angular_velocity, 10);  	rigidbody.add_force_linear({-100, -100});  	rigidbody.add_force_angular(-100);  	system.update(); -	EXPECT_EQ(rigidbody.data.linear_velocity.y, -10); -	EXPECT_EQ(rigidbody.data.linear_velocity.x, -10); +	EXPECT_NEAR(rigidbody.data.linear_velocity.y, -7.07, 0.01); +	EXPECT_NEAR(rigidbody.data.linear_velocity.x, -7.07, 0.01);  	EXPECT_EQ(rigidbody.data.angular_velocity, -10);  }  TEST_F(PhysicsTest, movement) { -	Config::get_instance().physics.gravity = 0;  	ComponentManager & mgr = this->component_manager;  	vector<reference_wrapper<Rigidbody>> rigidbodies = mgr.get_components_by_id<Rigidbody>(0);  	Rigidbody & rigidbody = rigidbodies.front().get(); +	rigidbody.data.gravity_scale = 0;  	vector<reference_wrapper<Transform>> transforms = mgr.get_components_by_id<Transform>(0);  	const Transform & transform = transforms.front().get();  	ASSERT_FALSE(rigidbodies.empty()); @@ -96,31 +100,31 @@ TEST_F(PhysicsTest, movement) {  	rigidbody.add_force_linear({1, 1});  	rigidbody.add_force_angular(1);  	system.update(); -	EXPECT_EQ(transform.position.x, 1); -	EXPECT_EQ(transform.position.y, 1); -	EXPECT_EQ(transform.rotation, 1); +	EXPECT_NEAR(transform.position.x, 0.02, 0.001); +	EXPECT_NEAR(transform.position.y, 0.02, 0.001); +	EXPECT_NEAR(transform.rotation, 0.02, 0.001);  	rigidbody.data.constraints = {1, 1, 1}; -	EXPECT_EQ(transform.position.x, 1); -	EXPECT_EQ(transform.position.y, 1); -	EXPECT_EQ(transform.rotation, 1); +	EXPECT_NEAR(transform.position.x, 0.02, 0.001); +	EXPECT_NEAR(transform.position.y, 0.02, 0.001); +	EXPECT_NEAR(transform.rotation, 0.02, 0.001);  	rigidbody.data.linear_velocity_coefficient.x = 0.5;  	rigidbody.data.linear_velocity_coefficient.y = 0.5;  	rigidbody.data.angular_velocity_coefficient = 0.5;  	system.update(); -	EXPECT_EQ(rigidbody.data.linear_velocity.x, 0.5); -	EXPECT_EQ(rigidbody.data.linear_velocity.y, 0.5); -	EXPECT_EQ(rigidbody.data.angular_velocity, 0.5); +	EXPECT_NEAR(rigidbody.data.linear_velocity.x, 0.98, 0.01); +	EXPECT_NEAR(rigidbody.data.linear_velocity.y, 0.98, 0.01); +	EXPECT_NEAR(rigidbody.data.angular_velocity, 0.98, 0.01);  	rigidbody.data.constraints = {1, 1, 0};  	rigidbody.data.angular_velocity_coefficient = 0;  	rigidbody.data.max_angular_velocity = 1000;  	rigidbody.data.angular_velocity = 360;  	system.update(); -	EXPECT_EQ(transform.rotation, 1); +	EXPECT_NEAR(transform.rotation, 7.22, 0.0001);  	rigidbody.data.angular_velocity = -360;  	system.update(); -	EXPECT_EQ(transform.rotation, 1); +	EXPECT_NEAR(transform.rotation, 0.02, 0.001);  } |