PickHandler.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // Include own headers
  2. #include "PickHandler.hpp"
  3. // Include modules
  4. #include "TrackPointRenderer.hpp"
  5. // Include dependencies
  6. #include <osg/io_utils>
  7. #include <osgUtil/IntersectionVisitor>
  8. #include <osgUtil/LineSegmentIntersector>
  9. #include <osg/ShapeDrawable>
  10. #include <osg/MatrixTransform>
  11. #include <osg/Material>
  12. #include <osg/StateSet>
  13. #include <osgViewer/Viewer>
  14. PickHandler::PickHandler(OSGWidget* osgWidget, osg::ref_ptr<osg::Group> root) {
  15. _osgWidget = osgWidget;
  16. _selectionRotateGroup = new osg::MatrixTransform;
  17. _selectionMoveToEndGroup = new osg::MatrixTransform;
  18. _selectionMoveToEndGroup->addChild(_selectionRotateGroup.get());
  19. _selectionTranslateGroup = new osg::MatrixTransform;
  20. _selectionTranslateGroup->addChild(_selectionMoveToEndGroup.get());
  21. _selectionSwitch = new osg::Switch;
  22. _selectionSwitch->addChild(_selectionTranslateGroup.get());
  23. root->addChild(_selectionSwitch.get());
  24. }
  25. osg::Node* PickHandler::getPickerRoot() {
  26. return _selectionSwitch.get();
  27. }
  28. bool PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
  29. if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) {
  30. if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH) {
  31. osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
  32. if (viewer) {
  33. osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY());
  34. osgUtil::IntersectionVisitor iv(intersector.get());
  35. iv.setTraversalMask(~0x1);
  36. viewer->getCamera()->accept(iv);
  37. if (intersector->containsIntersections()) {
  38. if (_addNewPoints) {
  39. for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) {
  40. if (std::find(result.nodePath.begin(), result.nodePath.end(), _osgWidget->getMesh()) != result.nodePath.end()) {
  41. _clickStartedOnElement = true;
  42. break;
  43. }
  44. }
  45. } else {
  46. bool found = false;
  47. for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) {
  48. if (found) break;
  49. for (PointShape* shape: _osgWidget->getPointRenderer()->getShapes()) {
  50. if (std::find(result.nodePath.begin(), result.nodePath.end(), shape->getMesh()) != result.nodePath.end()) {
  51. _clickStartedOnElement = true;
  52. found = true;
  53. break;
  54. }
  55. }
  56. }
  57. }
  58. }
  59. }
  60. } else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && _clickStartedOnElement) {
  61. _clickStartedOnElement = false;
  62. osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
  63. if (viewer) {
  64. osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY());
  65. osgUtil::IntersectionVisitor iv(intersector.get());
  66. iv.setTraversalMask(~0x1);
  67. viewer->getCamera()->accept(iv);
  68. if (intersector->containsIntersections()) {
  69. if (_addNewPoints) {
  70. for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) {
  71. if (std::find(result.nodePath.begin(), result.nodePath.end(), _osgWidget->getMesh()) != result.nodePath.end()) {
  72. moveTo(result.localIntersectionPoint);
  73. rotateToNormalVector(result.localIntersectionNormal);
  74. addPoint(result.localIntersectionPoint, result.localIntersectionNormal);
  75. break;
  76. }
  77. }
  78. } else {
  79. bool found = false;
  80. for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) {
  81. if (found) break;
  82. int shapeId = 0;
  83. for (PointShape* shape: _osgWidget->getPointRenderer()->getShapes()) {
  84. if (std::find(result.nodePath.begin(), result.nodePath.end(), shape->getMesh()) != result.nodePath.end()) {
  85. _selectedPoint = shapeId;
  86. MainWindow::getInstance()->getEditWiget()->setSelection(shapeId);
  87. found = true;
  88. break;
  89. }
  90. shapeId++;
  91. }
  92. }
  93. }
  94. }
  95. }
  96. }
  97. }
  98. // Update position of picker on mouse move
  99. if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE || ea.getEventType() == osgGA::GUIEventAdapter::DRAG) {
  100. osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
  101. if (viewer) {
  102. osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY());
  103. osgUtil::IntersectionVisitor iv(intersector.get());
  104. iv.setTraversalMask(~0x1);
  105. viewer->getCamera()->accept(iv);
  106. invalidateTrackPointColors();
  107. if (intersector->containsIntersections()) {
  108. if (_addNewPoints) {
  109. for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) {
  110. if (std::find(result.nodePath.begin(), result.nodePath.end(), _osgWidget->getMesh()) != result.nodePath.end()) {
  111. moveTo(result.localIntersectionPoint);
  112. rotateToNormalVector(result.localIntersectionNormal);
  113. setVisibility(true);
  114. break;
  115. }
  116. }
  117. } else {
  118. bool found = false;
  119. for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) {
  120. if (found) break;
  121. for (PointShape* shape: _osgWidget->getPointRenderer()->getShapes()) {
  122. if (std::find(result.nodePath.begin(), result.nodePath.end(), shape->getMesh()) != result.nodePath.end()) {
  123. shape->setColor(osg::Vec4(0.0f, 0.0f, 1.0f, 0.2f));
  124. found = true;
  125. break;
  126. }
  127. }
  128. }
  129. }
  130. } else {
  131. if (_addNewPoints) {
  132. MainWindow::getInstance()->getEditWiget()->invalidatePositions();
  133. }
  134. setVisibility(false);
  135. }
  136. }
  137. }
  138. return false;
  139. }
  140. void PickHandler::setSelection(bool addNewPoints) {
  141. _addNewPoints = addNewPoints;
  142. if (addNewPoints) {
  143. _selectedPoint = -1;
  144. }
  145. invalidateTrackPointColors();
  146. updateRenderer();
  147. }
  148. void PickHandler::moveTo(osg::Vec3f position) {
  149. _selectionTranslateGroup->setMatrix(osg::Matrix::translate(position));
  150. MainWindow::getInstance()->getEditWiget()->updatePositions(position);
  151. }
  152. void PickHandler::rotateToNormalVector(osg::Vec3f normal) {
  153. MainWindow::getInstance()->getEditWiget()->updateNormals(normal);
  154. osg::Vec3 modifier = MainWindow::getInstance()->getStore()->getNormalModifier();
  155. normal = normal.operator+(modifier);
  156. normal.normalize();
  157. _selectionRotateGroup->setMatrix(osg::Matrix::rotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normal));
  158. osg::Vec3f movementVector = normal.operator*(_optiTrackSteamVRLength / 2);
  159. _selectionMoveToEndGroup->setMatrix(osg::Matrix::translate(movementVector));
  160. }
  161. void PickHandler::updateRenderer() {
  162. removeAllShapes();
  163. switch(MainWindow::getInstance()->getEditWiget()->getSelectedTrackingSystem()) {
  164. case OptiTrack: {
  165. OptiTrackSettings settings = MainWindow::getInstance()->getStore()->getOptiTrackSettings();
  166. _optiTrackSteamVRLength = settings.length;
  167. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  168. osg::ref_ptr<osg::ShapeDrawable> cylinder = new osg::ShapeDrawable();
  169. cylinder->setShape(new osg::Cylinder(osg::Vec3(0.0f, 0.0f, 0.0f), settings.radius, settings.length));
  170. cylinder->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 0.2f));
  171. geode->addDrawable(cylinder.get());
  172. OSGWidget::fixMaterialState(geode);
  173. _selectionRotateGroup->addChild(geode.get());
  174. break;
  175. }
  176. case EMFTrack: {
  177. break;
  178. }
  179. case SteamVRTrack: {
  180. break;
  181. }
  182. case ActionPoints: {
  183. break;
  184. }
  185. }
  186. setVisibility(_addNewPoints);
  187. }
  188. void PickHandler::removeAllShapes() {
  189. _selectionRotateGroup->removeChildren(0, _selectionRotateGroup->getNumChildren());
  190. }
  191. void PickHandler::setVisibility(bool mode) {
  192. _selectionSwitch->setValue(0, mode);
  193. }
  194. void PickHandler::addPoint(osg::Vec3 point, osg::Vec3 normal) {
  195. ActiveTrackingSystem activeTrackingSystem = MainWindow::getInstance()->getEditWiget()->getSelectedTrackingSystem();
  196. MainWindow::getInstance()->getStore()->addTrackPoint(point, normal, activeTrackingSystem);
  197. _osgWidget->getPointRenderer()->render(MainWindow::getInstance()->getEditWiget()->getSelectedTrackingSystem());
  198. }
  199. void PickHandler::invalidateTrackPointColors() {
  200. int shapeId = 0;
  201. for (PointShape* shape: _osgWidget->getPointRenderer()->getShapes()) {
  202. if (_selectedPoint != shapeId) {
  203. shape->setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 0.2f));
  204. }
  205. shapeId++;
  206. }
  207. }