OSG中相机参数的更改

Posted lauzhishuai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OSG中相机参数的更改相关的知识,希望对你有一定的参考价值。

 

 

[cpp] view plain copy
 
  1. #pragma comment(lib, "osg.lib")  
  2. #pragma comment(lib, "osgDB.lib")  
  3. #pragma comment(lib, "osgViewer.lib")  
  4.   
  5. #include  "osgViewer/Viewer"  
  6. #include  "osgDB/ReadFile"  
  7. #include  "osg/Node"  
  8. #include "osg/Shape"  
  9. #include "osg/Geode"  
  10. #include "osg/ShapeDrawable"  
  11.   
  12. int main(){  
  13.       
  14.     //初始化视景器  
  15.     osg::ref_ptr<osgViewer::Viewer> viewer=new osgViewer::Viewer;  
  16.   
  17.     //初始化场景根节点  
  18.     osg::ref_ptr<osg::Group> root=new osg::Group;  
  19.   
  20.     //场景数据  
  21.     osg::ref_ptr<osg::Node>  node=osgDB::readNodeFile("glider.osg");  
  22.   
  23.     root->addChild(node);  
  24.   
  25.     //将场景数据加入视景器中  
  26.     viewer->setSceneData(root);  
  27.   
  28.     //得到相机默认的参数设置  
  29.     osg::Vec3d eye,center,up;  
  30.     viewer->getCamera()->getViewMatrixAsLookAt(eye,center,up);  
  31.   
  32.     //将相机参数打印出来  
  33.     printf("init eye: %f,%f,%f\n",eye._v[0],eye._v[1],eye._v[2]);  
  34.     printf("init center: %f,%f,%f\n",center._v[0],center._v[1],center._v[2]);  
  35.     printf("init up: %f,%f,%f\n",up._v[0],up._v[1],up._v[2]);  
  36.   
  37.     //修改相机参数  
  38.     eye=osg::Vec3d(0.0,-10.0,0.0);  
  39.     center=osg::Vec3d(0.0,0.0,0.0);  
  40.     up=osg::Vec3d(0.0,0.0,1.0);  
  41.   
  42.     //将参数设置给相机,并立即获取相机参数  
  43.     viewer->getCamera()->setViewMatrixAsLookAt(eye,center,up);  
  44.     viewer->getCamera()->getViewMatrixAsLookAt(eye,center,up);  
  45.   
  46.     //将参数打印出来  
  47.     printf("eye: %f,%f,%f new\n",eye._v[0],eye._v[1],eye._v[2]);  
  48.     printf("center: %f,%f,%f new\n",center._v[0],center._v[1],center._v[2]);  
  49.     printf("up: %f,%f,%f new\n",up._v[0],up._v[1],up._v[2]);  
  50.   
  51.     //仿真循环,注意不要使用viewer->run(),如果使用这个参数,上面关于相机的所有更改都会无效  
  52.     while(!viewer->done())  
  53.     {  
  54.         viewer->frame();  
  55.     }  
  56.   
  57.   
  58.     return 1;  
  59. }  


      结果如图:

 

技术分享

      上面的代码显示初始的相机参数是:

技术分享

      这个参数默认是看不到东西的,因为OSG中默认的坐标系是这个样子的:

技术分享

      这样,如果eye在原点,center在z轴负半轴的情况下是看不到东西,所以如果不自己手动设置参数是看不到的东西的。如下面的代码将设置相机位置的代码注释掉:

 

