Tucano  0.1
A library for rapid prototyping with modern OpenGL and GLSL
trackball.hpp
Go to the documentation of this file.
1 
23 #ifndef __TRACKBALL__
24 #define __TRACKBALL__
25 
26 #include <tucano/camera.hpp>
27 #include <tucano/utils/math.hpp>
28 #include <tucano/shapes/arrow.hpp>
29 #include <Eigen/Dense>
30 #include <cmath>
31 
32 namespace Tucano
33 {
34 
36 const string trackball_fragment_code = "\n"
37  "#version 430\n"
38  "in vec4 ex_Color;\n"
39  "out vec4 out_Color;\n"
40  "in float depth;\n"
41  "void main(void)\n"
42  "{\n"
43  " out_Color = ex_Color;\n"
44  " gl_FragDepth = depth;\n"
45  "}\n";
46 
48 const string trackball_vertex_code = "\n"
49  "#version 430\n"
50  "layout(location=0) in vec4 in_Position;\n"
51  "out vec4 ex_Color;\n"
52  "out float depth;\n"
53  "uniform mat4 modelMatrix;\n"
54  "uniform mat4 viewMatrix;\n"
55  "uniform mat4 projectionMatrix;\n"
56  "uniform vec4 in_Color;\n"
57  "uniform float nearPlane;\n"
58  "uniform float farPlane;\n"
59  "void main(void)\n"
60  "{\n"
61  " vec4 pos = (viewMatrix * modelMatrix) * in_Position;\n"
62  " depth = (farPlane+nearPlane)/(farPlane-nearPlane) + ( (2*nearPlane*farPlane)/(farPlane-nearPlane) ) * (1/pos[2]);\n"
63  " depth = (depth+1.0)/2.0;\n"
64  " gl_Position = projectionMatrix * pos;\n"
65  " ex_Color = in_Color;\n"
66  "}\n";
67 
79 class Trackball : public Tucano::Camera {
80 
81 
82 protected:
84  float zoom = 1.0;
85 
87  bool rotating = false;
88 
90  bool translating = false;
91 
93  bool drawTrackball = true;
94 
96  Eigen::Matrix4f trackballProjectionMatrix;
97 
99  Eigen::Vector3f initialPosition;
100 
102  Eigen::Vector3f finalPosition;
103 
105  Eigen::Vector2f initialTranslationPosition;
106 
108  Eigen::Vector2f finalTranslationPosition;
109 
111  Eigen::Quaternion<float> quaternion;
112 
114  Eigen::Quaternion<float> default_quaternion;
115 
117  Eigen::Vector3f translationVector;
118 
120  Eigen::Vector3f default_translation = Eigen::Vector3f (0.0, 0.0, -4.0);
121 
122 
125 
128 
130  float radius = 0.8;
131 
134 
135 public:
136 
141  Trackball (string shader_dir = "")
142  {
143  // initialize the shader used for trackball rendering:
144  if (shader_dir.empty())
145  {
146  trackball_shader.setShaderName("trackballShader");
147  use_default_shaders = true;
148  }
149  else
150  {
151  trackball_shader.load("trackballShader", shader_dir);
152  use_default_shaders = false;
153  }
154 
155  // creates the mesh that will be used to represent the trackball's sphere.
157 
159  loadShader();
160  reset();
161  }
162 
163 
164 
168  void reset (void)
169  {
170  quaternion = Eigen::Quaternion<float>::Identity();
171  default_quaternion = Eigen::Quaternion<float>::Identity();
172  zoom = 1.0;
173  translationVector << 0.0, 0.0, 0.0;
174  rotating = false;
175  translating = false;
178  }
179 
184  bool isRotating (void)
185  {
186  return rotating;
187  }
188 
193  bool isTranslating (void)
194  {
195  return translating;
196  }
197 
202  Eigen::Vector3f getDefaultTranslation (void)
203  {
204  return default_translation;
205  }
206 
211  void setDefaultTranslation (Eigen::Vector3f t)
212  {
213  default_translation = t;
214  }
215 
216 
221  Eigen::Quaternion<float> getDefaultRotation (void)
222  {
223  return default_quaternion;
224  }
225 
226 
231  virtual Eigen::Quaternion<float> getRotation (void)
232  {
233  return quaternion*default_quaternion;
234  }
235 
240  void setDefaultRotation (Eigen::Matrix3f rot)
241  {
242  default_quaternion = rot;
243  }
244 
245 
249  virtual void setRadius (float r)
250  {
251  radius = r;
252  }
253 
258  float getZoom (void)
259  {
260  return zoom;
261  }
262 
263 
269  void setTrackballProjectionMatrix (const Eigen::Matrix4f& mat)
270  {
271  trackballProjectionMatrix = mat;
272  }
273 
274 
279  virtual void endRotation (void)
280  {
281  rotating = false;
282  }
283 
288  void endTranslation (void)
289  {
290  translating = false;
291  }
292 
293 
294 
299  void setRenderFlag(bool flag)
300  {
301  drawTrackball = flag;
302  }
303 
305  void loadShader (void)
306  {
307  if (use_default_shaders)
308  {
309  trackball_shader.initializeFromStrings(trackball_vertex_code, trackball_fragment_code);
310  }
311  else
312  {
313  trackball_shader.initialize();
314  }
315  }
316 
317 private:
318 
323  virtual Eigen::Vector3f computeSpherePosition (const Eigen::Vector2f& pos)
324  {
325  //In order to handle points outside the sphere, we will use two surfaces: A Sphere with radius = 0.8 and a Hyperbolic Sheet. More information about this usage in: http://www.opengl.org/wiki/Trackball.
326  float z;
327 
328  Eigen::Vector2f p = pos;
329  float r = radius;
330 
331  //If pos corresponds to a point before the intersection of the two surfaces, z can be calculated by the Sphere's equation.
332  if(p[0]*p[0] + p[1]*p[1] <= (r*r)/2.0) {
333  z = sqrt(r*r - p[0]*p[0] - p[1]*p[1]);
334  }
335 
336  //Else, it will be calculated by the Hyperbolic Sheet's equation.
337  else {
338  z = (r*r)/(2.0*sqrt(p[0]*p[0] + p[1]*p[1]));
339  }
340 
341  Eigen::Vector3f position = Eigen::Vector3f(p[0], p[1], z);
342 
343  return position;
344  }
345 
346 public:
347 
352  void initOpenGLMatrices (void)
353  {
354  // reset all matrices
355  reset();
356 
357  // translate viewMatrix outside the origin to be able to see the model.
358  translate(default_translation);
359 
360  trackballProjectionMatrix = Eigen::Matrix4f::Identity();
361  }
362 
371  Eigen::Matrix4f setTrackballPerspectiveMatrix (float fy, float aspect_ratio, float near_plane, float far_plane)
372  {
373  Eigen::Matrix4f proj = createPerspectiveMatrix(fy, aspect_ratio, near_plane, far_plane);
375  return proj;
376  }
377 
388  Eigen::Matrix4f setTrackballOrthographicMatrix (float left, float right, float bottom, float top, float near_plane, float far_plane)
389  {
390  Eigen::Matrix4f proj = createOrthographicMatrix(left, right, bottom, top, near_plane, far_plane);
392  return proj;
393  }
394 
400  virtual Eigen::Quaternion<float> computeRotationAngle (float sensibility = 1.0)
401  {
402  //Given two position vectors, corresponding to the initial and final mouse coordinates, calculate the rotation of the sphere that will keep the mouse always in the initial position.
403 
404  if(initialPosition.norm() > 0) {
405  initialPosition.normalize();
406  }
407  if(finalPosition.norm() > 0) {
408  finalPosition.normalize();
409  }
410 
411  Eigen::Vector3f rotationAxis = initialPosition.cross(finalPosition);
412 
413  if(rotationAxis.norm() != 0) {
414  rotationAxis.normalize();
415  }
416 
417  float dot = initialPosition.dot(finalPosition);
418 
419  float rotationAngle = (dot <= 1) ? acos(dot) : 0;//If, by losing floating point precision, the dot product between the initial and final positions is bigger than one, ignore the rotation.
420 
421  rotationAngle *= sensibility;
422  Eigen::Quaternion<float> q (Eigen::AngleAxis<float>(rotationAngle,rotationAxis));
423  quaternion = q * quaternion;
424  quaternion.normalize();
425  return q;
426  }
427 
431  virtual Eigen::Vector3f computeTranslationVector (void)
432  {
433  Eigen::Vector2f translationFactor = finalTranslationPosition - initialTranslationPosition;
434  Eigen::Vector3f inc = quaternion.inverse() * Eigen::Vector3f(translationFactor[0],translationFactor[1], 0.0);
435 
436  translationVector += inc;
437  return inc;
438  }
439 
445  Eigen::Vector2f normalizePosition (const Eigen::Vector2f& pos)
446  {
447  return Eigen::Vector2f ((2.0*pos[0]/(viewport[2])) - 1.0,
448  1.0 - (2.0*pos[1]/(viewport[3])));
449  }
450 
455  virtual Eigen::Quaternion<float> rotateCamera (const Eigen::Vector2f& pos)
456  {
457  Eigen::Vector3f normalized_pos = computeSpherePosition(normalizePosition(pos));
458 
459  Eigen::Quaternion<float> increment = Eigen::Quaternion<float>::Identity();
460 
461  if (!rotating)
462  {
463  rotating = true;
464  initialPosition = normalized_pos;
465  }
466  else if ( pos != initialPosition.head(2))
467  {
468  finalPosition = normalized_pos;
469  increment = computeRotationAngle();
471  initialPosition = finalPosition;
472  }
473  return increment;
474  }
475 
481  virtual Eigen::Vector3f translateCamera (const Eigen::Vector2f& pos)
482  {
483  Eigen::Vector2f normalized_pos = normalizePosition(pos);
484  Eigen::Vector3f increment = Eigen::Vector3f::Zero();
485  if (!translating)
486  {
487  translating = true;
488  initialTranslationPosition = normalized_pos;
489  }
490  else if (pos != initialPosition.head(2))
491  {
492  finalTranslationPosition = normalized_pos;
493  increment = computeTranslationVector();
495  initialTranslationPosition = finalTranslationPosition;
496  }
497  return increment;
498  }
499 
500 
506  void increaseZoom (float scale)
507  {
508  zoom *= scale;
510  }
511 
517  void decreaseZoom (float scale)
518  {
519  zoom /= scale;
521  }
522 
529  {
530  zoom = scale;
532  }
533 
540  void translateViewMatrix (const Eigen::Vector3f& translation)
541  {
542  translationVector += translation;
543  }
544 
551  void rotateViewMatrix (const Eigen::Affine3f &rot)
552  {
553  Eigen::Quaternion<float> q (rot.rotation().matrix());
554  quaternion *= q;
555  quaternion.normalize();
556  }
557 
558 
562  virtual void updateViewMatrix (void)
563  {
564  resetViewMatrix();
565  rotate(default_quaternion);
566  translate(default_translation);
567  rotate(quaternion);
568  translate(translationVector);
569  scale(zoom);
570  }
571 
577  {
578  vector < Eigen::Vector4f > vertices;
579 
580  for (float theta = 0; theta<2*M_PI; theta += (2*M_PI)/200.0)
581  {
582  vertices.push_back ( Eigen::Vector4f (cos(theta), sin(theta), 0.0, 1.0) );
583  }
584  mesh.loadVertices(vertices);
586  }
587 
588 
596  virtual void render (Eigen::Affine3f ext_view_matrix = Eigen::Affine3f::Identity(), Eigen::Matrix4f ext_proj_matrix = Eigen::Matrix4f::Identity())
597  {
598  if(drawTrackball)
599  {
600  glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
601 
602  float ratio = (viewport[2]) / (viewport[3]);
603  setTrackballOrthographicMatrix(-ratio, ratio, -1.0, 1.0, 0.1, 100.0);
604  if (ext_proj_matrix != Eigen::Matrix4f::Identity())
605  trackballProjectionMatrix = ext_proj_matrix;
606 
607  trackball_shader.bind();
608 
609  //Using unique viewMatrix for the trackball, considering only the rotation to be visualized.
610  Eigen::Affine3f trackballViewMatrix = ext_view_matrix;
611  trackballViewMatrix.translate(default_translation);
612  trackballViewMatrix.rotate(quaternion);
613  trackballViewMatrix.scale(radius);
614  trackball_shader.setUniform("viewMatrix", trackballViewMatrix);
615  trackball_shader.setUniform("projectionMatrix", trackballProjectionMatrix);
616  trackball_shader.setUniform("nearPlane", near_plane);
617  trackball_shader.setUniform("farPlane", far_plane);
618 
619  mesh.bindBuffers();
620 
621  //X:
622  Eigen::Vector4f color_vector(1.0, 0.0, 0.0, 1.0);
623  trackball_shader.setUniform("modelMatrix", Eigen::Affine3f::Identity()*Eigen::AngleAxis<float>(M_PI/2.0,Eigen::Vector3f(0.0,1.0,0.0)));
624  trackball_shader.setUniform("in_Color", color_vector);
625  mesh.renderLineLoop();
626 
627  //Y:
628  color_vector << 0.0, 1.0, 0.0, 1.0;
629  trackball_shader.setUniform("modelMatrix", Eigen::Affine3f::Identity()*Eigen::AngleAxis<float>(M_PI/2.0,Eigen::Vector3f(1.0,0.0,0.0)));
630  trackball_shader.setUniform("in_Color", color_vector);
631  mesh.renderLineLoop();
632 
633  //Z:
634  color_vector << 0.0, 0.0, 1.0, 1.0;
635  trackball_shader.setUniform("modelMatrix", Eigen::Affine3f::Identity());
636  trackball_shader.setUniform("in_Color", color_vector);
637  mesh.renderLineLoop();
638 
639  mesh.unbindBuffers();
640 
641  trackball_shader.unbind();
642  }
643  }
644 
645 };
646 
651 {
652 private:
653 
656 
657  Eigen::Quaternion<float> quaternion_h;
658  Eigen::Quaternion<float> quaternion_v;
659 
660 protected:
661 
662 
666  Eigen::Quaternion<float> computeRotationAngle (float sensibility = 1.0)
667  {
668  //Given two position vectors, corresponding to the initial and final mouse coordinates, calculate the rotation of the sphere that will keep the mouse always in the initial position.
669 
670  if(initialPosition.norm() > 0) {
671  initialPosition.normalize();
672  }
673  if(finalPosition.norm() > 0) {
674  finalPosition.normalize();
675  }
676 
677  Eigen::Vector3f ini;
678  Eigen::Vector3f fin;
679  float dot, angle;
680 
681  ini << initialPosition[0], 0.0, initialPosition[2];
682  ini.normalize();
683  fin << finalPosition[0], 0.0, finalPosition[2];
684  fin.normalize();
685  dot = ini.dot(fin);
686  angle = (dot <= 1) ? acos(dot) : 0;
687  if (initialPosition[0] > finalPosition[0])
688  angle *= -1;
689  angle *= sensibility;
690  Eigen::Quaternion<float> qx (Eigen::AngleAxis<float>(angle, Eigen::Vector3f::UnitY()));
691 
692  ini << 0.0, initialPosition[1], initialPosition[2];
693  ini.normalize();
694  fin << 0.0, finalPosition[1], finalPosition[2];
695  fin.normalize();
696  dot = ini.dot(fin);
697  angle = (dot <= 1) ? acos(dot) : 0;
698  if (initialPosition[1] < finalPosition[1])
699  angle *= -1;
700  angle *= sensibility;
701  Eigen::Quaternion<float> qy (Eigen::AngleAxis<float>(angle, Eigen::Vector3f::UnitX()));
702 
703  quaternion_h = qx * quaternion_h;
704  quaternion_v = qy * quaternion_v;
705  quaternion_h.normalize();
706  quaternion_v.normalize();
707 
708  quaternion = quaternion_h * quaternion_v;
709  quaternion.normalize();
710  return qx * qy;
711  }
712 
713 
714 
715 public:
716 
718  {
719  arrow = Tucano::Shapes::Arrow(0.05, 0.8, 0.12, 0.2);
720  arrow.setColor(Eigen::Vector4f(0.8, 0.8, 0.2, 1.0));
721  quaternion_h = Eigen::Quaternion<float>::Identity();
722  quaternion_v = Eigen::Quaternion<float>::Identity();
723  }
724 
725 
730  void setRotation (Eigen::Quaternion<float> q)
731  {
732  quaternion = q;
734  }
735 
739  void renderDirection (Tucano::Camera &ext_camera, bool render_from_ext = false)
740  {
741  glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
742  float ratio = (viewport[2]) / (viewport[3]);
743 
744  Eigen::Matrix4f rep_projection_matrix = createOrthographicMatrix(-ratio, ratio, -1.0, 1.0, 0.1, 100.0);
745 
746  Eigen::Affine3f rep_view_matrix = Eigen::Affine3f::Identity();
747  rep_view_matrix.translate( Eigen::Vector3f(1.0, 0.75, -5.0));
748 
749  Tucano::Camera rep_camera;
750  rep_camera.setViewMatrix(rep_view_matrix);
751  rep_camera.viewMatrix()->rotate( ext_camera.getViewMatrix().rotation() );
752  rep_camera.setProjectionMatrix(rep_projection_matrix);
753  rep_camera.setViewport(ext_camera.getViewport());
754 
755  Tucano::Camera lightcam;
756  lightcam.viewMatrix()->translate(Eigen::Vector3f(0.0, 0.0, -3.0));
757 
758  arrow.resetModelMatrix();
759  arrow.modelMatrix()->rotate(quaternion);
760  if (render_from_ext)
761  {
762  arrow.modelMatrix()->translate(default_translation);
763  arrow.modelMatrix()->scale(0.3);
764  }
765  else
766  {
767  arrow.modelMatrix()->scale(0.12);
768  }
769  arrow.modelMatrix()->rotate ( Eigen::AngleAxis<float>(M_PI, Eigen::Vector3f::UnitY()));
770  arrow.normalizeModelMatrix();
771 
772  if (render_from_ext)
773  arrow.render(ext_camera, lightcam);
774  else
775  arrow.render(rep_camera, lightcam);
776 
777  }
778 
779 
783  void updateViewMatrix (void)
784  {
785  resetViewMatrix();
786  rotate(quaternion);
787  translate(default_translation);
788  }
789 
790 
791 };
792 
809 
810 protected:
811 
814 
816  Eigen::Vector3f sphere_position = Eigen::Vector3f::Zero();
817 
818 public:
822  Manipulator (void)
823  {
824  external_camera = 0;
825  default_translation = Eigen::Vector3f::Zero();
826  }
827 
832  Eigen::Vector3f getSpherePos (void)
833  {
834  return sphere_position;
835  }
836 
841  void setSpherePos (const Eigen::Vector3f& pos)
842  {
843  sphere_position = pos;
844  }
845 
846 
854  {
855  external_camera = ext_cam;
856  viewport = external_camera->getViewport();
857  }
858 
859 };
860 
865 {
866 
867 protected:
868 
869 
870 public:
871 
876  Eigen::Vector3f computeTranslationVector (void)
877  {
878  //Eigen::Vector2f translationFactor = finalTranslationPosition - initialTranslationPosition;
879  Eigen::Vector3f sphere_center = (view_matrix * Eigen::Vector4f(0.0, 0.0, 0.0, 1.0)).head(3);
880  sphere_center = translationVector;
881  Eigen::Vector3f ray_origin = external_camera->getCenter();
882 
883  Eigen::Vector3f ray_direction = Tucano::Math::rayDirection(finalTranslationPosition, external_camera->getViewportSize(), external_camera->getProjectionMatrix(), external_camera->getViewMatrix());
884 
885  //Eigen::Vector3f normal = (sphere_center - ray_origin).normalized();
886  Eigen::Vector3f normal = external_camera->getViewMatrix().rotation().inverse()*Eigen::Vector3f::UnitZ();
887 
888  Eigen::Vector3f inc = Eigen::Vector3f::Zero();
889  if (Tucano::Math::rayPlaneIntersection(ray_direction, ray_origin, sphere_center, normal, sphere_position))
890  {
891  inc = sphere_position - sphere_center;
892  translationVector += inc;
893  }
894  return inc;
895 
896  //translationVector += external_camera->getViewMatrix().rotation().inverse()*Eigen::Vector3f(translationFactor[0],translationFactor[1], 0.0);
897  }
898 
904  Eigen::Vector3f translateCamera (const Eigen::Vector2f& pos)
905  {
906  Eigen::Vector3f increment = Eigen::Vector3f::Zero();
907 
908 
909  if (!translating)
910  {
911  translating = true;
912  initialTranslationPosition = pos;
913  }
914  else if (pos != initialPosition.head(2))
915  {
916  finalTranslationPosition = pos;
917  increment = computeTranslationVector();
919  initialTranslationPosition = finalTranslationPosition;
920  }
921  return increment;
922  }
923 
927  void updateViewMatrix (void)
928  {
929  if (!external_camera)
930  return;
931 
932  resetViewMatrix();
933  translate(default_translation);
934  translate(translationVector);
935  scale(radius);
936  }
937 
938 };
939 
947 
948 private:
949 
950 
952  Eigen::Vector3f last_position = Eigen::Vector3f::Zero();
953 
955  Eigen::Vector3f sphere_position = Eigen::Vector3f::Zero();
956 
958  float inner_radius = 1.0;
959 
961  float outer_radius = 1.3;
962 
964  int selected_axis = -1;
965 
966  Eigen::Vector3f selected_normal = Eigen::Vector3f::Zero();
967 
968 protected:
969 
970  bool computeSphere3DPosition (const Eigen::Vector2f& pixel, Eigen::Vector3f& sphere_pos)
971  {
972  Eigen::Vector3f ray_direction = Tucano::Math::rayDirection(pixel, external_camera->getViewportSize(), external_camera->getProjectionMatrix(), external_camera->getViewMatrix());
973  Eigen::Vector3f sphere_center = (view_matrix * Eigen::Vector4f(0.0, 0.0, 0.0, 1.0)).head(3);
974  Eigen::Vector3f ray_origin = external_camera->getCenter();
975  if (Tucano::Math::raySphereIntersection(ray_direction, ray_origin, sphere_center, radius, sphere_pos))
976  {
977  sphere_pos = sphere_pos - sphere_center;
978  return true;
979  }
980  else if (rotating)
981  {
982  Eigen::Vector3f normal = (sphere_center - ray_origin).normalized();
983  if (Tucano::Math::rayPlaneIntersection(ray_direction, ray_origin, sphere_center, normal, sphere_pos))
984  {
985  sphere_pos = (sphere_pos - sphere_center).normalized() * radius;
986  return true;
987  }
988 
989  }
990  return false;
991  }
992 
993  bool computeRing3DPosition (const Eigen::Vector2f& pixel, Eigen::Vector3f& sphere_pos)
994  {
995  Eigen::Vector3f ray_direction = Tucano::Math::rayDirection(pixel, external_camera->getViewportSize(), external_camera->getProjectionMatrix(), external_camera->getViewMatrix());
996  Eigen::Vector3f sphere_center = (view_matrix * Eigen::Vector4f(0.0, 0.0, 0.0, 1.0)).head(3);
997  Eigen::Matrix3f normal_matrix = view_matrix.linear().inverse().transpose();
998  Eigen::Vector3f ray_origin = external_camera->getCenter();
999 
1000  if (selected_axis == -1)
1001  {
1002  if (Tucano::Math::rayRingIntersection(ray_direction, ray_origin, sphere_center, normal_matrix * Eigen::Vector3f::UnitX(), inner_radius, outer_radius, sphere_pos))
1003  {
1004  selected_axis = 0;
1005  selected_normal = Eigen::Vector3f::UnitX();
1006  sphere_pos = sphere_pos - sphere_center;
1007  return true;
1008  }
1009  if (Tucano::Math::rayRingIntersection(ray_direction, ray_origin, sphere_center, normal_matrix * Eigen::Vector3f::UnitY(), inner_radius, outer_radius, sphere_pos))
1010  {
1011  selected_axis = 1;
1012  selected_normal = Eigen::Vector3f::UnitY();
1013  sphere_pos = sphere_pos - sphere_center;
1014  return true;
1015  }
1016  if (Tucano::Math::rayRingIntersection(ray_direction, ray_origin, sphere_center, normal_matrix * Eigen::Vector3f::UnitZ(), inner_radius, outer_radius, sphere_pos))
1017  {
1018  selected_axis = 2;
1019  selected_normal = Eigen::Vector3f::UnitZ();
1020  sphere_pos = sphere_pos - sphere_center;
1021  return true;
1022  }
1023  }
1024  else
1025  {
1026  Tucano::Math::rayPlaneIntersection(ray_direction, ray_origin, sphere_center, view_matrix.linear().inverse().transpose()* selected_normal, sphere_pos);
1027  sphere_pos = sphere_pos - sphere_center;
1028  return true;
1029  }
1030 
1031  return false;
1032  }
1033 
1034 
1035 public:
1036 
1041  {
1042  external_camera = 0;
1043  default_translation = Eigen::Vector3f::Zero();
1044  radius = 1.0;
1045  inner_radius = radius * 1.3;
1046  outer_radius = radius * 1.5;
1047  }
1048 
1052  virtual void setRadius (float r)
1053  {
1054  radius = r;
1055  inner_radius = radius * 0.9;
1056  outer_radius = radius * 1.1;
1057  }
1058 
1064  Eigen::Quaternion<float> rotateCamera (const Eigen::Vector2f& screen_pos)
1065  {
1066  Eigen::Quaternion<float> increment = Eigen::Quaternion<float>::Identity();
1067 
1068  if (computeSphere3DPosition(screen_pos, sphere_position))
1069  {
1070  if (!rotating)
1071  {
1072  rotating = true;
1073  initialPosition = sphere_position;
1074  last_position = sphere_position;
1075  }
1076  else if ( screen_pos != initialPosition.head(2))
1077  {
1078  //Eigen::Affine3f mat = external_camera->getViewMatrix();
1079  //float sensibility = 1.0/mat.linear().col(0).norm();
1080  finalPosition = sphere_position;
1081  //increment = computeRotationAngle(sensibility);
1082  increment = computeRotationAngle(1.0);
1083  updateViewMatrix();
1084  initialPosition = finalPosition;
1085  }
1086  }
1087  return increment;
1088  }
1089 
1095  Eigen::Quaternion<float> computeRotationAngle (float sensibility = 1.0)
1096  {
1097  //Given two position vectors, corresponding to the initial and final mouse coordinates, calculate the rotation of the sphere that will keep the mouse always in the initial position.
1098 
1099  if(initialPosition.norm() > 0) {
1100  initialPosition.normalize();
1101  }
1102  if(finalPosition.norm() > 0) {
1103  finalPosition.normalize();
1104  }
1105 
1106  Eigen::Vector3f rotationAxis = initialPosition.cross(finalPosition);
1107 
1108  if(rotationAxis.norm() != 0) {
1109  rotationAxis.normalize();
1110  }
1111 
1112  float dot = initialPosition.dot(finalPosition);
1113 
1114  float rotationAngle = (dot <= 1) ? acos(dot) : 0;//If, by losing floating point precision, the dot product between the initial and final positions is bigger than one, ignore the rotation.
1115  Eigen::Quaternion<float> q (Eigen::AngleAxis<float>(rotationAngle,rotationAxis));
1116  return q;
1117  }
1118 
1119 
1124  virtual Eigen::Vector3f computeTranslationVector (void)
1125  {
1126  Eigen::Vector2f translationFactor = finalTranslationPosition - initialTranslationPosition;
1127  Eigen::Vector3f inc = external_camera->getViewMatrix().rotation().inverse()*Eigen::Vector3f(translationFactor[0],translationFactor[1], 0.0);
1128  translationVector += inc;
1129  return inc;
1130  }
1131 
1132 
1136  void updateViewMatrix (void)
1137  {
1138  if (!external_camera)
1139  return;
1140 
1141  resetViewMatrix();
1142  translate(default_translation);
1143  translate(translationVector);
1144  rotate(quaternion);
1145  rotate(default_quaternion);
1146  scale(radius);
1147  }
1148 
1153  void endRotation (void)
1154  {
1155  rotating = false;
1156  selected_axis = -1;
1157  }
1158 
1164  void render (void)
1165  {
1166  if(drawTrackball && external_camera)
1167  {
1168  viewport = external_camera->getViewport();
1169 
1170  glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
1171 
1172  trackballProjectionMatrix = external_camera->getProjectionMatrix();
1173 
1174  trackball_shader.bind();
1175 
1176  Eigen::Affine3f trackballViewMatrix = external_camera->getViewMatrix() * view_matrix;
1177 
1178  trackball_shader.setUniform("viewMatrix", trackballViewMatrix);
1179  trackball_shader.setUniform("projectionMatrix", trackballProjectionMatrix);
1180  trackball_shader.setUniform("nearPlane", near_plane);
1181  trackball_shader.setUniform("farPlane", far_plane);
1182 
1183  mesh.bindBuffers();
1184 
1185  //X:
1186  Eigen::Vector4f color_vector;
1187 
1188  color_vector << 0.8, 0.4, 0.4, 1.0;
1189  trackball_shader.setUniform("modelMatrix", Eigen::Affine3f::Identity()*Eigen::AngleAxis<float>(M_PI/2.0,Eigen::Vector3f(0.0,1.0,0.0)));
1190  trackball_shader.setUniform("in_Color", color_vector);
1191  mesh.renderLineLoop();
1192 
1193  //Y:
1194  color_vector << 0.0, 1.0, 0.0, 1.0;
1195  trackball_shader.setUniform("modelMatrix", Eigen::Affine3f::Identity()*Eigen::AngleAxis<float>(M_PI/2.0,Eigen::Vector3f(1.0,0.0,0.0)));
1196  trackball_shader.setUniform("in_Color", color_vector);
1197  mesh.renderLineLoop();
1198 
1199  //Z:
1200  color_vector << 0.0, 0.0, 1.0, 1.0;
1201  trackball_shader.setUniform("modelMatrix", Eigen::Affine3f::Identity());
1202  trackball_shader.setUniform("in_Color", color_vector);
1203  mesh.renderLineLoop();
1204 
1205  mesh.unbindBuffers();
1206 
1207  trackball_shader.unbind();
1208  }
1209  }
1210 };
1211 
1212 
1213 }
1214 #endif
bool raySphereIntersection(const Eigen::Vector3f &ray_direction, const Eigen::Vector3f &ray_origin, const Eigen::Vector3f &sphere_center, float sphere_radius, Eigen::Vector3f &intersection)
Computes the intersection point between a ray and a sphere.
Definition: math.hpp:45
void setColor(const Eigen::Vector4f c)
Sets the arrow color.
Definition: arrow.hpp:134
void setSpherePos(const Eigen::Vector3f &pos)
Sets the manipulator 3D position.
Definition: trackball.hpp:841
void setRotation(Eigen::Quaternion< float > q)
Sets directly the rotation quaternion.
Definition: trackball.hpp:730
bool isRotating(void)
Returns wether the trackball is being rotated or not.
Definition: trackball.hpp:184
void endTranslation(void)
Indicates that a translation has ended. Disable the translating flag, indicating that the mouse callb...
Definition: trackball.hpp:288
RotationManipulator(void)
Default constructor.
Definition: trackball.hpp:1040
virtual void setRadius(float r)
Sets the radius.
Definition: trackball.hpp:249
Eigen::Matrix4f setTrackballOrthographicMatrix(float left, float right, float bottom, float top, float near_plane, float far_plane)
Sets the trackball projection matrix as orthographic.
Definition: trackball.hpp:388
Mainpulator for translating a mesh.
Definition: trackball.hpp:864
bool isTranslating(void)
Returns wether the trackball is being translated or not.
Definition: trackball.hpp:193
virtual void updateViewMatrix(void)
Applies all trackball&#39;s transformations to the view matrix.
Definition: trackball.hpp:562
virtual void renderLineLoop(void)
Render all vertices as a continous line loop.
Definition: mesh.hpp:735
Eigen::Affine3f * modelMatrix(void)
Returns a pointer to the model matrix.
Definition: model.hpp:112
void getViewMatrix(GLdouble *matrix)
Return the modelview matrix as a GLdouble array.
Definition: camera.hpp:126
Eigen::Vector2f initialTranslationPosition
Initial position vector used to calculate trackball&#39;s translation.
Definition: trackball.hpp:105
DirectionalTrackball(void)
Definition: trackball.hpp:717
virtual void setRadius(float r)
Sets the radius.
Definition: trackball.hpp:1052
float aspect_ratio
Aspect ratio for projection matrix.
Definition: camera.hpp:72
void loadShader(void)
Load Trackball Shader file.
Definition: trackball.hpp:305
Eigen::Matrix4f setTrackballPerspectiveMatrix(float fy, float aspect_ratio, float near_plane, float far_plane)
Sets the trackball projection matrix as perspective.
Definition: trackball.hpp:371
void translateViewMatrix(const Eigen::Vector3f &translation)
Translates the view matrix by a given vector trans. This directly modifies the translation vector of ...
Definition: trackball.hpp:540
virtual Eigen::Quaternion< float > rotateCamera(const Eigen::Vector2f &pos)
Computes and applies the rotation transformations to the trackball given new position.
Definition: trackball.hpp:455
Class for object manipulator.
Definition: trackball.hpp:808
virtual void render(Eigen::Affine3f ext_view_matrix=Eigen::Affine3f::Identity(), Eigen::Matrix4f ext_proj_matrix=Eigen::Matrix4f::Identity())
Renders the trackball representation.
Definition: trackball.hpp:596
static Eigen::Matrix4f createPerspectiveMatrix(float fy, float in_aspect_ratio, float in_near_plane, float in_far_plane)
Returns a perspective projection matrix with the given parameters.
Definition: camera.hpp:377
bool drawTrackball
Flag that indicates wether the trackball&#39;s representation should be drawn.
Definition: trackball.hpp:93
void initOpenGLMatrices(void)
Initializes the view and projection matrices. They are all initialized as Identity matrices...
Definition: trackball.hpp:352
Eigen::Vector3f getDefaultTranslation(void)
Returns the default translation for placing the camera outside the trackball sphere.
Definition: trackball.hpp:202
Eigen::Vector3f initialPosition
Initial position vector used to calculate trackball&#39;s rotation.
Definition: trackball.hpp:99
Definition: bufferobject.hpp:34
Eigen::Matrix4f trackballProjectionMatrix
Projection matrix used for the trackball&#39;s drawing. By default it is defined as an orthogonal project...
Definition: trackball.hpp:96
Eigen::Quaternion< float > getDefaultRotation(void)
Returns the default rotation quaternion.
Definition: trackball.hpp:221
Manipulator(void)
Default constructor.
Definition: trackball.hpp:822
void setDefaultTranslation(Eigen::Vector3f t)
Sets the default translation vector.
Definition: trackball.hpp:211
Trackball class for manipulating a camera.
Definition: trackball.hpp:79
void initialize(void)
Calls all the functions related to the shader initialization, i.e., creates, loads the shaders from t...
Definition: shader.hpp:641
void setShaderName(string name)
Sets the shader name, very useful for debugging.
Definition: shader.hpp:329
void reset(void)
Resets trackball to initial position and orientation.
Definition: trackball.hpp:168
Eigen::Quaternion< float > computeRotationAngle(float sensibility=1.0)
Computes the trackball&#39;s rotation, using stored initial and final position vectors.
Definition: trackball.hpp:666
void createTrackballRepresentation(void)
Creates the circle representating rotation around Z axis. The other circles will be created by simply...
Definition: trackball.hpp:576
bool rayPlaneIntersection(const Eigen::Vector3f &ray_direction, const Eigen::Vector3f &ray_origin, const Eigen::Vector3f &plane_point, const Eigen::Vector3f &plane_normal, Eigen::Vector3f &intersection)
Computes the intersection between a ray and a plane.
Definition: math.hpp:84
void render(void)
Renders the trackball representation.
Definition: trackball.hpp:1164
virtual Eigen::Vector3f translateCamera(const Eigen::Vector2f &pos)
Computes and applies the translation transformations to the trackball given new position.
Definition: trackball.hpp:481
Eigen::Quaternion< float > rotateCamera(const Eigen::Vector2f &screen_pos)
Rotates the manipulator given a new 2D screen position.
Definition: trackball.hpp:1064
void setViewport(const Eigen::Vector4f &vp)
Sets the viewport coordinates.
Definition: camera.hpp:274
void updateViewMatrix(void)
Applies all trackball&#39;s transformations to the view matrix.
Definition: trackball.hpp:927
A Shader object represents one GLSL program.
Definition: shader.hpp:45
void renderDirection(Tucano::Camera &ext_camera, bool render_from_ext=false)
Renders the camera&#39;s view direction at the top right corner of the screen.
Definition: trackball.hpp:739
bool use_default_shaders
Flag to use default shaders set as const strings in class, or pass a directory with custom shaders...
Definition: trackball.hpp:133
float far_plane
Far plane used for projection matrix.
Definition: camera.hpp:57
Eigen::Vector3f getSpherePos(void)
Returns the manipulator 3D position.
Definition: trackball.hpp:832
void applyScaleToViewMatrix(float scale)
Applies a scale factor to the viewMatrix. The current scale used in view matrix will be substituted b...
Definition: trackball.hpp:528
virtual Eigen::Quaternion< float > getRotation(void)
Returns the rotation (without the default part) as a quaternion.
Definition: trackball.hpp:231
Eigen::Vector3f translateCamera(const Eigen::Vector2f &pos)
Computes and applies the translation transformations to the trackball given new position.
Definition: trackball.hpp:904
float near_plane
Near plane used for projection matrix.
Definition: camera.hpp:54
Eigen::Vector2f normalizePosition(const Eigen::Vector2f &pos)
Nomalizes a screen position to range [-1,1].
Definition: trackball.hpp:445
void initializeFromStrings(string in_vertex_code, string in_fragment_code, string in_geometry_code="", string in_tessellation_evaluation_code="", string in_tessellation_control_code="")
Initializes shader directly from string, no files.
Definition: shader.hpp:589
Eigen::Quaternion< float > quaternion
Trackball&#39;s quaternion.
Definition: trackball.hpp:111
Eigen::Quaternion< float > computeRotationAngle(float sensibility=1.0)
Computes the trackball&#39;s rotation, using stored initial and final position vectors.
Definition: trackball.hpp:1095
virtual Eigen::Vector3f computeSpherePosition(const Eigen::Vector2f &pos)
Computes 3d coordinates on sphere from 2d position.
Definition: trackball.hpp:323
void setViewMatrix(const Eigen::Affine3f &mat)
Sets the view matrix from a given an affine 3x3 matrix.
Definition: camera.hpp:309
void translate(const Eigen::Vector3f &translation)
Translates the view matrix by a given vector.
Definition: camera.hpp:489
void setProjectionMatrix(const Eigen::Matrix4f &mat)
Sets the projection matrix from a given 4x4 matrix.
Definition: camera.hpp:300
Eigen::Vector3f translationVector
Trackball&#39;s translation vector.
Definition: trackball.hpp:117
Tucano::Mesh mesh
Trackball visual representation.
Definition: trackball.hpp:127
Eigen::Vector3f rayDirection(const Eigen::Vector2f &pixel, const Eigen::Vector2i &viewport_size, const Eigen::Matrix4f &projection_matrix, const Eigen::Affine3f &view_matrix)
Computes the ray direction given a pixel position and camera matrices.
Definition: math.hpp:136
float radius
The trackball radius. It&#39;s defined as 0.8 times the smallest viewport dimension.
Definition: trackball.hpp:130
float zoom
The current scale being applied to the View Matrix.
Definition: trackball.hpp:84
virtual Eigen::Vector3f computeTranslationVector(void)
Compute the trackball&#39;s translation, using stored initial and final position vectors.
Definition: trackball.hpp:431
void rotate(const Eigen::Quaternion< float > &rotation)
Rotate the view matrix by a given quaternion.
Definition: camera.hpp:498
A directional trackball, useful for light direction for example.
Definition: trackball.hpp:650
void setExternalCamera(Tucano::Camera *ext_cam)
Sets the pointer to the external camera The external camera is the actual view camera since the track...
Definition: trackball.hpp:853
void updateViewMatrix(void)
Applies all trackball&#39;s transformations to the view matrix.
Definition: trackball.hpp:783
Eigen::Quaternion< float > default_quaternion
Trackball&#39;s default rotation.
Definition: trackball.hpp:114
void scale(const Eigen::Vector3f &scale_factors)
Scales the view matrix by given factors.
Definition: camera.hpp:507
bool translating
Flag that indicates wether the trackball is being translated.
Definition: trackball.hpp:90
Eigen::Vector4f viewport
Viewport dimensions [minX, minY, width, height].
Definition: camera.hpp:48
void setRenderFlag(bool flag)
Returns wether the trackball representation should be drawn or not.
Definition: trackball.hpp:299
virtual void endRotation(void)
Indicates that a rotation has ended. Disables the rotating flag, indicating that the mouse callback f...
Definition: trackball.hpp:279
virtual Eigen::Vector3f computeTranslationVector(void)
Compute the trackball&#39;s translation, using stored initial and final position vectors.
Definition: trackball.hpp:1124
float getZoom(void)
Retuns the zoom factor (the radius of the trackball).
Definition: trackball.hpp:258
void setDefaultAttribLocations(void)
Sets default attribute locations. vertex coords -> location 0 normals -> location 1 colors -> locatio...
Definition: mesh.hpp:474
void resetModelMatrix(void)
Resets the model matrix.
Definition: model.hpp:159
void unbind(void)
Disables the shader program.
Definition: shader.hpp:1184
Eigen::Quaternion< float > quaternion_v
Definition: trackball.hpp:658
void setTrackballProjectionMatrix(const Eigen::Matrix4f &mat)
Sets the projection matrix used for the trackball rendering. Note that this is usually different than...
Definition: trackball.hpp:269
bool computeRing3DPosition(const Eigen::Vector2f &pixel, Eigen::Vector3f &sphere_pos)
Definition: trackball.hpp:993
void render(const Tucano::Camera &camera, const Tucano::Camera &light)
Render arrow.
Definition: arrow.hpp:142
bool computeSphere3DPosition(const Eigen::Vector2f &pixel, Eigen::Vector3f &sphere_pos)
Definition: trackball.hpp:970
bool rayRingIntersection(const Eigen::Vector3f &ray_direction, const Eigen::Vector3f &ray_origin, const Eigen::Vector3f &plane_point, const Eigen::Vector3f &plane_normal, float inner_radius, float outer_radius, Eigen::Vector3f &intersection)
Computes the intersection between a ray and a ring in 3D space.
Definition: math.hpp:110
Tucano::Camera * external_camera
Pointer to external camera.
Definition: trackball.hpp:813
void setDefaultRotation(Eigen::Matrix3f rot)
Sets the default rotation quaternion.
Definition: trackball.hpp:240
virtual void unbindBuffers(void)
Unbinds all buffers.
Definition: mesh.hpp:702
Eigen::Affine3f * viewMatrix(void)
Returns a pointer to the view matrix as an Affine 3x3 matrix.
Definition: camera.hpp:186
void decreaseZoom(float scale)
Decreases the zoom on the scene by appling a scale to the View Matrix. The current scale used in View...
Definition: trackball.hpp:517
Tucano::Shader trackball_shader
Trackball Shader, used just for rendering the trackball&#39;s representation.
Definition: trackball.hpp:124
void updateViewMatrix(void)
Applies all trackball&#39;s transformations to the view matrix.
Definition: trackball.hpp:1136
Eigen::Vector3f computeTranslationVector(void)
Compute the trackball&#39;s translation, using stored initial and final position vectors.
Definition: trackball.hpp:876
void loadVertices(vector< Eigen::Vector4f > &vert)
Load vertices (x,y,z,w) and creates appropriate vertex attribute. The default attribute name is "in_P...
Definition: mesh.hpp:312
void normalizeModelMatrix(void)
Normalize model matrix to center and scale model. The model matrix will include a translation to plac...
Definition: model.hpp:141
void load(string name, string shader_dir="")
Loads a shader given a directory and a name. Searches for all shader extensions in directory...
Definition: shader.hpp:436
void bind(void)
Enables the shader program for usage.
Definition: shader.hpp:1176
void increaseZoom(float scale)
Increases the zoom on the scene by appling a scale to the View Matrix. The current scale used in View...
Definition: trackball.hpp:506
Eigen::Vector3f finalPosition
Final position vector used to calculate trackball&#39;s rotation.
Definition: trackball.hpp:102
bool rotating
Flag that indicates wether the trackball is being rotated.
Definition: trackball.hpp:87
Eigen::Quaternion< float > quaternion_h
Definition: trackball.hpp:657
Tucano::Shapes::Arrow arrow
Arrow for visualizing view direction (very useful for light trackball system)
Definition: trackball.hpp:655
Trackball(string shader_dir="")
Default constructor.
Definition: trackball.hpp:141
static Eigen::Matrix4f createOrthographicMatrix(float left, float right, float bottom, float top, float near_plane, float far_plane)
Returns an orthographic projection matrix with the given parameters.
Definition: camera.hpp:438
virtual void bindBuffers(void)
Binds all buffers.
Definition: mesh.hpp:677
const string trackball_fragment_code
Default fragment shader for rendering trackball representation.
Definition: trackball.hpp:36
void endRotation(void)
Indicates that a rotation has ended. Disables the rotating flag, indicating that the mouse callback f...
Definition: trackball.hpp:1153
A common Mesh, usually containing triagles or points.
Definition: mesh.hpp:194
Defines an abstract camera with a projection and view matrices.
Definition: camera.hpp:37
void resetViewMatrix(void)
Reset view matrix.
Definition: camera.hpp:88
Eigen::Vector4f getViewport(void) const
Returns the viewport coordinates.
Definition: camera.hpp:246
A rounded arrow shape defined by a arrow and a cone.
Definition: arrow.hpp:85
Eigen::Vector2f finalTranslationPosition
Final position vector used to calculate trackball&#39;s translation.
Definition: trackball.hpp:108
void rotateViewMatrix(const Eigen::Affine3f &rot)
Rotates the view matrix by a given rotation matrix. This directly modifies the quaternion of the trac...
Definition: trackball.hpp:551
Eigen::Affine3f view_matrix
View, or extrinsic, matrix.
Definition: camera.hpp:45
virtual Eigen::Quaternion< float > computeRotationAngle(float sensibility=1.0)
Computes the trackball&#39;s rotation, using stored initial and final position vectors.
Definition: trackball.hpp:400
Eigen::Vector3f default_translation
Default translation to move camera away from center.
Definition: trackball.hpp:120
const string trackball_vertex_code
Default vertex shader for rendering trackball representation.
Definition: trackball.hpp:48
Manipulator for rotating a mesh It works as a spherical manipulator (such as a trackball) or a ring m...
Definition: trackball.hpp:946
void setUniform(GLint location, GLint a, GLint b, GLint c, GLint d)
Sets an uniform integer 4D vector (ivec4) given a location and the vector values. ...
Definition: shader.hpp:1258