Advertisement
Guest User

Untitled

a guest
Sep 27th, 2016
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.38 KB | None | 0 0
  1. #include "MultiTouchOrbit3DManipulator.h"
  2. #include <osg/io_utils>
  3. #include <vector>
  4.  
  5. MultiTouchOrbit3DManipulator::MultiTouchOrbit3DManipulator(IfcPlusPlusSystem * sys, int flags) : Orbit3DManipulator (sys , flags)
  6. {
  7. setVerticalAxisFixed(false) ;
  8. }
  9.  
  10. /// Handles the multi - touch camera pan and zoom
  11. void MultiTouchOrbit3DManipulator::handleMultiTouchGesture (
  12. osgGA::GUIEventAdapter::TouchData * now,
  13. osgGA::GUIEventAdapter::TouchData * last,
  14. const osgGA :: GUIEventAdapter & ea,
  15. osgGA :: GUIActionAdapter & aa,
  16. const double eventTimeDelta)
  17. {
  18. /// Multipliers for screen size independent manipulations
  19. osg::Vec2 screenCompensationMultipliers(ea.getXmax() - ea.getXmin(),
  20. ea.getYmax() - ea.getYmin());
  21.  
  22. // Computations were done relative to iPhone screen
  23. screenCompensationMultipliers /= 640;
  24.  
  25. // Touch points normalized to [-1 , 1]
  26. osg::Vec2 pt1Now (now->get(0).x, now->get(0).y);
  27. osg::Vec2 pt2Now (now->get(1).x, now->get(1).y);
  28. osg::Vec2 pt1Last (last->get(0).x, last->get(0).y);
  29. osg::Vec2 pt2Last (last->get(1).x, last->get(1).y);
  30.  
  31. // Centers of the touch points for determining the ray intersection
  32. osg::Vec2 pxCenterPointLast = (pt1Last + pt2Last) / 2.;
  33. osg::Vec2 pxCenterPointNow = (pt1Now + pt2Now) / 2.;
  34. osg::Vec2 centerPointLast = normalizedScreenPoint (pxCenterPointLast, ea);
  35. osg::Vec2 centerPointNow = normalizedScreenPoint (pxCenterPointNow , ea);
  36.  
  37. // if any of the two fingers just begun , compute the ray
  38. // pointer intersection
  39. if (last->get(0).phase == osgGA::GUIEventAdapter::TOUCH_BEGAN
  40. || last->get(1).phase == osgGA::GUIEventAdapter::TOUCH_BEGAN) {
  41.  
  42. // The y axis is flipped in the device screen
  43. // coordinates
  44. computeRayPointer (ea , aa, osg::Vec2 (centerPointLast.x(), - centerPointLast.y()));
  45. }
  46.  
  47. // compensate the vectors for different screen
  48. // dimensions than the tested device
  49. std::vector <osg::Vec2 *> compensationVectors =
  50. {& pt1Now, &pt2Now , &pt1Last, &pt2Last, &centerPointLast, &centerPointNow};
  51.  
  52. for (auto vec : compensationVectors) {
  53. vec->x() *= screenCompensationMultipliers.x();
  54. vec->y() *= screenCompensationMultipliers.y();
  55. }
  56.  
  57. // compute sizes of gaps between fingers
  58. float gapNow ((pt1Now - pt2Now).length());
  59. float gapLast ((pt1Last - pt2Last).length());
  60.  
  61. osg::Vec3 intersectionCameraVector = m_eye - m_rotate_center;
  62. float gapDifference = gapNow - gapLast;
  63.  
  64. // empirically reached factor constant
  65. float scrollDistanceFactor = intersectionCameraVector.length() * 0.1;
  66.  
  67. // zoom camera more the further it is from the ray
  68. // intersection point
  69. zoomCamera (gapDifference * eventTimeDelta * scrollDistanceFactor);
  70.  
  71. // drag gesture
  72. osgViewer::View * view = dynamic_cast<osgViewer::View *>(&aa);
  73. if (!view) {
  74. return ;
  75. }
  76.  
  77. // move camera more the further it is from the ray intersection point
  78. osg :: Vec2 distanceRatioPanFactors =
  79. screenCompensationMultipliers * fmax(0.8, intersectionCameraVector.length() * 0.2);
  80.  
  81. osg::Vec2 dCenter = centerPointLast - centerPointNow;
  82.  
  83. // left camera vector is perpendicular to the camera up
  84. // vector and the direction of camera
  85. osg::Vec3 left = m_up ^ (m_lookat - m_eye);
  86.  
  87. // the m_up vector only defines camera 's roll but not its pitch
  88. // get the camera 's up direction vector
  89. osg::Vec3 camUp = left ^ (m_lookat - m_eye);
  90. camUp.normalize();
  91. left.normalize();
  92. osg::Vec3 leftShift = left * dCenter.x();
  93. osg::Vec3 upShift = camUp * dCenter.y();
  94.  
  95. leftShift *= distanceRatioPanFactors.x();
  96. upShift *= distanceRatioPanFactors.y();
  97. // translate the camera eye and lookat
  98. m_eye.set(m_eye - leftShift + upShift) ;
  99. m_lookat.set(m_lookat - leftShift + upShift);
  100. }
  101.  
  102. /// returns screen point normalized into interval [ -1 , 1]
  103. osg::Vec2 MultiTouchOrbit3DManipulator::normalizedScreenPoint (osg::Vec2 point,
  104. const osgGA::GUIEventAdapter & ea)
  105. {
  106. return ((osg::Vec2(point.x() / (ea.getXmax() - ea.getXmin()),
  107. point.y() / (ea.getYmax() - ea.getYmin()))) * 2.) - osg::Vec2(1., 1);
  108. }
  109.  
  110. bool MultiTouchOrbit3DManipulator::handle (const osgGA::GUIEventAdapter& ea ,
  111. osgGA::GUIActionAdapter& aa)
  112. {
  113. bool handled (false);
  114. switch (ea.getEventType()) {
  115. case osgGA::GUIEventAdapter::PUSH:
  116. case osgGA::GUIEventAdapter::DRAG:
  117. case osgGA::GUIEventAdapter::RELEASE:
  118. // Deselect the selected object and dismiss the menu
  119. if (this->selectionWasDismissedHandler) {
  120. this->selectionWasDismissedHandler (ea.getXnormalized(),
  121. ea.getYnormalized());
  122. }
  123.  
  124. if (ea.isMultiTouchEvent()) {
  125. float eventTimeDelta = 1./60.;
  126. osgGA::GUIEventAdapter::TouchData * touchData = ea.getTouchData();
  127.  
  128. // Ensure the number of touches is at least 2,
  129. // the others will be ignored
  130.  
  131. if (touchData->getNumTouchPoints() >= 2) {
  132. if (( _lastTouchData . valid () ) &&
  133. ( _lastTouchData- > getNumTouchPoints () >= 2)) {
  134.  
  135. handleMultiTouchGesture (touchData, _lastTouchData.get(), ea, aa, eventTimeDelta);
  136. }
  137.  
  138. handled = true;
  139. }
  140.  
  141. _lastTouchData = touchData;
  142. // check if all touches ended
  143. unsigned int num_touches_ended(0);
  144.  
  145. for (osgGA::GUIEventAdapter::TouchData::iterator i = touchData->begin(); i != touchData-> end(); ++i) {
  146. if ((*i).phase == osgGA::GUIEventAdapter::TOUCH_ENDED) {
  147. num_touches_ended ++;
  148. }
  149. }
  150.  
  151. }
  152. break;
  153. default:
  154. break;
  155. }
  156.  
  157. // if the touches were not handled , call the superclass's implementation
  158. return handled ? handled : Orbit3DManipulator::handle (ea, aa);
  159. }
  160.  
  161. void Orbit3DManipulator::zoomCamera (const float dy)
  162. {
  163. // push camera forward along mouse ray
  164. osg::Vec3d zoom_direction = m_ray_pointer_direction;
  165. zoom_direction.normalize();
  166. zoom_direction *= dy;
  167. m_eye += zoom_direction;
  168. m_lookat += zoom_direction;
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement