当前位置:   article > 正文

osg 操作 NodePathList 节点操作_osg 节点选取 详解

osg 节点选取 详解

 osg 节点操作和代码细节

  1. #include "stdafx.h"
  2. #include <osgViewer/Viewer>
  3. #include <osgDB/ReadFile>
  4. #include <osgUtil\Optimizer>
  5. #include <osg/Geode>
  6. #include <osg/Group>
  7. #include <osg/ShapeDrawable>
  8. #include <osg/MatrixTransform>
  9. #include <osg/Node>
  10. #include <osgGA/GUIEventHandler>
  11. #include <osgUtil/LineSegmentIntersector>
  12. #include <osgFX/Scribe>
  13. using namespace std;
  14. #include <iostream>
  15. #include <osg/Node>
  16. #include <osg/MatrixTransform>
  17. //#include <osgQt/GraphicsWindowQt>
  18. #include <osgGA/TrackballManipulator>
  19. #include <osgViewer/ViewerEventHandlers>
  20. class PrintInfo : public osgGA::GUIEventHandler //模拟一个事件类,响应h
  21. {
  22. public:
  23. bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){
  24. return false;
  25. }
  26. void getUsage(osg::ApplicationUsage& usage) const
  27. {
  28. usage.addKeyboardMouseBinding("h","Onscreen help.");
  29. }
  30. };
  31. //对象选取事件处理器
  32. class PickHandler : public osgGA::GUIEventHandler
  33. {
  34. public:
  35. PickHandler():
  36. _mx(0.0f),
  37. _my(0.0f)
  38. {
  39. //
  40. }
  41. ~PickHandler()
  42. {
  43. //
  44. }
  45. //事件处理函数
  46. bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
  47. {
  48. osg::ref_ptr<osgViewer::View> view = dynamic_cast<osgViewer::View*>(&aa);
  49. if (!view) return false;
  50. switch(ea.getEventType())
  51. {
  52. //鼠标按下
  53. case(osgGA::GUIEventAdapter::PUSH):
  54. {
  55. //更新鼠标位置
  56. _mx = ea.getX();
  57. _my = ea.getY();
  58. pick(view.get(), ea.getX(), ea.getY());
  59. break;
  60. }
  61. case(osgGA::GUIEventAdapter::RELEASE):
  62. {
  63. if (_mx==ea.getX() && _my==ea.getY())
  64. {
  65. //执行对象选取
  66. //pick(view.get(), ea.getX(), ea.getY());
  67. }
  68. break;
  69. }
  70. default:
  71. break;
  72. }
  73. return false;
  74. }
  75. //对象选取事件处理器
  76. void pick(osg::ref_ptr<osgViewer::View> view, float x, float y)
  77. {
  78. osg::ref_ptr<osg::Node> node = new osg::Node();
  79. osg::ref_ptr<osg::Group> parent = new osg::Group();
  80. //创建一个线段交集检测函数
  81. osgUtil::LineSegmentIntersector::Intersections intersections;
  82. if (view->computeIntersections(x, y, intersections))
  83. {
  84. osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin();
  85. osg::NodePath& nodePath = intersection.nodePath;//直接获取相交模型点的节点
  86. //得到选择的物体
  87. node = (nodePath.size()>=1)?nodePath[nodePath.size()-1]:0;
  88. parent = (nodePath.size()>=2)?dynamic_cast<osg::Group*>(nodePath[nodePath.size()-2]):0;
  89. }
  90. //用一种高亮显示来显示物体已经被选中
  91. if (parent.get() && node.get())
  92. {
  93. osg::ref_ptr<osgFX::Scribe> parentAsScribe = dynamic_cast<osgFX::Scribe*>(parent.get());
  94. if (!parentAsScribe)
  95. {
  96. //如果对象选择到,高亮显示
  97. osg::ref_ptr<osgFX::Scribe> scribe = new osgFX::Scribe();
  98. scribe->addChild(node.get());
  99. parent->replaceChild(node.get(),scribe.get());
  100. }
  101. else
  102. {
  103. //如果没有没有选择到,则移除高亮显示的对象
  104. osg::Node::ParentList parentList = parentAsScribe->getParents();
  105. for(osg::Node::ParentList::iterator itr=parentList.begin();
  106. itr!=parentList.end();
  107. ++itr)
  108. {
  109. (*itr)->replaceChild(parentAsScribe.get(),node.get());
  110. }
  111. }
  112. }
  113. }
  114. public:
  115. //得到鼠标的位置
  116. float _mx ;
  117. float _my;
  118. };
  119. class UseEventHandler : public osgGA::GUIEventHandler
  120. {
  121. public:
  122. ///
  123. /// \brief 事件处理的关键函数
  124. /// \param ea 用于识别事件类型
  125. /// \param aa 控制显示
  126. /// \return bool
  127. ///
  128. virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
  129. {
  130. //获取要响应的view
  131. osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
  132. if (!viewer) return false;
  133. //开始判断事件类型
  134. switch(ea.getEventType())
  135. {
  136. case osgGA::GUIEventAdapter::KEYDOWN:
  137. {
  138. if (ea.getKey()== 0xFF51)
  139. {
  140. viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(0) ;
  141. viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(1) ;
  142. }
  143. if (ea.getKey()== 0xFF53)
  144. {
  145. viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(0) ;
  146. viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(1) ;
  147. }
  148. }
  149. break;
  150. case osgGA::GUIEventAdapter ::PUSH:
  151. if(ea.getButton () == 4)
  152. {
  153. viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(0) ;
  154. viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(0) ;
  155. }
  156. break;
  157. case osgGA::GUIEventAdapter::DOUBLECLICK:
  158. if(ea.getButton() == 1)
  159. {
  160. viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(1) ;
  161. viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(1) ;
  162. }
  163. break;
  164. default:
  165. break;
  166. }
  167. return false;
  168. }
  169. };
  170. osg::Geode* createShpe();
  171. osg::Vec3 screen2World(osg::Vec3 screenPoint,osgViewer::Viewer* viewer)//将屏幕坐标转换到世界坐标
  172. {
  173. osg::Vec3d vec3;
  174. osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
  175. osg::Matrix mVPW = camera->getViewMatrix() *
  176. camera->getProjectionMatrix() *
  177. camera->getViewport()->computeWindowMatrix();
  178. osg::Matrix inverseVPW = osg::Matrix::inverse(mVPW);
  179. osg::Vec3 result=screenPoint *inverseVPW;
  180. return result;
  181. }
  182. osg::Vec3d Vec3dworld2Screen(osg::Vec3 worldPoint,osgViewer::Viewer* viewer)//世界到屏幕
  183. {
  184. osg::Vec3d vec3;
  185. osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
  186. osg::Matrix mVPW = camera->getViewMatrix() * camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix();
  187. vec3 = worldPoint * mVPW;
  188. return vec3;
  189. }
  190. osg::Vec3d world2Camera(osg::Vec3 worldPoint,osgViewer::Viewer* viewer)//世界转相机
  191. {
  192. osg::Vec3d vec3;
  193. osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
  194. osg::Matrix mV = camera->getViewMatrix();
  195. vec3 = worldPoint * mV;
  196. return vec3;
  197. }
  198. osg::Vec3d camera2World(osg::Vec3 cameraPoint,osgViewer::Viewer* viewer)//相机转世界
  199. {
  200. osg::Vec3d vec3;
  201. osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
  202. //osg::Vec3d vScreen(x,y, 0);
  203. osg::Matrix mV = camera->getViewMatrix();
  204. osg::Matrix invertmV;
  205. invertmV.invert(mV);
  206. vec3 = cameraPoint * invertmV ;
  207. return vec3;
  208. }
  209. osg::Vec3d screen2Camera(osg::Vec3 screenPoint,osgViewer::Viewer* viewer)//屏幕转相机
  210. {
  211. osg::Vec3d vec3;
  212. osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
  213. osg::Matrix mPW = camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix();
  214. osg::Matrix invertmPW;
  215. invertmPW.invert(mPW);
  216. vec3 = screenPoint * invertmPW;
  217. return vec3;
  218. }
  219. osg::Vec3d camera2Screen(osg::Vec3 cameraPoint,osgViewer::Viewer* viewer)//相机转屏幕
  220. {
  221. osg::Vec3d vec3;
  222. osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
  223. //osg::Vec3d vScreen(x,y, 0);
  224. osg::Matrix mPW = camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix();
  225. vec3 = cameraPoint * mPW;
  226. return vec3;
  227. }
  228. int main(int argc, char **argv)
  229. {
  230. osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
  231. osg::ref_ptr<osg::Group>group = new osg::Group;
  232. osg::Group* jiedian=(osg::Group*)createShpe();
  233. group->addChild(jiedian);
  234. osg::Matrixd matViewInverse = viewer->getCamera()->getViewMatrix();
  235. cout<<- matViewInverse(1,0)<< " " <<-matViewInverse(1,1) <<" "<<-matViewInverse(1,2)<<endl;
  236. cout<<- matViewInverse(2,0)<< " " <<-matViewInverse(2,1) <<" "<<-matViewInverse(2,2)<<endl;
  237. cout<<- matViewInverse(3,0)<< " " <<-matViewInverse(3,1) <<" "<<-matViewInverse(3,2)<<endl;
  238. osg::Vec3d lookVector(- matViewInverse(2,0),-matViewInverse(2,1),-matViewInverse(2,2));
  239. osg::Vec3d eyeVector(matViewInverse(3,0),matViewInverse(3,1),matViewInverse(3,2));
  240. osg::Vec3d pos1,pos2;
  241. pos1 = eyeVector;
  242. pos2 = eyeVector+lookVector*5;
  243. cout<<pos2.x()<< " " <<pos2.y() <<" "<<pos2.z()<<endl;
  244. osg::MatrixTransform* mt = new osg::MatrixTransform;
  245. mt->addChild(jiedian);
  246. mt->setMatrix(osg::Matrix::translate(pos2)) ; //v表示移动量,是一个Vec3,比如(001)表示向z轴移动一个单位
  247. osg::Vec3 haha1=mt->getBound().center();
  248. osg::Vec3 haha2=jiedian->getBound().center();
  249. osg::NodePathList nodePAthList1 = jiedian->getParentalNodePaths(0);
  250. cout<<"------------------------------" <<endl;
  251. cout<<haha1.x()<< " " <<haha1.y() <<" "<<haha1.z() <<endl;
  252. cout<<haha2.x()<< " " <<haha2.y() <<" "<<haha2.z() <<endl;
  253. group->addChild(mt);
  254. viewer->setSceneData(group);
  255. viewer->addEventHandler(new UseEventHandler) ;
  256. viewer->addEventHandler(new PickHandler());
  257. viewer->addEventHandler(new PrintInfo());
  258. viewer->realize();
  259. return viewer->run();
  260. }
  261. osg::Geode* createShpe()
  262. {
  263. //
  264. osg::Geode *geode = new osg::Geode();
  265. //半径
  266. float radius = 0.8f;
  267. //高度
  268. float height = 1.6f;
  269. //精细度
  270. osg::TessellationHints* hints1 = new osg::TessellationHints();
  271. //设置精细度
  272. hints1->setDetailRatio(0.5f);
  273. //创建正方体
  274. osg::Box *box = new osg::Box(osg::Vec3(10.0f, 0.0f, -5.0f), 2 * radius);
  275. osg::ShapeDrawable *draw1 = new osg::ShapeDrawable(box, hints1);
  276. geode->addDrawable(draw1);
  277. return geode;
  278. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/314902
推荐阅读
相关标签
  

闽ICP备14008679号