aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/crepe/api/Config.h2
-rw-r--r--src/crepe/api/Rigidbody.h2
-rw-r--r--src/crepe/system/AISystem.cpp8
-rw-r--r--src/crepe/system/CollisionSystem.cpp4
-rw-r--r--src/crepe/system/PhysicsSystem.cpp53
-rw-r--r--src/example/AITest.cpp24
-rw-r--r--src/example/game.cpp45
-rw-r--r--src/test/PhysicsTest.cpp40
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);
}