]> git.mxchange.org Git - flightgear.git/blob - src/Main/FGManipulator.cxx
Need to pull in config.h before plib/pu.h or else PUI thinks it's in
[flightgear.git] / src / Main / FGManipulator.cxx
1 #ifdef HAVE_CONFIG_H
2 #  include <config.h>
3 #endif
4 #include <osg/Math>
5 #include <osgViewer/Viewer>
6 #include <plib/pu.h>
7 #include "FGManipulator.hxx"
8
9 // The manipulator is responsible for updating a Viewer's camera. It's
10 // event handling method is also a convenient place to run the the FG
11 // idle and draw handlers.
12
13 void FGManipulator::setByMatrix(const osg::Matrixd& matrix)
14 {
15     // Yuck
16     position = matrix.getTrans();
17     attitude = matrix.getRotate();
18 }
19
20 osg::Matrixd FGManipulator::getMatrix() const
21 {
22     return osg::Matrixd::rotate(attitude) * osg::Matrixd::translate(position);
23 }
24
25 osg::Matrixd FGManipulator::getInverseMatrix() const
26 {
27     return (osg::Matrixd::translate(-position)
28             * osg::Matrixd::rotate(attitude.inverse())) ;
29 }
30
31 // Not used, but part of the interface.
32 void FGManipulator::setNode(osg::Node* node)
33 {
34     _node = node;
35 }
36     
37 const osg::Node* FGManipulator::getNode() const
38 {
39     return _node.get();
40 }
41
42 osg::Node* FGManipulator::getNode()
43 {
44     return _node.get();
45 }
46
47 namespace {
48 // All the usual translation from window system to FG / plib
49 int osgToFGModifiers(int modifiers)
50 {
51     int result = 0;
52     if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT |
53                      osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT))
54         result |= KEYMOD_SHIFT;
55     if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL |
56                      osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL))
57         result |= KEYMOD_CTRL;
58     if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_ALT |
59                      osgGA::GUIEventAdapter::MODKEY_RIGHT_ALT))
60         result |= KEYMOD_ALT;
61     return result;
62 }
63 } // namespace
64
65 void FGManipulator::init(const osgGA::GUIEventAdapter& ea,
66                          osgGA::GUIActionAdapter& us)
67 {
68     currentModifiers = osgToFGModifiers(ea.getModKeyMask());
69     (void)handle(ea, us);
70 }
71
72 namespace {
73 void eventToViewport(const osgGA::GUIEventAdapter& ea,
74                      osgGA::GUIActionAdapter& us,
75                      int& x, int& y)
76 {
77     osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&us);
78     osg::Viewport* viewport = viewer->getCamera()->getViewport();
79     const osg::GraphicsContext::Traits* traits
80         = viewer->getCamera()->getGraphicsContext()->getTraits();
81     x = (int)ea.getX();
82     y = (int)ea.getY();
83     if (ea.getMouseYOrientation()
84         == osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS)
85         y = (int)traits->height - y;
86 }
87 }
88
89 bool FGManipulator::handle(const osgGA::GUIEventAdapter& ea,
90                            osgGA::GUIActionAdapter& us)
91 {
92     int x, y;
93     switch (ea.getEventType()) {
94     case osgGA::GUIEventAdapter::FRAME:
95         if (idleHandler)
96             (*idleHandler)();
97         if (drawHandler)
98             (*drawHandler)();
99         return true;
100     case osgGA::GUIEventAdapter::KEYDOWN:
101     case osgGA::GUIEventAdapter::KEYUP:
102     {
103         int key, modmask;
104         handleKey(ea, key, modmask);
105         eventToViewport(ea, us, x, y);
106         if (keyHandler)
107             (*keyHandler)(key, modmask, x, y);
108     }
109     return true;
110     case osgGA::GUIEventAdapter::PUSH:
111     case osgGA::GUIEventAdapter::RELEASE:
112     {
113         eventToViewport(ea, us, x, y);
114         int button = 0;
115         switch (ea.getButton()) {
116         case osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON:
117             button = 0;
118             break;
119         case osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON:
120             button = 1;
121             break;
122         case osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON:
123             button = 2;
124             break;
125         }
126         if (mouseClickHandler)
127             (*mouseClickHandler)(button,
128                                  (ea.getEventType()
129                                   == osgGA::GUIEventAdapter::RELEASE), x, y);
130         return true;
131     }
132     case osgGA::GUIEventAdapter::MOVE:
133     case osgGA::GUIEventAdapter::DRAG:
134         eventToViewport(ea, us, x, y);
135         if (mouseMotionHandler)
136             (*mouseMotionHandler)(x, y);
137         return true;
138     case osgGA::GUIEventAdapter::RESIZE:
139         if (windowResizeHandler)
140             (*windowResizeHandler)(ea.getWindowWidth(), ea.getWindowHeight());
141         return true;
142     default:
143         return false;
144     }
145 }
146             
147 void FGManipulator::handleKey(const osgGA::GUIEventAdapter& ea, int& key,
148                               int& modifiers)
149 {
150     key = ea.getKey();
151     // XXX Probably other translations are needed too.
152     switch (key) {
153     case osgGA::GUIEventAdapter::KEY_Escape: key = 0x1b; break;
154     case osgGA::GUIEventAdapter::KEY_Return: key = '\n'; break;
155     case osgGA::GUIEventAdapter::KEY_Left:     key = PU_KEY_LEFT;      break;
156     case osgGA::GUIEventAdapter::KEY_Up:       key = PU_KEY_UP;        break;
157     case osgGA::GUIEventAdapter::KEY_Right:    key = PU_KEY_RIGHT;     break;
158     case osgGA::GUIEventAdapter::KEY_Down:     key = PU_KEY_DOWN;      break;
159     case osgGA::GUIEventAdapter::KEY_Page_Up:   key = PU_KEY_PAGE_UP;   break;
160     case osgGA::GUIEventAdapter::KEY_Page_Down: key = PU_KEY_PAGE_DOWN; break;
161     case osgGA::GUIEventAdapter::KEY_Home:     key = PU_KEY_HOME;      break;
162     case osgGA::GUIEventAdapter::KEY_End:      key = PU_KEY_END;       break;
163     case osgGA::GUIEventAdapter::KEY_Insert:   key = PU_KEY_INSERT;    break;
164     case osgGA::GUIEventAdapter::KEY_F1:       key = PU_KEY_F1;        break;
165     case osgGA::GUIEventAdapter::KEY_F2:       key = PU_KEY_F2;        break;
166     case osgGA::GUIEventAdapter::KEY_F3:       key = PU_KEY_F3;        break;
167     case osgGA::GUIEventAdapter::KEY_F4:       key = PU_KEY_F4;        break;
168     case osgGA::GUIEventAdapter::KEY_F5:       key = PU_KEY_F5;        break;
169     case osgGA::GUIEventAdapter::KEY_F6:       key = PU_KEY_F6;        break;
170     case osgGA::GUIEventAdapter::KEY_F7:       key = PU_KEY_F7;        break;
171     case osgGA::GUIEventAdapter::KEY_F8:       key = PU_KEY_F8;        break;
172     case osgGA::GUIEventAdapter::KEY_F9:       key = PU_KEY_F9;        break;
173     case osgGA::GUIEventAdapter::KEY_F10:      key = PU_KEY_F10;       break;
174     case osgGA::GUIEventAdapter::KEY_F11:      key = PU_KEY_F11;       break;
175     case osgGA::GUIEventAdapter::KEY_F12:      key = PU_KEY_F12;       break;
176     }
177     modifiers = osgToFGModifiers(ea.getModKeyMask());
178     currentModifiers = modifiers;
179     if (ea.getEventType() == osgGA::GUIEventAdapter::KEYUP)
180         modifiers |= KEYMOD_RELEASED;
181 }
182