查看: 1329|回复: 2

OSG多相机问题

[复制链接]

该用户从未签到

发表于 2013-12-14 14:32:26 | 显示全部楼层 |阅读模式
大家好 ,小弟最近在OSG多个相机上遇到了问题。现在有一辆车子,质心按照一定的规律运动,在车子的前方、后方和右侧各装有一个摄像机,它们的图像随着车辆运动而改变。这个问题用跟随节点的摄像机来处理,效果实现不了,小弟目前的主要代码(部分代码是Copy来的,小弟不是很明白,也请大家解惑;PS:这个问题在别的论坛也发过,大家给了答案小弟可以去那里回复自己,传播知识哈):


        osg::ref_ptr<osgViewer::CompositeViewer> viewer = new osgViewer::CompositeViewer;            
        osg::ref_ptr<osgViewer::View> view1 = new osgViewer::View;
        osg::ref_ptr<osgViewer::View> view2 = new osgViewer::View;
        osg::ref_ptr<osgViewer::View> view3 = new osgViewer::View;
        viewer->addView(view1.get());
        viewer->addView(view2.get());
        viewer->addView(view3.get());



        //设置图形环境特征
        osg::ref_ptr<osg::GraphicsContext::Traits>traits = new osg::GraphicsContext::Traits();
        traits->x=100;//x,y,w,h=100,100,1000,700
        traits->y=100;
        traits->width=800;//w:800,h:600是visualizer->createDefaultWindow()的默认参数
        traits->height=600;
        traits->windowDecoration = true;
        traits->doubleBuffer=true;
        traits->sharedContext=0;

        //创建图形环境特征
        osg::ref_ptr<osg::GraphicsContext>gc= osg::GraphicsContext::createGraphicsContext(traits.get());
        if(gc.valid())
        {
                osg::notify(osg::INFO)<<"GraphiceWindow has been created successfully."<<std::endl;
                //清除窗口颜色及清除颜色和深度缓冲
                gc->setClearColor(osg::Vec4f(1.0f,1.0f,1.0f,1.0f));//(0.2f,0.2f,0.6f,1.0f)
                gc->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
        }
        else
        {
                osg::notify(osg::NOTICE)<<"GraphiceWindow has not been created successfully."<<std::endl;
        }
        view1->getCamera()->setViewport(new osg::Viewport(0,0,traits->width,traits->height));
        view1->getCamera()->setGraphicsContext(gc.get());

       //后视图
        osg::ref_ptr<osg::Camera> camera = new osg::Camera;
        //设置上下文
        camera->setGraphicsContext(gc.get());
        //设置后视图的窗口位置
        camera->setViewport(new osg::Viewport(0,0,traits->width/2.5,traits->height/2.5));
        //添加相机到视口
        view2->addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::DegreesToRadians(180.0), 0.0, 1.0, 0.0));

        //前视图
        osg::ref_ptr<osg::Camera> cameraFront = new osg::Camera;  
        cameraFront->setGraphicsContext(gc.get());  
        cameraFront->setViewport(new osg::Viewport(traits->width*0.6,0,traits->width/2.5,traits->height/2.5));
        view3->addSlave(cameraFront.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::DegreesToRadians(0.0), 0.0, 1.0, 0.0));
        //*****************************************************************************

#ifdef USE_TRACKBALL_MANIP
        osgGA::TrackballManipulator* manip = new osgGA::TrackballManipulator;

        view1->setCameraManipulator(manip);
        osg::ref_ptr<osg::Group> sceneRoot = new osg::Group;
        sceneRoot->setName("Root");
        //createLight(sceneRoot.get());
        view1->setSceneData(sceneRoot.get());
        view2->setSceneData(sceneRoot.get());
        view3->setSceneData(sceneRoot.get());

        osg::Vec3d eye;        osg::Vec3d center, up;
        osg::Vec3d posCamera(position.v[0], position.v[1], position.v[2]);//position已知,车辆的质心
        osg::Vec3d target(position.v[0], position.v[1]-30, position.v[2]+10);//-30,-30,+10
        manip->getHomePosition(eye, center, up);
        manip->setHomePosition(posCamera, target, up, false );
        manip->home(0);


       上面的代码运行后,能够得到后视图和前视图,但是将:        view2->addSlave(camera.get(), osg::Matrixd(), osg::Matrixd::rotate(osg::DegreesToRadians(180.0), 0.0, 1.0, 0.0));
里面的180.0改成45.0、135.0等均不能获得左右视图。

       小弟现在主要的问题是:
1.如何实现多个在安装在不同位置、观察目标不同、跟随车辆运动而图像自动变化;

2.跟随节点的相机的含义,建立trackball后,摄像机跟随trackball运动吗?trackball的放置位置是与车辆质心相同,还是与摄像机的安装位置相同,还是与摄像机的观察目标target相同?按照1里面的情况,是不是每一个摄像机要单独指定一个trackball?

3.代码的最后一大段中,getHomePosition()和setHomePosition()的含义是什么?小弟知道eye、center、up等就像gluLookAt()中,是视点、观察点、正方向,那么getHomePosition()和setHomePosition()的含义是不是重新建立观察坐标系,而最后一句manip->home(0)的含义是什么?

该用户从未签到

发表于 2013-12-25 09:52:30 | 显示全部楼层
1. 我个人建议不要用Slave相机,因为Slave是默认一直跟随主相机的,只能设置view和proj的偏移矩阵,而这个偏移矩阵的计算不是您想象的那种简单变换。用CompositeViewer并且在回调里更新每个相机对现在的您应该是更好的选择
2. 您似乎并不理解什么叫做trackball,这是一种从2d操控3d的方式,基本原理就是把屏幕坐标想象成一个3d的球体然后将鼠标操作映射到球上。所以它不会有世界坐标的概念。看一看经典的ArcBall算法论文会很有好处
3. home就是让相机立即回到初始位置,setHomePosition就是设置这个初始位置

该用户从未签到

 楼主| 发表于 2013-12-25 22:48:24 | 显示全部楼层
array 发表于 2013-12-25 09:52
1. 我个人建议不要用Slave相机,因为Slave是默认一直跟随主相机的,只能设置view和proj的偏移矩阵,而这个 ...

嗯,我试试。刚刚下载了arcball的资料。谢谢array
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表