Quellcode durchsuchen

math: replace Interp with TimeInterp. We'll see how useful it gets.

legacy
Sam Hocevar sam vor 13 Jahren
Ursprung
Commit
80e0d4c1c0
2 geänderte Dateien mit 54 neuen und 18 gelöschten Zeilen
  1. +44
    -11
      src/lol/math/interp.h
  2. +10
    -7
      test/unit/interp.cpp

+ 44
- 11
src/lol/math/interp.h Datei anzeigen

@@ -19,35 +19,56 @@
namespace lol
{

template<typename T, int N = 16> class Interp
template<typename T, int N = 16> class TimeInterp
{
public:
inline Interp() : m_pos(-N) {}
inline ~Interp() {}
inline TimeInterp()
: m_precision(0.f),
m_accum(0.f),
m_pos(-N)
{}

void Set(float key, T const &val)
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)
{
m_key[m_pos + N] = key;
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
{
m_key[m_pos] = key;
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 key)
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);
@@ -55,15 +76,15 @@ public:
while (a + 1 < b)
{
int c = (a + b) / 2;
if (m_key[(start + c) % N] >= key)
if (GetTime((start + c) % N) >= seconds)
b = c;
else
a = c;
}

float ka = m_key[(start + a) % N];
float kb = m_key[(start + b) % N];
float u = (key - ka) / (kb - ka);
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];
}
@@ -74,9 +95,21 @@ public:
}

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;


+ 10
- 7
test/unit/interp.cpp Datei anzeigen

@@ -24,16 +24,19 @@ LOLUNIT_FIXTURE(InterpTest)

void TearDown() {}

LOLUNIT_TEST(FloatInterp)
LOLUNIT_TEST(TimeInterpTest)
{
Interp<float> interp;
TimeInterp<float> ti;

interp.Set(1.f, 100.f);
interp.Set(2.f, 150.f);
ti.Set(1.f, 10.f);
ti.Set(1.f, 20.f);
ti.Set(1.f, 30.f);

LOLUNIT_ASSERT_DOUBLES_EQUAL(75.f, interp.Get(0.5f), 1.e-5f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(125.f, interp.Get(1.5f), 1.e-5f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(175.f, interp.Get(2.5f), 1.e-5f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(0.f, ti.Get(-3.0f), 1.e-5f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(10.f, ti.Get(-2.0f), 1.e-5f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(20.f, ti.Get(-1.0f), 1.e-5f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(30.f, ti.Get(0.0f), 1.e-5f);
LOLUNIT_ASSERT_DOUBLES_EQUAL(40.f, ti.Get(1.0f), 1.e-5f);
}
};



Laden…
Abbrechen
Speichern