#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;
}
osg基本操作
最新推荐文章于 2024-04-24 14:13:53 发布