lanxun1988 发表于 2011-5-29 10:21:47

关于用setViewMatrixAsLookAt改变相机位置和朝向无效的问题

各位大侠早,想请教大家一个关于用setViewMatrixAsLookAt改变相机位置和朝向无效的问题,具体情况如下:
    (1)我首先仿照FreeSouth的那个CSouth漫游器写了一个 CTravelManipulator漫游器,然后用
mViewer->setCameraManipulator(new CTravelManipulator(mViewer));
      设置漫游器;同时在仿真循环中采用如下代码进行仿真循环
while(!viewer->done())
{
osg->PreFrameUpdate();
viewer->frame();
osg->PostFrameUpdate();
Sleep(10); // 让其它程也占用CPU,放出10MS
}

    (2)由于需要,我需要对viewer添加响应时间,因此在setCameraManipulator后立即进行那个如下设置:
mViewer->addEventHandler(new CMouseHandler(mViewer,camera.get()));

    这个CMouseHandler类是从public osgGA::GUIEventHandler类继承下来的,在这个类的handle函数中,我希望将传进来的camera的位置进行调整,主要是改变相机的位置、朝向这两个属性,改变的代码如下:

currentcamera ->setViewMatrixAsLookAt(cameraEyeNew,toCenterNew,cameraUpNew);

上面的cameraEyeNew,toCenterNew,cameraUpNew都是我根据需要重新计算过的新的值。

    (3)问题:按照如上设置,通过断点跟踪程序,发现handler函数中的setViewMatrixAsLookAt虽然执行了,但是相机的位置并没有发生变化。我在论坛搜了一下,可能的原因是我这边的设置又被漫游器给重置了,因此没有效果。那我想请问的是:
            1、是不是一定要写一个camera的更新回调才能改变camera的位置呢?我要的功能是,鼠标双击后根据鼠标当前所在位置去设置camera的位置和朝向,用回调不知道该怎么写。。。。
            2、有没有一种设置方法,使得我在handle函数中可以顺利地用setViewMatrixAsLookAt改变相机的位置和朝向呢?


       谢谢各位大侠~~~

我,建国 发表于 2017-3-23 20:09:28

GetViewer()->getCameraManipulator()->setByInverseMatrix(viewMatrix),亲测有效

lanxun1988 发表于 2011-5-29 10:22:17

自己顶一下先~~

garyliyong 发表于 2011-5-29 12:02:37

这个问题我是遇到过的,当设置viewer->cameraManipulator()后,setViewAtLookAt是不起作用的,你在你自己写的操作器中改变观察矩阵的值就可以了,使用相机回调也是可以的

wangjunchao 发表于 2011-5-29 12:04:43

我现在怀疑在你的view中不只有一个camera

lanxun1988 发表于 2011-5-29 14:05:02

回复 4# wangjunchao


    我只设置了一个camera,不可能有多个

lanxun1988 发表于 2011-5-29 14:05:35

回复 3# garyliyong


    我用相机事件回调来试试看

lanxun1988 发表于 2011-5-29 15:15:37

本帖最后由 lanxun1988 于 2011-5-29 15:17 编辑

回复 3# garyliyong


    您好,非常感谢您的指导。我根据我的理解,我需要在相机的事件回调中用setViewMatrixAsLookAt进行设置。我的几个重要代码如下:
    (1)首先定义了一个class CCameraEventCallback :public osg::NodeCallback 的相机回调类,类中几个重要的代码是这样的:

virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if(nv->getVisitorType()==osg::NodeVisitor::EVENT_VISITOR)
{
   osg::ref_ptr<osgGA::EventVisitor> ev = dynamic_cast<osgGA::EventVisitor*> (nv);
   if(ev)
   {
    osgGA::GUIActionAdapter* aa = ev->getActionAdapter();
    osgGA::EventQueue::Events& events = ev->getEvents();
    for(osgGA::EventQueue::Events::iterator itr = events.begin();itr != events.end();++itr)
    {
   handle(*(*itr),*(aa),node)//这个里面去改相机的位置
}
   }
}
}

    上面的handle的具体代码是:
