日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

9、osg3.2.1中漫游

發布時間:2023/12/8 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 9、osg3.2.1中漫游 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

效果圖如下:



以下是South.h文件的源碼

//操作器管理類,用來管理操作器 #include <osgViewer/Viewer> #include <osgGA/CameraManipulator> #include <osgUtil/IntersectVisitor> #include <osg/LineSegment> class CSouth:public osgGA::CameraManipulator { public:CSouth(); public:~CSouth(); private://節點值,用來測試碰撞檢測的osg::ref_ptr<osg::Node> m_node;//相機操作器unsigned int m_nID;//移動速度float m_fMoveSpeed;//位置osg::Vec3 m_vPosition;//旋轉角度osg::Vec3 m_vRotation;//左鍵是否按下bool m_bLeftButtonDown;//左鍵點下時屏幕坐標float m_fpushX;//碰撞檢測開啟狀態查詢。bool m_bPeng;//右鍵點下時屏幕坐標float m_fpushY; public://碰撞檢測是否開啟void setPeng(bool peng);//得到碰撞檢測開啟狀態bool getPeng();//如果碰撞檢測開啟則關閉,如果關閉則開啟void setFpeng();//設置要進行碰撞檢測的數據virtual void setNode(osg::Node *);virtual void setByMatrix(const osg::Matrixd& matrix);virtual void setByInverseMatrix(const osg::Matrixd& matrix);virtual osg::Matrixd getMatrix() const;//得到逆矩陣virtual osg::Matrixd getInverseMatrix() const;//主要事件控制器virtual bool handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &us);//屏幕角度float m_fAngle;//位置變換函數void changePostition(osg::Vec3 &delta);//得到當前速度float getSpend();//設置當前速度void setSpend(float);//設置視點位置void setPosition(osg::Vec3 &position);void setPosition(double *);//得到當前視點位置osg::Vec3 getPosition();//計算家的位置void computeHomePosition(); };以下是South.cpp文件的源碼:

