diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/object.cpp | 2 | ||||
-rw-r--r-- | src/path-search-dijkstra.cpp | 40 | ||||
-rw-r--r-- | src/path-search.hpp | 3 | ||||
-rw-r--r-- | src/point.cpp | 4 | ||||
-rw-r--r-- | src/point.hpp | 79 |
5 files changed, 76 insertions, 52 deletions
diff --git a/src/object.cpp b/src/object.cpp index 0605fcf3..b2efb6a1 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -149,7 +149,7 @@ point object::normalize_coords(global_coords coord, Vector2b cur, Vector2i new_o point object::normalize_coords(const point& pt, Vector2i delta) { - return object::normalize_coords(pt.coord, pt.offset, delta); + return object::normalize_coords(pt.coord(), pt.offset, delta); } template<bool neighbor = true> diff --git a/src/path-search-dijkstra.cpp b/src/path-search-dijkstra.cpp index a40d79ad..7a4f9789 100644 --- a/src/path-search-dijkstra.cpp +++ b/src/path-search-dijkstra.cpp @@ -80,7 +80,7 @@ struct heap_comparator uint32_t distance(point a, point b) { Vector2i dist; - dist += Math::abs(a.coord - b.coord)*iTILE_SIZE2; + dist += Math::abs(a.coord() - b.coord())*iTILE_SIZE2; dist += Vector2i(a.offset - b.offset); return (uint32_t)Math::sqrt(dist.dot()); } @@ -201,7 +201,7 @@ path_search_result astar::Dijkstra(world& w, point from_, point to_, object_id o auto& path = result.path(); path.clear(); indexes[from_] = 0; - nodes.push_back({.dist = 0, .coord = from, .offset = from_offset }); + nodes.push_back({.dist = 0, .pt = from_ }); add_to_heap(0); if (!from_offset.isZero()) @@ -219,7 +219,7 @@ path_search_result astar::Dijkstra(world& w, point from_, point to_, object_id o path_search::is_passable(w, from.chunk3(), bb, own_id, p)) { indexes[{from, offset}] = idx; - nodes.push_back({.dist = from_offset_len, .prev = 0, .coord = from, .offset = offset}); + nodes.push_back({.dist = from_offset_len, .prev = 0, .pt = {from, offset}}); add_to_heap(idx++); } } @@ -232,44 +232,40 @@ path_search_result astar::Dijkstra(world& w, point from_, point to_, object_id o while (!Q.empty()) { const auto id = pop_from_heap(); - point n_pt; - global_coords n_coord; - Vector2b n_offset; - uint32_t n_dist; + point cur_pt; + uint32_t cur_dist; { auto& n = nodes[id]; - n_coord = n.coord; - n_offset = n.offset; - n_pt = {n_coord, n_offset}; - n_dist = n.dist; + cur_pt = n.pt; + cur_dist = n.dist; #if FM_ASTAR_NO_EDGE_CACHE - (void)n_pt; + (void)cur_pt; #endif } - if (auto d = distance({n_coord, n_offset}, {to, to_offset}); d < closest) + if (auto d = distance(cur_pt, to_); d < closest) { closest = d; - closest_pos = {n_coord, n_offset}; - closest_path_len = n_dist; + closest_pos = cur_pt; + closest_path_len = cur_dist; } #ifndef FM_NO_DEBUG if (debug >= 2) [[unlikely]] DBG_nospace << "node" << " px:" << closest << " path:" << closest_path_len - << " pos:" << Vector3i(closest_pos.coord) + << " pos:" << Vector3i(closest_pos.coord()) << ";" << closest_pos.offset; #endif - const auto bb0 = bbox_from_pos(Vector2(n_coord.local()), n_offset, own_size); + const auto bb0 = bbox_from_pos(Vector2(cur_pt.local()), cur_pt.offset, own_size); for (auto [vec, len] : directions) { - auto [new_coord, new_offset] = object::normalize_coords(n_coord, n_offset, vec); - const auto dist = n_dist + len; + auto [new_coord, new_offset] = object::normalize_coords(cur_pt, vec); + const auto dist = cur_dist + len; if (dist >= max_dist) continue; - const auto new_pt = point{.coord = new_coord, .offset = new_offset}; + const auto new_pt = point{new_coord, new_offset}; const size_t new_pt_hash = hash_point(new_pt); auto new_idx = (uint32_t)-1; @@ -316,7 +312,7 @@ path_search_result astar::Dijkstra(world& w, point from_, point to_, object_id o indexes.insert({new_pt, new_idx}, new_pt_hash); auto new_node = visited { .dist = dist, .prev = id, - .coord = new_coord, .offset = new_offset, + .pt = {new_coord, new_offset}, }; nodes.push_back(new_node); } @@ -338,7 +334,7 @@ path_search_result astar::Dijkstra(world& w, point from_, point to_, object_id o if (debug >= 1) DBG_nospace << "dijkstra: closest px:" << closest << " path:" << closest_path_len - << " pos:" << Vector3i(closest_pos.coord) + << " pos:" << Vector3i(closest_pos.coord()) << ";" << closest_pos.offset << " nodes:" << nodes.size() #if !FM_ASTAR_NO_EDGE_CACHE diff --git a/src/path-search.hpp b/src/path-search.hpp index 464596a6..e3fad6e6 100644 --- a/src/path-search.hpp +++ b/src/path-search.hpp @@ -56,8 +56,7 @@ struct astar { uint32_t dist = (uint32_t)-1; uint32_t prev = (uint32_t)-1; - global_coords coord; - Vector2b offset; + point pt; }; using pred = path_search::pred; diff --git a/src/point.cpp b/src/point.cpp index f21e2d40..67a79475 100644 --- a/src/point.cpp +++ b/src/point.cpp @@ -7,8 +7,8 @@ Debug& operator<<(Debug& dbg, const point& pt) const auto flags = dbg.flags(); dbg.setFlags(flags | Debug::Flag::NoSpace); - auto c = Vector3i(pt.coord.chunk3()); - auto t = Vector2i(pt.coord.local()); + auto c = Vector3i(pt.chunk3()); + auto t = Vector2i(pt.local()); auto o = pt.offset; dbg << "point{"; diff --git a/src/point.hpp b/src/point.hpp index 0d9db1df..fd23f72d 100644 --- a/src/point.hpp +++ b/src/point.hpp @@ -1,45 +1,74 @@ #pragma once #include "global-coords.hpp" -#include <Corrade/Utility/Move.h> +#include "compat/defs.hpp" #include <compare> +#include <type_traits> +#include <Corrade/Utility/StlForwardTuple.h> + +namespace floormat { struct point; } + +template<> struct std::tuple_size<floormat::point> : std::integral_constant<floormat::size_t, 2> {}; + +template<floormat::size_t N> struct std::tuple_element<N, floormat::point>; + +template<> struct std::tuple_element<0, floormat::point> { using type = floormat::global_coords; }; +template<> struct std::tuple_element<1, floormat::point> { using type = Magnum::Vector2b; }; namespace floormat { -// todo pack this within 8 bytes struct point { - global_coords coord; + int16_t cx = 0, cy = 0; + int8_t cz = 0; + local_coords tile; Vector2b offset; - constexpr bool operator==(const point&) const = default; - friend constexpr std::strong_ordering operator<=>(const point& a, const point& b) noexcept; + constexpr point(); + constexpr point(global_coords coord, Vector2b offset); + constexpr point(chunk_coords_ coord, local_coords tile, Vector2b offset); + fm_DECLARE_DEFAULT_COPY_ASSIGNMENT(point); + + constexpr bool operator==(const point&) const noexcept = default; + friend constexpr std::strong_ordering operator<=>(const point& a, const point& b); + constexpr global_coords coord() const; + constexpr chunk_coords chunk() const; + constexpr chunk_coords_ chunk3() const; + constexpr local_coords local() const; friend Debug& operator<<(Debug& dbg, const point& pt); }; -constexpr std::strong_ordering operator<=>(const point& p1, const point& p2) noexcept +constexpr std::strong_ordering operator<=>(const point& p1, const point& p2) { - auto c1 = Vector3i(p1.coord), c2 = Vector3i(p2.coord); - - if (auto val = c1.z() <=> c2.z(); val != std::strong_ordering::equal) - return val; - if (auto val = c1.y() <=> c2.y(); val != std::strong_ordering::equal) - return val; - if (auto val = c1.x() <=> c2.x(); val != std::strong_ordering::equal) - return val; - if (auto val = p1.offset.y() <=> p2.offset.y(); val != std::strong_ordering::equal) - return val; - if (auto val = p1.offset.x() <=> p2.offset.x(); val != std::strong_ordering::equal) - return val; - + if (auto val = p1.cz <=> p2.cz; val != std::strong_ordering::equal) return val; + if (auto val = p1.cy <=> p2.cy; val != std::strong_ordering::equal) return val; + if (auto val = p1.cx <=> p2.cx; val != std::strong_ordering::equal) return val; + if (auto val = p1.tile.y <=> p2.tile.y; val != std::strong_ordering::equal) return val; + if (auto val = p1.tile.x <=> p2.tile.x; val != std::strong_ordering::equal) return val; + if (auto val = p1.offset.y() <=> p2.offset.y(); val != std::strong_ordering::equal) return val; + if (auto val = p1.offset.x() <=> p2.offset.x(); val != std::strong_ordering::equal) return val; return std::strong_ordering::equal; } -struct packed_point -{ - uint64_t cx : 12, cy : 12, cz : 4, - tx : 8, ty : 8, - ox : 4, oy : 4; -}; +constexpr point::point() = default; +constexpr point::point(global_coords coord, Vector2b offset) : point{coord.chunk3(), coord.local(), offset} { } + +constexpr point::point(chunk_coords_ coord, local_coords tile, Vector2b offset) : + cx{coord.x}, cy{coord.y}, cz{coord.z}, tile{tile}, offset{offset} +{} + +constexpr global_coords point::coord() const { return {{cx, cy}, tile, cz}; } +constexpr chunk_coords_ point::chunk3() const { return {cx, cy, cz}; } +constexpr chunk_coords point::chunk() const { return {cx, cy}; } +constexpr local_coords point::local() const { return tile; } + +template<size_t N> std::tuple_element_t<N, point> constexpr get(point pt) { + static_assert(N < 2); + if constexpr(N == 0) + return global_coords{{pt.cx, pt.cy}, pt.tile, pt.cz}; + if constexpr(N == 1) + return pt.offset; + return {}; +} } // namespace floormat |