diff options
Diffstat (limited to 'src/crepe/system/PhysicsSystem.cpp')
-rw-r--r-- | src/crepe/system/PhysicsSystem.cpp | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/crepe/system/PhysicsSystem.cpp b/src/crepe/system/PhysicsSystem.cpp new file mode 100644 index 0000000..62f8132 --- /dev/null +++ b/src/crepe/system/PhysicsSystem.cpp @@ -0,0 +1,106 @@ +#include <cmath> + +#include "../api/Config.h" +#include "../api/Rigidbody.h" +#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; + +void PhysicsSystem::fixed_update() { + 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>(); + float dt = loop_timer.get_scaled_fixed_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(); + + 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.constraints.y) { + rigidbody.data.linear_velocity.y + += (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 + && !rigidbody.data.constraints.x) { + rigidbody.data.linear_velocity.x + *= std::pow(rigidbody.data.linear_velocity_coefficient.x, dt); + } + + // Add coefficient movement horizontal + if (rigidbody.data.linear_velocity_coefficient.y > 0 + && !rigidbody.data.constraints.y) { + rigidbody.data.linear_velocity.y + *= 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; + } else if (rigidbody.data.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) { + rigidbody.data.linear_velocity.normalize(); + rigidbody.data.linear_velocity *= rigidbody.data.max_linear_velocity; + } + + // Move object + if (!rigidbody.data.constraints.rotation) { + transform.rotation += rigidbody.data.angular_velocity * dt; + transform.rotation = std::fmod(transform.rotation, 360.0); + if (transform.rotation < 0) { + transform.rotation += 360.0; + } + } + if (!rigidbody.data.constraints.x) { + transform.position.x += rigidbody.data.linear_velocity.x * dt; + } + if (!rigidbody.data.constraints.y) { + transform.position.y += rigidbody.data.linear_velocity.y * dt; + } + } + break; + case Rigidbody::BodyType::KINEMATIC: + break; //(scripts) + case Rigidbody::BodyType::STATIC: + break; //(unmoveable objects) + default: + break; + } + } +} |