transforms.cpp 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include <osgViewer/Viewer>
  2. #include <osg/ShapeDrawable>
  3. #include <osg/Geode>
  4. #include <osgDB/ReadFile>
  5. #include <osg/Group>
  6. #include <osg/MatrixTransform>
  7. #include <osg/Matrix>
  8. #include <osgGA/TrackballManipulator>
  9. #include <osgUtil/LineSegmentIntersector>
  10. #include <osgUtil/IntersectionVisitor>
  11. #include <osg/PolygonMode>
  12. class PickHandler: public osgGA::GUIEventHandler {
  13. public:
  14. osg::Node* getOrCreateSelectionCylinder();
  15. virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
  16. void moveTo(osg::Vec3f position);
  17. void rotateToNormalVector(osg::Vec3f normal);
  18. protected:
  19. osg::ref_ptr<osg::MatrixTransform> _selectionTranslateGroup;
  20. osg::ref_ptr<osg::MatrixTransform> _selectionRotateGroup;
  21. //osg::ref_ptr<osg::> _selectionTransformation;
  22. };
  23. osg::Node* PickHandler::getOrCreateSelectionCylinder() {
  24. if (!_selectionTranslateGroup) {
  25. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  26. geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0.0f, 0.0f, 0.0f), 1.0f, 10.0f)));
  27. _selectionRotateGroup = new osg::MatrixTransform;
  28. _selectionRotateGroup->addChild(geode.get());
  29. _selectionTranslateGroup = new osg::MatrixTransform;
  30. _selectionTranslateGroup->addChild(_selectionRotateGroup.get());
  31. osg::StateSet* ss = _selectionTranslateGroup->getOrCreateStateSet();
  32. ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
  33. ss->setAttributeAndModes(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE));
  34. }
  35. return _selectionTranslateGroup.get();
  36. }
  37. bool PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
  38. if (ea.getEventType() != osgGA::GUIEventAdapter::RELEASE || ea.getButton() != osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON || !(ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_CTRL)) {
  39. return false;
  40. }
  41. osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
  42. if (viewer) {
  43. osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY());
  44. osgUtil::IntersectionVisitor iv(intersector.get());
  45. iv.setTraversalMask(~0x1);
  46. viewer->getCamera()->accept(iv);
  47. if (intersector->containsIntersections()) {
  48. osgUtil::LineSegmentIntersector::Intersection result = *(intersector->getIntersections().begin());
  49. moveTo(result.localIntersectionPoint);
  50. rotateToNormalVector(result.localIntersectionNormal);
  51. }
  52. }
  53. return false;
  54. }
  55. void PickHandler::moveTo(osg::Vec3f position) {
  56. _selectionTranslateGroup->setMatrix(osg::Matrix::translate(position));
  57. }
  58. void PickHandler::rotateToNormalVector(osg::Vec3f normal) {
  59. _selectionRotateGroup->setMatrix(osg::Matrix::rotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normal));
  60. }
  61. int main(int argc, char** argv) {
  62. // Root node of the scene
  63. osg::ref_ptr<osg::Group> root = new osg::Group;
  64. // Create the viewer
  65. osgViewer::Viewer viewer;
  66. viewer.setSceneData(root);
  67. viewer.realize();
  68. // Add axesNode under root
  69. osg::ref_ptr<osg::Node> axesNode = osgDB::readNodeFile("../../testdata/zPlate_0.stl");
  70. if (!axesNode) {
  71. printf("Origin node not loaded, model not found\n");
  72. return 1;
  73. }
  74. root->addChild(axesNode);
  75. // Attach a manipulator (it's usually done for us when we use viewer.run())
  76. osg::ref_ptr<osgGA::TrackballManipulator> tm = new osgGA::TrackballManipulator;
  77. viewer.setCameraManipulator(tm);
  78. osg::ref_ptr<PickHandler> picker = new PickHandler();
  79. root->addChild(picker->getOrCreateSelectionCylinder());
  80. viewer.addEventHandler(picker.get());
  81. return viewer.run();
  82. }