瀏覽代碼

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

legacy
Sam Hocevar sam 13 年之前
父節點
當前提交
80e0d4c1c0
共有 2 個檔案被更改,包括 54 行新增18 行删除
  1. +44
    -11
      src/lol/math/interp.h
  2. +10
    -7
      test/unit/interp.cpp

+ 44
- 11
src/lol/math/interp.h 查看文件

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


template<typename T, int N = 16> class Interp
template<typename T, int N = 16> class TimeInterp
{ {
public: 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) 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_val[m_pos + N] = val;
++m_pos; ++m_pos;
} }
else 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_val[m_pos] = val;
m_pos = (m_pos + 1) % N; m_pos = (m_pos + 1) % N;
} }
} }


T Get(float key)
T Get(float seconds)
{ {
if (m_pos == -N) if (m_pos == -N)
return T(); return T();
if (m_pos == 1 - N) if (m_pos == 1 - N)
return m_val[0]; return m_val[0];


seconds += m_accum;

int start = max(0, m_pos); int start = max(0, m_pos);
int a = 0; int a = 0;
int b = min(m_pos + N - 1, N - 1); int b = min(m_pos + N - 1, N - 1);
@@ -55,15 +76,15 @@ public:
while (a + 1 < b) while (a + 1 < b)
{ {
int c = (a + b) / 2; int c = (a + b) / 2;
if (m_key[(start + c) % N] >= key)
if (GetTime((start + c) % N) >= seconds)
b = c; b = c;
else else
a = c; 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]; return (1.f - u) * m_val[(start + a) % N] + u * m_val[(start + b) % N];
} }
@@ -74,9 +95,21 @@ public:
} }


private: 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]; float m_key[N];
T m_val[N]; T m_val[N];


float m_precision, m_accum;

/* If m_pos < 0, the value indicates how many free slots /* If m_pos < 0, the value indicates how many free slots
* there are. */ * there are. */
int m_pos; int m_pos;


+ 10
- 7
test/unit/interp.cpp 查看文件

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


void TearDown() {} 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);
} }
}; };




Loading…
取消
儲存