forward_kinematics.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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. IGL_INLINE void igl::forward_kinematics(
  11. const Eigen::MatrixXd & C,
  12. const Eigen::MatrixXi & BE,
  13. const Eigen::VectorXi & P,
  14. const std::vector<
  15. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & dQ,
  16. std::vector<
  17. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & vQ,
  18. std::vector<Eigen::Vector3d> & vT)
  19. {
  20. using namespace std;
  21. using namespace Eigen;
  22. const int m = BE.rows();
  23. assert(m == P.rows());
  24. assert(m == (int)dQ.size());
  25. vector<bool> computed(m,false);
  26. vQ.resize(m);
  27. vT.resize(m);
  28. function<void (int) > fk_helper = [&] (int b)
  29. {
  30. if(!computed[b])
  31. {
  32. if(P(b) < 0)
  33. {
  34. // base case for roots
  35. vQ[b] = dQ[b];
  36. const Vector3d r = C.row(BE(b,0)).transpose();
  37. vT[b] = r-dQ[b]*r;
  38. }else
  39. {
  40. // Otherwise first compute parent's
  41. const int p = P(b);
  42. fk_helper(p);
  43. vQ[b] = vQ[p] * dQ[b];
  44. const Vector3d r = C.row(BE(b,0)).transpose();
  45. vT[b] = vT[p] - vQ[b]*r + vQ[p]*r;
  46. }
  47. computed[b] = true;
  48. }
  49. };
  50. for(int b = 0;b<m;b++)
  51. {
  52. fk_helper(b);
  53. }
  54. }
  55. IGL_INLINE void igl::forward_kinematics(
  56. const Eigen::MatrixXd & C,
  57. const Eigen::MatrixXi & BE,
  58. const Eigen::VectorXi & P,
  59. const std::vector<
  60. Eigen::Quaterniond,Eigen::aligned_allocator<Eigen::Quaterniond> > & dQ,
  61. Eigen::MatrixXd & T)
  62. {
  63. using namespace Eigen;
  64. using namespace std;
  65. vector< Quaterniond,aligned_allocator<Quaterniond> > vQ;
  66. vector< Vector3d> vT;
  67. forward_kinematics(C,BE,P,dQ,vQ,vT);
  68. const int dim = C.cols();
  69. T.resize(BE.rows()*(dim+1),dim);
  70. for(int e = 0;e<BE.rows();e++)
  71. {
  72. Affine3d a = Affine3d::Identity();
  73. a.translate(vT[e]);
  74. a.rotate(vQ[e]);
  75. T.block(e*(dim+1),0,dim+1,dim) =
  76. a.matrix().transpose().block(0,0,dim+1,dim);
  77. }
  78. }
  79. #ifdef IGL_STATIC_LIBRARY
  80. // Explicit template specialization
  81. #endif