|
- #include <osgViewer/Viewer>
- #include <osgViewer/ViewerEventHandlers>
- #include <osg/Node>
- #include <osg/Geode>
- #include <osg/Group>
- #include <osgDB/ReadFile>
- #include <osgDB/WriteFile>
- #include <osgFX/Scribe>
- #include <osgGA/GUIEventHandler>
- #include <osgUtil/Optimizer>
- #include <iostream>
- //对象选取事件处理器
- class PickHandler : public osgGA::GUIEventHandler
- {
- public:
- PickHandler():
- _mx(0.0f),
- _my(0.0f)
- {
- //
- }
- ~PickHandler()
- {
- //
- }
- //事件处理函数
- bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
- {
- osg::ref_ptr<osgViewer::View> view = dynamic_cast<osgViewer::View*>(&aa);
- if (!view) return false;
- switch(ea.getEventType())
- {
- //鼠标按下
- case(osgGA::GUIEventAdapter:USH):
- {
- //更新鼠标位置
- _mx = ea.getX();
- _my = ea.getY();
- pick(view.get(), ea.getX(), ea.getY());
- break;
- }
- case(osgGA::GUIEventAdapter::RELEASE):
- {
- if (_mx==ea.getX() && _my==ea.getY())
- {
- //执行对象选取
- //pick(view.get(), ea.getX(), ea.getY());
- }
- break;
- }
- default:
- break;
- }
- return false;
- }
- //对象选取事件处理器
- void pick(osg::ref_ptr<osgViewer::View> view, float x, float y)
- {
- osg::ref_ptr<osg::Node> node = new osg::Node();
- osg::ref_ptr<osg::Group> parent = new osg::Group();
- //创建一个线段交集检测函数
- osgUtil:ineSegmentIntersector::Intersections intersections;
- if (view->computeIntersections(x, y, intersections))
- {
- osgUtil::LineSegmentIntersector::Intersection intersection = *intersections.begin();
- osg::NodePath& nodePath = intersection.nodePath;
- //得到选择的物体
- node = (nodePath.size()>=1)?nodePath[nodePath.size()-1]:0;
- parent = (nodePath.size()>=2)?dynamic_cast<osg::Group*>(nodePath[nodePath.size()-2]):0;
- }
- //用一种高亮显示来显示物体已经被选中
- if (parent.get() && node.get())
- {
- osg::ref_ptr<osgFX::Scribe> parentAsScribe = dynamic_cast<osgFX::Scribe*>(parent.get());
- if (!parentAsScribe)
- {
- //如果对象选择到,高亮显示
- osg::ref_ptr<osgFX::Scribe> scribe = new osgFX::Scribe();
- scribe->addChild(node.get());
- parent->replaceChild(node.get(),scribe.get());
- }
- else
- {
- //如果没有没有选择到,则移除高亮显示的对象
- osg::Node::ParentList parentList = parentAsScribe->getParents();
- for(osg::Node::ParentList::iterator itr=parentList.begin();
- itr!=parentList.end();
- ++itr)
- {
- (*itr)->replaceChild(parentAsScribe.get(),node.get());
- }
- }
- }
- }
- public:
- //得到鼠标的位置
- float _mx ;
- float _my;
- };
- int main()
- {
- //创建Viewer对象,场景浏览器
- osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
- viewer->addEventHandler(new PickHandler());
- //创建场景组节点
- osg::ref_ptr<osg::Group> root = new osg::Group();
- //创建一个节点,读取牛的模型
- osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
- //添加到场景
- root->addChild(node.get());
- //优化场景数据
- osgUtil::Optimizer optimizer ;
- optimizer.optimize(root.get()) ;
- viewer->setSceneData(root.get());
- viewer->realize();
- viewer->run();
- return 0 ;
- }
这段程序是用来实现对象选取的,点一下牛就给个白边包上,再点一下就消失了,是从编程指南那本书上copy来的。
然后我把那个PickHandler类加到MFC的例子里,然后在它的InitCameraConfig函数中把这个事件加到viewer中。- void cOSG::InitCameraConfig(void)
- {
- // Local Variable to hold window size data
- RECT rect;
- // Create the viewer for this window
- mViewer = new osgViewer::Viewer();
- // Add a Stats Handler to the viewer
- mViewer->addEventHandler(new osgViewer::StatsHandler);
- mViewer->addEventHandler(new PickHandler); // 这行是我加的
- .....
- }
程序编译,运行,正常,然后打开模型,就出错。
这是怎么回事?
不过在我另一个MFC程序里,打开模型不出错,选中物体时会出错。这个MFC不过是我自己向导建的,然后把例子的代码原封不动的搬过来,添加了一些功能而已。。。。真是奇怪。
还有。。。。自带的MFC程序有内在泄露?我在debug模式退出的时候,vs2005会提示内在泄露。而我自己向导创建的多文档,然后把它的代码都移植过来的确没有。 |
|