OSG相机漫游
實(shí)現(xiàn)功能
自定義相機(jī)的位置位于世界坐標(biāo)系下的Y軸正方向斜向下45度觀察水平面。通過按鍵實(shí)現(xiàn)向前(按W)向后(按S)向左(按A)向右(按D)向上(按PageUp)向下(按PageDown)相機(jī)左右旋轉(zhuǎn)(J/L)、相機(jī)上下旋轉(zhuǎn)(I/K)觀察效果如圖:
基礎(chǔ)知識(shí)
實(shí)現(xiàn)相機(jī)我們所要用到的知識(shí)點(diǎn)有1.向量,矩陣,四元素等概念2.OSG坐標(biāo)系統(tǒng)的知識(shí)。3.視圖與相機(jī), 鍵盤事件消息處理的相關(guān)知識(shí)。最重要的需要自己的空間思維能力,如果對(duì)以上的知識(shí)點(diǎn)不熟悉的話,可以去相關(guān)的網(wǎng)站看看。實(shí)現(xiàn)原理
一.新建一個(gè)類共有繼承 osgGA::CameraManipulator,并且重寫四個(gè)虛函數(shù),具體的代碼需要根據(jù)要求來進(jìn)行編寫。1.virtual void setByMatrix(const osg::Matrixd& matrix);2.virtual void setByInverseMatrix(const osg::Matrixd& matrix) ;3.virtual osg::Matrixd getMatrix() const ;4.virtual osg::Matrixd getInverseMatrix() const ;二.進(jìn)行鍵盤事件處理我們需要重寫handle函數(shù)1.virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us) ;代碼實(shí)現(xiàn)
.h文件
class TraveManipulator :public osgGA::CameraManipulator { public://構(gòu)造函數(shù)TraveManipulator(osg::ref_ptr<osg::Node> node1);//析構(gòu)函數(shù)~TraveManipulator();//設(shè)置矩陣virtual void setByMatrix(const osg::Matrixd& matrix);//設(shè)置逆矩陣virtual void setByInverseMatrix(const osg::Matrixd& matrix) ;//得到矩陣virtual osg::Matrixd getMatrix() const ;//得到逆矩陣virtual osg::Matrixd getInverseMatrix() const ;//鍵盤事件處理函數(shù)virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us) ; private://視點(diǎn)位置osg::Vec3d m_Eye;//參照物中心osg::Vec3d m_Center;//方向向量osg::Vec3d m_Up;//距離double m_Distense;//移動(dòng)步長float m_Step;//旋轉(zhuǎn)矩陣osg::Matrix m_RotationMatrix;//相機(jī)上下旋轉(zhuǎn)的繞軸osg::Vec3 m_CameraRotation; };.cpp文件
TraveManipulator::TraveManipulator(osg::ref_ptr<osg::Node> node1) :m_Distense(4000.0), m_Step(30) {//保存物體的中心點(diǎn)osg::Vec3d node_Center = node1->getBound().center();osg::Matrix rotation_Anngle;//繞x軸旋轉(zhuǎn)45°rotation_Anngle = osg::Matrix::rotate(osg::Quat(-osg::PI_4,osg::Vec3f(1.0f, 0.0f, 0.0f)));//設(shè)置視點(diǎn)的位置,m_Eye = osg::Vec3d(0.0, 0.0, m_Distense);//設(shè)置中心點(diǎn)的位置m_Center = node_Center;//up向量m_Up = osg::Vec3d(0.0,- 1.0, 0.0);//視點(diǎn)位于Y軸的正方向斜向上45°m_Eye = m_Eye * rotation_Anngle;m_Up = m_Up * rotation_Anngle;m_CameraRotation = osg::Vec3(1.0f,0.0f,0.0f); } TraveManipulator::~TraveManipulator() { // } //設(shè)置矩陣 void TraveManipulator::setByMatrix(const osg::Matrixd& matrix) {// } //設(shè)置逆矩陣 void TraveManipulator::setByInverseMatrix(const osg::Matrixd& matrix) {// } //得到矩陣,用于控制場景 osg::Matrixd TraveManipulator::getMatrix() const {return osg::Matrixd(); } //得到逆矩陣 osg::Matrixd TraveManipulator::getInverseMatrix() const {return osg::Matrixd::lookAt(m_Eye,m_Center,m_Up); } //鍵盤事件處理函數(shù) bool TraveManipulator::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us) {//獲取事件switch (ea.getEventType()){//如果是一個(gè)鍵盤事件case osgGA::GUIEventAdapter::KEYDOWN:{//向前移動(dòng)(按W)if(ea.getKey() == 'w' || ea.getKey() == 'W'){m_Eye = m_Eye * osg::Matrix::translate(osg::Vec3(0.0,m_Step,0.0) * m_RotationMatrix);m_Center = m_Center * osg::Matrix::translate(osg::Vec3(0.0,m_Step,0.0) * m_RotationMatrix);} //向后移動(dòng)(按s)else if (ea.getKey() == 's' || ea.getKey() == 'S'){m_Eye = m_Eye * osg::Matrix::translate(osg::Vec3(0.0,-m_Step,0.0) * m_RotationMatrix);m_Center = m_Center * osg::Matrix::translate(osg::Vec3(0.0,-m_Step,0.0) * m_RotationMatrix);}//向左移動(dòng)(按a)else if (ea.getKey() == 'a' || ea.getKey() == 'A'){m_Eye = m_Eye * osg::Matrix::translate(osg::Vec3(-m_Step,0.0,0.0) * m_RotationMatrix);m_Center = m_Center * osg::Matrix::translate(osg::Vec3(-m_Step,0.0,0.0) * m_RotationMatrix);}//向右移動(dòng)(按d)else if (ea.getKey() == 'd' || ea.getKey() == 'D'){m_Eye = m_Eye * osg::Matrix::translate(osg::Vec3(m_Step,0.0,0.0) * m_RotationMatrix);m_Center = m_Center * osg::Matrix::translate(osg::Vec3(m_Step,0.0,0.0) * m_RotationMatrix);}//向上移動(dòng)(按Page UP)else if (ea.getKey() == 0XFF55){m_Eye = m_Eye * osg::Matrix::translate(osg::Vec3(m_Step,0.0,0.0) * m_RotationMatrix)*osg::Matrix::translate(osg::Vec3(0.0,m_Step,0.0) * m_RotationMatrix)*osg::Matrix::translate(osg::Vec3(0.0,0.0, m_Step) * m_RotationMatrix)*osg::Matrix::translate(osg::Vec3(-m_Step,0.0,0.0)* m_RotationMatrix);}//向下移動(dòng)(按Page Down)else if (ea.getKey() == 0xFF56){m_Eye = m_Eye * osg::Matrix::translate(osg::Vec3(m_Step,0.0,0.0) * m_RotationMatrix)*osg::Matrix::translate(osg::Vec3(0.0,-m_Step,0.0) * m_RotationMatrix)*osg::Matrix::translate(osg::Vec3(0.0,0.0,-m_Step) * m_RotationMatrix)*osg::Matrix::translate(osg::Vec3(-m_Step,0.0,0.0) * m_RotationMatrix);} //相機(jī)向左旋轉(zhuǎn)else if (ea.getKey() == 'j' || ea.getKey() == 'J'){osg::Matrix mt; //設(shè)置旋轉(zhuǎn)軸mt = osg::Matrixd::rotate(-osg::DegreesToRadians(15.0),osg::Vec3(0.0f,0.0f,1.0f));m_CameraRotation = m_CameraRotation * mt;m_RotationMatrix = m_RotationMatrix * mt ;m_Eye = m_Eye * mt;m_Up = m_Up * mt;m_Center = m_Center * mt;}//相機(jī)向右旋轉(zhuǎn)else if (ea.getKey() == 'l' || ea.getKey() == 'L'){osg::Matrix mt;//設(shè)置旋轉(zhuǎn)軸mt = osg::Matrixd::rotate(osg::DegreesToRadians(15.0),osg::Vec3(0.0f,0.0f,1.0f));m_CameraRotation = m_CameraRotation * mt;m_RotationMatrix = m_RotationMatrix * mt;m_Eye = m_Eye * mt;m_Up = m_Up * mt;m_Center = m_Center * mt;}//相機(jī)向上旋轉(zhuǎn)else if (ea.getKey() == 'i' || ea.getKey() == 'I'){osg::Matrix mt;//設(shè)置旋轉(zhuǎn)軸mt = osg::Matrix::rotate(osg::DegreesToRadians(15.0),m_CameraRotation);m_RotationMatrix = m_RotationMatrix* mt;m_Eye = m_Eye * osg::Matrix::rotate(osg::DegreesToRadians(15.0),m_CameraRotation);m_Up = m_Up * osg::Matrix::rotate(osg::DegreesToRadians(15.0),m_CameraRotation);m_Center = m_Center * osg::Matrix::rotate(osg::DegreesToRadians(15.0),m_CameraRotation);}//相機(jī)向下旋轉(zhuǎn)else if (ea.getKey() == 'k' || ea.getKey() == 'K'){osg::Matrix mt;//設(shè)置旋轉(zhuǎn)矩陣mt = osg::Matrix::rotate(-osg::DegreesToRadians(15.0),m_CameraRotation);m_RotationMatrix = m_RotationMatrix * mt;m_Eye = m_Eye * osg::Matrix::rotate(-osg::DegreesToRadians(15.0),m_CameraRotation);m_Up = m_Up * osg::Matrix::rotate(-osg::DegreesToRadians(15.0),m_CameraRotation);m_Center = m_Center * osg::Matrix::rotate(-osg::DegreesToRadians(15.0),m_CameraRotation);}}default:break;return false;}return false; }main.cpp文件
#include "Trave.h" #include "Setup.h" int main() {osg::ref_ptr<osgViewer::Viewer>viewer = new osgViewer::Viewer();osg::ref_ptr<osg::Group> root = new osg::Group();Changeport a(viewer);a.changeport();osg::ref_ptr<osg::Node> node = a.createNode();root->addChild(a.createTexture2DState(node));//添加漫游器viewer->setCameraManipulator(new TraveManipulator(node));osgUtil::Optimizer optimizer;optimizer.optimize(root.get());//設(shè)置場景數(shù)據(jù)viewer->setSceneData(root.get());viewer->realize();viewer->run(); return 0; }這是我對(duì)相機(jī)的理解和看法,代碼僅供參考。如果大家有什么不同的意見,歡迎評(píng)論區(qū)留言
總結(jié)
- 上一篇: 操作系统进程同步例题(三)汽车过桥2
- 下一篇: 【Code Pratice】—— 等差素