Symphony Of Empires
utils.hpp
Go to the documentation of this file.
1 // Eng3D - General purpouse game engine
2 // Copyright (C) 2021, Eng3D contributors
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // utils.hpp
20 //
21 // Abstract:
22 // General purpouse utility macros and other often-used stuff.
23 // ----------------------------------------------------------------------------
24 
25 #pragma once
26 
27 #include <cstdint>
28 #include <cstring>
29 
30 #if !defined(__cpp_lib_byteswap) || __cpp_lib_byteswap < 202110L
31 # include <bit>
32 # include <concepts>
33 # include <iomanip>
34 # include <algorithm>
35 namespace std {
36 #if !defined(__cpp_lib_bit_cast)
37  template <class To, class From>
38  std::enable_if_t<sizeof(To) == sizeof(From) && std::is_trivially_copyable_v<From> && std::is_trivially_copyable_v<To>, To> bit_cast(const From& src) noexcept {
39  static_assert(std::is_trivially_constructible_v<To>, "This implementation additionally requires destination type to be trivially constructible");
40  To dst;
41  ::memcpy(&dst, &src, sizeof(To));
42  return dst;
43  }
44 #endif
45  template<typename T>
46  constexpr T byteswap(T value) noexcept {
47 #ifdef __cpp_lib_ranges
48  static_assert(std::has_unique_object_representations_v<T>, "T may not have padding bits");
49  auto value_representation = std::bit_cast<std::array<std::byte, sizeof(T)>>(value);
50  std::ranges::reverse(value_representation);
51  return std::bit_cast<T>(value_representation);
52 #endif
53  if(sizeof(T) == sizeof(uint64_t)) {
54  uint64_t x = value;
55  return ((x << 56) & 0xff00000000000000ULL) |
56  ((x << 40) & 0x00ff000000000000ULL) |
57  ((x << 24) & 0x0000ff0000000000ULL) |
58  ((x << 8) & 0x000000ff00000000ULL) |
59  ((x >> 8) & 0x00000000ff000000ULL) |
60  ((x >> 24) & 0x0000000000ff0000ULL) |
61  ((x >> 40) & 0x000000000000ff00ULL) |
62  ((x >> 56) & 0x00000000000000ffULL);
63  } else if(sizeof(T) == sizeof(uint32_t)) {
64  uint32_t x = value;
65  return
66  ((x << 24) & 0xff000000UL) |
67  ((x << 8) & 0x00ff0000UL) |
68  ((x >> 8) & 0x0000ff00UL) |
69  ((x >> 24) & 0x000000ffUL);
70  } else {
71  uint16_t x = value;
72  return
73  ((x << 8) & 0xff00U) |
74  ((x >> 8) & 0x00ffU);
75  }
76  return value;
77  }
78 }
79 #endif
80 
81 #ifndef __cpp_lib_endian
82 namespace std {
83  enum class endian {
84 # if defined E3D_TARGET_WINDOWS
85  little = 0,
86  big = 1,
87  native = little
88 # else
89  little = __ORDER_LITTLE_ENDIAN__,
90  big = __ORDER_BIG_ENDIAN__,
91  native = __BYTE_ORDER__
92 # endif
93  };
94 }
95 #endif
96 
97 #if !defined(E3D_EXCEPTIONS)
98 # define CXX_THROW(class, ...) throw class(__VA_ARGS__);
99 #else
100 #include <cstdio>
101 # define CXX_THROW(class, ...) { fprintf(stderr, class(__VA_ARGS__).what()); abort(); }
102 #endif
103 
104 template<typename It>
105 class Range
106 {
107  It _b, _e;
108 public:
109  Range(It b, It e) : _b(b), _e(e) {}
110  It begin() const { return _b; }
111  It end() const { return _e; }
112 };
113 
114 template<typename ORange, typename OIt = decltype(std::begin(std::declval<ORange>())), typename It = std::reverse_iterator<OIt>>
115 Range<It> reverse(ORange && originalRange) {
116  return Range<It>(It(std::end(originalRange)), It(std::begin(originalRange)));
117 }
118 
119 #include <glm/common.hpp>
120 #include <glm/vec2.hpp>
121 #include <glm/vec3.hpp>
122 #include <glm/gtc/matrix_transform.hpp>
123 #include <glm/gtx/intersect.hpp>
124 
125 namespace Eng3D {
126  // Does the same as std::erase but doesn't keep the order
127  template <typename C, typename T>
128  inline void fast_erase(C& c, T value) noexcept {
129  for(auto i = c.size(); i-- > 0; ) {
130  if(c[i] == value) {
131  c[i] = c.back();
132  c.pop_back();
133  return;
134  }
135  }
136  }
137 
138  // Does the same as std::erase_all but doesn't keep the order
139  template <typename C, typename T>
140  inline void fast_erase_all(C& c, T value) noexcept {
141  for(auto i = c.size(); i-- > 0; ) {
142  if(c[i] == value) {
143  c[i] = c.back();
144  c.pop_back();
145  }
146  }
147  }
148 
149  inline glm::vec3 get_sphere_coord(glm::vec2 size, glm::vec2 pos, float radius) {
150  const auto normalized_pos = pos / size;
151  glm::vec2 radiance_pos;
152  radiance_pos.x = normalized_pos.x * 2.f * glm::pi<float>();
153  radiance_pos.y = normalized_pos.y * glm::pi<float>();
154 
155  glm::vec3 sphere_position;
156  sphere_position.x = glm::cos(radiance_pos.x) * glm::sin(radiance_pos.y);
157  sphere_position.y = glm::sin(radiance_pos.x) * glm::sin(radiance_pos.y);
158  sphere_position.z = glm::cos(radiance_pos.y);
159  sphere_position *= radius;
160  return sphere_position;
161  }
162 
166  inline float euclidean_distance(glm::vec2 size, float radius, glm::vec2 p0, glm::vec2 p1) {
167  const auto dt = glm::dot(Eng3D::get_sphere_coord(size, p0, radius), Eng3D::get_sphere_coord(size, p1, radius));
168  const auto cos_angle = dt / (radius * radius);
169  const auto angle = glm::acos(glm::clamp(cos_angle, -1.f, 1.f));
170  const auto distance = angle * radius;
171  return distance;
172  }
173 }
Definition: utils.hpp:106
It end() const
Definition: utils.hpp:111
It begin() const
Definition: utils.hpp:110
Range(It b, It e)
Definition: utils.hpp:109
void fast_erase(C &c, T value) noexcept
Definition: utils.hpp:128
float euclidean_distance(glm::vec2 size, float radius, glm::vec2 p0, glm::vec2 p1)
Obtain the euclidean distance from p0 to p1.
Definition: utils.hpp:166
glm::vec3 get_sphere_coord(glm::vec2 size, glm::vec2 pos, float radius)
Definition: utils.hpp:149
void fast_erase_all(C &c, T value) noexcept
Definition: utils.hpp:140
Definition: utils.hpp:35
std::enable_if_t< sizeof(To)==sizeof(From) &&std::is_trivially_copyable_v< From > &&std::is_trivially_copyable_v< To >, To > bit_cast(const From &src) noexcept
Definition: utils.hpp:38
constexpr T byteswap(T value) noexcept
Definition: utils.hpp:46
endian
Definition: utils.hpp:83
#define C
Definition: stb_vorbis.c:5132
Range< It > reverse(ORange &&originalRange)
Definition: utils.hpp:115