OSG拾取对应的实体

以下是所有代码:

[cpp] view plain copy

  1. #include "stdafx.h"
  2. #include <osgDB/ReadFile>
  3. #include <osgViewer/Viewer>
  4. #include <osg/Node>
  5. #include <osgFX/Scribe>
  6. #include <osgGA/GUIEventHandler>
  7. #include <osgUtil/LineSegmentIntersector>
  8. class CPickHandler:public osgGA::GUIEventHandler
  9. {
  10. public:
  11. CPickHandler(osgViewer::Viewer *viewer):mViewer(viewer){}
  12. virtual bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa)
  13. {
  14. switch(ea.getEventType())
  15. {
  16. case osgGA::GUIEventAdapter::PUSH:
  17. if (ea.getButton()==1)
  18. {
  19. Pick(ea.getX(),ea.getY());//可通过事件ea获得鼠标点击的坐标
  20. }
  21. return true;
  22. }
  23. return false;
  24. }
  25. protected:
  26. void Pick(float x,float y)
  27. {
  28. osgUtil::LineSegmentIntersector::Intersections intersections;//声明一个相交测试的结果集
  29. if (mViewer->computeIntersections(x, y, intersections))//利用view的computerIntersection函数来测试屏幕与场景相交结果存入到结果集中
  30. {
  31. osgUtil::LineSegmentIntersector::Intersections::iterator hitr=intersections.begin();
  32. for (;hitr!=intersections.end();hitr++)
  33. {
  34. if (!hitr->nodePath.empty()&&!(hitr->nodePath.back()->getName().empty()))
  35. {
  36. const osg::NodePath& np = hitr ->nodePath ;
  37. for (int i=np.size()-1;i>=0;--i)
  38. {
  39. //将场景中的模型动态转换为Scribe类型,如果场景的模型中有Scribe节点则返回的是实际的模型Scribe对象
  40. osgFX::Scribe *sc=dynamic_cast<osgFX::Scribe*>(np[i]);
  41. if (sc!=NULL)//如果找到相应的sc,则隐藏起来
  42. {
  43. if (sc->getNodeMask()!=0)
  44. {
  45. sc->setNodeMask(0);
  46. }
  47. }
  48. }
  49. }
  50. }
  51. }
  52. }
  53. osgViewer::Viewer *mViewer;
  54. };
  55. int _tmain(int argc, _TCHAR* argv[])
  56. {
  57. osgViewer::Viewer viewer;
  58. osg::ref_ptr<osg::Group> root=new osg::Group();
  59. root->addChild(osgDB::readNodeFile("cessna.osg"));
  60. osg::ref_ptr<osg::Node> cow=osgDB::readNodeFile("cow.osg");
  61. osg::ref_ptr<osgFX::Scribe> sc=new osgFX::Scribe();//添加一个scribe节点,该节点下的模型会被加白描线高亮显示。
  62. sc->addChild(cow.get());//将模型牛加入到scribe节点中,那么加入之后,该牛就会有白边高亮显示
  63. root->addChild(sc.get());//将加白边的模型牛加入到默认的原点位置,默认为原点
  64. root->addChild(cow.get());//将模型牛加入到默认的原点位置,那么此时原模型牛和之前加入的白边牛就会重叠
  65. viewer.setSceneData(root.get());//将root节点加入到场景当中
  66. viewer.addEventHandler(new CPickHandler(&viewer));//为场景加入事件处理功能,并将场景本身传入到事件内部
  67. viewer.realize();
  68. return viewer.run();
  69. }

2、首先在添加模型时,要有一个标示,以便点击鼠标时,通过该标示知道点击的是否是这个模型,在此是加入白边的模型牛,白边对象为Scribe。

