1 #pragma once
2 
3 #include <pangolin/display/opengl_render_state.h>
4 #include <pangolin/display/viewport.h>
5 #include <pangolin/gl/gldraw.h>
6 
7 #include <pangolin/scene/renderable.h>
8 #include <pangolin/scene/interactive_index.h>
9 
10 #ifdef HAVE_EIGEN
11 #  include <Eigen/Geometry>
12 #endif
13 
14 namespace pangolin {
15 
16 struct Axis : public Renderable, public Interactive
17 {
AxisAxis18     Axis()
19         : axis_length(1.0),
20           label_x(InteractiveIndex::I().Store(this)),
21           label_y(InteractiveIndex::I().Store(this)),
22           label_z(InteractiveIndex::I().Store(this))
23     {
24     }
25 
RenderAxis26     void Render(const RenderParams&) override {
27         glColor4f(1,0,0,1);
28         glPushName(label_x.Id());
29         glDrawLine(0,0,0, axis_length,0,0);
30         glPopName();
31 
32         glColor4f(0,1,0,1);
33         glPushName(label_y.Id());
34         glDrawLine(0,0,0, 0,axis_length,0);
35         glPopName();
36 
37         glColor4f(0,0,1,1);
38         glPushName(label_z.Id());
39         glDrawLine(0,0,0, 0,0,axis_length);
40         glPopName();
41     }
42 
MouseAxis43     bool Mouse(
44         int button,
45         const GLprecision /*win*/[3], const GLprecision /*obj*/[3], const GLprecision /*normal*/[3],
46         bool /*pressed*/, int button_state, int pickId
47     ) override
48     {
49         PANGOLIN_UNUSED(button);
50         PANGOLIN_UNUSED(button_state);
51         PANGOLIN_UNUSED(pickId);
52 
53 #ifdef HAVE_EIGEN
54         if((button == MouseWheelUp || button == MouseWheelDown) ) {
55             float scale = (button == MouseWheelUp) ? 0.01f : -0.01f;
56             if(button_state & KeyModifierShift) scale /= 10;
57 
58             Eigen::Vector3d rot = Eigen::Vector3d::Zero();
59             Eigen::Vector3d xyz = Eigen::Vector3d::Zero();
60 
61 
62             if(button_state & KeyModifierCtrl) {
63                 // rotate
64                 if(pickId == label_x.Id()) {
65                     rot << 1,0,0;
66                 }else if(pickId == label_y.Id()) {
67                     rot << 0,1,0;
68                 }else if(pickId == label_z.Id()) {
69                     rot << 0,0,1;
70                 }else{
71                     return false;
72                 }
73             }else if(button_state & KeyModifierShift){
74                 // translate
75                 if(pickId == label_x.Id()) {
76                     xyz << 1,0,0;
77                 }else if(pickId == label_y.Id()) {
78                     xyz << 0,1,0;
79                 }else if(pickId == label_z.Id()) {
80                     xyz << 0,0,1;
81                 }else{
82                     return false;
83                 }
84             }else{
85                 return false;
86             }
87 
88             // old from new
89             Eigen::Matrix<double,4,4> T_on = Eigen::Matrix<double,4,4>::Identity();
90             T_on.block<3,3>(0,0) = Eigen::AngleAxis<double>(scale,rot).toRotationMatrix();
91             T_on.block<3,1>(0,3) = scale*xyz;
92 
93             // Update
94             T_pc = (ToEigen<double>(T_pc) * T_on.inverse()).eval();
95 
96             return true;
97         }
98 #endif // HAVE_EIGEN
99 
100         return false;
101     }
102 
MouseMotionAxis103     virtual bool MouseMotion(
104         const GLprecision /*win*/[3], const GLprecision /*obj*/[3], const GLprecision /*normal*/[3],
105         int /*button_state*/, int /*pickId*/
106     ) override
107     {
108         return false;
109     }
110 
111     float axis_length;
112     const InteractiveIndex::Token label_x;
113     const InteractiveIndex::Token label_y;
114     const InteractiveIndex::Token label_z;
115 };
116 
117 }
118