splines.cpp 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include <splines.h>
  2. #include <glm/glm.hpp>
  3. glm::vec2 lerp(glm::vec2 a, glm::vec2 b, float r)
  4. {
  5. return a * (1.f - r) + b * r;
  6. }
  7. glm::dvec3 lerp(glm::dvec3 a, glm::dvec3 b, float r)
  8. {
  9. return a * (1.0 - (double)r) + b * (double)r;
  10. }
  11. float applySpline(float p, glm::vec2 *points, size_t s)
  12. {
  13. if (s >= 2)
  14. {
  15. for (int i = 1; i < s; i++)
  16. {
  17. if (p <= points[i].x)
  18. {
  19. auto p1 = points[i - 1];
  20. auto p2 = points[i];
  21. return lerp(p1.y, p2.y, (p - p1.x) / (p2.x - p1.x));
  22. }
  23. }
  24. }
  25. return p;
  26. }
  27. float applySpline(float p, Spline &s)
  28. {
  29. return applySpline(p, s.points, s.size);
  30. }
  31. void Spline::addSpline()
  32. {
  33. if (size < MAX_SPLINES_COUNT)
  34. {
  35. if (size >= 2)
  36. {
  37. points[size] = points[size - 1];
  38. points[size - 1] = lerp(points[size - 2], points[size], 0.5f);
  39. size++;
  40. }
  41. else
  42. {
  43. size = 2;
  44. points[0] = {0,0};
  45. points[1] = {1,1};
  46. }
  47. }
  48. }
  49. void Spline::removeSpline()
  50. {
  51. if (size > 2)
  52. {
  53. size--;
  54. points[size - 1].x = 1;
  55. }
  56. }
  57. float Spline::applySpline(float p)
  58. {
  59. return ::applySpline(p, *this);
  60. }
  61. std::string Spline::saveSettings(int tabs)
  62. {
  63. std::string rez;
  64. rez.reserve(100);
  65. auto addTabs = [&]() { for (int i = 0; i < tabs; i++) { rez += '\t'; } };
  66. addTabs();
  67. rez += "{\n";
  68. for (int i = 0; i < std::min(MAX_SPLINES_COUNT, size); i++)
  69. {
  70. addTabs();
  71. rez += std::to_string(points[i].x);
  72. rez += ",";
  73. rez += std::to_string(points[i].y);
  74. rez += ";\n";
  75. };
  76. addTabs();
  77. rez += "}\n";
  78. return rez;
  79. }
  80. void Spline::sanitize()
  81. {
  82. for (int i = 0; i < size; ++i)
  83. {
  84. points[i] = glm::clamp(points[i], {0,0}, {1,1});
  85. if (i > 0)
  86. {
  87. points[i] = glm::clamp(points[i], {points[i - 1].x,0}, {1,1});
  88. }
  89. }
  90. }