点选主要是重载osg的GUIEventHandler,

 class CPickHandler : public osgGA::GUIEventHandler{   //自定义回调函数名:CPickHandler
osgViewer::Viewer * mViewer; //在这里定义要在重载函数里使用的变量
osg::Group * mGroup;
osg::Node * lastSelect;
osg::Node * replacedNode;
int replaceNum;
public:
CPickHandler(osgViewer::Viewer * viewer, osg::Group *group) :mViewer(viewer),mGroup(group),lastSelect(),replacedNode(){} //声明回调函数,括号中是回调函数需要传入的参数,冒号后的内容是给函数内自定义的变量初始化,前面是变量名,括 号内是初始化值。
virtual bool handle(const osgGA::GUIEventAdapter & ea, osgGA::GUIActionAdapter & aa){
switch(ea.getEventType()){
case(osgGA::GUIEventAdapter::PUSH):{
if(lastSelect){
lastSelect = ;
}
Pick(ea.getX(),ea.getY()); //ea即鼠标点击的地方,ea.getX(),ea.getY(),是获得鼠标点击的屏幕坐标。
}
return true;
}
return false;
} protected:
void Pick(float x, float y){}//在pick()函数里传入了鼠标点击的屏幕坐标,然后可以根据屏幕坐标写你想要点击完成的动作。
}

其中需要注意的是,OSG中有多个坐标系,我们通过鼠标点击获得的只是屏幕坐标,我们往往需要在场景中添加东西时,都需要得到某个点的世界坐标才能比较好操作:

但是在我们知道是哪个节点的情况下,我们可以根据:

geode->getBound().center() * osg::computeLocalToWorld(geode->getParentalNodePaths()[])

来获得节点geode的世界坐标。

我的项目的3维模型是由Obj格式导出的ive和osg文件,原始的obj模型是用sketchup做的,在制作的时候把几个模型创建组的时候会给每个模型单独的命名,而在osg中可以通过->getName()获得这些名字,我可以通过用文本浏览器notePad++打开模型的obj文件来查看这些名字,这些名字的命名都是g mash开头的,为了方便,我把每个模型的各个部分的命名改成相同的,用python很好解决这个问题。

那么我的pick函数是这样的:

 void Pick(float x, float y){
osgUtil::LineSegmentIntersector::Intersections intersections; if(mViewer->computeIntersections(x, y, intersections)){
osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin();
for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin(); hitr!= intersections.end(); ++hitr){
if(!hitr->nodePath.empty() && !(hitr->nodePath.back()->getName().empty())){
const osg::NodePath& np = hitr->nodePath; for(int i = np.size() - ; i >= ; --i){ //遍历选中的节点
osg::Node* nd = dynamic_cast<osg::Node *> (np[i]);
if(nd){
if(nd->getName()=="pipelineTeam1"){ //根据模型的名字判断是否选中了某个模型
/*
在这儿写对该模型做的操作
*/
}
return;
}
}
}
}
}

但是,这只是写好了一个回调函数,最后需要在osg控制类(我的是OSG_MFC.cpp)中的void cOSG::InitCameraConfig(void){}函数中加上一句:

mViewer->addEventHandler(new CPickHandler(mViewer, mRoot));  //要把指针转为引用 ,因为mViewer定义的时候是 osgViewer::Viewer* mViewer;现在要使用&mViewer

那么在我们点击屏幕某点的时候,就会自动调用回调函数中的pick()函数,进行其中的操作。

我的项目在pick()回调中,做到了在选中节点的位置添加一个Geometry,在Geometry上显示文字消息,并给选中的模型加上选中效果,可以做成高亮显示和加上高亮的(自定义颜色)的边框,这些会在下一篇文章中介绍。