#include "stdafx.h" #include "South.h" //設置一些初始值 左鍵沒有按下,左鍵點下時初始坐標為0,初始角速度是2.5,開始時碰撞檢測關閉,右鍵點下時初始坐標也為0 CSouth::CSouth():m_fMoveSpeed(1.5),m_bLeftButtonDown(false),m_fpushX(0),m_fAngle(2.5),m_bPeng(false),m_fpushY(0) {//出生點為000m_vPosition=osg::Vec3(0.0,0.0,5.0);//初始角度m_vRotation=osg::Vec3(osg::PI_2,0.0,0.0); } CSouth::~CSouth() {} //碰撞檢測是否開啟 void CSouth::setPeng(bool peng) {m_bPeng=peng; } //得到碰撞檢測開啟狀態 bool CSouth::getPeng() {return m_bPeng; } //如果碰撞檢測開啟則關閉,如果關閉則開啟 void CSouth::setFpeng() {m_bPeng=!m_bPeng; } //設置要進行碰撞檢測的數據 void CSouth::setNode(osg::Node *node) {m_node=node; } void CSouth::setByMatrix(const osg::Matrixd &matrix) {} void CSouth::setByInverseMatrix(const osg::Matrixd &matrix) {} //得到矩陣,這是標準接口,用于控制場景 osg::Matrixd CSouth::getMatrix() const {//得到旋轉后的矩陣,其實也就是視口矩陣,用此控制場景osg::Matrixd mat;mat.makeRotate(m_vRotation._v[0],osg::Vec3(1.0,0.0,0.0),m_vRotation._v[1],osg::Vec3(0.0,1.0,0.0),m_vRotation._v[2],osg::Vec3(0.0,0.0,1.0));return mat*osg::Matrixd::translate(m_vRotation); } //得到逆矩陣,標準接口,控制場景 osg::Matrixd CSouth::getInverseMatrix() const {osg::Matrixd mat;mat.makeRotate(m_vRotation._v[0],osg::Vec3(1.0,0.0,0.0),m_vRotation._v[1],osg::Vec3(0.0,1.0,0.0),m_vRotation._v[2],osg::Vec3(0.0,0.0,1.0));return osg::Matrixd::inverse(mat*osg::Matrixd::translate(m_vPosition)); } //主要事件控制器 bool CSouth::handle(const osgGA::GUIEventAdapter &ea,osgGA::GUIActionAdapter &us) {//得到x的初始屏幕坐標float mouseX=ea.getX();//得到y的初始屏幕坐標float mouseY=ea.getY();//判斷事件類型switch(ea.getEventType()){case osgGA::GUIEventAdapter::KEYDOWN:{//如果是空格,重繪if (ea.getKey()==0x20){us.requestRedraw();us.requestContinuousUpdate(false);return true;}//如果是home鍵,則視點向上移動if (ea.getKey()==0xFF50){changePostition(osg::Vec3(0,0,m_fMoveSpeed));return true;}//如果是end鍵,同視點向下移動if (ea.getKey()==0xFF57){changePostition(osg::Vec3(0,0,-m_fMoveSpeed));return true;}//如果是加號鍵則加速if (ea.getKey()==0x2B){m_fMoveSpeed+=1.0;return true;}//如果是減號鍵則減速if (ea.getKey()==0x2D){m_fMoveSpeed-=1.0;if (m_fMoveSpeed<1.0){m_fMoveSpeed=1.0;}return true;}//向前走,W鍵,或者UP鍵if (ea.getKey()==0xFF52||ea.getKey()==0x57||ea.getKey()==0x77){changePostition(osg::Vec3(0,m_fMoveSpeed*sinf(osg::PI_2+m_vRotation._v[2]),0));changePostition(osg::Vec3(m_fMoveSpeed*cosf(osg::PI_2+m_vRotation._v[2]),0,0));return true;}//向后退,S鍵,或者DOWN鍵if (ea.getKey()==0xFF54||ea.getKey()==0x53||ea.getKey()==0x73){changePostition(osg::Vec3(0,-m_fMoveSpeed*sinf(osg::PI_2+m_vRotation._v[2]),0));changePostition(osg::Vec3(-m_fMoveSpeed*cosf(osg::PI_2+m_vRotation._v[2]),0,0));return true;}//Aif (ea.getKey()==0x41||ea.getKey()==0x61){changePostition(osg::Vec3(0,m_fMoveSpeed*cosf(osg::PI_2+m_vRotation._v[2]),0));changePostition(osg::Vec3(m_fMoveSpeed*sinf(osg::PI_2+m_vRotation._v[2]),0,0));return true;}//Dif (ea.getKey () == 0x44||ea.getKey () == 0x64) { changePostition(osg::Vec3 (0,-m_fMoveSpeed * cosf(osg::PI_2+m_vRotation._v[2]), 0)) ;changePostition(osg::Vec3 (m_fMoveSpeed * sinf(osg::PI_2+m_vRotation._v[2]), 0, 0)) ; return true; }if (ea.getKey() == 0xFF53)//Right { m_vRotation._v[2] -= osg::DegreesToRadians(m_fAngle); }if (ea.getKey()== 0xFF51)//Left { m_vRotation._v[2] += osg::DegreesToRadians(m_fAngle); }if (ea.getKey() == 0x46 || ea.getKey() == 0x66)//F { computeHomePosition(); m_fAngle -= 0.2 ; return true ; }if (ea.getKey() == 0x47 || ea.getKey() == 0x67)//G { m_fAngle += 0.2 ; return true ; }return false;}case osgGA::GUIEventAdapter::PUSH:if (ea.getButton()==1){//如果是左鍵,記錄下來,因為左鍵拖動時場景也要轉的m_fpushX=mouseX;m_fpushY=mouseY;m_bLeftButtonDown=true;}return false;case osgGA::GUIEventAdapter::DRAG://拖動if (m_bLeftButtonDown){m_vRotation._v[2]-=osg::DegreesToRadians(m_fAngle*(mouseX-m_fpushX));m_vRotation._v[0]+=osg::DegreesToRadians(1.1*(mouseY-mouseY));//防止背過去if (m_vRotation._v[0]>=3.14){m_vRotation._v[0]=3.14;}if (m_vRotation._v[0]<=0){m_vRotation._v[0]=0;}}return false;case osgGA::GUIEventAdapter::RELEASE://鍵彈起if (ea.getButton()==1){m_bLeftButtonDown=false;}return false;default:return false;} } //位置變換函數 void CSouth::changePostition(osg::Vec3 &delta) {if (m_bPeng){//看新值與舊值之間的連線是否與模型有交點!如果要到達的位置與現在的位置有交點的話,如果碰撞檢測也開啟了,就不移動。osg::Vec3 newPos=m_vRotation+delta;osgUtil::IntersectVisitor iv;//前后的線段osg::ref_ptr<osg::LineSegment> line=new osg::LineSegment(newPos,m_vPosition);//上下移動的線段,加入兩條線段來檢測碰撞osg::ref_ptr<osg::LineSegment> lineZ=new osg::LineSegment(newPos+osg::Vec3(0.0,0.0,m_fMoveSpeed),newPos-osg::Vec3(0.0,0.0,m_fMoveSpeed));iv.addLineSegment(lineZ.get());iv.addLineSegment(line.get());//接受碰撞的檢測nodem_node->accept(iv);if(!iv.hits()){//如果沒有碰撞,則移動舊位置到新的位置上m_vPosition+=delta;}}else{//如果碰撞檢測根本沒開,則直接移過去m_vPosition+=delta;} } //得到當前速度 float CSouth::getSpend() {return m_fMoveSpeed; } //設置當前速度 void CSouth::setSpend(float sp) {m_fMoveSpeed=sp; } //設置視點位置 void CSouth::setPosition(osg::Vec3 &position) {m_vPosition=position; } void CSouth::setPosition(double *position) {m_vPosition._v[0]=position[0];m_vPosition._v[1]=position[1];m_vPosition._v[2]=position[2]; } //得到當前視點位置 osg::Vec3 CSouth::getPosition() {return m_vPosition; } //計算家的位置,其實是包圍球的球心處 void CSouth::computeHomePosition() {//如果有模型,則計算包圍球的球心if (m_node.get()){const osg::BoundingSphere &boundingSphere=m_node->getBound();osg::Vec3 bp=boundingSphere._center;setPosition(bp);} }以下是main函數文件的源碼:

// HideModel.cpp : 定義控制臺應用程序的入口點。 // #include "stdafx.h" #include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osg/Node> #include "South.h" int _tmain(int argc, _TCHAR* argv[]) {osgViewer::Viewer viewer;osg::ref_ptr<osg::Group> root=new osg::Group();root->addChild(osgDB::readNodeFile("ceep.ive"));viewer.setSceneData(root.get());viewer.setCameraManipulator(new CSouth());viewer.realize();return viewer.run(); }
以下是ceep.ive文件的下載鏈接: http://pan.baidu.com/s/1kUgdUmV 密碼:umnc

注意:在此的ceep.ive我是放在了data目錄下的,因此不用加路徑


總結

以上是生活随笔為你收集整理的9、osg3.2.1中漫游的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。