25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

119 satır
2.4 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #pragma once
  11. //
  12. // Interpolator classes
  13. // --------------------
  14. //
  15. namespace lol
  16. {
  17. template<typename T, int N = 16> class TimeInterp
  18. {
  19. public:
  20. inline TimeInterp()
  21. : m_precision(0.f),
  22. m_accum(0.f),
  23. m_pos(-N)
  24. {}
  25. inline ~TimeInterp() {}
  26. void SetPrecision(float seconds)
  27. {
  28. m_precision = seconds;
  29. }
  30. void Set(float seconds, T const &val)
  31. {
  32. m_accum += seconds;
  33. if (m_accum < m_precision)
  34. return;
  35. m_accum = 0.f;
  36. if (m_pos < 0)
  37. {
  38. if (m_pos > -N)
  39. seconds += m_key[m_pos + N - 1];
  40. m_key[m_pos + N] = seconds;
  41. m_val[m_pos + N] = val;
  42. ++m_pos;
  43. }
  44. else
  45. {
  46. if (m_pos > 0)
  47. seconds += m_key[m_pos - 1];
  48. m_key[m_pos] = seconds;
  49. m_val[m_pos] = val;
  50. m_pos = (m_pos + 1) % N;
  51. }
  52. }
  53. T Get(float seconds)
  54. {
  55. if (m_pos == -N)
  56. return T();
  57. if (m_pos == 1 - N)
  58. return m_val[0];
  59. seconds += m_accum;
  60. int start = max(0, m_pos);
  61. int a = 0;
  62. int b = min(m_pos + N - 1, N - 1);
  63. while (a + 1 < b)
  64. {
  65. int c = (a + b) / 2;
  66. if (GetTime((start + c) % N) >= seconds)
  67. b = c;
  68. else
  69. a = c;
  70. }
  71. float ka = GetTime((start + a) % N);
  72. float kb = GetTime((start + b) % N);
  73. float u = (seconds - ka) / (kb - ka);
  74. return (1.f - u) * m_val[(start + a) % N] + u * m_val[(start + b) % N];
  75. }
  76. inline void Reset()
  77. {
  78. m_pos = -N;
  79. }
  80. private:
  81. inline float GetTime(int i)
  82. {
  83. float k = m_key[i % N];
  84. if (m_pos >= 0 && i >= m_pos)
  85. k -= m_key[N - 1];
  86. if (m_pos != 0)
  87. k -= m_key[(m_pos + N - 1) % N];
  88. return k;
  89. }
  90. float m_key[N];
  91. T m_val[N];
  92. float m_precision, m_accum;
  93. /* If m_pos < 0, the value indicates how many free slots
  94. * there are. */
  95. int m_pos;
  96. };
  97. } /* namespace lol */