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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值