header_utils
Loading...
Searching...
No Matches
squares.h
1
4
5#pragma once
6
7#include "direction.h"
8
10{
12
13 constexpr bool is_surrounding(glm::ivec2 a, glm::ivec2 b) { return glm::abs(a.x - b.x) < 2 && glm::abs(a.y - b.y) < 2; }
14 constexpr bool is_neighbor(glm::ivec2 a, glm::ivec2 b) { return is_surrounding(a, b) && glm::abs(a.y - b.y) != glm::abs(a.x - b.x); }
15 constexpr bool is_diagonal_neighbor(glm::ivec2 a, glm::ivec2 b) { return is_surrounding(a, b) && glm::abs(a.y - b.y) == glm::abs(a.x - b.x); }
16
17 template <typename T>
18 concept metric = false;
19
20 struct manhattan_metric
21 {
22 template <std::integral T>
23 static constexpr auto distance(glm::tvec2<T> a, glm::tvec2<T> b)
24 {
25 const auto d = glm::abs(b - a);
26 return d.x + d.y;
27 }
28
29 template <std::integral T>
30 static constexpr auto is_valid_neighbor(glm::tvec2<T> a, glm::tvec2<T> b)
31 {
32 return is_neighbor(a, b);
33 }
34
35 static constexpr auto is_valid_direction(direction dir)
36 {
37 return is_cardinal(dir);
38 }
39 };
40 using neighbor_metric = manhattan_metric;
41
42 struct chebyshev_metric
43 {
44 template <std::integral T>
45 static constexpr auto distance(glm::tvec2<T> a, glm::tvec2<T> b)
46 {
47 const auto d = glm::abs(b - a);
48 return max(d.x, d.y);
49 }
50
51 template <std::integral T>
52 static constexpr bool is_valid_neighbor(glm::tvec2<T> a, glm::tvec2<T> b)
53 {
54 return is_surrounding(a, b);
55 }
56
57 static constexpr bool is_valid_direction(direction dir)
58 {
59 return is_valid(dir);
60 }
61 };
62 using surrounding_metric = chebyshev_metric;
63
64 template <std::integral T>
65 constexpr auto manhattan_distance(glm::tvec2<T> a, glm::tvec2<T> b)
66 {
67 return manhattan_metric::distance(a, b);
68 }
69
70 template <std::integral T>
71 constexpr auto chebyshev_distance(glm::tvec2<T> a, glm::tvec2<T> b)
72 {
73 return chebyshev_metric::distance(a, b);
74 }
75
76 constexpr glm::vec2 tile_pos_to_world_pos(glm::ivec2 tile_pos, glm::vec2 tile_size) { return glm::vec2(tile_pos) * tile_size; }
77 constexpr glm::vec2 tile_pos_to_world_pos(glm::ivec2 tile_pos, float tile_size) { return glm::vec2(tile_pos) * tile_size; }
78 constexpr rec2 world_rect_for_tile(glm::ivec2 pos, glm::vec2 tile_size) { return rec2::from_size(tile_pos_to_world_pos(pos, tile_size), tile_size); }
79 constexpr rec2 world_rect_for_tile(glm::ivec2 pos, float tile_size) { return rec2::from_size(tile_pos_to_world_pos(pos, tile_size), { tile_size, tile_size }); }
80
81 glm::ivec2 world_pos_to_tile_pos(glm::vec2 world_pos, glm::vec2 tile_size) { return glm::ivec2(glm::floor(world_pos / tile_size)); }
82 glm::ivec2 world_pos_to_tile_pos(glm::vec2 world_pos, float tile_size) { return glm::ivec2(glm::floor(world_pos / tile_size)); }
83 irec2 world_rect_to_tile_rect(rec2 const& world_rect, glm::vec2 tile_size) { return irec2{ glm::floor(world_rect.p1 / tile_size), glm::ceil(world_rect.p2 / tile_size) }; }
84 irec2 world_rect_to_tile_rect(rec2 const& world_rect, float tile_size) { return irec2{ glm::floor(world_rect.p1 / tile_size), glm::ceil(world_rect.p2 / tile_size) }; }
85
86 glm::vec2 snap_world_pos_to_tile_grid(glm::vec2 world_pos, glm::vec2 tile_size) {
87 return glm::floor((world_pos + (tile_size * 0.5f)) / tile_size) * tile_size;
88 }
89
90 template <metric METRIC = chebyshev_metric>
91 struct tile_space
92 {
93 glm::vec2 tile_size;
94
95 constexpr glm::vec2 to_world_pos(glm::ivec2 tile_pos) const noexcept { return tile_pos_to_world_pos(tile_pos, tile_size); }
96 constexpr rec2 world_rect_for_tile(glm::ivec2 tile_pos) const noexcept { return ghassanpl::geometry::squares::world_rect_for_tile(tile_pos, tile_size); }
97 constexpr glm::ivec2 to_tile_pos(glm::vec2 world_pos) const noexcept { return world_pos_to_tile_pos(world_pos, tile_size); }
98 constexpr irec2 to_tile_rect(rec2 const& world_rect) const noexcept { return world_rect_to_tile_rect(world_rect, tile_size); }
99 };
100
101 using tile_pos = named<glm::ivec2, "tile_pos", traits::location>;
102 using world_pos = named<glm::vec2, "world_pos", traits::location>;
103
104 using tile_rec = named<irec2, "tile_rec">;
105 using world_rec = named<rec2, "world_rec">;
106}
constexpr auto bit_count
Equal to the number of bits in the type.
Definition bits.h:33
constexpr bool is_surrounding(glm::ivec2 a, glm::ivec2 b)
TODO: Should probably define the terms somewhere (surrounding, neighbor, adjacent,...
Definition squares.h:13