40 template <std::
integral T>
41 constexpr bool is_surrounding(glm::tvec2<T> a, glm::tvec2<T> b) {
const auto d = glm::abs_distance(a, b);
return d.x < 2 && d.y < 2 && d.x + d.y > 0; }
42 template <std::
integral T>
43 constexpr bool is_neighbor(glm::tvec2<T> a, glm::tvec2<T> b) {
const auto d = glm::abs_distance(a, b);
return d.x < 2 && d.y < 2 && d.x != d.y; }
44 template <std::
integral T>
45 constexpr bool is_diagonal_neighbor(glm::tvec2<T> a, glm::tvec2<T> b) {
const auto d = glm::abs_distance(a, b);
return d.x < 2 && d.y < 2 && d.x == d.y; }
48 template <
typename METRIC,
typename T>
49 concept metric = std::integral<T> &&
requires (T t, glm::tvec2<T> vec) {
51 { METRIC::is_adjacent(vec, vec) } -> std::convertible_to<bool>;
53 { METRIC::is_adjacent(direction{}) } -> std::convertible_to<bool>;
57 { METRIC::distance(vec, vec) } -> std::convertible_to<T>;
63 template <std::
integral T>
64 static constexpr auto is_adjacent(glm::tvec2<T> a, glm::tvec2<T> b)
66 return is_neighbor(a, b);
69 static constexpr auto is_adjacent(direction dir)
71 return is_cardinal(dir);
74 template <std::
integral T>
75 static constexpr auto distance(glm::tvec2<T> a, glm::tvec2<T> b)
77 const auto d = glm::abs_distance(a, b);
86 template <std::
integral T>
87 static constexpr bool is_adjacent(glm::tvec2<T> a, glm::tvec2<T> b)
89 return is_surrounding(a, b);
92 static constexpr bool is_adjacent(direction dir)
97 template <std::
integral T>
98 static constexpr auto distance(glm::tvec2<T> a, glm::tvec2<T> b)
100 const auto d = glm::abs_distance(a, b);
101 return glm::max(d.x, d.y);
107 template <std::
integral T>
108 constexpr auto manhattan_distance(glm::tvec2<T> a, glm::tvec2<T> b)
110 return manhattan_metric::distance(a, b);
112 template <std::
integral T>
113 constexpr auto neighbor_distance(glm::tvec2<T> a, glm::tvec2<T> b)
115 return neighbor_metric::distance(a, b);
118 template <std::
integral T>
119 constexpr auto chebyshev_distance(glm::tvec2<T> a, glm::tvec2<T> b)
121 return chebyshev_metric::distance(a, b);
123 template <std::
integral T>
124 constexpr auto surrounding_distance(glm::tvec2<T> a, glm::tvec2<T> b)
126 return surrounding_metric::distance(a, b);
129 template <std::
integral I, std::
floating_po
int F>
130 constexpr glm::tvec2<F> tile_pos_to_world_pos(glm::tvec2<I>
tile_pos, glm::tvec2<F> tile_size) {
return glm::tvec2<F>(
tile_pos) * tile_size; }
132 template <std::
integral I, std::
floating_po
int F>
133 constexpr glm::tvec2<F> tile_pos_to_world_pos(glm::tvec2<I>
tile_pos, F tile_size) {
return glm::tvec2<F>(
tile_pos) * tile_size; }
135 template <std::
integral I, std::
floating_po
int F>
136 constexpr trec2<F> world_rect_for_tile(glm::tvec2<I> pos, glm::tvec2<F> tile_size) {
return trec2<F>::from_size(tile_pos_to_world_pos(pos, tile_size), tile_size); }
138 template <std::
integral I, std::
floating_po
int F>
139 constexpr trec2<F> world_rect_for_tile(glm::tvec2<I> pos, F tile_size) {
return trec2<F>::from_size(tile_pos_to_world_pos(pos, tile_size), { tile_size, tile_size }); }
141 template <std::
integral I =
int, std::
floating_po
int F>
142 inline glm::tvec2<I> world_pos_to_tile_pos(glm::tvec2<F>
world_pos, glm::tvec2<F> tile_size) {
return glm::tvec2<I>(glm::floor(
world_pos / tile_size)); }
144 template <std::
integral I =
int, std::
floating_po
int F>
145 inline glm::tvec2<I> world_pos_to_tile_pos(glm::tvec2<F>
world_pos, F tile_size) {
return glm::tvec2<I>(glm::floor(
world_pos / tile_size)); }
147 template <std::
integral I =
int, std::
floating_po
int F>
148 inline trec2<I> world_rect_to_tile_rect(trec2<F>
const& world_rect, glm::tvec2<F> tile_size) {
return trec2<I>{ glm::floor(world_rect.p1 / tile_size), glm::ceil(world_rect.p2 / tile_size) }; }
150 template <std::
integral I =
int, std::
floating_po
int F>
151 inline trec2<I> world_rect_to_tile_rect(trec2<F>
const& world_rect, F tile_size) {
return trec2<I>{ glm::floor(world_rect.p1 / tile_size), glm::ceil(world_rect.p2 / tile_size) }; }
153 template <std::
floating_po
int F>
154 inline glm::tvec2<F> snap_world_pos_to_tile_grid(glm::tvec2<F>
world_pos, glm::tvec2<F> tile_size) {
155 return glm::floor((
world_pos + (tile_size * 0.5f)) / tile_size) * tile_size;
159 template <std::
integral I, std::
floating_po
int F, metric<I> METRIC = chebyshev_metric>
163 using vec2 = glm::tvec2<F>;
164 using ivec2 = glm::tvec2<I>;
171 using tile_rec =
named<rec2,
"tile_rec">;
172 using world_rec =
named<irec2,
"world_rec">;
174 vec2 tile_size{ F(1), F(1) };
176 constexpr vec2 to_world_pos(ivec2 tile_pos)
const noexcept {
return tile_pos_to_world_pos(tile_pos, tile_size); }
177 constexpr rec2 world_rect_for_tile(ivec2 tile_pos)
const noexcept {
return ghassanpl::geometry::squares::world_rect_for_tile(tile_pos, tile_size); }
178 constexpr ivec2 to_tile_pos(vec2 world_pos)
const noexcept {
return world_pos_to_tile_pos(world_pos, tile_size); }
179 constexpr irec2 to_tile_rect(rec2
const& world_rect)
const noexcept {
return world_rect_to_tile_rect(world_rect, tile_size); }
181 inline vec2 snap_to_grid(vec2 world_pos)
const {
return snap_world_pos_to_tile_grid(world_pos, tile_size); }
183 constexpr world_pos to_world_pos(tile_pos tile_pos)
const noexcept {
return to_world_pos(*tile_pos); }
184 constexpr world_rec world_rect_for_tile(tile_pos tile_pos)
const noexcept {
return world_rect_for_tile(*tile_pos); }
185 constexpr tile_pos to_tile_pos(world_pos world_pos)
const noexcept {
return to_tile_pos(*world_pos); }
186 constexpr tile_rec to_tile_rect(world_rec
const& world_rect)
const noexcept {
return to_tile_rect(*world_rect); }
188 inline world_pos snap_to_grid(world_pos world_pos)
const {
return snap_to_grid(*world_pos); }
190 static constexpr auto is_adjacent(ivec2 a, ivec2 b) {
return metric::is_adjacent(a, b); }
191 static constexpr auto is_adjacent(tile_pos a, tile_pos b) {
return is_adjacent(*a, *b); }
192 static constexpr auto is_adjacent(direction dir) {
return metric::is_adjacent(dir); }
193 static constexpr auto tile_distance(ivec2 a, ivec2 b) {
return metric::distance(a, b); }
194 static constexpr auto tile_distance(tile_pos a, tile_pos b) {
return distance(*a, *b); }
Any type that meets the criteria of a metric - specifying the adjacency/distances between squares.
named< glm::ivec2, "tile_pos", traits::location > tile_pos
Tile position with int values.
named< glm::vec2, "world_pos", traits::location > world_pos
World position with float values.
named< rec2, "world_rec"> world_rec
World rectangle with float values.
named< irec2, "tile_rec"> tile_rec
Tile rectangle with int values.
auto distance(S const &sh, glm::tvec2< T > pt)
Returns the distance between a shape and a point.
Metric in which the entire surrounding is adjacent.
Metric in which only neighbors are adjacent.
Combines a metric and tile size into a single type.
Represents a 2D rectangle polygon_shape.
Used to create a strong typedef of T.
This trait implies the named type is an affine type, that is, a type that does not have the addition ...