draw_skeleton.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <Eigen/Core>
  2. // Draw a skeleton
  3. //
  4. // Inputs:
  5. // C #C by dim List of joint rest positions
  6. // BE #BE by 2 list of bone edge indices into C
  7. template <typename DerivedC, typename DerivedBE>
  8. void draw_skeleton(
  9. const Eigen::PlainObjectBase<DerivedC> & C,
  10. const Eigen::PlainObjectBase<DerivedBE> & BE);
  11. template <typename DerivedC, typename DerivedBE, typename DerivedT>
  12. void draw_skeleton(
  13. const Eigen::PlainObjectBase<DerivedC> & C,
  14. const Eigen::PlainObjectBase<DerivedBE> & BE,
  15. const Eigen::PlainObjectBase<DerivedT> & T);
  16. // Implementation
  17. #include <igl/PI.h>
  18. #include <igl/OpenGL_convenience.h>
  19. #include <Eigen/Geometry>
  20. #include <iostream>
  21. template <typename DerivedC, typename DerivedBE>
  22. void draw_skeleton(
  23. const Eigen::PlainObjectBase<DerivedC> & C,
  24. const Eigen::PlainObjectBase<DerivedBE> & BE)
  25. {
  26. using namespace Eigen;
  27. typedef Eigen::Matrix<typename DerivedC::Scalar,Dynamic,Dynamic> Mat;
  28. Mat I = Mat::Identity(C.cols()+1,C.cols());
  29. Mat T = I.replicate(BE.rows(),1);
  30. return draw_skeleton(C,BE,T);
  31. }
  32. template <typename DerivedC, typename DerivedBE, typename DerivedT>
  33. void draw_skeleton(
  34. const Eigen::PlainObjectBase<DerivedC> & C,
  35. const Eigen::PlainObjectBase<DerivedBE> & BE,
  36. const Eigen::PlainObjectBase<DerivedT> & T)
  37. {
  38. using namespace Eigen;
  39. using namespace std;
  40. glDisable(GL_LIGHTING);
  41. glColor3d(70./255.,252./255.,167./255.);
  42. glLineWidth(2.0);
  43. auto draw_sphere = [](const double r)
  44. {
  45. auto draw_circle = []()
  46. {
  47. glBegin(GL_LINE_STRIP);
  48. for(double th = 0;th<2.0*igl::PI;th+=(2.0*igl::PI/30.0))
  49. {
  50. glVertex3d(cos(th),sin(th),0.0);
  51. }
  52. glVertex3d(cos(0),sin(0),0.0);
  53. glEnd();
  54. };
  55. glPushMatrix();
  56. glScaled(r,r,r);
  57. draw_circle();
  58. glRotated(90.0,1.0,0.0,0.0);
  59. draw_circle();
  60. glRotated(90.0,0.0,1.0,0.0);
  61. draw_circle();
  62. glPopMatrix();
  63. };
  64. auto draw_pyramid = [](const double r)
  65. {
  66. glBegin(GL_LINE_STRIP);
  67. glVertex3d(0, 1,-1);
  68. glVertex3d(0,-1,-1);
  69. glVertex3d(0,-1, 1);
  70. glVertex3d(0, 1, 1);
  71. glVertex3d(0, 1,-1);
  72. glEnd();
  73. glBegin(GL_LINES);
  74. glVertex3d(0, 1,-1);
  75. glVertex3d(1,0,0);
  76. glVertex3d(0,-1,-1);
  77. glVertex3d(1,0,0);
  78. glVertex3d(0,-1, 1);
  79. glVertex3d(1,0,0);
  80. glVertex3d(0, 1, 1);
  81. glVertex3d(1,0,0);
  82. glEnd();
  83. };
  84. // Loop over bones
  85. for(int e = 0;e < BE.rows();e++)
  86. {
  87. // Draw a sphere
  88. auto s = C.row(BE(e,0));
  89. auto d = C.row(BE(e,1));
  90. auto b = (d-s).transpose().eval();
  91. double r = 0.02;
  92. Matrix4d Te = Matrix4d::Identity();
  93. Te.block(0,0,3,4) = T.block(e*4,0,4,3).transpose();
  94. Quaterniond q;
  95. q.setFromTwoVectors(Vector3d(1,0,0),b);
  96. glPushMatrix();
  97. glMultMatrixd(Te.data());
  98. glTranslated(s(0),s(1),s(2));
  99. draw_sphere(r);
  100. const double len = b.norm()-2.*r;
  101. if(len>=0)
  102. {
  103. auto u = b.normalized()*r;
  104. glPushMatrix();
  105. glTranslated(u(0),u(1),u(2));
  106. glMultMatrixd(Affine3d(q).matrix().data());
  107. glScaled(b.norm()-2.*r,r,r);
  108. draw_pyramid(r);
  109. glPopMatrix();
  110. }
  111. glTranslated(b(0),b(1),b(2));
  112. draw_sphere(r);
  113. glPopMatrix();
  114. }
  115. }