From bc3cff2406e9d6bde138e855c33deccba354f241 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Mar 2013 14:03:28 +0000 Subject: [PATCH] Added arrow key support. Added support for using ctrl and shift keys to modulate how senstive the mouse and key movement is when modifying the keystone parameters. --- examples/osgkeystone/osgkeystone.cpp | 193 +++++++++++++++++---------- 1 file changed, 125 insertions(+), 68 deletions(-) diff --git a/examples/osgkeystone/osgkeystone.cpp b/examples/osgkeystone/osgkeystone.cpp index 856f59675..fb561c48b 100644 --- a/examples/osgkeystone/osgkeystone.cpp +++ b/examples/osgkeystone/osgkeystone.cpp @@ -20,8 +20,10 @@ #include #include +#include #include #include +#include class ControlPoints : public osg::Referenced @@ -196,10 +198,20 @@ public: CENTER }; + osg::Vec2d incrementScale(const osgGA::GUIEventAdapter& ea) const; + Region computeRegion(const osgGA::GUIEventAdapter& ea) const; + void move(Region region, const osg::Vec2d& delta); + protected: + osg::ref_ptr _keystone; + osg::Vec2d _defaultIncrement; + osg::Vec2d _ctrlIncrement; + osg::Vec2d _shiftIncrement; + osg::Vec2d _keyIncrement; + osg::Vec2d _startPosition; osg::ref_ptr _startControlPoints; @@ -210,46 +222,107 @@ protected: KeystoneHandler::KeystoneHandler(Keystone* keystone): _keystone(keystone), + _defaultIncrement(0.0,0.0), + _ctrlIncrement(1.0,1.0), + _shiftIncrement(0.1,0.1), + _keyIncrement(0.005, 0.005), _selectedRegion(NONE_SELECTED) { _startControlPoints = new ControlPoints; _currentControlPoints = new ControlPoints; } +KeystoneHandler::Region KeystoneHandler::computeRegion(const osgGA::GUIEventAdapter& ea) const +{ + float x = ea.getXnormalized(); + float y = ea.getYnormalized(); + if (x<-0.33) + { + // left side + if (y<-0.33) return BOTTOM_LEFT; + else if (y<0.33) return LEFT; + else return TOP_LEFT; + } + else if (x<0.33) + { + // center side + if (y<-0.33) return BOTTOM; + else if (y<0.33) return CENTER; + else return TOP; + } + else + { + // right side + if (y<-0.33) return BOTTOM_RIGHT; + else if (y<0.33) return RIGHT; + else return TOP_RIGHT; + } + return NONE_SELECTED; +} + +void KeystoneHandler::move(Region region, const osg::Vec2d& delta) +{ + switch(region) + { + case(TOP_LEFT): + _currentControlPoints->top_left += delta; + break; + case(TOP): + _currentControlPoints->top_left += delta; + _currentControlPoints->top_right += delta; + break; + case(TOP_RIGHT): + _currentControlPoints->top_right += delta; + break; + case(RIGHT): + _currentControlPoints->top_right += delta; + _currentControlPoints->bottom_right += delta; + break; + case(BOTTOM_RIGHT): + _currentControlPoints->bottom_right += delta; + break; + case(BOTTOM): + _currentControlPoints->bottom_right += delta; + _currentControlPoints->bottom_left += delta; + break; + case(BOTTOM_LEFT): + _currentControlPoints->bottom_left += delta; + break; + case(LEFT): + _currentControlPoints->bottom_left += delta; + _currentControlPoints->top_left += delta; + break; + case(CENTER): + _currentControlPoints->bottom_left += delta; + _currentControlPoints->top_left += delta; + _currentControlPoints->bottom_right += delta; + _currentControlPoints->top_right += delta; + break; + case(NONE_SELECTED): + break; + } + _keystone->updateKeystone(*_currentControlPoints); +} + +osg::Vec2d KeystoneHandler::incrementScale(const osgGA::GUIEventAdapter& ea) const +{ + if (_ctrlIncrement!=osg::Vec2d(0.0,0.0) && (ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL || ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL )) return _ctrlIncrement; + if (_shiftIncrement!=osg::Vec2d(0.0,0.0) && (ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT || ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT )) return _shiftIncrement; + return _defaultIncrement; +} + bool KeystoneHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { switch(ea.getEventType()) { case(osgGA::GUIEventAdapter::PUSH): { - if (ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL || ea.getModKeyMask()==osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL ) + osg::Vec2d scale = incrementScale(ea); + if (scale.length2()!=0.0) { - float x = ea.getXnormalized(); - float y = ea.getYnormalized(); - if (x<-0.33) - { - // left side - if (y<-0.33) _selectedRegion = BOTTOM_LEFT; - else if (y<0.33) _selectedRegion = LEFT; - else _selectedRegion = TOP_LEFT; - } - else if (x<0.33) - { - // center side - if (y<-0.33) _selectedRegion = BOTTOM; - else if (y<0.33) _selectedRegion = CENTER; - else _selectedRegion = TOP; - } - else - { - // right side - if (y<-0.33) _selectedRegion = BOTTOM_RIGHT; - else if (y<0.33) _selectedRegion = RIGHT; - else _selectedRegion = TOP_RIGHT; - } + _selectedRegion = computeRegion(ea); (*_startControlPoints) = (*_currentControlPoints); - _startPosition.set(x,y); - OSG_NOTICE<<"Region "<<_selectedRegion<top_left += delta; - break; - case(TOP): - _currentControlPoints->top_left += delta; - _currentControlPoints->top_right += delta; - break; - case(TOP_RIGHT): - _currentControlPoints->top_right += delta; - break; - case(RIGHT): - _currentControlPoints->top_right += delta; - _currentControlPoints->bottom_right += delta; - break; - case(BOTTOM_RIGHT): - _currentControlPoints->bottom_right += delta; - break; - case(BOTTOM): - _currentControlPoints->bottom_right += delta; - _currentControlPoints->bottom_left += delta; - break; - case(BOTTOM_LEFT): - _currentControlPoints->bottom_left += delta; - break; - case(LEFT): - _currentControlPoints->bottom_left += delta; - _currentControlPoints->top_left += delta; - break; - case(CENTER): - _currentControlPoints->bottom_left += delta; - _currentControlPoints->top_left += delta; - _currentControlPoints->bottom_right += delta; - _currentControlPoints->top_right += delta; - break; - case(NONE_SELECTED): - break; - } - _keystone->updateKeystone(*_currentControlPoints); + osg::Vec2d scale = incrementScale(ea); + move(_selectedRegion, osg::Vec2d(delta.x()*scale.x(), delta.y()*scale.y()) ); return true; } @@ -312,7 +346,6 @@ bool KeystoneHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionA } case(osgGA::GUIEventAdapter::RELEASE): { - OSG_NOTICE<<"Mouse released "<reset(); _keystone->updateKeystone(*_currentControlPoints); } + else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Up) + { + move(computeRegion(ea), osg::Vec2d(0.0, _keyIncrement.y()*incrementScale(ea).y()) ); + } + else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Down) + { + move(computeRegion(ea), osg::Vec2d(0.0, -_keyIncrement.y()*incrementScale(ea).y()) ); + } + else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left) + { + move(computeRegion(ea), osg::Vec2d(-_keyIncrement.x()*incrementScale(ea).x(), 0.0) ); + } + else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right) + { + move(computeRegion(ea), osg::Vec2d(_keyIncrement.x()*incrementScale(ea).x(), 0.0) ); + } return false; } default: @@ -367,6 +416,13 @@ int main( int argc, char **argv ) viewer.setSceneData(model.get()); + // add the state manipulator + viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); + + // add the stats handler + viewer.addEventHandler(new osgViewer::StatsHandler); + + // add camera manipulator viewer.setCameraManipulator(new osgGA::TrackballManipulator()); viewer.realize(); @@ -375,6 +431,7 @@ int main( int argc, char **argv ) osg::Matrixd original_pm = viewer.getCamera()->getProjectionMatrix(); + // Add keystone handler viewer.addEventHandler(new KeystoneHandler(keystone)); while(!viewer.done())