@@ -15,8 +15,6 @@ | |||||
src/lol/math/geometry.h | src/lol/math/geometry.h | ||||
src/lol/math/interp.h (but what is it?) | src/lol/math/interp.h (but what is it?) | ||||
src/numeric.h | |||||
## headers to keep in the engine | ## headers to keep in the engine | ||||
@@ -21,6 +21,9 @@ | |||||
#include <cstdio> | #include <cstdio> | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <type_traits> | #include <type_traits> | ||||
#if defined __cpp_lib_int_pow2 | |||||
#include <bit> | |||||
#endif | |||||
#include <stdint.h> | #include <stdint.h> | ||||
@@ -126,6 +129,24 @@ template<typename T, typename T2 = LOL_T_FLOATING_POINT> | |||||
return mix(a, b, x); | return mix(a, b, x); | ||||
} | } | ||||
// Round up to next power of two | |||||
template<typename T, typename T2=LOL_T_INTEGRAL> | |||||
[[nodiscard]] static inline T2 bit_ceil(T x) | |||||
{ | |||||
#if defined __cpp_lib_int_pow2 | |||||
return std::bit_ceil(x); | |||||
#else | |||||
x = x - 1; | |||||
if constexpr (sizeof(x) > 4) x |= uint64_t(x) >> 32; | |||||
if constexpr (sizeof(x) > 2) x |= uint64_t(x) >> 16; | |||||
if constexpr (sizeof(x) > 1) x |= uint64_t(x) >> 8; | |||||
x |= uint64_t(x) >> 4; | |||||
x |= uint64_t(x) >> 2; | |||||
x |= uint64_t(x) >> 1; | |||||
return x + 1; | |||||
#endif | |||||
} | |||||
// C++ doesn't define fabs() 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. | // convenience to avoid adding complexity to vector.h. | ||||
template<typename T, typename T2 = LOL_T_SIGNED> | template<typename T, typename T2 = LOL_T_SIGNED> | ||||
@@ -1,122 +0,0 @@ | |||||
// | |||||
// Lol Engine | |||||
// | |||||
// Copyright © 2010—2020 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | |||||
#pragma once | |||||
#include <lol/math> | |||||
// | |||||
// Interpolator classes | |||||
// -------------------- | |||||
// | |||||
namespace lol | |||||
{ | |||||
template<typename T, int N = 16> class TimeInterp | |||||
{ | |||||
public: | |||||
inline TimeInterp() | |||||
: m_precision(0.f), | |||||
m_accum(0.f), | |||||
m_pos(-N) | |||||
{} | |||||
inline ~TimeInterp() {} | |||||
void SetPrecision(float seconds) | |||||
{ | |||||
m_precision = seconds; | |||||
} | |||||
void Set(float seconds, T const &val) | |||||
{ | |||||
m_accum += seconds; | |||||
if (m_accum < m_precision) | |||||
return; | |||||
m_accum = 0.f; | |||||
if (m_pos < 0) | |||||
{ | |||||
if (m_pos > -N) | |||||
seconds += m_key[m_pos + N - 1]; | |||||
m_key[m_pos + N] = seconds; | |||||
m_val[m_pos + N] = val; | |||||
++m_pos; | |||||
} | |||||
else | |||||
{ | |||||
if (m_pos > 0) | |||||
seconds += m_key[m_pos - 1]; | |||||
m_key[m_pos] = seconds; | |||||
m_val[m_pos] = val; | |||||
m_pos = (m_pos + 1) % N; | |||||
} | |||||
} | |||||
T Get(float seconds) | |||||
{ | |||||
if (m_pos == -N) | |||||
return T(); | |||||
if (m_pos == 1 - N) | |||||
return m_val[0]; | |||||
seconds += m_accum; | |||||
int start = max(0, m_pos); | |||||
int a = 0; | |||||
int b = min(m_pos + N - 1, N - 1); | |||||
while (a + 1 < b) | |||||
{ | |||||
int c = (a + b) / 2; | |||||
if (GetTime((start + c) % N) >= seconds) | |||||
b = c; | |||||
else | |||||
a = c; | |||||
} | |||||
float ka = GetTime((start + a) % N); | |||||
float kb = GetTime((start + b) % N); | |||||
float u = (seconds - ka) / (kb - ka); | |||||
return (1.f - u) * m_val[(start + a) % N] + u * m_val[(start + b) % N]; | |||||
} | |||||
inline void Reset() | |||||
{ | |||||
m_pos = -N; | |||||
} | |||||
private: | |||||
inline float GetTime(int i) | |||||
{ | |||||
float k = m_key[i % N]; | |||||
if (m_pos >= 0 && i >= m_pos) | |||||
k -= m_key[N - 1]; | |||||
if (m_pos != 0) | |||||
k -= m_key[(m_pos + N - 1) % N]; | |||||
return k; | |||||
} | |||||
float m_key[N]; | |||||
T m_val[N]; | |||||
float m_precision, m_accum; | |||||
/* If m_pos < 0, the value indicates how many free slots | |||||
* there are. */ | |||||
int m_pos; | |||||
}; | |||||
} /* namespace lol */ | |||||
@@ -1,81 +0,0 @@ | |||||
// | |||||
// Lol Engine | |||||
// | |||||
// Copyright © 2010—2020 Sam Hocevar <sam@hocevar.net> | |||||
// | |||||
// Lol Engine is free software. It comes without any warranty, to | |||||
// the extent permitted by applicable law. You can redistribute it | |||||
// and/or modify it under the terms of the Do What the Fuck You Want | |||||
// to Public License, Version 2, as published by the WTFPL Task Force. | |||||
// See http://www.wtfpl.net/ for more details. | |||||
// | |||||
#pragma once | |||||
// | |||||
// Various math utility functions | |||||
// —————————————————————————————— | |||||
// | |||||
#include <lol/math> // lol::lerp, lol::clamp | |||||
#include <cstdlib> | |||||
#include <stdint.h> | |||||
namespace lol | |||||
{ | |||||
/* Next power of two. */ | |||||
template <typename T> static inline T PotUp(T val) | |||||
{ | |||||
val = val - 1; | |||||
if (sizeof(val) > 4) val = val | ((uint64_t)val >> 32); | |||||
if (sizeof(val) > 2) val = val | ((uint64_t)val >> 16); | |||||
if (sizeof(val) > 1) val = val | ((uint64_t)val >> 8); | |||||
val = val | ((uint64_t)val >> 4); | |||||
val = val | ((uint64_t)val >> 2); | |||||
val = val | ((uint64_t)val >> 1); | |||||
return val + 1; | |||||
} | |||||
//Damp for float | |||||
template <typename T1, typename T2, typename Tf> static inline T1 damp(const T1 &a, const T2 &b, const Tf &x, const Tf &dt) | |||||
{ | |||||
if (dt <= .0f) | |||||
return a; | |||||
return lol::lerp(a, b, dt / (dt + x)); | |||||
} | |||||
//SmoothClamp clamps x in [a - sd, b + sd] and returns a value in [a, b] that is smoothed at the borders. | |||||
static inline float SmoothClamp(float &x, float a, float b, float sd) | |||||
{ | |||||
if (b < a) | |||||
Swap(a, b); | |||||
float tx = x; | |||||
float ta = a - sd; | |||||
float tb = b + sd; | |||||
if (sd > 0.f) | |||||
{ | |||||
if ((b - a) < 2.f * sd) | |||||
sd = .5f * (b - a); | |||||
if (tx < a + sd && tx > a - sd) | |||||
{ | |||||
float t = (tx - a) / sd; | |||||
t = 0.25f * (t + 1.0f) * (t + 1.0f); | |||||
tx = a + t * sd; | |||||
} | |||||
else if (tx < b + sd && tx > b - sd) | |||||
{ | |||||
float t = -(tx - b) / sd; | |||||
t = 0.25f * (t + 1.0f) * (t + 1.0f); | |||||
tx = b - t * sd; | |||||
} | |||||
} | |||||
x = lol::clamp(x, ta, tb); | |||||
return lol::clamp(tx, a, b); | |||||
} | |||||
} /* namespace lol */ | |||||