diff options
-rw-r--r-- | src/crepe/api/Rigidbody.h | 31 | ||||
-rw-r--r-- | src/crepe/system/CollisionSystem.cpp | 17 | ||||
-rw-r--r-- | src/crepe/system/CollisionSystem.h | 41 | ||||
-rw-r--r-- | src/example/game.cpp | 15 |
4 files changed, 60 insertions, 44 deletions
diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h index df97763..9dbb42b 100644 --- a/src/crepe/api/Rigidbody.h +++ b/src/crepe/api/Rigidbody.h @@ -123,26 +123,37 @@ public: */ float elastisity_coefficient = 0.0; - //! Enable static collision handeling for object colliding with kinematic object in collision system - bool kinematic_collision = true; - /** - * \brief Defines the collision layers of a GameObject. + * \brief Enables collision handling for objects colliding with kinematic objects. * - * The `collision_layers` specifies the layers that the GameObject will collide with. - * Each element represents a layer ID, and the GameObject will only detect - * collisions with other GameObjects that belong to that `collision_layer`. + * Enables collision handling for objects colliding with kinematic objects in the collision system. + * If `kinematic_collision` is true, dynamic objects cannot pass through this kinematic object. + * This ensures that kinematic objects delegate collision handling to the collision system. */ + bool kinematic_collision = true; + + /** + * \brief Defines the collision layers a GameObject interacts with. + * + * The `collision_layers` represent the set of layers the GameObject can detect collisions with. + * Each element in this set corresponds to a layer ID. The GameObject will only collide with other + * GameObjects that belong to one these layers. + */ std::set<int> collision_layers = {0}; - //! the collision layer of the object. + /** + * \brief Specifies the collision layer of the GameObject. + * + * The `collision_layer` indicates the single layer that this GameObject belongs to. + * This determines which layers other objects must match to detect collisions with this object. + */ int collision_layer = 0; /** * \brief Defines the collision layers of a GameObject. * * The `collision_names` specifies where the GameObject will collide with. - * Each element represents a name. + * Each element represents a name from the Metadata of the gameobject. */ std::set<std::string> collision_names; @@ -150,7 +161,7 @@ public: * \brief Defines the collision layers of a GameObject. * * The `collision_tags` specifies where the GameObject will collide with. - * Each element represents a tag. + * Each element represents a tag from the Metadata of the gameobject. */ std::set<std::string> collision_tags; diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp index 6ed640a..3da8a50 100644 --- a/src/crepe/system/CollisionSystem.cpp +++ b/src/crepe/system/CollisionSystem.cpp @@ -167,7 +167,7 @@ bool CollisionSystem::detect_collision(CollisionInternal & self,CollisionInterna .rigidbody = other.info.rigidbody }; resolution = this->get_box_box_detection(BOX1, BOX2); - if(resolution == vec2{-1,-1}) return false; + if(std::isnan(resolution.x) && std::isnan(resolution.y)) return false; break; } @@ -183,7 +183,7 @@ bool CollisionSystem::detect_collision(CollisionInternal & self,CollisionInterna .rigidbody = other.info.rigidbody }; resolution = this->get_box_circle_detection(BOX1, CIRCLE2); - if(resolution == vec2{-1,-1}) return false; + if(std::isnan(resolution.x) && std::isnan(resolution.y)) return false; resolution = -resolution; break; } @@ -199,7 +199,7 @@ bool CollisionSystem::detect_collision(CollisionInternal & self,CollisionInterna .rigidbody = other.info.rigidbody }; resolution = this->get_circle_circle_detection(CIRCLE1,CIRCLE2); - if(resolution == vec2{-1,-1}) return false; + if(std::isnan(resolution.x) && std::isnan(resolution.y)) return false; break; } case CollisionInternalType::CIRCLE_BOX: { @@ -214,7 +214,7 @@ bool CollisionSystem::detect_collision(CollisionInternal & self,CollisionInterna .rigidbody = other.info.rigidbody }; resolution = this->get_box_circle_detection(BOX2, CIRCLE1); - if(resolution == vec2{-1,-1}) return false; + if(std::isnan(resolution.x) && std::isnan(resolution.y)) return false; break; } case CollisionInternalType::NONE: @@ -228,7 +228,7 @@ bool CollisionSystem::detect_collision(CollisionInternal & self,CollisionInterna } vec2 CollisionSystem::get_box_box_detection(const BoxColliderInternal & box1, const BoxColliderInternal & box2) const { - vec2 resolution; + 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); @@ -266,9 +266,8 @@ vec2 CollisionSystem::get_box_box_detection(const BoxColliderInternal & box1, co resolution.y = (delta.y > 0) ? -overlap_y : overlap_y; } } - return resolution; } - return vec2{-1,-1}; + return resolution; } vec2 CollisionSystem::get_box_circle_detection(const BoxColliderInternal & box, const CircleColliderInternal & circle) const { @@ -312,7 +311,7 @@ vec2 CollisionSystem::get_box_circle_detection(const BoxColliderInternal & box, return vec2{collision_normal * penetration_depth}; } // No collision - return vec2{-1,-1}; + return vec2{std::nanf(""), std::nanf("")}; } vec2 CollisionSystem::get_circle_circle_detection(const CircleColliderInternal & circle1, const CircleColliderInternal & circle2) const { @@ -353,7 +352,7 @@ vec2 CollisionSystem::get_circle_circle_detection(const CircleColliderInternal & return resolution; } // No collision - return vec2{-1,-1}; + return vec2{std::nanf(""), std::nanf("")}; } CollisionSystem::Direction CollisionSystem::resolution_correction(vec2 & resolution,const Rigidbody::Data & rigidbody) { diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h index 13ce8f0..2e9901c 100644 --- a/src/crepe/system/CollisionSystem.h +++ b/src/crepe/system/CollisionSystem.h @@ -31,7 +31,7 @@ private: //! Movement in the Y direction. Y_DIRECTION, //! Movement in both X and Y directions. - BOTH + BOTH, }; public: @@ -87,19 +87,17 @@ private: Direction resolution_direction = Direction::NONE; }; - //! Structure of collider with addtitional components - struct BoxColliderInternal { - BoxCollider & collider; - Transform & transform; - Rigidbody & rigidbody; - }; - - //! Structure of collider with addtitional components - struct CircleColliderInternal { - CircleCollider & collider; - Transform & transform; - Rigidbody & rigidbody; + //! Structure of a collider with additional components + template <typename ColliderType> + struct ColliderInternal { + ColliderType& collider; + Transform& transform; + Rigidbody& rigidbody; }; + //! Predefined BoxColliderInternal. (System is only made for this type) + using BoxColliderInternal = ColliderInternal<BoxCollider>; + //! Predefined CircleColliderInternal. (System is only made for this type) + using CircleColliderInternal = ColliderInternal<CircleCollider>; public: //! Updates the collision system by checking for collisions between colliders and handling them. @@ -119,9 +117,11 @@ private: private: /** - * \brief Handles collision resolution between two colliders. + * \brief Converts internal collision data into user-accessible collision information. * - * Processes collision data and adjusts objects to resolve collisions and/or calls the user oncollision script function. + * This function processes collision data from two colliding entities and packages it + * into a structured format that is accessible for further use, + * such as resolving collisions and triggering user-defined collision scripts. * * \param data1 Collision data for the first collider. * \param data2 Collision data for the second collider. @@ -130,14 +130,17 @@ private: /** - * \brief Corrects the resolution of the collision + * \brief Corrects the collision resolution vector and determines its direction. * - * This function corrects the resolution by fixing the x or y if it is empty. - * Besides this with the input of the resolution the direction is saved before correction. + * This function adjusts the provided resolution vector based on the + * rigidbody's linear velocity to ensure consistent collision correction. If the resolution + * vector has only one non-zero component (either x or y), the missing component is computed + * based on the rigidbody's velocity. If both components are non-zero, it indicates a corner + * collision. The function also identifies the direction of the resolution and returns it. * * \param resolution resolution vector that needs to be corrected * \param rigidbody rigidbody data used to correct resolution - * \return Direction of resolution + * \return A Direction indicating the resolution direction */ Direction resolution_correction(vec2 & resolution,const Rigidbody::Data & rigidbody); diff --git a/src/example/game.cpp b/src/example/game.cpp index 2660055..f757d5f 100644 --- a/src/example/game.cpp +++ b/src/example/game.cpp @@ -197,7 +197,7 @@ public: world.add_component<Rigidbody>(Rigidbody::Data{ .mass = 1, .gravity_scale = 0, - .body_type = Rigidbody::BodyType::STATIC, + .body_type = Rigidbody::BodyType::DYNAMIC, }); world.add_component<BoxCollider>( vec2{world_collider, world_collider}, @@ -224,7 +224,7 @@ public: game_object1.add_component<Rigidbody>(Rigidbody::Data{ .mass = 1, .gravity_scale = 0, - .body_type = Rigidbody::BodyType::STATIC, + .body_type = Rigidbody::BodyType::DYNAMIC, .linear_velocity = {0, 0}, .constraints = {0, 0, 0}, .elastisity_coefficient = 1, @@ -283,20 +283,20 @@ public: }) .active = false; - Asset img5{"asset/texture/test_ap43.png"}; + Asset img5{"asset/texture/square.png"}; GameObject particle = new_object( "Name", "Tag", vec2{screen_size_width / 2, screen_size_height / 2}, 90, 1); auto & particle_image = particle.add_component<Sprite>(img5, Sprite::Data{ - .size = {20, 20}, + .size = {5, 5}, .angle_offset = 45, - .scale_offset = 2, + .scale_offset = 1, }); auto & test = particle.add_component<ParticleEmitter>(particle_image, ParticleEmitter::Data{ .offset = {0, 0}, .max_particles = 256, - .emission_rate = 1, + .emission_rate = 4, .min_speed = 10, .max_speed = 20, .min_angle = -20, @@ -304,6 +304,9 @@ public: .begin_lifespan = 0, .end_lifespan = 5, }); + particle.add_component<Rigidbody>(Rigidbody::Data{ + .angular_velocity = 20, + }); } string get_name() const { return "scene1"; } |