• osg 操作 NodePathList 节点操作


     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. }

  • 相关阅读:
    freertos源码下载和目录结构分析
    【openGauss】如何在openGauss中实现类似Oracle中constructor function、member function的功能
    Unity ToLua热更框架使用教程(1)
    MySQL的安全性
    Powerful number
    PHP代码审计入门-DVWA靶场CSRF篇
    qt中加载qss样式不生效的问题
    2022年上半年中国数字藏品(NFT)市场分析总结
    Java8 JSR310规范-时间日期API使用总结
    Vue:vue-cli中render函数的作用
  • 原文地址:https://blog.csdn.net/vcit102/article/details/127647974