math_helper.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #ifndef DEPTHGUIDE_MATH_HELPER_HPP
  2. #define DEPTHGUIDE_MATH_HELPER_HPP
  3. #include "core/utility.hpp"
  4. #include <glm/glm.hpp>
  5. #include <glm/gtc/matrix_access.hpp>
  6. #include <glm/gtc/quaternion.hpp>
  7. #include <glm/gtx/transform.hpp>
  8. #include <Eigen/Geometry>
  9. // r in radius
  10. inline glm::mat4 to_transform_mat(glm::vec3 t, glm::vec3 r) {
  11. static constexpr auto unit_x = glm::vec3(1.0f, 0.0f, 0.0f);
  12. static constexpr auto unit_y = glm::vec3(0.0f, 1.0f, 0.0f);
  13. static constexpr auto unit_z = glm::vec3(0.0f, 0.0f, 1.0f);
  14. auto rot = glm::angleAxis(r.x, unit_x)
  15. * glm::angleAxis(r.y, unit_y)
  16. * glm::angleAxis(r.z, unit_z);
  17. auto offset = glm::translate(t);
  18. return offset * glm::mat4_cast(rot);
  19. }
  20. inline glm::mat4 to_transform_mat(glm::vec3 t, glm::mat3 r) {
  21. auto ret = glm::mat4(r);
  22. ret[3] = glm::vec4(t, 1.f);
  23. return ret;
  24. }
  25. template<typename Scalar, int Mode>
  26. inline glm::mat4 to_mat4(const Eigen::Transform<Scalar, 3, Mode> &m) {
  27. auto ret = glm::mat4();
  28. auto &mat = m.matrix();
  29. for (auto j = 0; j < 4; ++j)
  30. for (auto i = 0; i < 4; ++i) {
  31. ret[j][i] = mat(i, j);
  32. }
  33. return ret;
  34. }
  35. template<typename Scalar, int Mode>
  36. inline auto to_eigen_transform(const glm::mat4 &m) {
  37. auto ret = Eigen::Transform<Scalar, 3, Mode>();
  38. auto &mat = ret.matrix();
  39. for (auto j = 0; j < 4; ++j)
  40. for (auto i = 0; i < 4; ++i) {
  41. mat(i, j) = m[j][i];
  42. }
  43. return ret;
  44. }
  45. template<typename Scalar, int Mode>
  46. inline void to_eigen_transform(const glm::mat4 &m,
  47. Eigen::Transform<Scalar, 3, Mode> &ret) {
  48. ret = to_eigen_transform<Scalar, Mode>(m);
  49. }
  50. template<typename T>
  51. concept Vec2Type = requires(T t) {
  52. { t.x } -> std::convertible_to<float>;
  53. { t.y } -> std::convertible_to<float>;
  54. };
  55. template<Vec2Type T>
  56. inline auto to_vec2(const T &v) {
  57. return glm::vec2(v.x, v.y);
  58. }
  59. template<typename T>
  60. concept Vec3Type = requires(T t) {
  61. { t.x } -> std::convertible_to<float>;
  62. { t.y } -> std::convertible_to<float>;
  63. { t.z } -> std::convertible_to<float>;
  64. };
  65. template<Vec3Type T>
  66. inline auto to_vec3(const T &v) {
  67. return glm::vec3(v.x, v.y, v.z);
  68. }
  69. template<typename EigenType>
  70. glm::vec3 to_vec3(const Eigen::MatrixBase<EigenType> &v) {
  71. static_assert(EigenType::SizeAtCompileTime == 3);
  72. return glm::vec3(v.x(), v.y(), v.z());
  73. }
  74. inline auto to_homo(const glm::vec3 &v) {
  75. return glm::vec4(v, 1.f);
  76. }
  77. inline auto to_homo(const glm::vec2 &v) {
  78. return glm::vec3(v, 1.f);
  79. }
  80. inline auto from_homo(const glm::vec4 &v) {
  81. return glm::vec3(v) / v.w;
  82. }
  83. inline auto from_homo(const glm::vec3 &v) {
  84. return glm::vec2(v) / v.z;
  85. }
  86. // transform point
  87. inline glm::vec3 transform_p(const glm::mat4 &mat, const glm::vec3 &point) {
  88. return from_homo(mat * to_homo(point));
  89. }
  90. inline glm::vec2 transform_p(const glm::mat3 &mat, const glm::vec2 &point) {
  91. return from_homo(mat * to_homo(point));
  92. }
  93. // transform vector
  94. inline glm::vec3 transform_v(const glm::mat4 &mat, const glm::vec3 &vec) {
  95. return glm::mat3(mat) * vec;
  96. }
  97. inline glm::vec3 to_translation(const glm::mat4 &mat) {
  98. return glm::column(mat, 3);
  99. }
  100. inline glm::mat4 transform_mix(const glm::mat4 &x, const glm::mat4 &y, float a) {
  101. // translation
  102. auto xt = to_translation(x);
  103. auto yt = to_translation(y);
  104. auto zt = glm::mix(xt, yt, a);
  105. // rotation
  106. auto xq = glm::quat_cast(glm::mat3(x));
  107. auto yq = glm::quat_cast(glm::mat3(y));
  108. auto zq = glm::slerp(xq, yq, a);
  109. return to_transform_mat(zt, glm::mat3_cast(zq));
  110. }
  111. class transform_buffer {
  112. public:
  113. transform_buffer();
  114. ~transform_buffer();
  115. void add(const glm::mat4 &mat, timestamp_type ts);
  116. glm::mat4 query(timestamp_type ts);
  117. void remove_old(int max_offset);
  118. private:
  119. struct impl;
  120. std::unique_ptr<impl> pimpl;
  121. };
  122. #endif //DEPTHGUIDE_MATH_HELPER_HPP