[cpp] view plain copy

  1. osg::ref_ptr<osgFX::Scribe> sc=new osgFX::Scribe();//添加一个scribe节点,该节点下的模型会被加白描线高亮显示。
  2. sc->addChild(cow.get());//将模型牛加入到scribe节点中,那么加入之后,该牛就会有白边高亮显示
  3. root->addChild(sc.get());//将加白边的模型牛加入到默认的原点位置,默认为原点

3、创建一个事件对象,并将该对象添加到场景中,那么在场景中就可以通过获取鼠标来做相应的动作。

[cpp] view plain copy

  1. viewer.addEventHandler(new CPickHandler(&viewer));//为场景加入事件处理功能,并将场景本身传入到事件内部

4、在事件对象中有一个虚函数handle,那么在此函数中将处理所有的事件,并在此事件中获取鼠标点击的坐标。

[cpp] view plain copy

  1. virtual bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &aa)

5、获取之后调用Pick函数,并将坐标传入到该函数内。

[cpp] view plain copy

  1. Pick(ea.getX(),ea.getY());//可通过事件ea获得鼠标点击的坐标

6、在该函数内通过computeIntersections函数,然后根据坐标来拾取该鼠标下的模型集合。

[cpp] view plain copy

  1. mViewer->computeIntersections(x, y, intersections)

7、定义一个迭代器。

[cpp] view plain copy

  1. osgUtil::LineSegmentIntersector::Intersections::iterator hitr=intersections.begin();

8、遍历该迭代器。

[cpp] view plain copy

  1. for (;hitr!=intersections.end();hitr++)

9、判断模型的路径以及名称是否为空。

[cpp] view plain copy

  1. !hitr->nodePath.empty()&&!(hitr->nodePath.back()->getName().empty())

10、如果不为空,则遍历该路径下的所有节点。

[cpp] view plain copy

  1. const osg::NodePath& np = hitr ->nodePath ;
  2. for (int i=np.size()-1;i>=0;--i)
  3. {
  4. ............
  5. }

11、将节点动态转换为Scribe指针,如果在节点中存在Scribe对象,则返回的不为NULL,否则为NULL,有节点在第2步加入的,因此有一个模型时不为NULL

[cpp] view plain copy

  1. //将场景中的模型动态转换为Scribe类型,如果场景的模型中有Scribe节点则返回的是实际的模型Scribe对象
  2. osgFX::Scribe *sc=dynamic_cast<osgFX::Scribe*>(np[i]);

12、如果找到了Scribe对象,则判断该对象是否已经隐藏,如果未隐藏,则将该节点隐藏起来。

[cpp] view plain copy

  1. if (sc!=NULL)//如果找到相应的sc,则隐藏起来
  2. {
  3. if (sc->getNodeMask()!=0)
  4. {
  5. sc->setNodeMask(0);
  6. }
  7. }
时间: 2024-10-11 19:05:28

OSG拾取对应的实体的相关文章

OSG开发概览(转载)

OSG开发概览 1 OSG基础知识 Ø OSG是Open Scene Graphic 的缩写,OSG于1997年诞生于以为滑翔机爱好者之手,Don burns  为了对滑翔机的飞行进行模拟,对openGL的库进行了封装,osg的雏形就这样诞生了,1998年Don burns 遇到了同样喜欢滑翔机和计算机图形学的Robert Osfield ,从此Robert Osfield加入了osg小组的开发并一直担任开发小组的组长. Ø OSG不但有openGL的跨平台的特性和较高的渲染性能,还提供了一系列

osg实例介绍

转自:http://blog.csdn.net/yungis/article/list/1 [原]osgmotionblur例子 该例子演示了运动模糊的效果.一下内容是转自网上的:原理:引用内容对于运动画面,将当前帧画面与上一帧画面进行alpha融合,以产生出残影——运动模糊效果.通过使用累积缓存来完成这项工作.OpenGL提供一个累积缓存,可以用来存储当前指定的颜色缓存里面的内容,并进行一定的运算操作.通过函数glAccum可以对累积缓存进行操作. glAccum介绍如下:引用内容void g

