diff options
-rw-r--r-- | src/crepe/api/Rigidbody.h | 2 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.cpp | 8 | ||||
-rw-r--r-- | src/crepe/system/CollisionSystem.cpp | 335 | ||||
-rw-r--r-- | src/crepe/system/CollisionSystem.h | 42 | ||||
-rw-r--r-- | src/crepe/system/ParticleSystem.cpp | 3 | ||||
-rw-r--r-- | src/crepe/system/RenderSystem.cpp | 2 | ||||
-rw-r--r-- | src/example/game.cpp | 4 | ||||
-rw-r--r-- | src/test/CollisionTest.cpp | 1 |
8 files changed, 198 insertions, 199 deletions
diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index 28c376b..b63d941 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -164,8 +164,6 @@ public: * Each element represents a tag from the Metadata of the gameobject. */ std::set<std::string> collision_tags; - - }; public: diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index ca45b79..164d35e 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -229,10 +229,10 @@ void SDLContext::draw_text(const RenderText & data) { = {tmp_font_texture, [](SDL_Texture * texture) { SDL_DestroyTexture(texture); }}; vec2 size = text.dimensions * cam_aux_data.render_scale * data.transform.scale; - vec2 screen_pos = (absoluut_pos - cam_aux_data.cam_pos - + (cam_aux_data.zoomed_viewport) / 2) - * cam_aux_data.render_scale - - size / 2 + cam_aux_data.bar_size; + vec2 screen_pos + = (absoluut_pos - cam_aux_data.cam_pos + (cam_aux_data.zoomed_viewport) / 2) + * cam_aux_data.render_scale + - size / 2 + cam_aux_data.bar_size; SDL_FRect dstrect{ .x = screen_pos.x, diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 00b56a4..f0f1fa8 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -26,12 +26,12 @@ using namespace crepe; using enum Rigidbody::BodyType; CollisionSystem::CollisionInfo CollisionSystem::CollisionInfo::operator-() const { - return { - .self = this->other, + return { + .self = this->other, .other = this->self, .resolution = -this->resolution, .resolution_direction = this->resolution_direction, - }; + }; } void CollisionSystem::update() { @@ -52,8 +52,7 @@ void CollisionSystem::update() { if (!boxcollider.active) continue; all_colliders.push_back({.id = id, .collider = collider_variant{boxcollider}, - .info = {transform,rigidbody, metadata} - }); + .info = {transform, rigidbody, metadata}}); } // Check if the circlecollider is active and has the same id as the rigidbody. RefVector<CircleCollider> circlecolliders @@ -63,8 +62,7 @@ void CollisionSystem::update() { if (!circlecollider.active) continue; all_colliders.push_back({.id = id, .collider = collider_variant{circlecollider}, - .info = {transform,rigidbody, metadata} - }); + .info = {transform, rigidbody, metadata}}); } } @@ -75,13 +73,14 @@ void CollisionSystem::update() { // For the object convert the info and call the collision handler if needed for (auto & collision_pair : collided) { // Convert internal struct to external struct - CollisionInfo info = this->get_collision_info(collision_pair.first, collision_pair.second); + CollisionInfo info + = this->get_collision_info(collision_pair.first, collision_pair.second); // Determine if and/or what collison handler is needed. this->determine_collision_handler(info); } } -// Below is for collision detection +// Below is for collision detection std::vector<std::pair<CollisionSystem::CollisionInternal, CollisionSystem::CollisionInternal>> CollisionSystem::gather_collisions(std::vector<CollisionInternal> & colliders) { @@ -101,17 +100,18 @@ CollisionSystem::gather_collisions(std::vector<CollisionInternal> & colliders) { for (size_t j = i + 1; j < colliders.size(); ++j) { if (colliders[i].id == colliders[j].id) continue; if (!should_collide(colliders[i], colliders[j])) continue; - CollisionInternalType type = get_collider_type(colliders[i].collider, colliders[j].collider); - if (!detect_collision(colliders[i],colliders[j],type)) continue; - //fet - collisions_ret.emplace_back(colliders[i], colliders[j]); + CollisionInternalType type + = get_collider_type(colliders[i].collider, colliders[j].collider); + if (!detect_collision(colliders[i], colliders[j], type)) continue; + //fet + collisions_ret.emplace_back(colliders[i], colliders[j]); } } return collisions_ret; } - -bool CollisionSystem::should_collide(const CollisionInternal & self, const CollisionInternal & other) const{ +bool CollisionSystem::should_collide(const CollisionInternal & self, + const CollisionInternal & other) const { const Rigidbody::Data & self_rigidbody = self.info.rigidbody.data; const Rigidbody::Data & other_rigidbody = other.info.rigidbody.data; @@ -119,21 +119,20 @@ bool CollisionSystem::should_collide(const CollisionInternal & self, const Colli const Metadata & other_metadata = other.info.metadata; // Check collision layers - if(self_rigidbody.collision_layers.contains(other_rigidbody.collision_layer)) return true; - if(other_rigidbody.collision_layers.contains(self_rigidbody.collision_layer)) return true; + if (self_rigidbody.collision_layers.contains(other_rigidbody.collision_layer)) return true; + if (other_rigidbody.collision_layers.contains(self_rigidbody.collision_layer)) return true; // Check names - if(self_rigidbody.collision_names.contains(other_metadata.name)) return true; - if(other_rigidbody.collision_names.contains(self_metadata.name)) return true; + if (self_rigidbody.collision_names.contains(other_metadata.name)) return true; + if (other_rigidbody.collision_names.contains(self_metadata.name)) return true; // Check tags - if(self_rigidbody.collision_tags.contains(other_metadata.tag)) return true; - if(other_rigidbody.collision_tags.contains(self_metadata.tag)) return true; + if (self_rigidbody.collision_tags.contains(other_metadata.tag)) return true; + if (other_rigidbody.collision_tags.contains(self_metadata.tag)) return true; return false; } - CollisionSystem::CollisionInternalType CollisionSystem::get_collider_type(const collider_variant & collider1, const collider_variant & collider2) const { @@ -152,93 +151,86 @@ CollisionSystem::get_collider_type(const collider_variant & collider1, } } -bool CollisionSystem::detect_collision(CollisionInternal & self,CollisionInternal & other,const CollisionInternalType & type) { +bool CollisionSystem::detect_collision(CollisionInternal & self, CollisionInternal & other, + const CollisionInternalType & type) { vec2 resolution; switch (type) { - case CollisionInternalType::BOX_BOX: { + case CollisionInternalType::BOX_BOX: { // Box-Box collision detection - const BoxColliderInternal BOX1 = { - .collider = std::get<std::reference_wrapper<BoxCollider>>(self.collider), - .transform = self.info.transform, - .rigidbody = self.info.rigidbody - }; - const BoxColliderInternal BOX2 = { - .collider = std::get<std::reference_wrapper<BoxCollider>>(other.collider), - .transform = other.info.transform, - .rigidbody = other.info.rigidbody - }; + const BoxColliderInternal BOX1 + = {.collider = std::get<std::reference_wrapper<BoxCollider>>(self.collider), + .transform = self.info.transform, + .rigidbody = self.info.rigidbody}; + const BoxColliderInternal BOX2 + = {.collider = std::get<std::reference_wrapper<BoxCollider>>(other.collider), + .transform = other.info.transform, + .rigidbody = other.info.rigidbody}; // Get resolution vector from box-box collision detection resolution = this->get_box_box_detection(BOX1, BOX2); // If no collision (NaN values), return false - if(std::isnan(resolution.x) && std::isnan(resolution.y)) return false; + if (std::isnan(resolution.x) && std::isnan(resolution.y)) return false; break; - } case CollisionInternalType::BOX_CIRCLE: { // Box-Circle collision detection - const BoxColliderInternal BOX1 = { - .collider = std::get<std::reference_wrapper<BoxCollider>>(self.collider), - .transform = self.info.transform, - .rigidbody = self.info.rigidbody - }; + const BoxColliderInternal BOX1 + = {.collider = std::get<std::reference_wrapper<BoxCollider>>(self.collider), + .transform = self.info.transform, + .rigidbody = self.info.rigidbody}; const CircleColliderInternal CIRCLE2 = { .collider = std::get<std::reference_wrapper<CircleCollider>>(other.collider), .transform = other.info.transform, - .rigidbody = other.info.rigidbody - }; + .rigidbody = other.info.rigidbody}; // Get resolution vector from box-circle collision detection resolution = this->get_box_circle_detection(BOX1, CIRCLE2); // If no collision (NaN values), return false - if(std::isnan(resolution.x) && std::isnan(resolution.y)) return false; + if (std::isnan(resolution.x) && std::isnan(resolution.y)) return false; // Invert the resolution vector for proper collision response resolution = -resolution; break; } - case CollisionInternalType::CIRCLE_CIRCLE: { + case CollisionInternalType::CIRCLE_CIRCLE: { // Circle-Circle collision detection - const CircleColliderInternal CIRCLE1 = { - .collider = std::get<std::reference_wrapper<CircleCollider>>(self.collider), - .transform = self.info.transform, - .rigidbody = self.info.rigidbody - }; + const CircleColliderInternal CIRCLE1 + = {.collider = std::get<std::reference_wrapper<CircleCollider>>(self.collider), + .transform = self.info.transform, + .rigidbody = self.info.rigidbody}; const CircleColliderInternal CIRCLE2 = { .collider = std::get<std::reference_wrapper<CircleCollider>>(other.collider), .transform = other.info.transform, - .rigidbody = other.info.rigidbody - }; + .rigidbody = other.info.rigidbody}; // Get resolution vector from circle-circle collision detection - resolution = this->get_circle_circle_detection(CIRCLE1,CIRCLE2); + resolution = this->get_circle_circle_detection(CIRCLE1, CIRCLE2); // If no collision (NaN values), return false - if(std::isnan(resolution.x) && std::isnan(resolution.y)) return false; + if (std::isnan(resolution.x) && std::isnan(resolution.y)) return false; break; } - case CollisionInternalType::CIRCLE_BOX: { + case CollisionInternalType::CIRCLE_BOX: { // Circle-Box collision detection - const CircleColliderInternal CIRCLE1 = { - .collider = std::get<std::reference_wrapper<CircleCollider>>(self.collider), - .transform = self.info.transform, - .rigidbody = self.info.rigidbody - }; - const BoxColliderInternal BOX2 = { - .collider = std::get<std::reference_wrapper<BoxCollider>>(other.collider), - .transform = other.info.transform, - .rigidbody = other.info.rigidbody - }; + const CircleColliderInternal CIRCLE1 + = {.collider = std::get<std::reference_wrapper<CircleCollider>>(self.collider), + .transform = self.info.transform, + .rigidbody = self.info.rigidbody}; + const BoxColliderInternal BOX2 + = {.collider = std::get<std::reference_wrapper<BoxCollider>>(other.collider), + .transform = other.info.transform, + .rigidbody = other.info.rigidbody}; // Get resolution vector from box-circle collision detection (order swapped) resolution = this->get_box_circle_detection(BOX2, CIRCLE1); // If no collision (NaN values), return false - if(std::isnan(resolution.x) && std::isnan(resolution.y)) return false; + if (std::isnan(resolution.x) && std::isnan(resolution.y)) return false; break; } case CollisionInternalType::NONE: - // No collision detection needed if the type is NONE - return false; - break; + // No collision detection needed if the type is NONE + return false; + break; } - // Store the calculated resolution vector for the 'self' collider + // Store the calculated resolution vector for the 'self' collider self.resolution = resolution; // Calculate the resolution direction based on the rigidbody data - self.resolution_direction = this->resolution_correction(self.resolution, self.info.rigidbody.data); + self.resolution_direction + = this->resolution_correction(self.resolution, self.info.rigidbody.data); // For the 'other' collider, the resolution is the opposite direction of 'self' other.resolution = -self.resolution; other.resolution_direction = self.resolution_direction; @@ -247,18 +239,18 @@ bool CollisionSystem::detect_collision(CollisionInternal & self,CollisionInterna return true; } -vec2 CollisionSystem::get_box_box_detection(const BoxColliderInternal & box1, const BoxColliderInternal & box2) const { +vec2 CollisionSystem::get_box_box_detection(const BoxColliderInternal & box1, + const BoxColliderInternal & box2) const { vec2 resolution{std::nanf(""), std::nanf("")}; // Get current positions of colliders - vec2 pos1 = AbsolutePosition::get_position(box1.transform, box1.collider.offset); - vec2 pos2 = AbsolutePosition::get_position(box2.transform, box2.collider.offset); + vec2 pos1 = AbsolutePosition::get_position(box1.transform, box1.collider.offset); + vec2 pos2 = AbsolutePosition::get_position(box2.transform, box2.collider.offset); // Scale dimensions vec2 scaled_box1 = box1.collider.dimensions * box1.transform.scale; vec2 scaled_box2 = box2.collider.dimensions * box2.transform.scale; vec2 delta = pos2 - pos1; - // Calculate half-extents (half width and half height) float half_width1 = scaled_box1.x / 2.0; float half_height1 = scaled_box1.y / 2.0; @@ -266,79 +258,85 @@ vec2 CollisionSystem::get_box_box_detection(const BoxColliderInternal & box1, co float half_height2 = scaled_box2.y / 2.0; if (pos1.x + half_width1 > pos2.x - half_width2 - && pos1.x - half_width1 < pos2.x + half_width2 - && pos1.y + half_height1 > pos2.y - half_height2 - && pos1.y - half_height1 < pos2.y + half_height2) - { - resolution = {0,0}; + && pos1.x - half_width1 < pos2.x + half_width2 + && pos1.y + half_height1 > pos2.y - half_height2 + && pos1.y - half_height1 < pos2.y + half_height2) { + resolution = {0, 0}; float overlap_x = (half_width1 + half_width2) - std::abs(delta.x); float overlap_y = (half_height1 + half_height2) - std::abs(delta.y); if (overlap_x > 0 && overlap_y > 0) { - // Determine the direction of resolution - if (overlap_x < overlap_y) { - // Resolve along the X-axis (smallest overlap) - resolution.x = (delta.x > 0) ? -overlap_x : overlap_x; - } else if (overlap_y < overlap_x) { - // Resolve along the Y-axis (smallest overlap) - resolution.y = (delta.y > 0) ? -overlap_y : overlap_y; - } else { - // Equal overlap, resolve both directions with preference - resolution.x = (delta.x > 0) ? -overlap_x : overlap_x; - resolution.y = (delta.y > 0) ? -overlap_y : overlap_y; + // Determine the direction of resolution + if (overlap_x < overlap_y) { + // Resolve along the X-axis (smallest overlap) + resolution.x = (delta.x > 0) ? -overlap_x : overlap_x; + } else if (overlap_y < overlap_x) { + // Resolve along the Y-axis (smallest overlap) + resolution.y = (delta.y > 0) ? -overlap_y : overlap_y; + } else { + // Equal overlap, resolve both directions with preference + resolution.x = (delta.x > 0) ? -overlap_x : overlap_x; + resolution.y = (delta.y > 0) ? -overlap_y : overlap_y; + } } } - } return resolution; } -vec2 CollisionSystem::get_box_circle_detection(const BoxColliderInternal & box, const CircleColliderInternal & circle) const { +vec2 CollisionSystem::get_box_circle_detection(const BoxColliderInternal & box, + const CircleColliderInternal & circle) const { /// Get current positions of colliders - vec2 box_pos = AbsolutePosition::get_position(box.transform, box.collider.offset); - vec2 circle_pos = AbsolutePosition::get_position(circle.transform, circle.collider.offset); - - // Scale dimensions - vec2 scaled_box = box.collider.dimensions * box.transform.scale; - float scaled_circle_radius = circle.collider.radius * circle.transform.scale; - - // Calculate box half-extents - float half_width = scaled_box.x / 2.0f; - float half_height = scaled_box.y / 2.0f; - - // Find the closest point on the box to the circle's center - float closest_x = std::max(box_pos.x - half_width, std::min(circle_pos.x, box_pos.x + half_width)); - float closest_y = std::max(box_pos.y - half_height, std::min(circle_pos.y, box_pos.y + half_height)); - - float distance_x = circle_pos.x - closest_x; - float distance_y = circle_pos.y - closest_y; - float distance_squared = distance_x * distance_x + distance_y * distance_y; - if(distance_squared < scaled_circle_radius * scaled_circle_radius){ - vec2 delta = circle_pos - box_pos; - - // Clamp circle center to the nearest point on the box - vec2 closest_point; - closest_point.x = std::clamp(delta.x, -half_width, half_width); - closest_point.y = std::clamp(delta.y, -half_height, half_height); - - // Find the vector from the circle center to the closest point - vec2 closest_delta = delta - closest_point; - - float distance = std::sqrt(closest_delta.x * closest_delta.x + closest_delta.y * closest_delta.y); - vec2 collision_normal = closest_delta / distance; - - // Compute penetration depth - float penetration_depth = scaled_circle_radius - distance; - - // Compute the resolution vector - return vec2{collision_normal * penetration_depth}; - } - // No collision - return vec2{std::nanf(""), std::nanf("")}; + vec2 box_pos = AbsolutePosition::get_position(box.transform, box.collider.offset); + vec2 circle_pos = AbsolutePosition::get_position(circle.transform, circle.collider.offset); + + // Scale dimensions + vec2 scaled_box = box.collider.dimensions * box.transform.scale; + float scaled_circle_radius = circle.collider.radius * circle.transform.scale; + + // Calculate box half-extents + float half_width = scaled_box.x / 2.0f; + float half_height = scaled_box.y / 2.0f; + + // Find the closest point on the box to the circle's center + float closest_x + = std::max(box_pos.x - half_width, std::min(circle_pos.x, box_pos.x + half_width)); + float closest_y + = std::max(box_pos.y - half_height, std::min(circle_pos.y, box_pos.y + half_height)); + + float distance_x = circle_pos.x - closest_x; + float distance_y = circle_pos.y - closest_y; + float distance_squared = distance_x * distance_x + distance_y * distance_y; + if (distance_squared < scaled_circle_radius * scaled_circle_radius) { + vec2 delta = circle_pos - box_pos; + + // Clamp circle center to the nearest point on the box + vec2 closest_point; + closest_point.x = std::clamp(delta.x, -half_width, half_width); + closest_point.y = std::clamp(delta.y, -half_height, half_height); + + // Find the vector from the circle center to the closest point + vec2 closest_delta = delta - closest_point; + + float distance + = std::sqrt(closest_delta.x * closest_delta.x + closest_delta.y * closest_delta.y); + vec2 collision_normal = closest_delta / distance; + + // Compute penetration depth + float penetration_depth = scaled_circle_radius - distance; + + // Compute the resolution vector + return vec2{collision_normal * penetration_depth}; + } + // No collision + return vec2{std::nanf(""), std::nanf("")}; } -vec2 CollisionSystem::get_circle_circle_detection(const CircleColliderInternal & circle1, const CircleColliderInternal & circle2) const { +vec2 CollisionSystem::get_circle_circle_detection( + const CircleColliderInternal & circle1, const CircleColliderInternal & circle2) const { // Get current positions of colliders - vec2 final_position1 = AbsolutePosition::get_position(circle1.transform, circle1.collider.offset); - vec2 final_position2 = AbsolutePosition::get_position(circle2.transform, circle2.collider.offset); + vec2 final_position1 + = AbsolutePosition::get_position(circle1.transform, circle1.collider.offset); + vec2 final_position2 + = AbsolutePosition::get_position(circle2.transform, circle2.collider.offset); // Scale dimensions float scaled_circle1 = circle1.collider.radius * circle1.transform.scale; @@ -376,7 +374,8 @@ vec2 CollisionSystem::get_circle_circle_detection(const CircleColliderInternal & return vec2{std::nanf(""), std::nanf("")}; } -CollisionSystem::Direction CollisionSystem::resolution_correction(vec2 & resolution,const Rigidbody::Data & rigidbody) { +CollisionSystem::Direction +CollisionSystem::resolution_correction(vec2 & resolution, const Rigidbody::Data & rigidbody) { // Calculate the other value to move back correctly // If only X or Y has a value determine what is should be to move back. @@ -384,63 +383,64 @@ CollisionSystem::Direction CollisionSystem::resolution_correction(vec2 & resolut // If both are not zero a perfect corner has been hit if (resolution.x != 0 && resolution.y != 0) { resolution_direction = Direction::BOTH; - // If x is not zero a horizontal action was latest action. + // If x is not zero a horizontal action was latest action. } else if (resolution.x != 0) { resolution_direction = Direction::X_DIRECTION; // If both are 0 resolution y should not be changed (y_velocity can be 0 by kinematic object movement) if (rigidbody.linear_velocity.x != 0 && rigidbody.linear_velocity.y != 0) - resolution.y = -rigidbody.linear_velocity.y * (resolution.x / rigidbody.linear_velocity.x); + resolution.y + = -rigidbody.linear_velocity.y * (resolution.x / rigidbody.linear_velocity.x); } else if (resolution.y != 0) { resolution_direction = Direction::Y_DIRECTION; // If both are 0 resolution x should not be changed (x_velocity can be 0 by kinematic object movement) if (rigidbody.linear_velocity.x != 0 && rigidbody.linear_velocity.y != 0) - resolution.x = -rigidbody.linear_velocity.x * (resolution.y / rigidbody.linear_velocity.y); + resolution.x + = -rigidbody.linear_velocity.x * (resolution.y / rigidbody.linear_velocity.y); } return resolution_direction; } -CollisionSystem::CollisionInfo CollisionSystem::get_collision_info(const CollisionInternal & in_self, const CollisionInternal & in_other) const{ +CollisionSystem::CollisionInfo +CollisionSystem::get_collision_info(const CollisionInternal & in_self, + const CollisionInternal & in_other) const { - crepe::CollisionSystem::ColliderInfo self { - .transform = in_self.info.transform, - .rigidbody = in_self.info.rigidbody, - .metadata = in_self.info.metadata, + crepe::CollisionSystem::ColliderInfo self{ + .transform = in_self.info.transform, + .rigidbody = in_self.info.rigidbody, + .metadata = in_self.info.metadata, }; - crepe::CollisionSystem::ColliderInfo other { - .transform = in_other.info.transform, - .rigidbody = in_other.info.rigidbody, - .metadata = in_other.info.metadata, + crepe::CollisionSystem::ColliderInfo other{ + .transform = in_other.info.transform, + .rigidbody = in_other.info.rigidbody, + .metadata = in_other.info.metadata, }; - struct CollisionInfo collision_info{ - .self = self, - .other = other, - .resolution = in_self.resolution, + struct CollisionInfo collision_info { + .self = self, .other = other, .resolution = in_self.resolution, .resolution_direction = in_self.resolution_direction, }; return collision_info; } void CollisionSystem::determine_collision_handler(const CollisionInfo & info) { - Rigidbody::BodyType self_type = info.self.rigidbody.data.body_type; - Rigidbody::BodyType other_type = info.other.rigidbody.data.body_type; + Rigidbody::BodyType self_type = info.self.rigidbody.data.body_type; + Rigidbody::BodyType other_type = info.other.rigidbody.data.body_type; bool self_kinematic = info.self.rigidbody.data.kinematic_collision; bool other_kinematic = info.other.rigidbody.data.kinematic_collision; // Inverted collision info CollisionInfo inverted = -info; // If both objects are static skip handle call collision script - if (self_type == STATIC - && other_type == STATIC) - return; + if (self_type == STATIC && other_type == STATIC) return; // First body is not dynamic if (self_type != DYNAMIC) { bool static_collision = self_type == STATIC && other_type == DYNAMIC; - bool kinematic_collision = self_type == KINEMATIC && other_type == DYNAMIC && self_kinematic; + bool kinematic_collision + = self_type == KINEMATIC && other_type == DYNAMIC && self_kinematic; - // Handle collision + // Handle collision if (static_collision || kinematic_collision) this->static_collision_handler(inverted); // Call scripts this->call_collision_events(inverted); @@ -451,7 +451,7 @@ void CollisionSystem::determine_collision_handler(const CollisionInfo & info) { if (other_type != DYNAMIC) { bool static_collision = other_type == STATIC; bool kinematic_collision = other_type == KINEMATIC && other_kinematic; - // Handle collision + // Handle collision if (static_collision || kinematic_collision) this->static_collision_handler(info); // Call scripts this->call_collision_events(info); @@ -459,18 +459,18 @@ void CollisionSystem::determine_collision_handler(const CollisionInfo & info) { } // Dynamic - // Handle collision + // Handle collision this->dynamic_collision_handler(info); // Call scripts this->call_collision_events(info); } void CollisionSystem::static_collision_handler(const CollisionInfo & info) { - + vec2 & transform_pos = info.self.transform.position; float elasticity = info.self.rigidbody.data.elasticity_coefficient; vec2 & rigidbody_vel = info.self.rigidbody.data.linear_velocity; - + // Move object back using calculate move back value transform_pos += info.resolution; @@ -588,10 +588,5 @@ void CollisionSystem::call_collision_events(const CollisionInfo & info) { CollisionEvent data_inverted(-info); EventManager & emgr = this->mediator.event_manager; emgr.trigger_event<CollisionEvent>(data, info.self.transform.game_object_id); - emgr.trigger_event<CollisionEvent>(data_inverted, - -info.self.transform.game_object_id); + emgr.trigger_event<CollisionEvent>(data_inverted, -info.self.transform.game_object_id); } - - - - diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index b7808f1..7be280a 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -21,6 +21,7 @@ namespace crepe { class CollisionSystem : public System { public: using System::System; + private: //! Enum representing movement directions during collision resolution. enum class Direction { @@ -33,13 +34,13 @@ private: //! Movement in both X and Y directions. BOTH, }; + public: - //! Structure representing components of the collider struct ColliderInfo { - Transform & transform; - Rigidbody & rigidbody; - Metadata & metadata; + Transform & transform; + Rigidbody & rigidbody; + Metadata & metadata; }; /** @@ -54,7 +55,7 @@ public: vec2 resolution; //! The direction of movement for resolving the collision. Direction resolution_direction = Direction::NONE; - CollisionInfo operator - () const; + CollisionInfo operator-() const; }; private: @@ -90,9 +91,9 @@ private: //! Structure of a collider with additional components template <typename ColliderType> struct ColliderInternal { - ColliderType& collider; - Transform& transform; - Rigidbody& rigidbody; + ColliderType & collider; + Transform & transform; + Rigidbody & rigidbody; }; //! Predefined BoxColliderInternal. (System is only made for this type) using BoxColliderInternal = ColliderInternal<BoxCollider>; @@ -113,7 +114,8 @@ private: * \param collider2 Second collider variant (BoxCollider or CircleCollider). * \return The combined type of the two colliders. */ - CollisionInternalType get_collider_type(const collider_variant & collider1, const collider_variant & collider2) const; + CollisionInternalType get_collider_type(const collider_variant & collider1, + const collider_variant & collider2) const; private: /** @@ -126,8 +128,8 @@ private: * \param data1 Collision data for the first collider. * \param data2 Collision data for the second collider. */ - CollisionInfo get_collision_info(const CollisionInternal & data1, const CollisionInternal & data2) const; - + CollisionInfo get_collision_info(const CollisionInternal & data1, + const CollisionInternal & data2) const; /** * \brief Corrects the collision resolution vector and determines its direction. @@ -142,8 +144,7 @@ private: * \param rigidbody rigidbody data used to correct resolution * \return A Direction indicating the resolution direction */ - Direction resolution_correction(vec2 & resolution,const Rigidbody::Data & rigidbody); - + Direction resolution_correction(vec2 & resolution, const Rigidbody::Data & rigidbody); /** * \brief Determines the appropriate collision handler for a given collision event. @@ -220,7 +221,8 @@ private: * \param other_metadata Rigidbody of second object * \return Returns true if there is at least one comparison found. */ - bool should_collide(const CollisionInternal & self, const CollisionInternal & other) const; //done + bool should_collide(const CollisionInternal & self, + const CollisionInternal & other) const; //done /** * \brief Checks for collision between two colliders. @@ -234,7 +236,8 @@ private: * \param type The type of collider pair. * \return True if a collision is detected, otherwise false. */ - bool detect_collision(CollisionInternal & first_info, CollisionInternal & second_info, const CollisionInternalType & type); + bool detect_collision(CollisionInternal & first_info, CollisionInternal & second_info, + const CollisionInternalType & type); /** * \brief Detects collisions between two BoxColliders. @@ -247,7 +250,8 @@ private: * \param box2 Information about the second BoxCollider. * \return If colliding, returns the resolution vector; otherwise, returns {NaN, NaN}. */ - vec2 get_box_box_detection(const BoxColliderInternal & box1, const BoxColliderInternal & box2) const; + vec2 get_box_box_detection(const BoxColliderInternal & box1, + const BoxColliderInternal & box2) const; /** * \brief Check collision for box on circle collider @@ -260,7 +264,8 @@ private: * \param circle2 Information about the circleCollider. * \return If colliding, returns the resolution vector; otherwise, returns {NaN, NaN}. */ - vec2 get_box_circle_detection(const BoxColliderInternal & box1, const CircleColliderInternal & circle2) const; + vec2 get_box_circle_detection(const BoxColliderInternal & box1, + const CircleColliderInternal & circle2) const; /** * \brief Check collision for circle on circle collider @@ -273,7 +278,8 @@ private: * \param circle2 Information about the second circleCollider. * \return If colliding, returns the resolution vector; otherwise, returns {NaN, NaN}. */ - vec2 get_circle_circle_detection(const CircleColliderInternal & circle1, const CircleColliderInternal & circle2) const; + vec2 get_circle_circle_detection(const CircleColliderInternal & circle1, + const CircleColliderInternal & circle2) const; }; /** diff --git a/src/crepe/system/ParticleSystem.cpp b/src/crepe/system/ParticleSystem.cpp index 31c1800..e66c603 100644 --- a/src/crepe/system/ParticleSystem.cpp +++ b/src/crepe/system/ParticleSystem.cpp @@ -51,7 +51,8 @@ void ParticleSystem::emit_particle(ParticleEmitter & emitter, const Transform & vec2 initial_position = AbsolutePosition::get_position(transform, emitter.data.offset); float random_angle - = this->generate_random_angle(emitter.data.min_angle+transform.rotation, emitter.data.max_angle+transform.rotation); + = this->generate_random_angle(emitter.data.min_angle + transform.rotation, + emitter.data.max_angle + transform.rotation); float random_speed = this->generate_random_speed(emitter.data.min_speed, emitter.data.max_speed); diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 9d8e683..8c31743 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -16,9 +16,9 @@ #include "../facade/Texture.h" #include "../manager/ComponentManager.h" #include "../manager/ResourceManager.h" -#include "util/AbsolutePosition.h" #include "api/Text.h" #include "facade/Font.h" +#include "util/AbsolutePosition.h" #include "RenderSystem.h" #include "types.h" diff --git a/src/example/game.cpp b/src/example/game.cpp index 76ea8c2..fb7fb63 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -220,7 +220,7 @@ public: }); GameObject game_object1 = new_object( - "Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2+20}, 0, 1); + "Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2 + 20}, 0, 1); game_object1.add_component<Rigidbody>(Rigidbody::Data{ .mass = 1, .gravity_scale = 0, @@ -270,7 +270,7 @@ public: .size = {20, 20}, .angle_offset = 45, .scale_offset = 1, - .position_offset = {0,20}, + .position_offset = {0, 20}, }); //add circle with cirlcecollider deactiveated diff --git a/src/test/CollisionTest.cpp b/src/test/CollisionTest.cpp index 8f566df..11916eb 100644 --- a/src/test/CollisionTest.cpp +++ b/src/test/CollisionTest.cpp @@ -25,7 +25,6 @@ using namespace std::chrono_literals; using namespace crepe; using namespace testing; - class CollisionHandler : public Script { public: int box_id; |