[cpp] view plain copy
 
  1. #pragma comment(lib, "osg.lib")  
  2. #pragma comment(lib, "osgDB.lib")  
  3. #pragma comment(lib, "osgViewer.lib")  
  4.   
  5. #include  "osgViewer/Viewer"  
  6. #include  "osgDB/ReadFile"  
  7. #include  "osg/Node"  
  8. #include "osg/Shape"  
  9. #include "osg/Geode"  
  10. #include "osg/ShapeDrawable"  
  11.   
  12. int main(){  
  13.       
  14.     //初始化视景器  
  15.     osg::ref_ptr<osgViewer::Viewer> viewer=new osgViewer::Viewer;  
  16.   
  17.     //初始化场景根节点  
  18.     osg::ref_ptr<osg::Group> root=new osg::Group;  
  19.   
  20.     //场景数据  
  21.     osg::ref_ptr<osg::Node>  node=osgDB::readNodeFile("glider.osg");  
  22.   
  23.     root->addChild(node);  
  24.   
  25.     //将场景数据加入视景器中  
  26.     viewer->setSceneData(root);  
  27.   
  28.     //得到相机默认的参数设置  
  29.     osg::Vec3d eye,center,up;  
  30.     viewer->getCamera()->getViewMatrixAsLookAt(eye,center,up);  
  31.   
  32.     //将相机参数打印出来  
  33.     printf("init eye: %f,%f,%f\n",eye._v[0],eye._v[1],eye._v[2]);  
  34.     printf("init center: %f,%f,%f\n",center._v[0],center._v[1],center._v[2]);  
  35.     printf("init up: %f,%f,%f\n",up._v[0],up._v[1],up._v[2]);  
  36.   
  37.     ////修改相机参数  
  38.     //eye=osg::Vec3d(0.0,-10.0,0.0);  
  39.     //center=osg::Vec3d(0.0,0.0,0.0);  
  40.     //up=osg::Vec3d(0.0,0.0,1.0);  
  41.   
  42.     ////将参数设置给相机,并立即获取相机参数  
  43.     //viewer->getCamera()->setViewMatrixAsLookAt(eye,center,up);  
  44.     //viewer->getCamera()->getViewMatrixAsLookAt(eye,center,up);  
  45.   
  46.     ////将参数打印出来  
  47.     //printf("eye: %f,%f,%f new\n",eye._v[0],eye._v[1],eye._v[2]);  
  48.     //printf("center: %f,%f,%f new\n",center._v[0],center._v[1],center._v[2]);  
  49.     //printf("up: %f,%f,%f new\n",up._v[0],up._v[1],up._v[2]);  
  50.   
  51.     //仿真循环,注意不要使用viewer->run(),如果使用这个参数,上面关于相机的所有更改都会无效  
  52.     while(!viewer->done())  
  53.     {  
  54.         viewer->frame();  
  55.     }  
  56.   
  57.   
  58.     return 1;  
  59. }  



 

      在这种情况下的效果如下图,什么都看不到:

技术分享

      使用下面这一组测试数据后:

 

[cpp] view plain copy
 
  1. //修改相机参数  
  2. eye=osg::Vec3d(-10.0,0.0,0.0);  
  3. center=osg::Vec3d(0.0,0.0,0.0);  
  4. up=osg::Vec3d(0.0,0.0,1.0);  


      即从x轴负半轴看去,看到的应该是飞机的正面,效果如下图:

 

技术分享

      正常。在这种情况下场景中是没有漫游器的,也不存在默认的漫游器这个说法,如果需要实现场景漫游,自己加个漫游器就可以了。

 

      注意:如果直接使用:

 

[cpp] view plain copy
 
  1. viewer->run();  

      怎么修改相机参数都是无效的,
      即使加上

 

 

[cpp] view plain copy
 
  1. viewer->setCameraManipulator(NULL);  

      也是一样,因为在

 

 

[cpp] view plain copy
 
  1. viewer->run();  

      这个函数里会对场景中是否存在漫游器进行判断,如果没有漫游器,它会自己添加一个TrackballManipulator漫游器。

 

      run函数的实现如下:

 

[cpp] view plain copy
 
  1. int Viewer::run()  
  2. {  
  3.     if (!getCameraManipulator() && getCamera()->getAllowEventFocus())  
  4.     {  
  5.         setCameraManipulator(new osgGA::TrackballManipulator());  
  6.     }  
  7.   
  8.     setReleaseContextAtEndOfFrameHint(false);  
  9.   
  10.     return ViewerBase::run();  
  11. }  

      很容易看出问题所在了。

以上是关于OSG中相机参数的更改的主要内容,如果未能解决你的问题,请参考以下文章

[osg]OSG相机添加动画路径

OpenGL的视图变换与OSG漫游器

OSG立体模式下动态修改相机远近裁剪面的实现

osg osgViewer::View::setUpViewInWindow()

c_cpp 使用OSG绘制球体

osg移动视点