PickHandler.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include "PickHandler.hpp"
  2. #include <osg/io_utils>
  3. #include <osgUtil/IntersectionVisitor>
  4. #include <osgUtil/LineSegmentIntersector>
  5. #include <osg/ShapeDrawable>
  6. #include <osg/MatrixTransform>
  7. #include <osg/Material>
  8. #include <osg/StateSet>
  9. #include <osgViewer/Viewer>
  10. PickHandler::PickHandler(StoreHandler* storeHandler, OpenScadRenderer* openScadRenderer, ThreeMFWriter* threeMFWriter, osg::ref_ptr<osg::Node> axesNode) {
  11. _storeHandler = storeHandler;
  12. _openScadRenderer = openScadRenderer;
  13. _threeMFWriter = threeMFWriter;
  14. _axesNode = axesNode;
  15. }
  16. osg::Node* PickHandler::getOrCreateSelectionCylinder() {
  17. if (!_selectionTranslateGroup) {
  18. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  19. osg::ref_ptr<osg::ShapeDrawable> cylinder = new osg::ShapeDrawable();
  20. cylinder->setShape(new osg::Cylinder(osg::Vec3(0.0f, 0.0f, 0.0f), 1.0f, 10.0f));
  21. cylinder->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 0.2f));
  22. geode->addDrawable(cylinder.get());
  23. {
  24. osg::StateSet* stateSet = geode->getOrCreateStateSet();
  25. osg::Material* material = new osg::Material;
  26. material->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE);
  27. stateSet->setAttributeAndModes(material, osg::StateAttribute::ON);
  28. stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
  29. }
  30. _selectionRotateGroup = new osg::MatrixTransform;
  31. _selectionRotateGroup->addChild(geode.get());
  32. _selectionMoveToEndGroup = new osg::MatrixTransform;
  33. _selectionMoveToEndGroup->addChild(_selectionRotateGroup.get());
  34. _selectionTranslateGroup = new osg::MatrixTransform;
  35. _selectionTranslateGroup->addChild(_selectionMoveToEndGroup.get());
  36. _selectionSwitch = new osg::Switch;
  37. _selectionSwitch->addChild(_selectionTranslateGroup.get());
  38. }
  39. return _selectionSwitch.get();
  40. }
  41. bool PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
  42. if (ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_CTRL) {
  43. isSelection = !isSelection;
  44. setVisibility(false);
  45. }
  46. if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE && ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON && isSelection) {
  47. osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
  48. if (viewer) {
  49. osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY());
  50. osgUtil::IntersectionVisitor iv(intersector.get());
  51. iv.setTraversalMask(~0x1);
  52. viewer->getCamera()->accept(iv);
  53. if (intersector->containsIntersections()) {
  54. for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) {
  55. if (std::find(result.nodePath.begin(), result.nodePath.end(), _axesNode) != result.nodePath.end()) {
  56. moveTo(result.localIntersectionPoint);
  57. rotateToNormalVector(result.localIntersectionNormal);
  58. _storeHandler->addTrackingPoint(result.localIntersectionPoint, result.localIntersectionNormal);
  59. _openScadRenderer->render(_storeHandler->getPoints());
  60. _threeMFWriter->writeTrackPoints(_storeHandler->getPoints(), "/tmp/export.3mf");
  61. break;
  62. }
  63. }
  64. }
  65. }
  66. }
  67. if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE && isSelection) {
  68. osgViewer::View* viewer = dynamic_cast<osgViewer::View*>(&aa);
  69. if (viewer) {
  70. osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY());
  71. osgUtil::IntersectionVisitor iv(intersector.get());
  72. iv.setTraversalMask(~0x1);
  73. viewer->getCamera()->accept(iv);
  74. if (intersector->containsIntersections()) {
  75. for (const osgUtil::LineSegmentIntersector::Intersection result: intersector->getIntersections()) {
  76. if (std::find(result.nodePath.begin(), result.nodePath.end(), _axesNode) != result.nodePath.end()) {
  77. moveTo(result.localIntersectionPoint);
  78. rotateToNormalVector(result.localIntersectionNormal);
  79. setVisibility(true);
  80. break;
  81. }
  82. }
  83. } else {
  84. setVisibility(false);
  85. }
  86. }
  87. }
  88. return false;
  89. }
  90. void PickHandler::moveTo(osg::Vec3f position) {
  91. _selectionTranslateGroup->setMatrix(osg::Matrix::translate(position));
  92. }
  93. void PickHandler::rotateToNormalVector(osg::Vec3f normal) {
  94. _selectionRotateGroup->setMatrix(osg::Matrix::rotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normal));
  95. osg::Vec3f movementVector = normal.operator*(5.0f);
  96. _selectionMoveToEndGroup->setMatrix(osg::Matrix::translate(movementVector));
  97. }
  98. void PickHandler::setVisibility(bool mode) {
  99. _selectionSwitch->setValue(0, mode);
  100. }