forward_kinematics.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "forward_kinematics.h"
  9. #include <functional>
  10. #include <iostream>
  11. IGL_INLINE void igl::forward_kinematics(
  12. const Eigen::MatrixXd & C,
  13. const Eigen::MatrixXi & BE,
  14. const Eigen::VectorXi & P,
  15. const std::vector<
  16. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & dQ,
  17. const std::vector<Eigen::Vector3d> & dT,
  18. std::vector<
  19. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & vQ,
  20. std::vector<Eigen::Vector3d> & vT)
  21. {
  22. using namespace std;
  23. using namespace Eigen;
  24. const int m = BE.rows();
  25. assert(m == P.rows());
  26. assert(m == (int)dQ.size());
  27. assert(m == (int)dT.size());
  28. vector<bool> computed(m,false);
  29. vQ.resize(m);
  30. vT.resize(m);
  31. // Dynamic programming
  32. function<void (int) > fk_helper = [&] (int b)
  33. {
  34. if(!computed[b])
  35. {
  36. if(P(b) < 0)
  37. {
  38. // base case for roots
  39. vQ[b] = dQ[b];
  40. const Vector3d r = C.row(BE(b,0)).transpose();
  41. vT[b] = r-dQ[b]*r + dT[b];
  42. }else
  43. {
  44. // Otherwise first compute parent's
  45. const int p = P(b);
  46. fk_helper(p);
  47. vQ[b] = vQ[p] * dQ[b];
  48. const Vector3d r = C.row(BE(b,0)).transpose();
  49. vT[b] = vT[p] - vQ[b]*r + vQ[p]*(r + dT[b]);
  50. }
  51. computed[b] = true;
  52. }
  53. };
  54. for(int b = 0;b<m;b++)
  55. {
  56. fk_helper(b);
  57. }
  58. }
  59. IGL_INLINE void igl::forward_kinematics(
  60. const Eigen::MatrixXd & C,
  61. const Eigen::MatrixXi & BE,
  62. const Eigen::VectorXi & P,
  63. const std::vector<
  64. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & dQ,
  65. std::vector<
  66. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & vQ,
  67. std::vector<Eigen::Vector3d> & vT)
  68. {
  69. std::vector<Eigen::Vector3d> dT(BE.rows(),Eigen::Vector3d(0,0,0));
  70. return forward_kinematics(C,BE,P,dQ,dT,vQ,vT);
  71. }
  72. IGL_INLINE void igl::forward_kinematics(
  73. const Eigen::MatrixXd & C,
  74. const Eigen::MatrixXi & BE,
  75. const Eigen::VectorXi & P,
  76. const std::vector<
  77. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & dQ,
  78. const std::vector<Eigen::Vector3d> & dT,
  79. Eigen::MatrixXd & T)
  80. {
  81. using namespace Eigen;
  82. using namespace std;
  83. vector< Quaterniond,aligned_allocator<Quaterniond> > vQ;
  84. vector< Vector3d> vT;
  85. forward_kinematics(C,BE,P,dQ,dT,vQ,vT);
  86. const int dim = C.cols();
  87. T.resize(BE.rows()*(dim+1),dim);
  88. for(int e = 0;e<BE.rows();e++)
  89. {
  90. Affine3d a = Affine3d::Identity();
  91. a.translate(vT[e]);
  92. a.rotate(vQ[e]);
  93. T.block(e*(dim+1),0,dim+1,dim) =
  94. a.matrix().transpose().block(0,0,dim+1,dim);
  95. }
  96. }
  97. IGL_INLINE void igl::forward_kinematics(
  98. const Eigen::MatrixXd & C,
  99. const Eigen::MatrixXi & BE,
  100. const Eigen::VectorXi & P,
  101. const std::vector<
  102. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & dQ,
  103. Eigen::MatrixXd & T)
  104. {
  105. std::vector<Eigen::Vector3d> dT(BE.rows(),Eigen::Vector3d(0,0,0));
  106. return forward_kinematics(C,BE,P,dQ,dT,T);
  107. }
  108. #ifdef IGL_STATIC_LIBRARY
  109. // Explicit template specialization
  110. #endif