osg坦克大战游戏开发过程

一.3D建模 (1)实现方法 3D建模是3D游戏开发中重要的一部分,若没有3D建模的过程而只靠osg内置的基本体,就不会有精致的模型.我们使用了Maya 2014来完成相应的建模工作,得到了我们的游戏中的主体——一辆虎式坦克. (2)实现过程 在建模过程中,我们主要使用了立方体模型,通过大量的挤压命令,产生棱角分明的装甲.而最为复杂的履带则是通过建立运动路径并在路径上克隆单一履带单元来完成的. (3)效果展示 二.纹理映射 (1)实现方法 在游戏中,我们需要将地图铺上贴图,以此来分辨角色是否在移

OSG中的示例程序简介

OSG中的示例程序简介 转自:http://www.cnblogs.com/indif/archive/2011/05/13/2045136.html 1.example_osganimate一)演示了路径动画的使用(AnimationPath.AnimationPathCallback),路径动画回调可以作用在Camera.CameraView.MatrixTransform.PositionAttitudeTransform等四种类型的节点上.二)演示了osgSim::OverlayNode

转:关于 OGRE 与 OSG 的简单比较

1   前言 我曾经细致阅读过 OGRE 和 OSG 官方提供的文档,有<Pro OGRE 3D Programming>.OGRE自带手册(manual).王锐老师等翻译的<OpenSceneGraph  Quick  Guide>,同时在网络上查阅了大量的 OGRE 架构源码分析的文章.简单使用过 OSG,对 OSG 的场景管理器设计和编程风格有所了解,而在近期的项目中大量使用 OGRE,相对于 OSG,对 OGRE 的认识比较深刻一些.目前 OGRE 的最新版本是 1.7,O

关于OGRE与OSG的简单比较【转】

关于OGRE与OSG的简单比较 林乃养 lnychina{at}gmail.com 浙江大学CAD&CG实验室 2010年3月27日 1 前言 我曾经细致阅读过OGRE和OSG官方提供的文档,有<Pro OGRE 3D Programming>.OGRE自带手册(manual).王锐老师等翻译的<OpenSceneGraph Quick Guide>,同时在网络上查阅了大量的OGRE架构源码分析的文章.简单使用过OSG,对OSG的场景管理器设计和编程风格有所了解,而在近期的

OSG学习过程中的笔记

1.osg库: Notify:osg库提供了一系列的控制调试,警告和错误输出的函数.用户可以通过指定一个来自notifyseveritu枚举量的数值,设定输出的信息量. osg::Camera    为视口添加camera的类.用于显示. 2.交运算osgUtil库: 通过提供大量用于场景图形交运算,使用如下类可以获得场景图形中被拾取部分的信息: Intersector:纯虚类,定义了相交测试的接口.执行相交测试时,应用程序将继承自intersector的某个类实例化,传递给intersecti

WebGL——osg框架学习一

从今天开始,我们开始正式的学习osg框架,今天我们学习的是osg的渲染模块,我们来看一下代码结构. 所有DrawXXX的js模块都是渲染的模块,我们逐一来简单介绍一下,第一个Drawable.js,这个模块是描述可绘制对象的类,也是我们今天要讨论的类.在osg框架中,渲染管道在准备时期首先要统计管理可绘制对象,我们来看看Drawable模块到底做了什么操作,进行了哪些管理.先贴出代码. /* 可绘制对象 */ let StateBin = require('./StateBin'); let B

Learning OSG programing---osgShape

本例示范了osg中Shape ---- 基本几何元素的绘制过程.参照osg官方文档,Shape 类包含以下子类: 在示例程序中,函数createShapes函数用于生成需要绘制的几何形状. 1 osg::Geode* createShapes(osg::ArgumentParser& arguments) 2 { 3 osg::Geode* geode = new osg::Geode(); 4 5 6 // --------------------------------------- 7 /