osg项目经验1<MFC+OSG中模型点选效果>的更多相关文章

  1. OSG项目经验2<在场景中添加文字面版>

    添加文字版需要用到osg的三个名字空间:                         osgText::Text,这个类用来添加文字和设置文字的一些属性:                     ...

  2. 如何在面试中介绍自己的项目经验(面向java改进版)

    本人于3年前写的博文,如何在面试中介绍自己的项目经验,经过大家的捧场,陆续得到了将近7万个点击量,也得到了众多网站公众号的转载,不过自己感觉,这篇文章更多的是偏重于方法,没有具体给到Java方面相关的 ...

  3. 《项目经验》--通过js获取前台数据向一般处理程序传递Json数据,并解析Json数据,将前台传来的Json数据写入数据库表中

      先看一下我要实现的功能界面:   这个界面的功能在图中已有展现,课程分配(教师教授哪门课程)在之前的页面中已做好.这个页面主要实现的是授课,即给老师教授的课程分配学生.此页面实现功能的步骤已在页面 ...

  4. 从面试官甄别项目经验的角度,说说如何在简历中写项目经验(java后端方向)

    在大多的JD(职位介绍)里,会写明该职位需要xx时间的相关经验,换句话说就是需要在简历中看到一定年限的相关商业项目经验,否则估计连面试的机会都没. 在本文里,不讨论这种门槛是否合理,而会以Java相关 ...

  5. java程序员面试交流项目经验

    粘贴自:https://blog.csdn.net/wangyuxuan_java/article/details/8778211 1:请你介绍一下你自己 这是面试官常问的问题.一般人回答这个问题过于 ...

  6. 转:java项目经验面试总结

    转载: 在前期已经讲过怎样分析自己,对自己进行一个准确的定位,选择一个合适的求职方向!并结合自己的实际个人情况来写一份针对性很强的个人简历!个人简历就是个人的广告!好的简历可以更受到用人需求单位青睐! ...

  7. 《MFC dialog中加入OpenGL窗体》

    <MFC dialog中加入OpenGL窗体> 最近学习了如何在MFC对话框程序中加入OpenGL窗体的方法,在这里将自己的实现过程归纳一下. 步骤零: 加入PictureControl控 ...

  8. 【Java EE 学习 70 下】【数据采集系统第二天】【Action中User注入】【设计调查页面】【Action中模型赋值问题】【编辑调查】

    一.Action中User注入问题 Action中可能会经常用到已经登陆的User对象,如果每次都从Session中拿会显得非常繁琐.可以想一种方法,当Action想要获取User对象的时候直接使用, ...

  9. MFC对话框中使用CHtmlEditCtrl

    MFC对话框中使用CHtmlEditCtrl 感谢原帖作者: http://blog.csdn.net/tingya/article/details/2028172 我在VS2008校正了一些代码. ...

随机推荐

  1. 为Spring添加REST功能

    1 关于REST 我的理解,REST就是将资源以最合适的形式在服务端和客户端之间传递. 系统中资源采用URL进行标识(可以理解为URL路径中带参数) 使用HTTP方法进行资源的管理(GET,PUT,P ...

  2. Triangle LOVE(拓扑排序)

    Triangle LOVE Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/65536K (Java/Other) Total ...

  3. openstack之horizon源码分析

    一.基础准备: Horizon是基于django webframework开发的标准的Python wsgi程序,django的设计专注于代码的高度可重用,信奉DRY原则,一切面向对象,而Horizo ...

  4. ajax 实例

    jsp页面代码: <script type="text/javascript"> var xmlHttp; function createXMLHttp(){ if(w ...

  5. C++虚基类的作用

    虚基类的作用     当一个基类被声明为虚基类后,即使它成为了多继承链路上的公共基类,最后的派生类中也只有它的一个备份.例如:class CBase { }:class CDerive1:virtua ...

  6. Python核心编程读笔 12:OOP

    第13章 面向对象编程 一.基本概念 1.object类是所有类的基类,如果你的类没有继承任何其他父类,object 将作为默认的父类. 2.python创建实例时无需new: myFirstObje ...

  7. C++中的函数指针和指针函数

    C++中的函数指针和指针函数       数组名一般可以被当成指向数组第一个元素的常量指针,同样的情况,在函数中,函数名可以本当成指向函数的常量指针,假如一个函数已经定义,那么它在计算机中一定有特定的 ...

  8. 字节数转换为b,kb,mb,gb的方法 通用的手机流量计算方法

    //通用的手机流量计算方法 private String byteToMB(long size){ long kb = 1024; long mb = kb*1024; long gb = mb*10 ...

  9. hdu 4512 吉哥系列故事——完美队形I LCIS

    题目链接 给一个数列, 在里面选出一些数组成一个对称的数列, 数的顺序不能打乱. 使得左半边是一个严格递增的数列, 右边递减, 并且a[i] = a[n-i+1]. 就是一个对称的LCIS.. #in ...

  10. 【转】 UIButton上使用UIEdgeInsetsMaketitle跟图片对齐

    [转]http://blog.csdn.net/yanxiaoqing/article/details/7230660 默认情况下,不设置的效果,都使居中现实,button为150*150 使用以下设 ...