General Purpose library for Freestanding C++ and POSIX systems
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

343 lignes
5.3 KiB

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