transforms.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. #include <vector>
  13. class TrackPoint {
  14. public:
  15. TrackPoint(osg::Vec3 point, osg::Vec3 normal);
  16. osg::ref_ptr<osg::MatrixTransform> getUppermostRoot();
  17. protected:
  18. osg::ref_ptr<osg::MatrixTransform> _translationGroup;
  19. osg::ref_ptr<osg::MatrixTransform> _rotationGroup;
  20. private:
  21. osg::Vec3 point;
  22. osg::Vec3 normal;
  23. };
  24. TrackPoint::TrackPoint(osg::Vec3 point, osg::Vec3 normal) {
  25. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  26. osg::ref_ptr<osg::ShapeDrawable> cylinder = new osg::ShapeDrawable();
  27. cylinder->setShape(new osg::Cylinder(osg::Vec3(0.0f, 0.0f, 0.0f), 1.0f, 10.0f));
  28. cylinder->setColor(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
  29. geode->addDrawable(cylinder.get());
  30. _rotationGroup = new osg::MatrixTransform;
  31. _rotationGroup->addChild(geode.get());
  32. _rotationGroup->setMatrix(osg::Matrix::rotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normal));
  33. _translationGroup = new osg::MatrixTransform;
  34. _translationGroup->addChild(_rotationGroup.get());
  35. _translationGroup->setMatrix(osg::Matrix::translate(point));
  36. }
  37. osg::ref_ptr<osg::MatrixTransform> TrackPoint::getUppermostRoot() {
  38. return _translationGroup.get();
  39. }
  40. class StoreHandler {
  41. public:
  42. void addTrackingPoint(osg::Vec3 point, osg::Vec3 normal);
  43. StoreHandler(osg::ref_ptr<osg::Group> root);
  44. protected:
  45. std::vector<TrackPoint*> points;
  46. private:
  47. osg::ref_ptr<osg::Group> _root;
  48. };
  49. void StoreHandler::addTrackingPoint(osg::Vec3 point, osg::Vec3 normal) {
  50. TrackPoint* trackPoint = new TrackPoint(point, normal);
  51. points.push_back(trackPoint);
  52. _root->addChild(trackPoint->getUppermostRoot());
  53. }
  54. StoreHandler::StoreHandler(osg::ref_ptr<osg::Group> root) {
  55. _root = root;
  56. }
  57. StoreHandler* storeHandler;
  58. class PickHandler: public osgGA::GUIEventHandler {
  59. public:
  60. osg::Node* getOrCreateSelectionCylinder();
  61. virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
  62. void moveTo(osg::Vec3f position);
  63. void rotateToNormalVector(osg::Vec3f normal);
  64. protected:
  65. osg::ref_ptr<osg::MatrixTransform> _selectionTranslateGroup;
  66. osg::ref_ptr<osg::MatrixTransform> _selectionRotateGroup;
  67. };
  68. osg::Node* PickHandler::getOrCreateSelectionCylinder() {
  69. if (!_selectionTranslateGroup) {
  70. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  71. osg::ref_ptr<osg::ShapeDrawable> cylinder = new osg::ShapeDrawable();
  72. cylinder->setShape(new osg::Cylinder(osg::Vec3(0.0f, 0.0f, 0.0f), 1.0f, 10.0f));
  73. cylinder->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 0.2f));
  74. geode->addDrawable(cylinder.get());
  75. _selectionRotateGroup = new osg::MatrixTransform;
  76. _selectionRotateGroup->addChild(geode.get());
  77. _selectionTranslateGroup = new osg::MatrixTransform;
  78. _selectionTranslateGroup->addChild(_selectionRotateGroup.get());
  79. }
  80. return _selectionTranslateGroup.get();
  81. }
  82. bool PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) {
  83. if (ea.getEventType() != osgGA::GUIEventAdapter::RELEASE || ea.getButton() != osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON || !(ea.getModKeyMask()&osgGA::GUIEventAdapter::MODKEY_CTRL)) {
  84. return false;
  85. }
  86. osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
  87. if (viewer) {
  88. osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, ea.getX(), ea.getY());
  89. osgUtil::IntersectionVisitor iv(intersector.get());
  90. iv.setTraversalMask(~0x1);
  91. viewer->getCamera()->accept(iv);
  92. if (intersector->containsIntersections()) {
  93. osgUtil::LineSegmentIntersector::Intersection result = *(intersector->getIntersections().begin());
  94. moveTo(result.localIntersectionPoint);
  95. rotateToNormalVector(result.localIntersectionNormal);
  96. storeHandler->addTrackingPoint(result.localIntersectionPoint, result.localIntersectionNormal);
  97. }
  98. }
  99. return false;
  100. }
  101. void PickHandler::moveTo(osg::Vec3f position) {
  102. _selectionTranslateGroup->setMatrix(osg::Matrix::translate(position));
  103. }
  104. void PickHandler::rotateToNormalVector(osg::Vec3f normal) {
  105. _selectionRotateGroup->setMatrix(osg::Matrix::rotate(osg::Vec3f(0.0f, 0.0f, 1.0f), normal));
  106. }
  107. int main(int argc, char** argv) {
  108. // Root node of the scene
  109. osg::ref_ptr<osg::Group> root = new osg::Group;
  110. // Create the viewer
  111. osgViewer::Viewer viewer;
  112. viewer.setSceneData(root);
  113. viewer.realize();
  114. // Add axesNode under root
  115. osg::ref_ptr<osg::Node> axesNode = osgDB::readNodeFile("../../testdata/zPlate_0.stl");
  116. if (!axesNode) {
  117. printf("Origin node not loaded, model not found\n");
  118. return 1;
  119. }
  120. root->addChild(axesNode);
  121. // Attach a manipulator (it's usually done for us when we use viewer.run())
  122. osg::ref_ptr<osgGA::TrackballManipulator> tm = new osgGA::TrackballManipulator;
  123. viewer.setCameraManipulator(tm);
  124. storeHandler = new StoreHandler(root);
  125. osg::ref_ptr<PickHandler> picker = new PickHandler();
  126. root->addChild(picker->getOrCreateSelectionCylinder());
  127. viewer.addEventHandler(picker.get());
  128. return viewer.run();
  129. }