aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/crepe/Collider.cpp2
-rw-r--r--src/crepe/Collider.h6
-rw-r--r--src/crepe/api/BoxCollider.cpp7
-rw-r--r--src/crepe/api/BoxCollider.h15
-rw-r--r--src/crepe/api/CMakeLists.txt4
-rw-r--r--src/crepe/api/CircleCollider.cpp6
-rw-r--r--src/crepe/api/CircleCollider.h9
-rw-r--r--src/crepe/api/Rigidbody.h2
-rw-r--r--src/crepe/api/Vector2.cpp4
-rw-r--r--src/crepe/api/Vector2.h3
-rw-r--r--src/crepe/system/CollisionSystem.cpp275
-rw-r--r--src/crepe/system/CollisionSystem.h25
-rw-r--r--src/example/CMakeLists.txt1
-rw-r--r--src/example/collision.cpp68
-rw-r--r--src/test/CMakeLists.txt2
-rw-r--r--src/test/CollisionTest.cpp83
-rw-r--r--src/test/PhysicsTest.cpp1
17 files changed, 504 insertions, 9 deletions
diff --git a/src/crepe/Collider.cpp b/src/crepe/Collider.cpp
index bbec488..0706371 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) : Component(id) {}
+Collider::Collider(game_object_id_t id, Vector2 offset) : Component(id), offset(offset) {}
diff --git a/src/crepe/Collider.h b/src/crepe/Collider.h
index 827f83d..54695b1 100644
--- a/src/crepe/Collider.h
+++ b/src/crepe/Collider.h
@@ -1,14 +1,14 @@
#pragma once
#include "Component.h"
+#include "api/Vector2.h"
namespace crepe {
class Collider : public Component {
public:
- Collider(game_object_id_t id);
-
- int size;
+ Collider(game_object_id_t id, Vector2 offset);
+ Vector2 offset;
};
} // namespace crepe
diff --git a/src/crepe/api/BoxCollider.cpp b/src/crepe/api/BoxCollider.cpp
new file mode 100644
index 0000000..eafbdb2
--- /dev/null
+++ b/src/crepe/api/BoxCollider.cpp
@@ -0,0 +1,7 @@
+#include "BoxCollider.h"
+#include "../Collider.h"
+
+using namespace crepe;
+
+
+BoxCollider::BoxCollider(game_object_id_t game_object_id,Vector2 offset, double width, double height) : Collider(game_object_id,offset), width(width), height(height) {}
diff --git a/src/crepe/api/BoxCollider.h b/src/crepe/api/BoxCollider.h
new file mode 100644
index 0000000..357c979
--- /dev/null
+++ b/src/crepe/api/BoxCollider.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "Vector2.h"
+#include "../Collider.h"
+
+namespace crepe {
+
+class BoxCollider : public Collider {
+public:
+ BoxCollider(game_object_id_t game_object_id,Vector2 offset, double width, double height);
+ double width;
+ double height;
+};
+
+} // namespace crepe
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index 53b3041..07341e2 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -18,6 +18,8 @@ target_sources(crepe PUBLIC
Vector2.cpp
Camera.cpp
Animator.cpp
+ BoxCollider.cpp
+ CircleCollider.cpp
EventManager.cpp
EventHandler.cpp
IKeyListener.cpp
@@ -48,6 +50,8 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
SceneManager.hpp
Camera.h
Animator.h
+ BoxCollider.h
+ CircleCollider.h
EventManager.h
EventManager.hpp
EventHandler.h
diff --git a/src/crepe/api/CircleCollider.cpp b/src/crepe/api/CircleCollider.cpp
new file mode 100644
index 0000000..04a4995
--- /dev/null
+++ b/src/crepe/api/CircleCollider.cpp
@@ -0,0 +1,6 @@
+#include "CircleCollider.h"
+
+using namespace crepe;
+
+
+CircleCollider::CircleCollider(game_object_id_t game_object_id,Vector2 offset, int radius) : Collider(game_object_id,offset), radius(radius) {}
diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h
index e77a592..29a9c1e 100644
--- a/src/crepe/api/CircleCollider.h
+++ b/src/crepe/api/CircleCollider.h
@@ -1,14 +1,15 @@
#pragma once
+
+#include "Vector2.h"
+
#include "../Collider.h"
namespace crepe {
class CircleCollider : public Collider {
public:
- CircleCollider(game_object_id_t game_object_id, int radius)
- : Collider(game_object_id),
- radius(radius) {}
- int radius;
+ CircleCollider(game_object_id_t game_object_id,Vector2 offset, int radius);
+ double radius;
};
} // namespace crepe
diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h
index 68481f4..b9edec2 100644
--- a/src/crepe/api/Rigidbody.h
+++ b/src/crepe/api/Rigidbody.h
@@ -75,6 +75,8 @@ public:
bool use_gravity = true;
//! if object bounces
bool bounce = false;
+ //! offset of all colliders
+ Vector2 offset;
};
public:
diff --git a/src/crepe/api/Vector2.cpp b/src/crepe/api/Vector2.cpp
index 09b3fa3..947c49e 100644
--- a/src/crepe/api/Vector2.cpp
+++ b/src/crepe/api/Vector2.cpp
@@ -54,4 +54,8 @@ bool Vector2::operator!=(const Vector2 & other) const {
return !(*this == other);
}
+double Vector2::dot(const Vector2& other) const {
+ return this->x * other.x + this->y * other.y;
+}
+
} // namespace crepe
diff --git a/src/crepe/api/Vector2.h b/src/crepe/api/Vector2.h
index 5a57484..90d9d57 100644
--- a/src/crepe/api/Vector2.h
+++ b/src/crepe/api/Vector2.h
@@ -42,6 +42,9 @@ public:
//! Checks if this vector is not equal to another vector.
bool operator!=(const Vector2 & other) const;
+
+ //!
+ double dot(const Vector2& other) const;
};
} // namespace crepe
diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp
index 55e0fdc..ac35026 100644
--- a/src/crepe/system/CollisionSystem.cpp
+++ b/src/crepe/system/CollisionSystem.cpp
@@ -1,7 +1,280 @@
+#include <cmath>
+#include <algorithm>
+#include <cstddef>
+#include <tuple>
+#include <utility>
+#include <variant>
+
#include "CollisionSystem.h"
+#include "../ComponentManager.h"
+#include "../api/BoxCollider.h"
+#include "../api/CircleCollider.h"
+#include "../api/Vector2.h"
+#include "../api/Rigidbody.h"
+#include "../api/Transform.h"
+
+#include "Collider.h"
+#include "iostream"
+
using namespace crepe;
CollisionSystem::CollisionSystem() {}
-void CollisionSystem::update() {}
+void CollisionSystem::update() {
+ ComponentManager & mgr = ComponentManager::get_instance();
+ std::vector<std::reference_wrapper<BoxCollider>> boxcolliders = mgr.get_components_by_type<BoxCollider>();
+ std::vector<std::reference_wrapper<CircleCollider>> circlecolliders = mgr.get_components_by_type<CircleCollider>();
+ std::vector<std::pair<CollidedInfoStor,CollidedInfoStor>> collided = check_collisions(boxcolliders,circlecolliders);
+ std::cout << "DEBUG INFO" << std::endl;
+ for (const auto& collision_pair : collided) {
+ call_collision_handler(collision_pair.first,collision_pair.second); // First collider
+ call_collision_handler(collision_pair.second,collision_pair.first); // First collider
+ }
+
+ if(collided.empty()) {
+ std::cout << "No objects collided" << std::endl;
+ }
+}
+
+void CollisionSystem::call_collision_handler(const CollidedInfoStor& data1,const CollidedInfoStor& data2){
+
+ // Check collision type and get values for handler
+ game_object_id_t first = 0,second = 0;
+ if (std::holds_alternative<BoxCollider>(data1.collider)) {
+ if (std::holds_alternative<BoxCollider>(data2.collider)) {
+ const BoxCollider& box_collider1 = std::get<BoxCollider>(data1.collider);
+ const BoxCollider& box_collider2 = std::get<BoxCollider>(data2.collider);
+ first = box_collider1.game_object_id;
+ second = box_collider2.game_object_id;
+ }
+ else {
+ const BoxCollider& box_collider = std::get<BoxCollider>(data1.collider);
+ const CircleCollider& circle_collider = std::get<CircleCollider>(data2.collider);
+ first = box_collider.game_object_id;
+ second = circle_collider.game_object_id;
+ }
+ }
+ else {
+ if (std::holds_alternative<CircleCollider>(data2.collider)) {
+ const CircleCollider& circle_collider1 = std::get<CircleCollider>(data1.collider);
+ const CircleCollider& circle_collider2 = std::get<CircleCollider>(data2.collider);
+ first = circle_collider1.game_object_id;
+ second = circle_collider2.game_object_id;
+ }
+ else {
+ const CircleCollider& circle_collider = std::get<CircleCollider>(data1.collider);
+ const BoxCollider& box_collider = std::get<BoxCollider>(data2.collider);
+ first = circle_collider.game_object_id;
+ second = box_collider.game_object_id;
+ }
+ }
+
+ // check rigidbody type
+ if(data1.rigidbody.data.body_type != Rigidbody::BodyType::STATIC)
+ {
+ // If second body is static move back
+ if(data2.rigidbody.data.body_type == Rigidbody::BodyType::STATIC) return;
+ //call static handler (is bounce true?)
+
+ // call script handler
+ }
+}
+
+std::vector<std::pair<CollisionSystem::CollidedInfoStor,CollisionSystem::CollidedInfoStor>> CollisionSystem::check_collisions(const std::vector<std::reference_wrapper<BoxCollider>>& boxcolliders, const std::vector<std::reference_wrapper<CircleCollider>>& circlecolliders) {
+ ComponentManager & mgr = ComponentManager::get_instance();
+ std::vector<std::pair<CollidedInfoStor,CollidedInfoStor>> collisions_ret;
+ //if no colliders skip
+ //check if colliders has rigibocdy if not skip
+
+ //if amount is higer than lets say 16 for now use quadtree otwerwise skip
+ //quadtree code
+ //quadtree is placed over the input vector
+
+ // Check collisions
+ for (size_t i = 0; i < boxcolliders.size(); ++i) {
+ // Fetch components for the first box collider
+ if(!boxcolliders[i].get().active) continue;
+ int game_object_id_1 = boxcolliders[i].get().game_object_id;
+ Transform& transform1 = mgr.get_components_by_id<Transform>(game_object_id_1).front().get();
+ if(!transform1.active) continue;
+ Rigidbody& rigidbody1 = mgr.get_components_by_id<Rigidbody>(game_object_id_1).front().get();
+ if(!rigidbody1.active) continue;
+
+ // Check CircleCollider vs CircleCollider
+ for (size_t j = i + 1; j < boxcolliders.size(); ++j) {
+ if(!boxcolliders[j].get().active) continue;
+ // Skip self collision
+ int game_object_id_2 = boxcolliders[j].get().game_object_id;
+ if (game_object_id_1 == game_object_id_2) continue;
+
+ // Fetch components for the second box collider
+ Transform & transform2 = mgr.get_components_by_id<Transform>(boxcolliders[j].get().game_object_id).front().get();
+ if(!transform2.active) continue;
+ Rigidbody & rigidbody2 = mgr.get_components_by_id<Rigidbody>(boxcolliders[j].get().game_object_id).front().get();
+ if(!rigidbody2.active) continue;
+ // Check collision
+ if (check_box_box_collision(boxcolliders[i], boxcolliders[j], transform1, transform2, rigidbody1, rigidbody2)) {
+ collisions_ret.emplace_back(std::make_pair(
+ CollidedInfoStor{boxcolliders[i], transform1, rigidbody1},
+ CollidedInfoStor{boxcolliders[j], transform2, rigidbody2}
+ ));
+ }
+ }
+
+ // Check BoxCollider vs CircleCollider
+ for (size_t j = 0; j < circlecolliders.size(); ++j) {
+ if(!circlecolliders[j].get().active) continue;
+ // Skip self collision
+ int game_object_id_2 = circlecolliders[j].get().game_object_id;
+ if (game_object_id_1 == game_object_id_2) continue;
+
+ // Fetch components for the second collider (circle)
+ Transform & transform2 = mgr.get_components_by_id<Transform>(circlecolliders[j].get().game_object_id).front().get();
+ if(!transform2.active) continue;
+ Rigidbody & rigidbody2 = mgr.get_components_by_id<Rigidbody>(circlecolliders[j].get().game_object_id).front().get();
+ if(!rigidbody2.active) continue;
+
+ // Check collision
+ if (check_box_circle_collision(boxcolliders[i], circlecolliders[j], transform1, transform2, rigidbody1, rigidbody2)) {
+
+ collisions_ret.emplace_back(std::make_pair(
+ CollidedInfoStor{boxcolliders[i], transform1, rigidbody1},
+ CollidedInfoStor{circlecolliders[j], transform2, rigidbody2}
+ ));
+ }
+ }
+ }
+ // Check CircleCollider vs CircleCollider
+ for (size_t i = 0; i < circlecolliders.size(); ++i) {
+ if(!circlecolliders[i].get().active) continue;
+ // Fetch components for the first circle collider
+ int game_object_id_1 = circlecolliders[i].get().game_object_id;
+ Transform & transform1 = mgr.get_components_by_id<Transform>(circlecolliders[i].get().game_object_id).front().get();
+ if(!transform1.active) continue;
+ Rigidbody & rigidbody1 = mgr.get_components_by_id<Rigidbody>(circlecolliders[i].get().game_object_id).front().get();
+ if(!rigidbody1.active) continue;
+
+ for (size_t j = i + 1; j < circlecolliders.size(); ++j) {
+ if(!circlecolliders[j].get().active) continue;
+ // Skip self collision
+ int game_object_id_2 = circlecolliders[j].get().game_object_id;
+ if (game_object_id_1 == game_object_id_2) continue;
+
+ // Fetch components for the second circle collider
+ Transform & transform2 = mgr.get_components_by_id<Transform>(circlecolliders[j].get().game_object_id).front().get();
+ if(!transform2.active) continue;
+ Rigidbody & rigidbody2 = mgr.get_components_by_id<Rigidbody>(circlecolliders[j].get().game_object_id).front().get();
+ if(!rigidbody2.active) continue;
+
+ // Check collision
+ if (check_circle_circle_collision(circlecolliders[i], circlecolliders[j], transform1, transform2, rigidbody1, rigidbody2)) {
+ collisions_ret.emplace_back(std::make_pair(
+ CollidedInfoStor{circlecolliders[i], transform1, rigidbody1},
+ CollidedInfoStor{circlecolliders[j], transform2, rigidbody2}
+ ));
+ }
+ }
+ }
+ return collisions_ret;
+}
+
+bool CollisionSystem::check_box_box_collision(const BoxCollider& box1, const BoxCollider& box2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2)
+{
+ // Get current positions of colliders
+ Vector2 final_position1 = current_position(box1,transform1,rigidbody1);
+ Vector2 final_position2 = current_position(box2,transform2,rigidbody2);
+
+ // Log final positions for debugging purposes
+ std::cout << "Final Position of Box 1: (" << final_position1.x << ", " << final_position1.y << ")" << std::endl;
+ std::cout << "Final Position of Box 2: (" << final_position2.x << ", " << final_position2.y << ")" << std::endl;
+
+ // Log rotation values for debugging
+ std::cout << "Rotation of Box 1: " << transform1.rotation << " degrees" << std::endl;
+ std::cout << "Rotation of Box 2: " << transform2.rotation << " degrees" << std::endl;
+
+
+ // Calculate half-extents (half width and half height)
+ double half_width1 = box1.width / 2.0;
+ double half_height1 = box1.height / 2.0;
+ double half_width2 = box2.width / 2.0;
+ double half_height2 = box2.height / 2.0;
+
+ // Check if the boxes overlap along the X and Y axes
+ return !(final_position1.x + half_width1 < final_position2.x - half_width2 || // box1 is left of box2
+ final_position1.x - half_width1 > final_position2.x + half_width2 || // box1 is right of box2
+ final_position1.y + half_height1 < final_position2.y - half_height2 || // box1 is above box2
+ final_position1.y - half_height1 > final_position2.y + half_height2); // box1 is below box2
+}
+
+bool CollisionSystem::check_box_circle_collision(const BoxCollider& box1, const CircleCollider& circle2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) {
+ // Get current positions of colliders
+ Vector2 final_position1 = current_position(box1, transform1, rigidbody1);
+ Vector2 final_position2 = current_position(circle2, transform2, rigidbody2);
+
+ // Log final positions for debugging purposes
+ std::cout << "Final Position of Box: (" << final_position1.x << ", " << final_position1.y << ")" << std::endl;
+ std::cout << "Final Position of Circle: (" << final_position2.x << ", " << final_position2.y << ")" << std::endl;
+
+ // Calculate box half-extents
+ double half_width = box1.width / 2.0;
+ double half_height = box1.height / 2.0;
+
+ // Find the closest point on the box to the circle's center
+ double closest_x = std::max(final_position1.x - half_width, std::min(final_position2.x, final_position1.x + half_width));
+ double 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
+ double distance_x = final_position2.x - closest_x;
+ double distance_y = final_position2.y - closest_y;
+ double distance_squared = distance_x * distance_x + distance_y * distance_y;
+
+ // Compare distance squared with the square of the circle's radius
+ return distance_squared <= circle2.radius * circle2.radius;
+}
+
+bool CollisionSystem::check_circle_circle_collision(const CircleCollider& circle1, const CircleCollider& circle2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2) {
+ // Get current positions of colliders
+ Vector2 final_position1 = current_position(circle1,transform1,rigidbody1);
+ Vector2 final_position2 = current_position(circle2,transform2,rigidbody2);
+
+ // Log final positions for debugging purposes
+ std::cout << "Final Position of Circle 1: (" << final_position1.x << ", " << final_position1.y << ")" << std::endl;
+ std::cout << "Final Position of Circle 2: (" << final_position2.x << ", " << final_position2.y << ")" << std::endl;
+
+ // Log rotation values for debugging (circles do not rotate, so this might not be needed for circles)
+ std::cout << "Rotation of Circle 1: " << transform1.rotation << " degrees" << std::endl;
+ std::cout << "Rotation of Circle 2: " << transform2.rotation << " degrees" << std::endl;
+
+ double distance_x = final_position1.x - final_position2.x;
+ double distance_y = final_position1.y - final_position2.y;
+ double distance_squared = distance_x * distance_x + distance_y * distance_y;
+
+ // Calculate the sum of the radii
+ double radius_sum = circle1.radius + circle2.radius;
+
+ // Check if the distance between the centers is less than or equal to the sum of the radii
+ return distance_squared <= radius_sum * radius_sum;
+}
+
+Vector2 CollisionSystem::current_position(const Collider& collider, const Transform& transform, const Rigidbody& rigidbody) {
+ // Function to convert degrees to radians
+ auto degrees_to_radians = [](double degrees) {
+ return degrees * (M_PI / 180.0);
+ };
+
+ // Get the rotation in radians
+ double radians1 = degrees_to_radians(transform.rotation);
+
+ // Calculate total offset with scale
+ Vector2 total_offset = (rigidbody.data.offset + collider.offset) * transform.scale;
+
+ // Rotate
+ double rotated_total_offset_x1 = total_offset.x * cos(radians1) - total_offset.y * sin(radians1);
+ double rotated_total_offset_y1 = total_offset.x * sin(radians1) + total_offset.y * cos(radians1);
+
+ // Final positions considering scaling and rotation
+ return(transform.position + Vector2(rotated_total_offset_x1, rotated_total_offset_y1));
+
+}
diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h
index 1e9f1aa..9a72948 100644
--- a/src/crepe/system/CollisionSystem.h
+++ b/src/crepe/system/CollisionSystem.h
@@ -1,11 +1,36 @@
#pragma once
+#include "Collider.h"
+#include "api/Rigidbody.h"
+#include "api/Transform.h"
+#include "api/BoxCollider.h"
+#include "api/CircleCollider.h"
+#include <tuple>
+#include <vector>
+#include <variant>
+
namespace crepe {
+
class CollisionSystem {
+private:
+ using collider_stor = std::variant<BoxCollider, CircleCollider>;
+private:
+ struct CollidedInfoStor {
+ collider_stor collider; // Store either BoxCollider or CircleCollider
+ Transform transform; // Transform data
+ Rigidbody rigidbody; // Rigidbody data
+ };
public:
CollisionSystem();
void update();
+private:
+ void call_collision_handler(const CollidedInfoStor& data1,const CollidedInfoStor& data2);
+ std::vector<std::pair<CollidedInfoStor,CollidedInfoStor>> check_collisions(const std::vector<std::reference_wrapper<BoxCollider>>& boxcolliders, const std::vector<std::reference_wrapper<CircleCollider>>& circlecolliders);
+ bool check_box_box_collision(const BoxCollider& box1, const BoxCollider& box2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2);
+ bool check_box_circle_collision(const BoxCollider& box1, const CircleCollider& circle2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2);
+ bool check_circle_circle_collision(const CircleCollider& circle1, const CircleCollider& circle2, const Transform& transform1, const Transform& transform2, const Rigidbody& rigidbody1, const Rigidbody& rigidbody2);
+ Vector2 current_position(const Collider& collider, const Transform& transform, const Rigidbody& rigidbody);
};
} // namespace crepe
diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt
index ddb0262..d2ea926 100644
--- a/src/example/CMakeLists.txt
+++ b/src/example/CMakeLists.txt
@@ -28,6 +28,7 @@ add_example(proxy)
add_example(db)
add_example(ecs)
add_example(scene_manager)
+add_example(collision)
add_example(events)
add_example(particles)
add_example(gameloop)
diff --git a/src/example/collision.cpp b/src/example/collision.cpp
new file mode 100644
index 0000000..e82b493
--- /dev/null
+++ b/src/example/collision.cpp
@@ -0,0 +1,68 @@
+#include "api/BoxCollider.h"
+#include "system/CollisionSystem.h"
+#include <crepe/Component.h>
+#include <crepe/ComponentManager.h>
+#include <crepe/api/GameObject.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/BoxCollider.h>
+#include <crepe/api/Transform.h>
+#include <crepe/system/PhysicsSystem.h>
+#include <crepe/system/RenderSystem.h>
+#include <crepe/util/log.h>
+
+#include <crepe/api/AssetManager.h>
+#include <crepe/api/Color.h>
+#include <crepe/api/Sprite.h>
+#include <crepe/api/Texture.h>
+#include <crepe/api/Transform.h>
+#include <crepe/api/Vector2.h>
+
+#include <chrono>
+#include <memory>
+
+using namespace crepe;
+using namespace std;
+
+int main(int argc, char * argv[]) {
+ Color color(0, 0, 0, 0);
+
+ GameObject game_object1(0, "Name", "Tag", Vector2{10, 10}, 0, 1);
+ game_object1.add_component<Rigidbody>(Rigidbody::Data{
+ .mass = 1,
+ .gravity_scale = 1,
+ .body_type = Rigidbody::BodyType::DYNAMIC,
+ .constraints = {0, 0, 0},
+ .use_gravity = true,
+ .bounce = false,
+ .offset = {0,0}
+ });
+ game_object1.add_component<BoxCollider>(Vector2{5, 5}, 5, 5);
+ // game_object1.add_component<Sprite>(
+ // make_shared<Texture>("/home/jaro/crepe/asset/texture/img.png"), color,
+ // FlipSettings{true, true});
+
+
+ GameObject game_object2(1, "Name", "Tag", Vector2{20, 0}, 90, 1);
+ game_object2.add_component<Rigidbody>(Rigidbody::Data{
+ .mass = 1,
+ .gravity_scale = 1,
+ .body_type = Rigidbody::BodyType::DYNAMIC,
+ .constraints = {0, 0, 0},
+ .use_gravity = true,
+ .bounce = false,
+ .offset = {0,0}
+ });
+ game_object2.add_component<BoxCollider>(Vector2{5, 5}, 5, 5);
+ // game_object2.add_component<Sprite>(
+ // make_shared<Texture>("/home/jaro/crepe/asset/texture/img.png"), color,
+ // FlipSettings{true, true});
+
+ CollisionSystem coltest;
+ coltest.update();
+ // auto & sys = crepe::RenderSystem::get_instance();
+ // auto start = std::chrono::steady_clock::now();
+ // while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) {
+ // sys.update();
+ // }
+ return 0;
+}
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index acab388..50802de 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -1,6 +1,8 @@
target_sources(test_main PUBLIC
dummy.cpp
# audio.cpp
+ PhysicsTest.cpp
+ CollisionTest.cpp
# PhysicsTest.cpp
ParticleTest.cpp
)
diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp
new file mode 100644
index 0000000..3e43479
--- /dev/null
+++ b/src/test/CollisionTest.cpp
@@ -0,0 +1,83 @@
+#include "api/BoxCollider.h"
+#include "api/CircleCollider.h"
+#include "api/Vector2.h"
+#include <crepe/ComponentManager.h>
+#include <crepe/api/Config.h>
+#include <crepe/api/GameObject.h>
+#include <crepe/api/Rigidbody.h>
+#include <crepe/api/Transform.h>
+#include <crepe/system/CollisionSystem.h>
+#include <gtest/gtest.h>
+
+using namespace std;
+using namespace std::chrono_literals;
+using namespace crepe;
+
+class CollisionTest : public ::testing::Test {
+protected:
+ GameObject * game_object1;
+ GameObject * game_object2;
+ CollisionSystem collision_system;
+ void SetUp() override {
+ ComponentManager & mgr = ComponentManager::get_instance();
+ mgr.delete_all_components();
+ std::vector<std::reference_wrapper<Transform>> transforms
+ = mgr.get_components_by_id<Transform>(0);
+
+ // ob 1
+ game_object1 = new GameObject(0, "", "", Vector2{0, 0}, 0, 0);
+ game_object1->add_component<Rigidbody>(Rigidbody::Data{
+ .mass = 1,
+ .gravity_scale = 1,
+ .body_type = Rigidbody::BodyType::DYNAMIC,
+ .max_linear_velocity = Vector2{10, 10},
+ .max_angular_velocity = 10,
+ .constraints = {0, 0, 0},
+ .use_gravity = false,
+ .bounce = false,
+ });
+
+ game_object1->add_component<BoxCollider>(Vector2{0,0},10,10);
+
+
+ //ob 2
+ game_object2 = new GameObject(1, "", "", Vector2{50, 50}, 0, 0);
+ game_object2->add_component<Rigidbody>(Rigidbody::Data{
+ .mass = 1,
+ .gravity_scale = 1,
+ .body_type = Rigidbody::BodyType::DYNAMIC,
+ .max_linear_velocity = Vector2{10, 10},
+ .max_angular_velocity = 10,
+ .constraints = {0, 0, 0},
+ .use_gravity = false,
+ .bounce = false,
+ });
+ game_object2->add_component<CircleCollider>(Vector2{0,0},5);
+ }
+};
+
+TEST_F(CollisionTest, box_box_collision) {
+ Config::get_instance().physics.gravity = 1;
+ ComponentManager & mgr = ComponentManager::get_instance();
+ std::vector<std::reference_wrapper<Transform>> transforms
+ = mgr.get_components_by_id<Transform>(0);
+ Transform & transform = transforms.front().get();
+ ASSERT_FALSE(transforms.empty());
+ transform.position = {39,50};
+ collision_system.update();
+ transform.position = {40,50};
+ collision_system.update();
+ transform.position = {50,39};
+ collision_system.update();
+ transform.position = {50,40};
+ collision_system.update();
+ transform.position = {50,60};
+ collision_system.update();
+ transform.position = {50,61};
+ collision_system.update();
+ transform.position = {60,50};
+ collision_system.update();
+ transform.position = {61,50};
+ collision_system.update();
+}
+
diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp
index 5385962..3332f74 100644
--- a/src/test/PhysicsTest.cpp
+++ b/src/test/PhysicsTest.cpp
@@ -16,6 +16,7 @@ protected:
PhysicsSystem physics_system;
void SetUp() override {
ComponentManager & mgr = ComponentManager::get_instance();
+ mgr.delete_all_components();
std::vector<std::reference_wrapper<Transform>> transforms
= mgr.get_components_by_id<Transform>(0);
if (transforms.empty()) {