forward_kinematics.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <[email protected]>
  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. const int m = BE.rows();
  23. assert(m == P.rows());
  24. assert(m == (int)dQ.size());
  25. assert(m == (int)dT.size());
  26. std::vector<bool> computed(m,false);
  27. vQ.resize(m);
  28. vT.resize(m);
  29. // Dynamic programming
  30. std::function<void (int) > fk_helper = [&] (int b)
  31. {
  32. if(!computed[b])
  33. {
  34. if(P(b) < 0)
  35. {
  36. // base case for roots
  37. vQ[b] = dQ[b];
  38. const Eigen::Vector3d r = C.row(BE(b,0)).transpose();
  39. vT[b] = r-dQ[b]*r + dT[b];
  40. }else
  41. {
  42. // Otherwise first compute parent's
  43. const int p = P(b);
  44. fk_helper(p);
  45. vQ[b] = vQ[p] * dQ[b];
  46. const Eigen::Vector3d r = C.row(BE(b,0)).transpose();
  47. vT[b] = vT[p] - vQ[b]*r + vQ[p]*(r + dT[b]);
  48. }
  49. computed[b] = true;
  50. }
  51. };
  52. for(int b = 0;b<m;b++)
  53. {
  54. fk_helper(b);
  55. }
  56. }
  57. IGL_INLINE void igl::forward_kinematics(
  58. const Eigen::MatrixXd & C,
  59. const Eigen::MatrixXi & BE,
  60. const Eigen::VectorXi & P,
  61. const std::vector<
  62. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & dQ,
  63. std::vector<
  64. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & vQ,
  65. std::vector<Eigen::Vector3d> & vT)
  66. {
  67. std::vector<Eigen::Vector3d> dT(BE.rows(),Eigen::Vector3d(0,0,0));
  68. return forward_kinematics(C,BE,P,dQ,dT,vQ,vT);
  69. }
  70. IGL_INLINE void igl::forward_kinematics(
  71. const Eigen::MatrixXd & C,
  72. const Eigen::MatrixXi & BE,
  73. const Eigen::VectorXi & P,
  74. const std::vector<
  75. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & dQ,
  76. const std::vector<Eigen::Vector3d> & dT,
  77. Eigen::MatrixXd & T)
  78. {
  79. std::vector< Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > vQ;
  80. std::vector< Eigen::Vector3d> vT;
  81. forward_kinematics(C,BE,P,dQ,dT,vQ,vT);
  82. const int dim = C.cols();
  83. T.resize(BE.rows()*(dim+1),dim);
  84. for(int e = 0;e<BE.rows();e++)
  85. {
  86. Eigen::Affine3d a = Eigen::Affine3d::Identity();
  87. a.translate(vT[e]);
  88. a.rotate(vQ[e]);
  89. T.block(e*(dim+1),0,dim+1,dim) =
  90. a.matrix().transpose().block(0,0,dim+1,dim);
  91. }
  92. }
  93. IGL_INLINE void igl::forward_kinematics(
  94. const Eigen::MatrixXd & C,
  95. const Eigen::MatrixXi & BE,
  96. const Eigen::VectorXi & P,
  97. const std::vector<
  98. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & dQ,
  99. Eigen::MatrixXd & T)
  100. {
  101. std::vector<Eigen::Vector3d> dT(BE.rows(),Eigen::Vector3d(0,0,0));
  102. return forward_kinematics(C,BE,P,dQ,dT,T);
  103. }
  104. #ifdef IGL_STATIC_LIBRARY
  105. // Explicit template instantiation
  106. #endif