OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #include "WGE2DManipulator.h" 00026 00027 00028 WGE2DManipulator::WGE2DManipulator() 00029 : m_positionX( -64.0 ), 00030 m_positionY( 0.0 ), 00031 m_zoom( 1.0 ) 00032 { 00033 } 00034 00035 const char* WGE2DManipulator::className() const 00036 { 00037 return "WGE2DManipulator"; 00038 } 00039 00040 void WGE2DManipulator::setByMatrix( const osg::Matrixd& matrix ) 00041 { 00042 m_positionX = matrix.getTrans().x(); 00043 m_positionY = matrix.getTrans().y(); 00044 m_zoom = 1.0 / matrix.getScale().x(); 00045 } 00046 00047 void WGE2DManipulator::setByInverseMatrix( const osg::Matrixd& matrix ) 00048 { 00049 m_positionX = -matrix.getTrans().x(); 00050 m_positionY = -matrix.getTrans().y(); 00051 m_zoom = matrix.getScale().x(); 00052 } 00053 00054 osg::Matrixd WGE2DManipulator::getMatrix() const 00055 { 00056 return osg::Matrixd::scale( 1.0 / m_zoom, 1.0 / m_zoom, 1.0 ) * osg::Matrixd::translate( m_positionX, m_positionY, 0.0 ); 00057 } 00058 00059 osg::Matrixd WGE2DManipulator::getInverseMatrix() const 00060 { 00061 return osg::Matrixd::translate( -m_positionX, -m_positionY, 0.0 ) * osg::Matrixd::scale( m_zoom, m_zoom, 1.0 ); 00062 } 00063 00064 void WGE2DManipulator::home( const osgGA::GUIEventAdapter& /*ea*/, osgGA::GUIActionAdapter& us ) // NOLINT We can not change the interface of OSG 00065 { 00066 m_positionX = -64.0; 00067 m_positionY = 0.0; 00068 m_zoom = 1.0; 00069 00070 us.requestRedraw(); 00071 flushMouseEventStack(); 00072 } 00073 00074 void WGE2DManipulator::init( const osgGA::GUIEventAdapter& /*ea*/, osgGA::GUIActionAdapter& us ) // NOLINT We can not change the interface of OSG 00075 { 00076 flushMouseEventStack(); 00077 00078 us.requestContinuousUpdate( false ); 00079 } 00080 00081 bool WGE2DManipulator::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us ) 00082 { 00083 bool handled; 00084 switch( ea.getEventType() ) 00085 { 00086 case( osgGA::GUIEventAdapter::PUSH ): 00087 { 00088 addMouseEvent( ea ); 00089 handled = true; 00090 break; 00091 } 00092 case( osgGA::GUIEventAdapter::DRAG ): 00093 { 00094 addMouseEvent( ea ); 00095 if( calcMovement() ) 00096 { 00097 us.requestRedraw(); 00098 } 00099 handled = true; 00100 break; 00101 } 00102 case( osgGA::GUIEventAdapter::SCROLL ): 00103 { 00104 if( zoom( ea ) ) 00105 { 00106 us.requestRedraw(); 00107 } 00108 handled = true; 00109 break; 00110 } 00111 // TODO(cornimueller): Also allow to zoom using +/- keys. 00112 case( osgGA::GUIEventAdapter::KEYDOWN ): 00113 { 00114 if( ea.getKey() == osgGA::GUIEventAdapter::KEY_Space ) 00115 { 00116 home( ea, us ); 00117 handled = true; 00118 } 00119 else 00120 { 00121 handled = false; 00122 } 00123 break; 00124 } 00125 default: 00126 handled = false; 00127 } 00128 00129 return handled; 00130 } 00131 00132 void WGE2DManipulator::getUsage( osg::ApplicationUsage& usage ) const // NOLINT We can not change the interface of OSG 00133 { 00134 usage.addKeyboardMouseBinding( "Space", "Reset the view to home" ); 00135 } 00136 00137 WGE2DManipulator::~WGE2DManipulator() 00138 { 00139 } 00140 00141 void WGE2DManipulator::flushMouseEventStack() 00142 { 00143 m_ga_t1 = NULL; 00144 m_ga_t0 = NULL; 00145 } 00146 00147 void WGE2DManipulator::addMouseEvent( const osgGA::GUIEventAdapter& ea ) 00148 { 00149 m_ga_t1 = m_ga_t0; 00150 m_ga_t0 = &ea; 00151 } 00152 00153 bool WGE2DManipulator::calcMovement() 00154 { 00155 bool changed = false; 00156 // return if less then two events have been added. 00157 if( m_ga_t0.valid() && m_ga_t1.valid() ) 00158 { 00159 unsigned int buttonMask = m_ga_t0->getButtonMask(); 00160 if( buttonMask == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON 00161 || buttonMask == ( osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON | osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON ) ) 00162 { 00163 m_positionX += ( m_ga_t1->getX() - m_ga_t0->getX() ) / m_zoom; 00164 m_positionY += ( m_ga_t1->getY() - m_ga_t0->getY() ) / m_zoom; 00165 changed = true; 00166 } 00167 } 00168 00169 return changed; 00170 } 00171 00172 bool WGE2DManipulator::zoom( const osgGA::GUIEventAdapter& ea ) 00173 { 00174 bool changed = false; 00175 double zoomDelta; 00176 00177 switch( ea.getScrollingMotion() ) 00178 { 00179 case osgGA::GUIEventAdapter::SCROLL_UP: 00180 zoomDelta = -0.05; 00181 break; 00182 case osgGA::GUIEventAdapter::SCROLL_DOWN: 00183 zoomDelta = 0.05; 00184 break; 00185 case osgGA::GUIEventAdapter::SCROLL_2D: 00186 zoomDelta = -0.05 / 120.0 * ea.getScrollingDeltaY(); 00187 break; 00188 // case osgGA::GUIEventAdapter::SCROLL_LEFT: 00189 // case osgGA::GUIEventAdapter::SCROLL_RIGHT: 00190 // case osgGA::GUIEventAdapter::SCROLL_NONE: 00191 default: 00192 // do nothing 00193 zoomDelta = 0.0; 00194 } 00195 00196 if( zoomDelta != 0.0 ) 00197 { 00198 m_zoom *= 1.0 + zoomDelta; 00199 // TODO(cornimueller): Correct m_positionX and m_positionY to zoom into the current 00200 // mouse position, not into the lower left corner. 00201 changed = true; 00202 } 00203 00204 return changed; 00205 }