TranslateWidget.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 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. #ifndef IGL_OPENGL2_TRANSLATE_WIDGET_H
  9. #define IGL_OPENGL2_TRANSLATE_WIDGET_H
  10. #include <Eigen/Geometry>
  11. #include <Eigen/Core>
  12. #include <vector>
  13. #include "../material_colors.h"
  14. namespace igl
  15. {
  16. namespace opengl2
  17. {
  18. class TranslateWidget
  19. {
  20. public:
  21. // m_pos position of center
  22. // m_trans translation vector
  23. // m_down_xy mouse position on down
  24. // m_drag_xy mouse position on drag
  25. // m_is_enabled whether enabled
  26. Eigen::Vector3d m_pos,m_trans,m_down_trans;
  27. Eigen::Vector2d m_down_xy, m_drag_xy;
  28. bool m_is_enabled;
  29. double m_len;
  30. enum DownType
  31. {
  32. DOWN_TYPE_X = 0,
  33. DOWN_TYPE_Y = 1,
  34. DOWN_TYPE_Z = 2,
  35. DOWN_TYPE_CENTER = 3,
  36. DOWN_TYPE_NONE = 4,
  37. NUM_DOWN_TYPES = 5
  38. } m_down_type, m_selected_type;
  39. inline TranslateWidget(const Eigen::Vector3d & pos = Eigen::Vector3d(0,0,0));
  40. inline bool down(const int x, const int y);
  41. inline bool drag(const int x, const int y);
  42. inline bool up(const int x, const int y);
  43. inline bool is_down() const;
  44. inline void draw() const;
  45. public:
  46. EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
  47. };
  48. }
  49. }
  50. // Implementation
  51. #include "project.h"
  52. #include "unproject.h"
  53. inline igl::opengl2::TranslateWidget::TranslateWidget(
  54. const Eigen::Vector3d & pos):
  55. m_pos(pos),
  56. m_trans(0,0,0),
  57. m_down_xy(-1,-1),
  58. m_drag_xy(-1,-1),
  59. m_is_enabled(true),
  60. m_len(50),
  61. m_down_type(DOWN_TYPE_NONE),
  62. m_selected_type(DOWN_TYPE_NONE)
  63. {
  64. }
  65. inline bool igl::opengl2::TranslateWidget::down(const int x, const int y)
  66. {
  67. using namespace Eigen;
  68. using namespace std;
  69. if(!m_is_enabled)
  70. {
  71. return false;
  72. }
  73. m_down_trans = m_trans;
  74. m_down_xy = Vector2d(x,y);
  75. m_drag_xy = m_down_xy;
  76. m_down_type = DOWN_TYPE_NONE;
  77. m_selected_type = DOWN_TYPE_NONE;
  78. Vector3d ppos = project((m_pos+m_trans).eval());
  79. const double r = (ppos.head(2) - m_down_xy).norm();
  80. const double center_thresh = 10;
  81. if(r < center_thresh)
  82. {
  83. m_down_type = DOWN_TYPE_CENTER;
  84. m_selected_type = m_down_type;
  85. return true;
  86. }else if(r < m_len)
  87. {
  88. // Might be hit on lines
  89. }
  90. return false;
  91. }
  92. inline bool igl::opengl2::TranslateWidget::drag(const int x, const int y)
  93. {
  94. using namespace std;
  95. using namespace Eigen;
  96. if(!m_is_enabled)
  97. {
  98. return false;
  99. }
  100. m_drag_xy = Vector2d(x,y);
  101. switch(m_down_type)
  102. {
  103. case DOWN_TYPE_NONE:
  104. return false;
  105. default:
  106. {
  107. Vector3d ppos = project((m_pos+m_trans).eval());
  108. Vector3d drag3(m_drag_xy(0),m_drag_xy(1),ppos(2));
  109. Vector3d down3(m_down_xy(0),m_down_xy(1),ppos(2));
  110. m_trans = m_down_trans + unproject(drag3)-unproject(down3);
  111. return true;
  112. }
  113. }
  114. }
  115. inline bool igl::opengl2::TranslateWidget::up(const int /*x*/, const int /*y*/)
  116. {
  117. // even if disabled process up
  118. m_down_type = DOWN_TYPE_NONE;
  119. return false;
  120. }
  121. inline bool igl::opengl2::TranslateWidget::is_down() const
  122. {
  123. return m_down_type != DOWN_TYPE_NONE;
  124. }
  125. inline void igl::opengl2::TranslateWidget::draw() const
  126. {
  127. using namespace Eigen;
  128. using namespace std;
  129. glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_LINE_BIT);
  130. glDisable(GL_LIGHTING);
  131. glDisable(GL_DEPTH_TEST);
  132. glLineWidth(2.0);
  133. auto draw_axes = [&]()
  134. {
  135. glBegin(GL_LINES);
  136. glColor3f(1,0,0);
  137. glVertex3f(0,0,0);
  138. glVertex3f(1,0,0);
  139. glColor3f(0,1,0);
  140. glVertex3f(0,0,0);
  141. glVertex3f(0,1,0);
  142. glColor3f(0,0,1);
  143. glVertex3f(0,0,0);
  144. glVertex3f(0,0,1);
  145. glEnd();
  146. };
  147. auto draw_cube = []
  148. {
  149. glBegin(GL_LINES);
  150. glVertex3f(-1.0f, 1.0f, 1.0f);
  151. glVertex3f(1.0f, 1.0f, 1.0f);
  152. glVertex3f(1.0f, 1.0f, 1.0f);
  153. glVertex3f(1.0f, -1.0f, 1.0f);
  154. glVertex3f(1.0f, -1.0f, 1.0f);
  155. glVertex3f(-1.0f, -1.0f, 1.0f);
  156. glVertex3f(-1.0f, -1.0f, 1.0f);
  157. glVertex3f(-1.0f, 1.0f, 1.0f);
  158. glVertex3f(1.0f, 1.0f, 1.0f);
  159. glVertex3f(1.0f, 1.0f, -1.0f);
  160. glVertex3f(1.0f, 1.0f, -1.0f);
  161. glVertex3f(1.0f, -1.0f, -1.0f);
  162. glVertex3f(1.0f, -1.0f, -1.0f);
  163. glVertex3f(1.0f, -1.0f, 1.0f);
  164. glVertex3f(1.0f, 1.0f, -1.0f);
  165. glVertex3f(-1.0f, 1.0f, -1.0f);
  166. glVertex3f(-1.0f, -1.0f, -1.0f);
  167. glVertex3f(1.0f, -1.0f, -1.0f);
  168. glVertex3f(-1.0f, -1.0f, -1.0f);
  169. glVertex3f(-1.0f, 1.0f, -1.0f);
  170. glVertex3f(-1.0f, 1.0f, -1.0f);
  171. glVertex3f(-1.0f, 1.0f, 1.0f);
  172. glVertex3f(-1.0f, -1.0f, 1.0f);
  173. glVertex3f(-1.0f, -1.0f, -1.0f);
  174. glEnd();
  175. };
  176. glPushMatrix();
  177. glTranslated( m_pos(0)+m_trans(0), m_pos(1)+m_trans(1), m_pos(2)+m_trans(2));
  178. {
  179. Vector3d off,ppos,ppos_off,pos_off;
  180. project((m_pos+m_trans).eval(),ppos);
  181. ppos_off = ppos;
  182. ppos_off(0) += m_len;
  183. unproject(ppos_off,pos_off);
  184. const double r = (m_pos+m_trans-pos_off).norm();
  185. glScaled(r,r,r);
  186. }
  187. draw_axes();
  188. glScaled(0.05,0.05,0.05);
  189. if(m_selected_type == DOWN_TYPE_CENTER)
  190. {
  191. glColor3fv(MAYA_YELLOW.data());
  192. }else
  193. {
  194. glColor3fv(MAYA_GREY.data());
  195. }
  196. draw_cube();
  197. glPopMatrix();
  198. glPopAttrib();
  199. }
  200. #endif