|
@ -5,13 +5,68 @@ |
|
|
#if !defined(NO_FP_MATH)
|
|
|
#if !defined(NO_FP_MATH)
|
|
|
# include "gp/math/fp_math.hpp"
|
|
|
# include "gp/math/fp_math.hpp"
|
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
#include "gp/algorithm/repeat.hpp"
|
|
|
|
|
|
|
|
|
namespace gp { |
|
|
namespace gp { |
|
|
|
|
|
template<typename T, size_t fixed_passes = 16> |
|
|
|
|
|
T fixed_sqrt(T value) { |
|
|
|
|
|
if(value == 0) return 0; |
|
|
|
|
|
T ret = value / 2; |
|
|
|
|
|
T tmp; |
|
|
|
|
|
|
|
|
|
|
|
gp::repeat(fixed_passes, [&](){ |
|
|
|
|
|
tmp = ret; |
|
|
|
|
|
ret = (value / tmp + tmp) / 2; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template<typename T, size_t cap_passes = 16> |
|
|
|
|
|
T epsilon_sqrt(T value) { |
|
|
|
|
|
if(value == 0) return 0; |
|
|
|
|
|
T ret = value / 2; |
|
|
|
|
|
T tmp; |
|
|
|
|
|
constexpr T epsilon = gp_config::rendering::epsilon; |
|
|
|
|
|
size_t cnt = 0; |
|
|
|
|
|
while( |
|
|
|
|
|
!( |
|
|
|
|
|
(ret+epsilon)*ret > value |
|
|
|
|
|
&& (ret-epsilon)*ret < value |
|
|
|
|
|
) |
|
|
|
|
|
&& cnt < cap_passes |
|
|
|
|
|
){ |
|
|
|
|
|
tmp = ret; |
|
|
|
|
|
ret = (value / tmp + tmp) / 2; |
|
|
|
|
|
++cnt; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
template<typename T, size_t cap_passes = 16> |
|
|
|
|
|
T stable_sqrt(T value) { |
|
|
|
|
|
if(value == 0) return 0; |
|
|
|
|
|
T ret = value / 2; |
|
|
|
|
|
T tmp; |
|
|
|
|
|
while(ret != tmp){ |
|
|
|
|
|
tmp = ret; |
|
|
|
|
|
ret = (value / tmp + tmp) / 2; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
template<typename T = gp_config::rendering::default_type> |
|
|
template<typename T = gp_config::rendering::default_type> |
|
|
struct vec2_g { |
|
|
struct vec2_g { |
|
|
T x; |
|
|
T x; |
|
|
T y; |
|
|
T y; |
|
|
|
|
|
|
|
|
|
|
|
vec2_g() |
|
|
|
|
|
: x{} |
|
|
|
|
|
, y{} |
|
|
|
|
|
{} |
|
|
|
|
|
|
|
|
vec2_g( |
|
|
vec2_g( |
|
|
T _x, |
|
|
T _x, |
|
|
T _y |
|
|
T _y |
|
@ -27,10 +82,21 @@ namespace gp { |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
vec2_g operator*(vec2_g rhs) { |
|
|
|
|
|
return { |
|
|
|
|
|
x * rhs.x, |
|
|
|
|
|
y * rhs.y |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
vec2_g operator+(vec2_g oth) { |
|
|
vec2_g operator+(vec2_g oth) { |
|
|
return {x+oth.x, y+oth.y}; |
|
|
return {x+oth.x, y+oth.y}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
vec2_g operator-(vec2_g oth) { |
|
|
|
|
|
return {x-oth.x, y-oth.y}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
vec2_g normalize() { |
|
|
vec2_g normalize() { |
|
|
T ilen = fast_isqrt(x*x+y*y); |
|
|
T ilen = fast_isqrt(x*x+y*y); |
|
|
return {x*ilen, y*ilen}; |
|
|
return {x*ilen, y*ilen}; |
|
@ -43,6 +109,12 @@ namespace gp { |
|
|
T y; |
|
|
T y; |
|
|
T z; |
|
|
T z; |
|
|
|
|
|
|
|
|
|
|
|
vec3_g() |
|
|
|
|
|
: x{} |
|
|
|
|
|
, y{} |
|
|
|
|
|
, z{} |
|
|
|
|
|
{} |
|
|
|
|
|
|
|
|
vec3_g( |
|
|
vec3_g( |
|
|
T _x, |
|
|
T _x, |
|
|
T _y, |
|
|
T _y, |
|
@ -73,10 +145,22 @@ namespace gp { |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
vec3_g operator*(vec3_g rhs) { |
|
|
|
|
|
return { |
|
|
|
|
|
x * rhs.x, |
|
|
|
|
|
y * rhs.y, |
|
|
|
|
|
z * rhs.z |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
vec3_g operator+(vec3_g oth) { |
|
|
vec3_g operator+(vec3_g oth) { |
|
|
return {x+oth.x, y+oth.y, z+oth.z}; |
|
|
return {x+oth.x, y+oth.y, z+oth.z}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
vec3_g operator-(vec3_g oth) { |
|
|
|
|
|
return {x-oth.x, y-oth.y, z-oth.z}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
vec3_g normalize() { |
|
|
vec3_g normalize() { |
|
|
T ilen = fast_isqrt(x*x+y*y+z*z); |
|
|
T ilen = fast_isqrt(x*x+y*y+z*z); |
|
|
return {x*ilen, y*ilen, z*ilen}; |
|
|
return {x*ilen, y*ilen, z*ilen}; |
|
@ -90,6 +174,13 @@ namespace gp { |
|
|
T z; |
|
|
T z; |
|
|
T w; |
|
|
T w; |
|
|
|
|
|
|
|
|
|
|
|
vec4_g() |
|
|
|
|
|
: x{} |
|
|
|
|
|
, y{} |
|
|
|
|
|
, z{} |
|
|
|
|
|
, w{} |
|
|
|
|
|
{} |
|
|
|
|
|
|
|
|
vec4_g( |
|
|
vec4_g( |
|
|
T _x, |
|
|
T _x, |
|
|
T _y, |
|
|
T _y, |
|
@ -125,10 +216,23 @@ namespace gp { |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
vec4_g operator*(vec4_g rhs) { |
|
|
|
|
|
return { |
|
|
|
|
|
x * rhs.x, |
|
|
|
|
|
y * rhs.y, |
|
|
|
|
|
z * rhs.z, |
|
|
|
|
|
w * rhs.w |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
vec4_g operator+(vec4_g oth) { |
|
|
vec4_g operator+(vec4_g oth) { |
|
|
return {x+oth.x, y+oth.y, z+oth.z, w+oth.w}; |
|
|
return {x+oth.x, y+oth.y, z+oth.z, w+oth.w}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
vec4_g operator-(vec4_g oth) { |
|
|
|
|
|
return {x-oth.x, y-oth.y, z-oth.w, z-oth.w}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
vec4_g normalize() { |
|
|
vec4_g normalize() { |
|
|
T ilen = fast_isqrt(x*x+y*y+z*z+w*w); |
|
|
T ilen = fast_isqrt(x*x+y*y+z*z+w*w); |
|
|
return {x*ilen, y*ilen, z*ilen, w*ilen}; |
|
|
return {x*ilen, y*ilen, z*ilen, w*ilen}; |
|
|