OpenWalnut  1.5.0dev
WGE2DManipulator.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include "WGE2DManipulator.h"
26 
27 
29  : m_positionX( -64.0 ),
30  m_positionY( 0.0 ),
31  m_zoom( 1.0 )
32 {
33 }
34 
35 const char* WGE2DManipulator::className() const
36 {
37  return "WGE2DManipulator";
38 }
39 
40 void WGE2DManipulator::setByMatrix( const osg::Matrixd& matrix )
41 {
42  m_positionX = matrix.getTrans().x();
43  m_positionY = matrix.getTrans().y();
44  m_zoom = 1.0 / matrix.getScale().x();
45 }
46 
47 void WGE2DManipulator::setByInverseMatrix( const osg::Matrixd& matrix )
48 {
49  m_positionX = -matrix.getTrans().x();
50  m_positionY = -matrix.getTrans().y();
51  m_zoom = matrix.getScale().x();
52 }
53 
54 osg::Matrixd WGE2DManipulator::getMatrix() const
55 {
56  return osg::Matrixd::scale( 1.0 / m_zoom, 1.0 / m_zoom, 1.0 ) * osg::Matrixd::translate( m_positionX, m_positionY, 0.0 );
57 }
58 
60 {
61  return osg::Matrixd::translate( -m_positionX, -m_positionY, 0.0 ) * osg::Matrixd::scale( m_zoom, m_zoom, 1.0 );
62 }
63 
64 void WGE2DManipulator::home( const osgGA::GUIEventAdapter& /*ea*/, osgGA::GUIActionAdapter& us ) // NOLINT We can not change the interface of OSG
65 {
66  m_positionX = -64.0;
67  m_positionY = 0.0;
68  m_zoom = 1.0;
69 
70  us.requestRedraw();
72 }
73 
74 void WGE2DManipulator::init( const osgGA::GUIEventAdapter& /*ea*/, osgGA::GUIActionAdapter& us ) // NOLINT We can not change the interface of OSG
75 {
77 
78  us.requestContinuousUpdate( false );
79 }
80 
81 bool WGE2DManipulator::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us )
82 {
83  bool handled;
84  switch( ea.getEventType() )
85  {
86  case( osgGA::GUIEventAdapter::PUSH ):
87  {
88  addMouseEvent( ea );
89  handled = true;
90  break;
91  }
92  case( osgGA::GUIEventAdapter::DRAG ):
93  {
94  addMouseEvent( ea );
95  if( calcMovement() )
96  {
97  us.requestRedraw();
98  }
99  handled = true;
100  break;
101  }
102  case( osgGA::GUIEventAdapter::SCROLL ):
103  {
104  if( zoom( ea ) )
105  {
106  us.requestRedraw();
107  }
108  handled = true;
109  break;
110  }
111  // TODO(cornimueller): Also allow to zoom using +/- keys.
112  case( osgGA::GUIEventAdapter::KEYDOWN ):
113  {
114  if( ea.getKey() == osgGA::GUIEventAdapter::KEY_Space )
115  {
116  home( ea, us );
117  handled = true;
118  }
119  else
120  {
121  handled = false;
122  }
123  break;
124  }
125  default:
126  handled = false;
127  }
128 
129  return handled;
130 }
131 
132 void WGE2DManipulator::getUsage( osg::ApplicationUsage& usage ) const // NOLINT We can not change the interface of OSG
133 {
134  usage.addKeyboardMouseBinding( "Space", "Reset the view to home" );
135 }
136 
138 {
139 }
140 
142 {
143  m_ga_t1 = NULL;
144  m_ga_t0 = NULL;
145 }
146 
147 void WGE2DManipulator::addMouseEvent( const osgGA::GUIEventAdapter& ea )
148 {
149  m_ga_t1 = m_ga_t0;
150  m_ga_t0 = &ea;
151 }
152 
154 {
155  bool changed = false;
156  // return if less then two events have been added.
157  if( m_ga_t0.valid() && m_ga_t1.valid() )
158  {
159  unsigned int buttonMask = m_ga_t0->getButtonMask();
160  if( buttonMask == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON
161  || buttonMask == ( osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON | osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON ) )
162  {
163  m_positionX += ( m_ga_t1->getX() - m_ga_t0->getX() ) / m_zoom;
164  m_positionY += ( m_ga_t1->getY() - m_ga_t0->getY() ) / m_zoom;
165  changed = true;
166  }
167  }
168 
169  return changed;
170 }
171 
172 bool WGE2DManipulator::zoom( const osgGA::GUIEventAdapter& ea )
173 {
174  bool changed = false;
175  double zoomDelta;
176 
177  switch( ea.getScrollingMotion() )
178  {
179  case osgGA::GUIEventAdapter::SCROLL_UP:
180  zoomDelta = -0.05;
181  break;
182  case osgGA::GUIEventAdapter::SCROLL_DOWN:
183  zoomDelta = 0.05;
184  break;
185  case osgGA::GUIEventAdapter::SCROLL_2D:
186  zoomDelta = -0.05 / 120.0 * ea.getScrollingDeltaY();
187  break;
188  // case osgGA::GUIEventAdapter::SCROLL_LEFT:
189  // case osgGA::GUIEventAdapter::SCROLL_RIGHT:
190  // case osgGA::GUIEventAdapter::SCROLL_NONE:
191  default:
192  // do nothing
193  zoomDelta = 0.0;
194  }
195 
196  if( zoomDelta != 0.0 )
197  {
198  m_zoom *= 1.0 + zoomDelta;
199  // TODO(cornimueller): Correct m_positionX and m_positionY to zoom into the current
200  // mouse position, not into the lower left corner.
201  changed = true;
202  }
203 
204  return changed;
205 }
double m_zoom
zoom factor
bool calcMovement()
Calculate the movement of the camera for the given mouse movement.
virtual const char * className() const
Return the name of the object's class type.
bool zoom(const osgGA::GUIEventAdapter &ea)
Handles events related to zooming.
void flushMouseEventStack()
Reset the internal GUIEvent stack.
osg::ref_ptr< const osgGA::GUIEventAdapter > m_ga_t0
The newer event from the internal event stack.
virtual void setByInverseMatrix(const osg::Matrixd &matrix)
Set the position of the matrix manipulator using a 4x4 matrix.
virtual void getUsage(osg::ApplicationUsage &usage) const
Get the keyboard and mouse usage of this manipulator.
void addMouseEvent(const osgGA::GUIEventAdapter &ea)
Add the current mouse GUIEvent to the internal stack.
virtual void home(const osgGA::GUIEventAdapter &, osgGA::GUIActionAdapter &us)
Move the camera to the default position.
virtual osg::Matrixd getMatrix() const
Get the position of the manipulator as 4x4 matrix.
WGE2DManipulator()
Constructor.
double m_positionX
The x-position of the viewing window's lower left corner.
virtual void setByMatrix(const osg::Matrixd &matrix)
Set the position of the matrix manipulator using a 4x4 matrix.
virtual ~WGE2DManipulator()
Destructor.
virtual osg::Matrixd getInverseMatrix() const
Get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model...
osg::ref_ptr< const osgGA::GUIEventAdapter > m_ga_t1
The older event from the internal event stack.
virtual void init(const osgGA::GUIEventAdapter &, osgGA::GUIActionAdapter &us)
Start/restart the manipulator.
virtual bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &us)
Handle events.
double m_positionY
The y-position of the viewing window's lower left corner.