General Purpose library for Freestanding C++ and POSIX systems
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

296 linhas
4.3 KiB

há 4 anos
há 4 anos
há 4 anos
há 4 anos
há 4 anos
há 4 anos
há 4 anos
há 4 anos
há 4 anos
há 4 anos
há 4 anos
  1. #pragma once
  2. #include "gp_config.hpp"
  3. #include "gp/math/integer_math.hpp"
  4. #include "gp/math/q_math.hpp"
  5. #if !defined(NO_FP_MATH)
  6. # include "gp/math/fp_math.hpp"
  7. #endif
  8. #include "gp/algorithm/repeat.hpp"
  9. namespace gp {
  10. template<typename T, size_t fixed_passes = 16>
  11. T fixed_sqrt(T value) {
  12. if(value == 0) return 0;
  13. T ret = value / 2;
  14. T tmp;
  15. gp::repeat(fixed_passes, [&](){
  16. tmp = ret;
  17. ret = (value / tmp + tmp) / 2;
  18. });
  19. return ret;
  20. }
  21. template<typename T, size_t cap_passes = 16>
  22. T epsilon_sqrt(T value) {
  23. if(value == 0) return 0;
  24. T ret = value / 2;
  25. T tmp;
  26. constexpr T epsilon = gp_config::rendering::epsilon;
  27. size_t cnt = 0;
  28. while(
  29. !(
  30. (ret+epsilon)*ret > value
  31. && (ret-epsilon)*ret < value
  32. )
  33. && cnt < cap_passes
  34. ){
  35. tmp = ret;
  36. ret = (value / tmp + tmp) / 2;
  37. ++cnt;
  38. };
  39. return ret;
  40. }
  41. template<typename T, size_t cap_passes = 16>
  42. T stable_sqrt(T value) {
  43. if(value == 0) return 0;
  44. T ret = value / 2;
  45. T tmp;
  46. while(ret != tmp){
  47. tmp = ret;
  48. ret = (value / tmp + tmp) / 2;
  49. };
  50. return ret;
  51. }
  52. template<typename T = gp_config::rendering::default_type>
  53. struct vec2_g {
  54. T x;
  55. T y;
  56. vec2_g()
  57. : x{}
  58. , y{}
  59. {}
  60. vec2_g(
  61. T _x,
  62. T _y
  63. )
  64. : x{_x}
  65. , y{_y}
  66. {}
  67. vec2_g operator/(vec2_g rhs) {
  68. return {
  69. x / rhs.x,
  70. y / rhs.y
  71. };
  72. }
  73. vec2_g operator*(vec2_g rhs) {
  74. return {
  75. x * rhs.x,
  76. y * rhs.y
  77. };
  78. }
  79. vec2_g operator+(vec2_g oth) {
  80. return {x+oth.x, y+oth.y};
  81. }
  82. vec2_g operator-(vec2_g oth) {
  83. return {x-oth.x, y-oth.y};
  84. }
  85. vec2_g normalize() {
  86. T ilen = fast_isqrt(x*x+y*y);
  87. return {x*ilen, y*ilen};
  88. }
  89. };
  90. template<typename T = gp_config::rendering::default_type>
  91. struct vec3_g {
  92. T x;
  93. T y;
  94. T z;
  95. T& r(){
  96. return x;
  97. }
  98. T& g(){
  99. return y;
  100. }
  101. T& b(){
  102. return z;
  103. }
  104. vec3_g()
  105. : x{}
  106. , y{}
  107. , z{}
  108. {}
  109. vec3_g(
  110. T _x,
  111. T _y,
  112. T _z
  113. )
  114. : x{_x}
  115. , y{_y}
  116. , z{_z}
  117. {}
  118. vec3_g(vec2_g<T> left, T right)
  119. : x{left.x}
  120. , y{left.y}
  121. , z{right}
  122. {}
  123. vec3_g(T left, vec2_g<T> right)
  124. : x{left}
  125. , y{right.x}
  126. , z{right.y}
  127. {}
  128. vec3_g operator/(vec3_g rhs) {
  129. return {
  130. x / rhs.x,
  131. y / rhs.y,
  132. z / rhs.z
  133. };
  134. }
  135. vec3_g operator*(vec3_g rhs) {
  136. return {
  137. x * rhs.x,
  138. y * rhs.y,
  139. z * rhs.z
  140. };
  141. }
  142. vec3_g operator+(vec3_g oth) {
  143. return {x+oth.x, y+oth.y, z+oth.z};
  144. }
  145. vec3_g operator-(vec3_g oth) {
  146. return {x-oth.x, y-oth.y, z-oth.z};
  147. }
  148. vec3_g normalize() {
  149. T ilen = fast_isqrt(x*x+y*y+z*z);
  150. return {x*ilen, y*ilen, z*ilen};
  151. }
  152. };
  153. template<typename T = gp_config::rendering::default_type>
  154. struct vec4_g {
  155. T x;
  156. T y;
  157. T z;
  158. T w;
  159. T& r(){
  160. return x;
  161. }
  162. T& g(){
  163. return y;
  164. }
  165. T& b(){
  166. return z;
  167. }
  168. T& a(){
  169. return w;
  170. }
  171. vec4_g()
  172. : x{}
  173. , y{}
  174. , z{}
  175. , w{}
  176. {}
  177. vec4_g(
  178. T _x,
  179. T _y,
  180. T _z,
  181. T _w
  182. )
  183. : x{_x}
  184. , y{_y}
  185. , z{_z}
  186. , w{_w}
  187. {}
  188. vec4_g(T left, vec3_g<> right)
  189. : x{left}
  190. , y{right.x}
  191. , z{right.y}
  192. , w{right.z}
  193. {}
  194. vec4_g(vec3_g<> left, T right)
  195. : x{left.x}
  196. , y{left.y}
  197. , z{left.z}
  198. , w{right}
  199. {}
  200. vec4_g operator/(vec4_g rhs) {
  201. return {
  202. x / rhs.x,
  203. y / rhs.y,
  204. z / rhs.z,
  205. w / rhs.w
  206. };
  207. }
  208. vec4_g operator*(vec4_g rhs) {
  209. return {
  210. x * rhs.x,
  211. y * rhs.y,
  212. z * rhs.z,
  213. w * rhs.w
  214. };
  215. }
  216. vec4_g operator+(vec4_g oth) {
  217. return {x+oth.x, y+oth.y, z+oth.z, w+oth.w};
  218. }
  219. vec4_g operator-(vec4_g oth) {
  220. return {x-oth.x, y-oth.y, z-oth.w, z-oth.w};
  221. }
  222. vec4_g normalize() {
  223. T ilen = fast_isqrt(x*x+y*y+z*z+w*w);
  224. return {x*ilen, y*ilen, z*ilen, w*ilen};
  225. }
  226. };
  227. template<typename T>
  228. vec2_g<T> operator*(vec2_g<T> p, T v) {
  229. return {p.x*v, p.y*v};
  230. }
  231. template<typename T>
  232. vec3_g<T> operator*(vec3_g<T> p, T v) {
  233. return {p.x*v, p.y*v, p.z*v};
  234. }
  235. template<typename T>
  236. vec4_g<T> operator*(vec4_g<T> p, T v) {
  237. return {p.x*v, p.y*v, p.z*v, p.w*v};
  238. }
  239. template<typename T>
  240. vec2_g<T> operator*(T v, vec2_g<T> p) {
  241. return p*v;
  242. }
  243. template<typename T>
  244. vec3_g<T> operator*(T v, vec3_g<T> p) {
  245. return p*v;
  246. }
  247. template<typename T>
  248. vec4_g<T> operator*(T v, vec4_g<T> p) {
  249. return p*v;
  250. }
  251. }
  252. static_assert(sizeof(gp::vec3_g<int>) == sizeof(int)*3, "vec3_g has strange alignment");
  253. static_assert(sizeof(gp::vec4_g<int>) == sizeof(int)*4, "vec4_g has strange alignment");