aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/system/CollisionSystem.h
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-12-20 11:10:06 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-12-20 11:10:06 +0100
commit5b1a26a13d8a2f44a7ef1fa8c0fc609c37adc28b (patch)
tree801ff9f3bbd82efacb5d4fdb1cbe4c09cfedf7c5 /src/crepe/system/CollisionSystem.h
parent88d84763147fbd6bcc087f15a7460566a009cdb2 (diff)
parent69ca2bafcd617ac8af1b8f715f0c802205a60ab1 (diff)
merge masterloek/replay
Diffstat (limited to 'src/crepe/system/CollisionSystem.h')
-rw-r--r--src/crepe/system/CollisionSystem.h290
1 files changed, 137 insertions, 153 deletions
diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h
index 48a8f86..3fb9723 100644
--- a/src/crepe/system/CollisionSystem.h
+++ b/src/crepe/system/CollisionSystem.h
@@ -23,6 +23,42 @@ public:
using System::System;
private:
+ //! Enum representing movement directions during collision resolution.
+ enum class Direction {
+ //! No movement required.
+ NONE,
+ //! Movement in the X direction.
+ X_DIRECTION,
+ //! Movement in the Y direction.
+ Y_DIRECTION,
+ //! Movement in both X and Y directions.
+ BOTH,
+ };
+
+public:
+ //! Structure representing components of the collider
+ struct ColliderInfo {
+ Transform & transform;
+ Rigidbody & rigidbody;
+ Metadata & metadata;
+ };
+
+ /**
+ * \brief Structure representing detailed collision information between two colliders.
+ *
+ * Includes information about the colliding objects and the resolution data for handling the collision.
+ */
+ struct CollisionInfo {
+ ColliderInfo self;
+ ColliderInfo other;
+ //! The resolution vector for the collision.
+ vec2 resolution;
+ //! The direction of movement for resolving the collision.
+ Direction resolution_direction = Direction::NONE;
+ CollisionInfo operator-() const;
+ };
+
+private:
//! A variant type that can hold either a BoxCollider or a CircleCollider.
using collider_variant = std::variant<std::reference_wrapper<BoxCollider>,
std::reference_wrapper<CircleCollider>>;
@@ -33,12 +69,13 @@ private:
CIRCLE_CIRCLE,
BOX_CIRCLE,
CIRCLE_BOX,
+ NONE,
};
/**
* \brief A structure to store the collision data of a single collider.
*
- * This structure all components and id that are for needed within this system when calculating or handeling collisions.
+ * This structure all components and id that are for needed within this system when calculating or handling collisions.
* The transform and rigidbody are mostly needed for location and rotation.
* In rigidbody additional info is written about what the body of the object is,
* and how it should respond on a collision.
@@ -46,43 +83,23 @@ private:
struct CollisionInternal {
game_object_id_t id = 0;
collider_variant collider;
- Transform & transform;
- Rigidbody & rigidbody;
- };
-
- //! Enum representing movement directions during collision resolution.
- enum class Direction {
- //! No movement required.
- NONE,
- //! Movement in the X direction.
- X_DIRECTION,
- //! Movement in the Y direction.
- Y_DIRECTION,
- //! Movement in both X and Y directions.
- BOTH
- };
-
-public:
- /**
- * \brief Structure representing detailed collision information between two colliders.
- *
- * Includes information about the colliding objects and the resolution data for handling the collision.
- */
- struct CollisionInfo {
- Collider & this_collider;
- Transform & this_transform;
- Rigidbody & this_rigidbody;
- Metadata & this_metadata;
- Collider & other_collider;
- Transform & other_transform;
- Rigidbody & other_rigidbody;
- Metadata & other_metadata;
- //! The resolution vector for the collision.
+ ColliderInfo info;
vec2 resolution;
- //! The direction of movement for resolving the collision.
Direction resolution_direction = Direction::NONE;
};
+ //! 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.
void fixed_update() override;
@@ -100,114 +117,90 @@ private:
CollisionInternalType get_collider_type(const collider_variant & collider1,
const collider_variant & collider2) const;
- /**
- * \brief Calculates the current position of a collider.
- *
- * Combines the Collider offset, Transform position, and Rigidbody offset to compute the position of the collider.
- *
- * \param collider_offset The offset of the collider.
- * \param transform The Transform of the associated game object.
- * \param rigidbody The Rigidbody of the associated game object.
- * \return The calculated position of the collider.
- */
- vec2 get_current_position(const vec2 & collider_offset, const Transform & transform,
- const Rigidbody & rigidbody) const;
-
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.
*/
- void collision_handler_request(CollisionInternal & data1, CollisionInternal & data2);
+ CollisionInfo get_collision_info(const CollisionInternal & data1,
+ const CollisionInternal & data2) const;
/**
- * \brief Resolves collision between two colliders and calculates the movement required.
+ * \brief Corrects the collision resolution vector and determines its direction.
*
- * Determines the displacement and direction needed to separate colliders based on their types.
+ * 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 data1 Collision data for the first collider.
- * \param data2 Collision data for the second collider.
- * \param type The type of collider pair.
- * \return A pair containing the resolution vector and direction for the first collider.
+ * \param resolution resolution vector that needs to be corrected
+ * \param rigidbody rigidbody data used to correct resolution
+ * \return A Direction indicating the resolution direction
*/
- std::pair<vec2, Direction> collision_handler(CollisionInternal & data1,
- CollisionInternal & data2,
- CollisionInternalType type);
+ Direction resolution_correction(vec2 & resolution, const Rigidbody::Data & rigidbody);
/**
- * \brief Calculates the resolution vector for two BoxColliders.
+ * \brief Determines the appropriate collision handler for a given collision event.
*
- * Computes the displacement required to separate two overlapping BoxColliders.
+ * This function identifies the correct collision resolution process based on the body types
+ * of the colliders involved in the collision. It delegates
+ * collision handling to specific handlers and calls collision event scripts
+ * as needed.
*
- * \param box_collider1 The first BoxCollider.
- * \param box_collider2 The second BoxCollider.
- * \param position1 The position of the first BoxCollider.
- * \param position2 The position of the second BoxCollider.
- * \return The resolution vector for the collision.
+ * \param info Collision information containing data about both colliders.
*/
- vec2 get_box_box_resolution(const BoxCollider & box_collider1,
- const BoxCollider & box_collider2, const vec2 & position1,
- const vec2 & position2) const;
+ void determine_collision_handler(const CollisionInfo & info);
/**
- * \brief Calculates the resolution vector for two CircleCollider.
+ * \brief Calls both collision script
*
- * Computes the displacement required to separate two overlapping CircleCollider.
+ * Calls both collision script to let user add additonal handling or handle full collision.
*
- * \param circle_collider1 The first CircleCollider.
- * \param circle_collider2 The second CircleCollider.
- * \param final_position1 The position of the first CircleCollider.
- * \param final_position2 The position of the second CircleCollider.
- * \return The resolution vector for the collision.
+ * \param info Collision information containing data about both colliders.
*/
- vec2 get_circle_circle_resolution(const CircleCollider & circle_collider1,
- const CircleCollider & circle_collider2,
- const vec2 & final_position1,
- const vec2 & final_position2) const;
+ void call_collision_events(const CollisionInfo & info);
/**
- * \brief Calculates the resolution vector for two CircleCollider.
- *
- * Computes the displacement required to separate two overlapping CircleCollider.
+ * \brief Handles collisions involving static objects.
*
- * \param circle_collider The first CircleCollider.
- * \param box_collider The second CircleCollider.
- * \param circle_position The position of the CircleCollider.
- * \param box_position The position of the BoxCollider.
- * \return The resolution vector for the collision.
- */
- vec2 get_circle_box_resolution(const CircleCollider & circle_collider,
- const BoxCollider & box_collider,
- const vec2 & circle_position,
- const vec2 & box_position) const;
-
- /**
- * \brief Determines the appropriate collision handler for a collision.
+ * This function resolves collisions between static and dynamic objects by adjusting
+ * the position of the static object and modifying the velocity of the dynamic object
+ * if elasticity is enabled. The position of the static object is corrected
+ * based on the collision resolution, and the dynamic object's velocity is adjusted
+ * accordingly to reflect the collision response.
*
- * Decides the correct resolution process based on the dynamic or static nature of the colliders involved.
+ * The handling includes stopping movement, applying bouncing based on the elasticity
+ * coefficient, and adjusting the position of the dynamic object if needed.
*
* \param info Collision information containing data about both colliders.
*/
- void determine_collision_handler(CollisionInfo & info);
+ void static_collision_handler(const CollisionInfo & info);
/**
- * \brief Handles collisions involving static objects.
+ * \brief Handles collisions involving dynamic objects.
*
- * Resolves collisions by adjusting positions and modifying velocities if bounce is enabled.
+ * Resolves collisions between two dynamic objects by adjusting their positions and modifying
+ * their velocities based on the collision resolution. If elasticity is enabled,
+ * the velocity of both objects is reversed and scaled by the respective elasticity coefficient.
+ * The positions of the objects are adjusted based on the collision resolution.
*
* \param info Collision information containing data about both colliders.
*/
- void static_collision_handler(CollisionInfo & info);
+ void dynamic_collision_handler(const CollisionInfo & info);
private:
/**
* \brief Checks for collisions between colliders.
*
- * Identifies collisions and generates pairs of colliding objects for further processing.
+ * This function checks all active colliders and identifies pairs of colliding objects.
+ * For each identified collision, the appropriate collision data is returned as pairs for further processing.
*
* \param colliders A collection of all active colliders.
* \return A list of collision pairs with their associated data.
@@ -216,86 +209,77 @@ private:
gather_collisions(std::vector<CollisionInternal> & colliders);
/**
- * \brief Checks if two collision layers have at least one common layer.
+ * \brief Checks if the settings allow collision
*
- * This function checks if there is any overlapping layer between the two inputs.
- * It compares each layer from the first input to see
- * if it exists in the second input. If at least one common layer is found,
- * the function returns true, indicating that the two colliders share a common
- * collision layer.
+ * This function checks if there is any collison layer where each object is located in.
+ * After checking the layers it checks the names and at last the tags.
+ * if in all three sets nothing is found collision can not happen.
*
- * \param layers1 all collision layers for the first collider.
- * \param layers2 all collision layers for the second collider.
- * \return Returns true if there is at least one common layer, false otherwise.
+ * \param this_rigidbody Rigidbody of first object
+ * \param other_rigidbody Rigidbody of second collider
+ * \param this_metadata Rigidbody of first object
+ * \param other_metadata Rigidbody of second object
+ * \return Returns true if there is at least one comparison found.
*/
-
- bool have_common_layer(const std::set<int> & layers1, const std::set<int> & layers2);
+ bool should_collide(const CollisionInternal & self,
+ const CollisionInternal & other) const; //done
/**
* \brief Checks for collision between two colliders.
*
- * Calls the appropriate collision detection function based on the collider types.
+ * This function determines whether two colliders are colliding based on their types.
+ * It calls the appropriate collision detection function based on the collider pair type and stores the collision resolution data.
+ * If a collision is detected, it returns true, otherwise false.
*
* \param first_info Collision data for the first collider.
* \param second_info Collision data for the second collider.
* \param type The type of collider pair.
* \return True if a collision is detected, otherwise false.
*/
- bool get_collision(const CollisionInternal & first_info,
- const CollisionInternal & second_info,
- CollisionInternalType type) const;
+ bool detect_collision(CollisionInternal & first_info, CollisionInternal & second_info,
+ const CollisionInternalType & type);
/**
* \brief Detects collisions between two BoxColliders.
*
- * \param box1 The first BoxCollider.
- * \param box2 The second BoxCollider.
- * \param transform1 Transform of the first object.
- * \param transform2 Transform of the second object.
- * \param rigidbody1 Rigidbody of the first object.
- * \param rigidbody2 Rigidbody of the second object.
- * \return True if a collision is detected, otherwise false.
+ * This function checks whether two `BoxCollider` are colliding based on their positions and scaled dimensions.
+ * If a collision is detected, it calculates the overlap along the X and Y axes and returns the resolution vector.
+ * If no collision is detected, it returns a vector with NaN values.
+
+ * \param box1 Information about the first BoxCollider.
+ * \param box2 Information about the second BoxCollider.
+ * \return If colliding, returns the resolution vector; otherwise, returns {NaN, NaN}.
*/
- bool get_box_box_collision(const BoxCollider & box1, const BoxCollider & box2,
- const Transform & transform1, const Transform & transform2,
- const Rigidbody & rigidbody1,
- const Rigidbody & rigidbody2) const;
+ vec2 get_box_box_detection(const BoxColliderInternal & box1,
+ const BoxColliderInternal & box2) const;
/**
* \brief Check collision for box on circle collider
*
- * \param box1 The BoxCollider
- * \param circle2 The CircleCollider
- * \param transform1 Transform of the first object.
- * \param transform2 Transform of the second object.
- * \param rigidbody1 Rigidbody of the first object.
- * \param rigidbody2 Rigidbody of the second object.
- * \return True if a collision is detected, otherwise false.
+ * This function detects if a collision occurs between a rectangular box and a circular collider.
+ * If a collision is detected, the function calculates the resolution vector to resolve the collision.
+ * If no collision is detected, it returns a vector with NaN values
+ *
+ * \param box1 Information about the BoxCollider.
+ * \param circle2 Information about the circleCollider.
+ * \return If colliding, returns the resolution vector; otherwise, returns {NaN, NaN}.
*/
- bool get_box_circle_collision(const BoxCollider & box1, const CircleCollider & circle2,
- const Transform & transform1, const Transform & transform2,
- const Rigidbody & rigidbody1,
- const Rigidbody & rigidbody2) const;
+ vec2 get_box_circle_detection(const BoxColliderInternal & box1,
+ const CircleColliderInternal & circle2) const;
/**
* \brief Check collision for circle on circle collider
*
- * \param circle1 First CircleCollider
- * \param circle2 Second CircleCollider
- * \param transform1 Transform of the first object.
- * \param transform2 Transform of the second object.
- * \param rigidbody1 Rigidbody of the first object.
- * \param rigidbody2 Rigidbody of the second object.
- * \return True if a collision is detected, otherwise false.
+ * This function detects if a collision occurs between two circular colliders.
+ * If a collision is detected, it calculates the resolution vector to resolve the collision.
+ * If no collision is detected, it returns a vector with NaN values.
*
- * \return status of collision
+ * \param circle1 Information about the first circleCollider.
+ * \param circle2 Information about the second circleCollider.
+ * \return If colliding, returns the resolution vector; otherwise, returns {NaN, NaN}.
*/
- bool get_circle_circle_collision(const CircleCollider & circle1,
- const CircleCollider & circle2,
- const Transform & transform1,
- const Transform & transform2,
- const Rigidbody & rigidbody1,
- const Rigidbody & rigidbody2) const;
+ vec2 get_circle_circle_detection(const CircleColliderInternal & circle1,
+ const CircleColliderInternal & circle2) const;
};
/**