summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/object.cpp2
-rw-r--r--src/path-search-dijkstra.cpp40
-rw-r--r--src/path-search.hpp3
-rw-r--r--src/point.cpp4
-rw-r--r--src/point.hpp79
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