@@ -22,6 +22,9 @@ | |||
#include <lol/math/vector.h> // vec_t | |||
#include <lol/math/transform.h> // mat_t | |||
#include <cmath> // std::fabs | |||
#include <algorithm> // std::min | |||
namespace lol | |||
{ | |||
@@ -125,9 +128,10 @@ public: | |||
*/ | |||
static vec3_t hsv_to_rgb(vec3_t src) | |||
{ | |||
vec3_t tmp = vec3_t(-1.f + abs(6.f * src.x - 3.f), | |||
2.f - abs(6.f * src.x - 2.f), | |||
2.f - abs(6.f * src.x - 4.f)); | |||
using std::fabs; | |||
vec3_t tmp = vec3_t(-1.f + fabs(6.f * src.x - 3.f), | |||
2.f - fabs(6.f * src.x - 2.f), | |||
2.f - fabs(6.f * src.x - 4.f)); | |||
return src.z * mix(vec3_t(1.f), clamp(tmp, 0.f, 1.f), src.y); | |||
} | |||
@@ -141,6 +145,8 @@ public: | |||
*/ | |||
static vec3_t rgb_to_hsv(vec3_t src) | |||
{ | |||
using std::fabs, std::min; | |||
float K = 0.f; | |||
if (src.g < src.b) | |||
@@ -152,7 +158,7 @@ public: | |||
float chroma = src.r - min(src.g, src.b); | |||
/* XXX: we use min() here because numerical stability is not | |||
* guaranteed with -ffast-math, I’ve seen it fail on i386. */ | |||
return vec3_t(min(abs(K + (src.g - src.b) / (6.f * chroma)), 1.f), | |||
return vec3_t(min(fabs(K + (src.g - src.b) / (6.f * chroma)), 1.f), | |||
chroma / (src.r + 1e-20f), | |||
src.r); | |||
} | |||
@@ -167,6 +173,8 @@ public: | |||
*/ | |||
static vec3_t rgb_to_hsl(vec3_t src) | |||
{ | |||
using std::fabs, std::min; | |||
float K = 0.f; | |||
if (src.g < src.b) | |||
@@ -179,7 +187,7 @@ public: | |||
float luma = src.r + min(src.g, src.b); | |||
/* XXX: we use min() here because numerical stability is not | |||
* guaranteed with -ffast-math, I’ve seen it fail on i386. */ | |||
float h = min(abs(K + (src.g - src.b) / (6.f * chroma)), 1.f); | |||
float h = min(fabs(K + (src.g - src.b) / (6.f * chroma)), 1.f); | |||
float s = clamp(chroma / (min(luma, 2.f - luma)), 0.f, 1.f); | |||
return vec3_t(h, s, 0.5f * luma); | |||
} | |||
@@ -194,6 +202,8 @@ public: | |||
*/ | |||
static vec3_t hsv_to_hsl(vec3_t src) | |||
{ | |||
using std::min; | |||
float tmp = (2 - src.y) * src.z; | |||
return vec3_t(src.x, | |||
src.y * src.z / (min(tmp, 2.f - tmp) + 1e-20f), | |||
@@ -210,7 +220,7 @@ public: | |||
*/ | |||
static vec3_t hsl_to_hsv(vec3_t src) | |||
{ | |||
float tmp = src.y * (0.5f - abs(0.5f - src.z)); | |||
float tmp = src.y * (0.5f - fabs(0.5f - src.z)); | |||
return vec3_t(src.x, 2.f * tmp / (src.z + tmp + 1e-20f), src.z + tmp); | |||
} | |||
@@ -17,11 +17,12 @@ | |||
// —————————————————— | |||
// | |||
#include <ostream> | |||
#include "ops.h" | |||
#include <lol/math/vector.h> | |||
#include <ostream> // std::ostream | |||
#include <cmath> // std::fabs | |||
#if _WIN32 | |||
# pragma push_macro("near") | |||
# pragma push_macro("far") | |||
@@ -402,6 +403,8 @@ T cofactor(mat_t<T, 2, 2> const &m, int i, int j) | |||
template<typename T, int N> [[nodiscard]] | |||
std::tuple<mat_t<T, N, N>, vec_t<int, N>, int> lu_decomposition(mat_t<T, N, N> const &m) | |||
{ | |||
using std::fabs; | |||
mat_t<T, N, N> lu = m; | |||
vec_t<int, N> perm; | |||
int sign = 1; | |||
@@ -20,6 +20,7 @@ | |||
#include <cassert> | |||
#include <ostream> // std::ostream | |||
#include <type_traits> | |||
#include <algorithm> // std::min, std::max | |||
#include <cmath> // std::fabs, std::cos… | |||
// FIXME: get rid of this, too | |||
@@ -1004,6 +1005,7 @@ operator *(T const &val, vec_t<T,N,SWIZZLE> const &a) | |||
inline vec_t<T,N> fun(vec_t<T,N,SWIZZLE1> const &a, \ | |||
vec_t<T,N,SWIZZLE2> const &b) \ | |||
{ \ | |||
using std::fun; \ | |||
vec_t<T,N> ret; \ | |||
for (int i = 0; i < N; ++i) \ | |||
ret[i] = fun(a[i], b[i]); \ | |||
@@ -1013,6 +1015,7 @@ operator *(T const &val, vec_t<T,N,SWIZZLE> const &a) | |||
template<typename T, int N, int SWIZZLE> \ | |||
inline vec_t<T,N> fun(vec_t<T,N,SWIZZLE> const &a, T const &b) \ | |||
{ \ | |||
using std::fun; \ | |||
vec_t<T,N> ret; \ | |||
for (int i = 0; i < N; ++i) \ | |||
ret[i] = fun(a[i], b); \ | |||
@@ -1022,6 +1025,7 @@ operator *(T const &val, vec_t<T,N,SWIZZLE> const &a) | |||
template<typename T, int N, int SWIZZLE> \ | |||
inline vec_t<T,N> fun(T const &a, vec_t<T,N,SWIZZLE> const &b) \ | |||
{ \ | |||
using std::fun; \ | |||
vec_t<T,N> ret; \ | |||
for (int i = 0; i < N; ++i) \ | |||
ret[i] = fun(a, b[i]); \ | |||
@@ -1165,15 +1169,24 @@ static inline vec_t<T,N> normalize(vec_t<T,N,SWIZZLE> const &a) | |||
return norm ? a / norm : vec_t<T,N>(T(0)); | |||
} | |||
// We define fabs() because that’s the C++ std library uses for | |||
// floating-point numbers, and abs() because GLSL does. | |||
template<typename T, int N, int SWIZZLE> | |||
static inline vec_t<T,N> abs(vec_t<T,N,SWIZZLE> const &a) | |||
static inline vec_t<T,N> fabs(vec_t<T,N,SWIZZLE> const &a) | |||
{ | |||
using std::fabs; | |||
vec_t<T,N> ret; | |||
for (int i = 0; i < N; ++i) | |||
ret[i] = abs(a[i]); | |||
ret[i] = fabs(a[i]); | |||
return ret; | |||
} | |||
template<typename T, int N, int SWIZZLE> | |||
static inline vec_t<T,N> abs(vec_t<T,N,SWIZZLE> const &a) | |||
{ | |||
return fabs(a); | |||
} | |||
template<typename T, int N, int SWIZZLE> | |||
static inline vec_t<T,N> degrees(vec_t<T,N,SWIZZLE> const &a) | |||
{ | |||
@@ -243,7 +243,7 @@ static inline float fmod(half a, half b) | |||
static inline float fract(half a) { return fract((float)a); } | |||
static inline float degrees(half a) { return degrees((float)a); } | |||
static inline float radians(half a) { return radians((float)a); } | |||
static inline half abs(half a) { return half::frombits(a.bits() & 0x7fffu); } | |||
static inline half fabs(half a) { return half::frombits(a.bits() & 0x7fffu); } | |||
static inline half clamp(half x, half a, half b) | |||
{ | |||
@@ -970,11 +970,6 @@ template<typename T> real_t<T> fabs(real_t<T> const &x) | |||
return ret; | |||
} | |||
template<typename T> real_t<T> abs(real_t<T> const &x) | |||
{ | |||
return fabs(x); | |||
} | |||
template<typename T> real_t<T> fract(real_t<T> const &x) | |||
{ | |||
return x - floor(x); | |||
@@ -161,7 +161,6 @@ public: | |||
real_t<U> const &y); | |||
// Functions inherited from GLSL | |||
template<typename U> friend real_t<U> abs(real_t<U> const &x); | |||
template<typename U> friend real_t<U> fract(real_t<U> const &x); | |||
template<typename U> friend real_t<U> degrees(real_t<U> const &x); | |||
template<typename U> friend real_t<U> radians(real_t<U> const &x); | |||
@@ -149,12 +149,12 @@ template<typename T, typename T2 = LOL_T_FLOATING_POINT> | |||
return mix(a, b, x); | |||
} | |||
// C++ doesn't define abs() or fmod() for all types; we add these for | |||
// C++ doesn't define fabs() or fmod() for all types; we add these for | |||
// convenience to avoid adding complexity to vector.h. | |||
template<typename T, typename T2 = LOL_T_SIGNED> | |||
[[nodiscard]] static inline T2 abs(T x) { return std::abs(x); } | |||
[[nodiscard]] static inline T2 fabs(T x) { return std::abs(x); } | |||
template<typename T, typename T2 = T, typename DUMMY = LOL_T_UNSIGNED> | |||
[[nodiscard]] static inline T2 abs(T x) { return x; } | |||
[[nodiscard]] static inline T2 fabs(T x) { return x; } | |||
template<typename T, typename T2 = LOL_T_INTEGRAL> | |||
[[nodiscard]] static inline T2 fmod(T x, T y) { return x % y; } | |||
@@ -175,7 +175,7 @@ template<typename T, typename T2 = LOL_T_ARITHMETIC> | |||
template<typename T, typename T2 = LOL_T_ARITHMETIC> | |||
[[nodiscard]] static inline T2 saturate(T x) { return clamp(x, (T)0, (T)1); } | |||
template<typename T, typename T2 = LOL_T_ARITHMETIC> | |||
[[nodiscard]] static inline T2 gcd(T x, T y) { return y == (T)0 ? lol::abs(x) : lol::gcd(y, lol::fmod(x, y)); } | |||
[[nodiscard]] static inline T2 gcd(T x, T y) { return y == (T)0 ? lol::fabs(x) : lol::gcd(y, lol::fmod(x, y)); } | |||
template<typename T, typename T2 = LOL_T_SIGNED> | |||
[[nodiscard]] static inline T2 sign(T x) { return (T)(((T)0 < x) - (x < (T)0)); } | |||
@@ -25,7 +25,7 @@ | |||
#include <algorithm> | |||
#include <map> | |||
#include <cmath> | |||
#include <cmath> // std::fabs | |||
#include <cstdio> | |||
#include <stdint.h> | |||
@@ -213,6 +213,8 @@ public: | |||
//-- | |||
static inline bool TestAABBVsAABB(box2 const &b1, box2 const &b2) | |||
{ | |||
using std::fabs; | |||
vec2 c = b1.center() - b2.center(); | |||
vec2 e1 = 0.5f * b1.extent(); | |||
vec2 e2 = 0.5f * b2.extent(); | |||
@@ -227,6 +229,8 @@ static inline bool TestAABBVsPoint(box2 const &b1, vec2 const &p) | |||
static inline bool TestAABBVsAABB(box3 const &b1, box3 const &b2) | |||
{ | |||
using std::fabs; | |||
vec3 c = b1.center() - b2.center(); | |||
vec3 e1 = 0.5f * b1.extent(); | |||
vec3 e2 = 0.5f * b2.extent(); | |||
@@ -19,6 +19,7 @@ | |||
#include <lol/math/transform.h> // mat_t | |||
#include <vector> // std::vector | |||
#include <cmath> // std::fabs | |||
#include <algorithm> // std::min, std::max | |||
namespace lol | |||
@@ -88,6 +89,8 @@ protected: | |||
inline float get_noise(vec_t<int, N> origin, | |||
vec_t<float, N> const & pos) const | |||
{ | |||
using std::min; | |||
/* For a given position [0…1]^N inside a regular N-hypercube, find | |||
* the N-simplex which contains that position, and return a path | |||
* along the hypercube edges from (0,0,…,0) to (1,1,…,1) which | |||
@@ -141,9 +144,9 @@ protected: | |||
// -4.f: centre (-2.f), | |||
// -3.f: r=0.38 sphere of influence (contribution = 1/4) | |||
// -2.f: r=0.52 sphere of influence (contribution = 1/24) | |||
if (d > 0.99f) special = std::min(special, -4.f); | |||
if (d > 0.7f && d < 0.72f) special = std::min(special, -3.f); | |||
if (d > 0.44f && d < 0.46f) special = std::min(special, -2.f); | |||
if (d > 0.99f) special = min(special, -4.f); | |||
if (d > 0.7f && d < 0.72f) special = min(special, -3.f); | |||
if (d > 0.44f && d < 0.46f) special = min(special, -2.f); | |||
#endif | |||
if (d > 0) | |||
@@ -230,6 +233,8 @@ protected: | |||
private: | |||
void debugprint() | |||
{ | |||
using std::min, std::max, std::fabs; | |||
// Print some debug information | |||
printf("Simplex Noise of Dimension %d\n", N); | |||
@@ -281,8 +286,8 @@ private: | |||
continue; | |||
float l = length(vertices[i] - vertices[j]); | |||
minlength = std::min(minlength, l); | |||
maxlength = std::max(maxlength, l); | |||
minlength = min(minlength, l); | |||
maxlength = max(maxlength, l); | |||
} | |||
printf(" · edge lengths between %f and %f\n", | |||
minlength, maxlength); | |||
@@ -306,7 +311,7 @@ private: | |||
p += k * vertices[j]; | |||
sum += k; | |||
} | |||
mindist = std::min(mindist, distance(vertices[i], p / sum)); | |||
mindist = min(mindist, distance(vertices[i], p / sum)); | |||
} | |||
printf(" · approx. dist. to opposite hyperplane: %f\n", mindist); | |||
#endif | |||
@@ -388,11 +393,11 @@ private: | |||
t = best_t2; | |||
} | |||
} | |||
minval = std::min(t, minval); | |||
maxval = std::max(t, maxval); | |||
minval = min(t, minval); | |||
maxval = max(t, maxval); | |||
} | |||
printf(" - noise value min/max: %f %f\n", minval, maxval); | |||
float newscale = 1.f / std::max(-minval, maxval); | |||
float newscale = 1.f / max(-minval, maxval); | |||
if (newscale < 1.f) | |||
printf(" - could replace scale %f with %f\n", | |||
get_scale(), newscale * get_scale()); | |||