osg 节点操作和代码细节
- #include "stdafx.h"
- #include <osgViewer/Viewer>
- #include <osgDB/ReadFile>
-
- #include <osgUtil\Optimizer>
- #include <osg/Geode>
- #include <osg/Group>
- #include <osg/ShapeDrawable>
- #include <osg/MatrixTransform>
- #include <osg/Node>
- #include <osgGA/GUIEventHandler>
- #include <osgUtil/LineSegmentIntersector>
-
-
- #include <osgFX/Scribe>
-
-
-
- using namespace std;
- #include <iostream>
-
-
-
- #include <osg/Node>
- #include <osg/MatrixTransform>
- //#include <osgQt/GraphicsWindowQt>
- #include <osgGA/TrackballManipulator>
-
- #include <osgViewer/ViewerEventHandlers>
-
- class PrintInfo : public osgGA::GUIEventHandler //模拟一个事件类,响应h
- {
- public:
- bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){
- return false;
- }
- void getUsage(osg::ApplicationUsage& usage) const
- {
- usage.addKeyboardMouseBinding("h","Onscreen help.");
- }
- };
-
-
- //对象选取事件处理器
- 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::PUSH):
- {
- //更新鼠标位置
- _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::LineSegmentIntersector::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;
-
- };
-
- class UseEventHandler : public osgGA::GUIEventHandler
- {
- public:
- ///
- /// \brief 事件处理的关键函数
- /// \param ea 用于识别事件类型
- /// \param aa 控制显示
- /// \return bool
- ///
- virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
- {
- //获取要响应的view
- osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
- if (!viewer) return false;
- //开始判断事件类型
- switch(ea.getEventType())
- {
- case osgGA::GUIEventAdapter::KEYDOWN:
- {
- if (ea.getKey()== 0xFF51)
- {
- viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(0) ;
- viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(1) ;
- }
- if (ea.getKey()== 0xFF53)
- {
- viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(0) ;
- viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(1) ;
- }
- }
- break;
- case osgGA::GUIEventAdapter ::PUSH:
- if(ea.getButton () == 4)
- {
- viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(0) ;
- viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(0) ;
- }
- break;
- case osgGA::GUIEventAdapter::DOUBLECLICK:
- if(ea.getButton() == 1)
- {
- viewer ->getSceneData() ->asGroup() ->getChild(0) ->setNodeMask(1) ;
- viewer ->getSceneData() ->asGroup() ->getChild(1) ->setNodeMask(1) ;
- }
- break;
- default:
- break;
- }
- return false;
- }
-
- };
-
-
- osg::Geode* createShpe();
-
- osg::Vec3 screen2World(osg::Vec3 screenPoint,osgViewer::Viewer* viewer)//将屏幕坐标转换到世界坐标
- {
- osg::Vec3d vec3;
- osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
- osg::Matrix mVPW = camera->getViewMatrix() *
- camera->getProjectionMatrix() *
- camera->getViewport()->computeWindowMatrix();
- osg::Matrix inverseVPW = osg::Matrix::inverse(mVPW);
- osg::Vec3 result=screenPoint *inverseVPW;
- return result;
- }
- osg::Vec3d Vec3dworld2Screen(osg::Vec3 worldPoint,osgViewer::Viewer* viewer)//世界到屏幕
- {
- osg::Vec3d vec3;
- osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
- osg::Matrix mVPW = camera->getViewMatrix() * camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix();
- vec3 = worldPoint * mVPW;
- return vec3;
- }
-
- osg::Vec3d world2Camera(osg::Vec3 worldPoint,osgViewer::Viewer* viewer)//世界转相机
- {
- osg::Vec3d vec3;
- osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
- osg::Matrix mV = camera->getViewMatrix();
- vec3 = worldPoint * mV;
- return vec3;
- }
- osg::Vec3d camera2World(osg::Vec3 cameraPoint,osgViewer::Viewer* viewer)//相机转世界
- {
- osg::Vec3d vec3;
- osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
- //osg::Vec3d vScreen(x,y, 0);
- osg::Matrix mV = camera->getViewMatrix();
- osg::Matrix invertmV;
- invertmV.invert(mV);
- vec3 = cameraPoint * invertmV ;
- return vec3;
- }
- osg::Vec3d screen2Camera(osg::Vec3 screenPoint,osgViewer::Viewer* viewer)//屏幕转相机
- {
- osg::Vec3d vec3;
- osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
- osg::Matrix mPW = camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix();
- osg::Matrix invertmPW;
- invertmPW.invert(mPW);
- vec3 = screenPoint * invertmPW;
- return vec3;
- }
- osg::Vec3d camera2Screen(osg::Vec3 cameraPoint,osgViewer::Viewer* viewer)//相机转屏幕
- {
- osg::Vec3d vec3;
- osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
- //osg::Vec3d vScreen(x,y, 0);
- osg::Matrix mPW = camera->getProjectionMatrix() * camera->getViewport()->computeWindowMatrix();
- vec3 = cameraPoint * mPW;
- return vec3;
- }
-
-
- int main(int argc, char **argv)
- {
- osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
-
- osg::ref_ptr<osg::Group>group = new osg::Group;
- osg::Group* jiedian=(osg::Group*)createShpe();
- group->addChild(jiedian);
- osg::Matrixd matViewInverse = viewer->getCamera()->getViewMatrix();
- cout<<- matViewInverse(1,0)<< " " <<-matViewInverse(1,1) <<" "<<-matViewInverse(1,2)<<endl;
- cout<<- matViewInverse(2,0)<< " " <<-matViewInverse(2,1) <<" "<<-matViewInverse(2,2)<<endl;
- cout<<- matViewInverse(3,0)<< " " <<-matViewInverse(3,1) <<" "<<-matViewInverse(3,2)<<endl;
- osg::Vec3d lookVector(- matViewInverse(2,0),-matViewInverse(2,1),-matViewInverse(2,2));
- osg::Vec3d eyeVector(matViewInverse(3,0),matViewInverse(3,1),matViewInverse(3,2));
- osg::Vec3d pos1,pos2;
- pos1 = eyeVector;
- pos2 = eyeVector+lookVector*5;
- cout<<pos2.x()<< " " <<pos2.y() <<" "<<pos2.z()<<endl;
-
- osg::MatrixTransform* mt = new osg::MatrixTransform;
-
- mt->addChild(jiedian);
- mt->setMatrix(osg::Matrix::translate(pos2)) ; //v表示移动量,是一个Vec3,比如(0, 0, 1)表示向z轴移动一个单位
-
-
- osg::Vec3 haha1=mt->getBound().center();
- osg::Vec3 haha2=jiedian->getBound().center();
- osg::NodePathList nodePAthList1 = jiedian->getParentalNodePaths(0);
-
-
-
- cout<<"------------------------------" <<endl;
- cout<<haha1.x()<< " " <<haha1.y() <<" "<<haha1.z() <<endl;
- cout<<haha2.x()<< " " <<haha2.y() <<" "<<haha2.z() <<endl;
- group->addChild(mt);
-
-
- viewer->setSceneData(group);
- viewer->addEventHandler(new UseEventHandler) ;
-
- viewer->addEventHandler(new PickHandler());
- viewer->addEventHandler(new PrintInfo());
-
- viewer->realize();
- return viewer->run();
- }
- osg::Geode* createShpe()
- {
- //
- osg::Geode *geode = new osg::Geode();
- //半径
- float radius = 0.8f;
- //高度
- float height = 1.6f;
-
- //精细度
- osg::TessellationHints* hints1 = new osg::TessellationHints();
- //设置精细度
- hints1->setDetailRatio(0.5f);
-
- //创建正方体
- osg::Box *box = new osg::Box(osg::Vec3(10.0f, 0.0f, -5.0f), 2 * radius);
- osg::ShapeDrawable *draw1 = new osg::ShapeDrawable(box, hints1);
-
-
- geode->addDrawable(draw1);
-
-
- return geode;
- }