| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | #include <osgGA/MultiTouchTrackballManipulator> |
|---|
| 16 | #include <osg/io_utils> |
|---|
| 17 | |
|---|
| 18 | using namespace osg; |
|---|
| 19 | using namespace osgGA; |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | MultiTouchTrackballManipulator::MultiTouchTrackballManipulator( int flags ) |
|---|
| 25 | : inherited( flags ) |
|---|
| 26 | { |
|---|
| 27 | setVerticalAxisFixed( false ); |
|---|
| 28 | } |
|---|
| 29 | |
|---|
| 30 | |
|---|
| 31 | |
|---|
| 32 | MultiTouchTrackballManipulator::MultiTouchTrackballManipulator( const MultiTouchTrackballManipulator& tm, const CopyOp& copyOp ) |
|---|
| 33 | : inherited( tm, copyOp ) |
|---|
| 34 | { |
|---|
| 35 | } |
|---|
| 36 | |
|---|
| 37 | |
|---|
| 38 | void MultiTouchTrackballManipulator::handleMultiTouchDrag(GUIEventAdapter::TouchData* now, GUIEventAdapter::TouchData* last, const double eventTimeDelta) |
|---|
| 39 | { |
|---|
| 40 | const float zoom_threshold = 1.0f; |
|---|
| 41 | |
|---|
| 42 | osg::Vec2 pt_1_now(now->get(0).x,now->get(0).y); |
|---|
| 43 | osg::Vec2 pt_2_now(now->get(1).x,now->get(1).y); |
|---|
| 44 | osg::Vec2 pt_1_last(last->get(0).x,last->get(0).y); |
|---|
| 45 | osg::Vec2 pt_2_last(last->get(1).x,last->get(1).y); |
|---|
| 46 | |
|---|
| 47 | |
|---|
| 48 | |
|---|
| 49 | float gap_now((pt_1_now - pt_2_now).length()); |
|---|
| 50 | float gap_last((pt_1_last - pt_2_last).length()); |
|---|
| 51 | |
|---|
| 52 | |
|---|
| 53 | |
|---|
| 54 | if (fabs(gap_last - gap_now) >= zoom_threshold) |
|---|
| 55 | { |
|---|
| 56 | |
|---|
| 57 | zoomModel( (gap_last - gap_now) * eventTimeDelta, true ); |
|---|
| 58 | } |
|---|
| 59 | |
|---|
| 60 | |
|---|
| 61 | |
|---|
| 62 | osg::Vec2 delta = ((pt_1_last - pt_1_now) + (pt_2_last - pt_2_now)) / 2.0f; |
|---|
| 63 | |
|---|
| 64 | float scale = 0.2f * _distance * eventTimeDelta; |
|---|
| 65 | |
|---|
| 66 | |
|---|
| 67 | |
|---|
| 68 | panModel( delta.x() * scale, delta.y() * scale * (-1)); |
|---|
| 69 | } |
|---|
| 70 | |
|---|
| 71 | |
|---|
| 72 | bool MultiTouchTrackballManipulator::handle( const GUIEventAdapter& ea, GUIActionAdapter& us ) |
|---|
| 73 | { |
|---|
| 74 | |
|---|
| 75 | bool handled(false); |
|---|
| 76 | |
|---|
| 77 | switch(ea.getEventType()) |
|---|
| 78 | { |
|---|
| 79 | |
|---|
| 80 | case osgGA::GUIEventAdapter::PUSH: |
|---|
| 81 | case osgGA::GUIEventAdapter::DRAG: |
|---|
| 82 | case osgGA::GUIEventAdapter::RELEASE: |
|---|
| 83 | if (ea.isMultiTouchEvent()) |
|---|
| 84 | { |
|---|
| 85 | double eventTimeDelta = 1/60.0; |
|---|
| 86 | if( eventTimeDelta < 0. ) |
|---|
| 87 | { |
|---|
| 88 | OSG_WARN << "Manipulator warning: eventTimeDelta = " << eventTimeDelta << std::endl; |
|---|
| 89 | eventTimeDelta = 0.; |
|---|
| 90 | } |
|---|
| 91 | osgGA::GUIEventAdapter::TouchData* data = ea.getTouchData(); |
|---|
| 92 | |
|---|
| 93 | |
|---|
| 94 | if ((data->getNumTouchPoints() == 3) || ((data->getNumTouchPoints() == 1) && (data->get(0).tapCount >= 2))) |
|---|
| 95 | { |
|---|
| 96 | flushMouseEventStack(); |
|---|
| 97 | _thrown = false; |
|---|
| 98 | home(ea,us); |
|---|
| 99 | handled = true; |
|---|
| 100 | } |
|---|
| 101 | |
|---|
| 102 | else if (data->getNumTouchPoints() >= 2) |
|---|
| 103 | { |
|---|
| 104 | if ((_lastTouchData.valid()) && (_lastTouchData->getNumTouchPoints() >= 2)) |
|---|
| 105 | { |
|---|
| 106 | handleMultiTouchDrag(data, _lastTouchData.get(), eventTimeDelta); |
|---|
| 107 | } |
|---|
| 108 | |
|---|
| 109 | handled = true; |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | _lastTouchData = data; |
|---|
| 113 | |
|---|
| 114 | |
|---|
| 115 | unsigned int num_touches_ended(0); |
|---|
| 116 | for(osgGA::GUIEventAdapter::TouchData::iterator i = data->begin(); i != data->end(); ++i) |
|---|
| 117 | { |
|---|
| 118 | if ((*i).phase == osgGA::GUIEventAdapter::TOUCH_ENDED) |
|---|
| 119 | num_touches_ended++; |
|---|
| 120 | } |
|---|
| 121 | |
|---|
| 122 | if(num_touches_ended == data->getNumTouchPoints()) |
|---|
| 123 | { |
|---|
| 124 | _lastTouchData = NULL; |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | } |
|---|
| 128 | break; |
|---|
| 129 | default: |
|---|
| 130 | break; |
|---|
| 131 | } |
|---|
| 132 | |
|---|
| 133 | return handled ? handled : TrackballManipulator::handle(ea, us); |
|---|
| 134 | } |
|---|