From e26deb3ae34d484bddb1fb1f7e648eb28b197e49 Mon Sep 17 00:00:00 2001 From: MatusGuy <85036874+MatusGuy@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:20:55 +0100 Subject: [PATCH 1/5] raycast function that returns what raycast hit --- src/collision/collision_system.cpp | 34 ++++++++++++++++++++++-------- src/collision/collision_system.hpp | 14 ++++++++++++ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/collision/collision_system.cpp b/src/collision/collision_system.cpp index 35afbbf74cf..59f0e38c51c 100644 --- a/src/collision/collision_system.cpp +++ b/src/collision/collision_system.cpp @@ -690,8 +690,11 @@ CollisionSystem::is_free_of_movingstatics(const Rectf& rect, const CollisionObje return true; } -bool -CollisionSystem::free_line_of_sight(const Vector& line_start, const Vector& line_end, bool ignore_objects, const CollisionObject* ignore_object) const +CollisionSystem::RaycastResult +CollisionSystem::get_first_line_intersection(const Vector &line_start, + const Vector &line_end, + bool ignore_objects, + const CollisionObject *ignore_object) const { using namespace collision; @@ -709,16 +712,21 @@ CollisionSystem::free_line_of_sight(const Vector& line_start, const Vector& line { continue; } - - const Tile& tile = solids->get_tile_at(test_vector); + + const Tile* tile = &solids->get_tile_at(test_vector); + + // Get the rect of the tile. + const Rectf tilebox(glm::floor((test_vector - solids->get_offset()) / 32.0f), {32.f, 32.f}); + // FIXME: check collision with slope tiles - if ((tile.get_attributes() & Tile::SOLID)) return false; + if ((tile->get_attributes() & Tile::SOLID)) + return {true, true, nullptr, tile, tilebox}; } } } if (ignore_objects) - return true; + return {false}; // Check if no object is in the way. for (const auto& object : m_objects) { @@ -726,12 +734,20 @@ CollisionSystem::free_line_of_sight(const Vector& line_start, const Vector& line if (!object->is_valid()) continue; if ((object->get_group() == COLGROUP_MOVING) || (object->get_group() == COLGROUP_MOVING_STATIC) - || (object->get_group() == COLGROUP_STATIC)) { - if (intersects_line(object->get_bbox(), line_start, line_end)) return false; + || (object->get_group() == COLGROUP_STATIC)) + { + if (intersects_line(object->get_bbox(), line_start, line_end)) + return {true, false, object}; } } - return true; + return {false}; +} + +bool +CollisionSystem::free_line_of_sight(const Vector& line_start, const Vector& line_end, bool ignore_objects, const CollisionObject* ignore_object) const +{ + return !get_first_line_intersection(line_start, line_end, ignore_objects, ignore_object).is_valid; } std::vector diff --git a/src/collision/collision_system.hpp b/src/collision/collision_system.hpp index c422f9755ab..d48ed8b5d44 100644 --- a/src/collision/collision_system.hpp +++ b/src/collision/collision_system.hpp @@ -56,6 +56,20 @@ class CollisionSystem final bool is_free_of_tiles(const Rectf& rect, const bool ignoreUnisolid = false, uint32_t tiletype = Tile::SOLID) const; bool is_free_of_statics(const Rectf& rect, const CollisionObject* ignore_object, const bool ignoreUnisolid) const; bool is_free_of_movingstatics(const Rectf& rect, const CollisionObject* ignore_object) const; + + struct RaycastResult + { + const bool is_valid; /**< true if raycast hit something */ + const bool is_tile = true; /**< true if raycast hit a tile */ + const CollisionObject* object = nullptr; /**< object that the raycast hit, nullptr if is_tile is true */ + const Tile* tile = nullptr; /**< tile that the raycast hit, nullptr if is_tile is false */ + const Rectf tile_box = {0,0,0,0}; /**< hitbox of tile, empty if is_tile is false */ + }; + + RaycastResult get_first_line_intersection(const Vector& line_start, + const Vector& line_end, + bool ignore_objects, + const CollisionObject* ignore_object) const; bool free_line_of_sight(const Vector& line_start, const Vector& line_end, bool ignore_objects, const CollisionObject* ignore_object) const; std::vector get_nearby_objects(const Vector& center, float max_distance) const; From 3ad742675a574a6ec653c91a845c0c52db9c2c08 Mon Sep 17 00:00:00 2001 From: MatusGuy <85036874+MatusGuy@users.noreply.github.com> Date: Fri, 8 Sep 2023 17:04:30 +0100 Subject: [PATCH 2/5] fix random segfault? --- src/collision/collision_system.cpp | 2 +- src/collision/collision_system.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/collision/collision_system.cpp b/src/collision/collision_system.cpp index 59f0e38c51c..3b8a4daf31c 100644 --- a/src/collision/collision_system.cpp +++ b/src/collision/collision_system.cpp @@ -716,7 +716,7 @@ CollisionSystem::get_first_line_intersection(const Vector &line_start, const Tile* tile = &solids->get_tile_at(test_vector); // Get the rect of the tile. - const Rectf tilebox(glm::floor((test_vector - solids->get_offset()) / 32.0f), {32.f, 32.f}); + const Rectf tilebox(glm::floor((test_vector - solids->get_offset()) / 32.0f), Sizef(32.f, 32.f)); // FIXME: check collision with slope tiles if ((tile->get_attributes() & Tile::SOLID)) diff --git a/src/collision/collision_system.hpp b/src/collision/collision_system.hpp index d48ed8b5d44..ac059a7b8fc 100644 --- a/src/collision/collision_system.hpp +++ b/src/collision/collision_system.hpp @@ -63,7 +63,7 @@ class CollisionSystem final const bool is_tile = true; /**< true if raycast hit a tile */ const CollisionObject* object = nullptr; /**< object that the raycast hit, nullptr if is_tile is true */ const Tile* tile = nullptr; /**< tile that the raycast hit, nullptr if is_tile is false */ - const Rectf tile_box = {0,0,0,0}; /**< hitbox of tile, empty if is_tile is false */ + const Rectf tile_box = {}; /**< hitbox of tile, empty if is_tile is false */ }; RaycastResult get_first_line_intersection(const Vector& line_start, From 5ba9902c3c926784f8664b202909dcc265a20e16 Mon Sep 17 00:00:00 2001 From: MatusGuy <85036874+MatusGuy@users.noreply.github.com> Date: Thu, 14 Sep 2023 21:35:56 +0100 Subject: [PATCH 3/5] use union for hit --- src/collision/collision_system.cpp | 4 ++-- src/collision/collision_system.hpp | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/collision/collision_system.cpp b/src/collision/collision_system.cpp index 3b8a4daf31c..2dbdb8e0a40 100644 --- a/src/collision/collision_system.cpp +++ b/src/collision/collision_system.cpp @@ -720,7 +720,7 @@ CollisionSystem::get_first_line_intersection(const Vector &line_start, // FIXME: check collision with slope tiles if ((tile->get_attributes() & Tile::SOLID)) - return {true, true, nullptr, tile, tilebox}; + return {true, {.tile = tile}, tilebox}; } } } @@ -737,7 +737,7 @@ CollisionSystem::get_first_line_intersection(const Vector &line_start, || (object->get_group() == COLGROUP_STATIC)) { if (intersects_line(object->get_bbox(), line_start, line_end)) - return {true, false, object}; + return {true, {.object = object}, object->get_bbox()}; } } diff --git a/src/collision/collision_system.hpp b/src/collision/collision_system.hpp index ac059a7b8fc..c6e2b86939c 100644 --- a/src/collision/collision_system.hpp +++ b/src/collision/collision_system.hpp @@ -35,6 +35,17 @@ class Sector; class CollisionSystem final { public: + struct RaycastResult + { + const bool is_valid; /**< true if raycast hit something */ + union + { + const CollisionObject* object; + const Tile* tile; + } hit; /**< tile/object that the raycast hit */ + const Rectf box = {}; /**< hitbox of tile/object */ + }; + CollisionSystem(Sector& sector); void add(CollisionObject* object); @@ -57,14 +68,6 @@ class CollisionSystem final bool is_free_of_statics(const Rectf& rect, const CollisionObject* ignore_object, const bool ignoreUnisolid) const; bool is_free_of_movingstatics(const Rectf& rect, const CollisionObject* ignore_object) const; - struct RaycastResult - { - const bool is_valid; /**< true if raycast hit something */ - const bool is_tile = true; /**< true if raycast hit a tile */ - const CollisionObject* object = nullptr; /**< object that the raycast hit, nullptr if is_tile is true */ - const Tile* tile = nullptr; /**< tile that the raycast hit, nullptr if is_tile is false */ - const Rectf tile_box = {}; /**< hitbox of tile, empty if is_tile is false */ - }; RaycastResult get_first_line_intersection(const Vector& line_start, const Vector& line_end, From f0e900d42205a0d4699d8ceaded2fea2b51b76c0 Mon Sep 17 00:00:00 2001 From: MatusGuy <85036874+MatusGuy@users.noreply.github.com> Date: Sun, 17 Sep 2023 22:23:40 +0100 Subject: [PATCH 4/5] at last... union initializaiton done right --- src/collision/collision_system.cpp | 27 ++++++++++++++++++++------- src/collision/collision_system.hpp | 4 ++-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/collision/collision_system.cpp b/src/collision/collision_system.cpp index 2dbdb8e0a40..b83dcda5d19 100644 --- a/src/collision/collision_system.cpp +++ b/src/collision/collision_system.cpp @@ -697,6 +697,8 @@ CollisionSystem::get_first_line_intersection(const Vector &line_start, const CollisionObject *ignore_object) const { using namespace collision; + using RaycastResult = CollisionSystem::RaycastResult; + RaycastResult result{}; // Check if no tile is in the way. const float lsx = std::min(line_start.x, line_end.x); @@ -715,18 +717,23 @@ CollisionSystem::get_first_line_intersection(const Vector &line_start, const Tile* tile = &solids->get_tile_at(test_vector); - // Get the rect of the tile. - const Rectf tilebox(glm::floor((test_vector - solids->get_offset()) / 32.0f), Sizef(32.f, 32.f)); - // FIXME: check collision with slope tiles if ((tile->get_attributes() & Tile::SOLID)) - return {true, {.tile = tile}, tilebox}; + { + result.is_valid = true; + result.hit.tile = tile; + result.box = {glm::floor((test_vector - solids->get_offset()) / 32.0f), Sizef(32.f, 32.f)}; + return result; + } } } } if (ignore_objects) - return {false}; + { + result.is_valid = false; + return result; + } // Check if no object is in the way. for (const auto& object : m_objects) { @@ -737,11 +744,17 @@ CollisionSystem::get_first_line_intersection(const Vector &line_start, || (object->get_group() == COLGROUP_STATIC)) { if (intersects_line(object->get_bbox(), line_start, line_end)) - return {true, {.object = object}, object->get_bbox()}; + { + result.is_valid = true; + result.hit.object = object; + result.box = object->get_bbox(); + return result; + } } } - return {false}; + result.is_valid = false; + return result; } bool diff --git a/src/collision/collision_system.hpp b/src/collision/collision_system.hpp index c6e2b86939c..9c4f876547e 100644 --- a/src/collision/collision_system.hpp +++ b/src/collision/collision_system.hpp @@ -37,13 +37,13 @@ class CollisionSystem final public: struct RaycastResult { - const bool is_valid; /**< true if raycast hit something */ + bool is_valid; /**< true if raycast hit something */ union { const CollisionObject* object; const Tile* tile; } hit; /**< tile/object that the raycast hit */ - const Rectf box = {}; /**< hitbox of tile/object */ + Rectf box = {}; /**< hitbox of tile/object */ }; CollisionSystem(Sector& sector); From ffbb339212286919d2207bf789b929ec5b6d8ad0 Mon Sep 17 00:00:00 2001 From: MatusGuy <85036874+MatusGuy@users.noreply.github.com> Date: Mon, 18 Sep 2023 19:48:37 +0100 Subject: [PATCH 5/5] minor changes --- src/collision/collision_system.cpp | 7 +++---- src/collision/collision_system.hpp | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/collision/collision_system.cpp b/src/collision/collision_system.cpp index b83dcda5d19..7a5dedd11c4 100644 --- a/src/collision/collision_system.cpp +++ b/src/collision/collision_system.cpp @@ -691,13 +691,12 @@ CollisionSystem::is_free_of_movingstatics(const Rectf& rect, const CollisionObje } CollisionSystem::RaycastResult -CollisionSystem::get_first_line_intersection(const Vector &line_start, - const Vector &line_end, +CollisionSystem::get_first_line_intersection(const Vector& line_start, + const Vector& line_end, bool ignore_objects, - const CollisionObject *ignore_object) const + const CollisionObject* ignore_object) const { using namespace collision; - using RaycastResult = CollisionSystem::RaycastResult; RaycastResult result{}; // Check if no tile is in the way. diff --git a/src/collision/collision_system.hpp b/src/collision/collision_system.hpp index 9c4f876547e..a263e439d3c 100644 --- a/src/collision/collision_system.hpp +++ b/src/collision/collision_system.hpp @@ -46,6 +46,7 @@ class CollisionSystem final Rectf box = {}; /**< hitbox of tile/object */ }; +public: CollisionSystem(Sector& sector); void add(CollisionObject* object);