OSG相机漫游
實現功能
自定義相機的位置位于世界坐標系下的Y軸正方向斜向下45度觀察水平面。通過按鍵實現向前(按W)向后(按S)向左(按A)向右(按D)向上(按PageUp)向下(按PageDown)相機左右旋轉(J/L)、相機上下旋轉(I/K)觀察效果如圖:
基礎知識
實現相機我們所要用到的知識點有1.向量,矩陣,四元素等概念2.OSG坐標系統的知識。3.視圖與相機, 鍵盤事件消息處理的相關知識。最重要的需要自己的空間思維能力,如果對以上的知識點不熟悉的話,可以去相關的網站看看。實現原理
一.新建一個類共有繼承 osgGA::CameraManipulator,并且重寫四個虛函數,具體的代碼需要根據要求來進行編寫。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 ;二.進行鍵盤事件處理我們需要重寫handle函數1.virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us) ;代碼實現
.h文件
class TraveManipulator :public osgGA::CameraManipulator { public://構造函數TraveManipulator(osg::ref_ptr<osg::Node> node1);//析構函數~TraveManipulator();//設置矩陣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) ; private://視點位置osg::Vec3d m_Eye;//參照物中心osg::Vec3d m_Center;//方向向量osg::Vec3d m_Up;//距離double m_Distense;//移動步長float m_Step;//旋轉矩陣osg::Matrix m_RotationMatrix;//相機上下旋轉的繞軸osg::Vec3 m_CameraRotation; };.cpp文件
TraveManipulator::TraveManipulator(osg::ref_ptr<osg::Node> node1) :m_Distense(4000.0), m_Step(30) {//保存物體的中心點osg::Vec3d node_Center = node1->getBound().center();osg::Matrix rotation_Anngle;//繞x軸旋轉45°rotation_Anngle = osg::Matrix::rotate(osg::Quat(-osg::PI_4,osg::Vec3f(1.0f, 0.0f, 0.0f)));//設置視點的位置,m_Eye = osg::Vec3d(0.0, 0.0, m_Distense);//設置中心點的位置m_Center = node_Center;//up向量m_Up = osg::Vec3d(0.0,- 1.0, 0.0);//視點位于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() { // } //設置矩陣 void TraveManipulator::setByMatrix(const osg::Matrixd& matrix) {// } //設置逆矩陣 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); } //鍵盤事件處理函數 bool TraveManipulator::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us) {//獲取事件switch (ea.getEventType()){//如果是一個鍵盤事件case osgGA::GUIEventAdapter::KEYDOWN:{//向前移動(按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);} //向后移動(按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);}//向左移動(按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)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);}//向上移動(按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);}//向下移動(按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);} //相機向左旋轉else if (ea.getKey() == 'j' || ea.getKey() == 'J'){osg::Matrix mt; //設置旋轉軸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;}//相機向右旋轉else if (ea.getKey() == 'l' || ea.getKey() == 'L'){osg::Matrix mt;//設置旋轉軸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;}//相機向上旋轉else if (ea.getKey() == 'i' || ea.getKey() == 'I'){osg::Matrix mt;//設置旋轉軸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);}//相機向下旋轉else if (ea.getKey() == 'k' || ea.getKey() == 'K'){osg::Matrix mt;//設置旋轉矩陣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());//設置場景數據viewer->setSceneData(root.get());viewer->realize();viewer->run(); return 0; }這是我對相機的理解和看法,代碼僅供參考。如果大家有什么不同的意見,歡迎評論區留言
總結
- 上一篇: 操作系统进程同步例题(三)汽车过桥2
- 下一篇: 【Code Pratice】—— 等差素