bool CCameraEventCallback::handle(const osgGA::GUIEventAdapter& ea ,osgGA::GUIActionAdapter& aa,osg::Node* node)
{
switch(ea.getEventType())
{
case osgGA::GUIEventAdapter::DOUBLECLICK://如果是鼠标双击事件
if(ea.getButton()==1)//确保是鼠标左键双击
{
osg::Vec3 cameraEye;
osg::Vec3 toCenter;
osg::Vec3 cameraUp;//这些变量用来保存camera的各个参数
//自己写的那个漫游器类的初始化为
// m_vPosition = osg::Vec3(0.0f,-70.0f,0.0f);
// m_vRotation = osg::Vec3(osg::PI_2,0.0f,0.0f);


dynamic_cast<osg::Camera*>(node)->getViewMatrixAsLookAt(cameraEye,toCenter,cameraUp);//获取当前camera的各个参数
//断点后发现cameraEye确实是(0.0f,-70.0f,0.0f)
dynamic_cast<osg::Camera*>(node)->setViewMatrixAsLookAt(osg::Vec3(cameraEye.x(),cameraEye.y()+50,cameraEye.z()),toCenter,cameraUp);//只是想让这个cameraEye的y变大一点,也就是感觉上相机往前进了一些
AfxMessageBox("双击事件捕获到了");//这个是我来测试双击事件有没有捕获到的
}
break;
default:
break;
}
return false;
}

    (3)另外,相机初始时候是这样设置的
mViewer->addSlave(camera.get());

mViewer->setCameraManipulator(new CTravelManipulator(mViewer));

camera->setEventCallback(new CCameraEventCallback());//用camera来设置事件回调,因此handle函数中的node其实就是这个camera

mViewer->setSceneData(mRoot.get());

    但是很悲催的是,相机的位置依旧没有改变。。。。不知道我哪里理解错了。。。。。至于您说的第一种去漫游器里面改变matrix的值的方法,我不知道具体该如何操作。。。。。麻烦您了

garyliyong 发表于 2011-5-29 20:24:35

回复 7# lanxun1988

   你不是看过freesouth的csouth类吗?如果想改变相机的位置,只要根据你的要求,设置m_rotation,m_positon的值就可以了,你的要求是拉近,只要设置m_position.y()+50就可以了,你试试。关于第一个方法,我目前是这样解决的就是viewer->getManipulator()->setHomePosition(eye,enter,up),viewer->home();另外setViewMatrixlookat在setcameraManilulator(NULL)会起作用的,至于为什么,我没有得到明确的答案,也没有找到很好的解决方法。

array 发表于 2011-5-30 10:39:18

handler函数中的setViewMatrixAsLookAt看起来您完全没有理解漫游器的编写方法……最重要的是重写虚函数getMatrix()和getInverseMatrix(),因为系统会在每帧自动调用后者来设置主相机,这个函数没有重写的话,任何handle()中的设置都毫无意义

smengq 发表于 2012-9-15 09:43:36

lanxun1988 发表于 2011-5-29 15:15 static/image/common/back.gif
回复 3# garyliyong




你好,你用相机回调设置相机位置的问题有没有解决?我也遇到了同样的问题,谢谢分享

dingshuaiyu 发表于 2017-3-24 16:34:54

我之前遇到这种情况,原因是有其他操作器,在没有操作器的情况下setViewMatrixAsLookAt就是好用的,你可以试一下viewer()->setCameraManipulator(NULL) 之后在setViewMatrixAsLookAt就是好用的,如果想要在具体某个操作器下移动相机,参考array大大的办法
页: [1]
查看完整版本: 关于用setViewMatrixAsLookAt改变相机位置和朝向无效的问题