查看: 1468|回复: 2

请教关于怎么实现CS游戏中视线跟随鼠标移动的问题

[复制链接]

该用户从未签到

发表于 2012-12-13 11:00:42 | 显示全部楼层 |阅读模式
本帖最后由 hzxfrank2010 于 2012-12-13 11:02 编辑

想实现一个在场景中类似FPS游戏的操作,查了一些资料在OpenGL中实现的部分代码如下:

        float speed=0.5f;                                       
        float x=g_eye[0],y=g_eye[1],z=g_eye[2];

        g_Angle +=  (xmouse-xmouseOld)*0.2f;            
        g_elev  += -(ymouse-ymouseOld)*0.2f;         

        xmouseOld=xmouse;
        ymouseOld=ymouse;


        if (KEY_DOWN(VK_LEFT))   g_Angle-=speed*2;
        if (KEY_DOWN(VK_RIGHT))  g_Angle+=speed*2;
       
        rad_xz = float (3.13149* g_Angle/180.0f);       

        if (KEY_DOWN(33))                   g_elev +=speed;
        if (KEY_DOWN(34))                   g_elev -=speed;
        if (g_elev<-360)                   g_elev  =-360;
        if (g_elev> 360)                   g_elev  = 360;
       
        //w s a d 移动 支持上下键移动
        if (KEY_DOWN(KEY_W) || KEY_DOWN(VK_UP) )                                       
        {
                z+=(float)sin(rad_xz)*speed;       
                x+=(float)cos(rad_xz)*speed;       
        }
        if (KEY_DOWN(KEY_S) || KEY_DOWN(VK_DOWN) )                                       
        {
                z-=(float)sin(rad_xz)*speed;       
                x-=(float)cos(rad_xz)*speed;
        }
        if (KEY_DOWN(KEY_A))                                       
        {
                z-=(float)cos(rad_xz)*speed;       
                x+=(float)sin(rad_xz)*speed;       
        }
        if (KEY_DOWN(KEY_D))               
        {
                z+=(float)cos(rad_xz)*speed;       
                x-=(float)sin(rad_xz)*speed;       
        }

        g_eye[1] =VIEW_HEIGHT;

        g_look[0] = (float)(g_eye[0] +100*cos(rad_xz));
        g_look[2] = (float)(g_eye[2] +100*sin(rad_xz));
        g_look[1] = g_eye[1] +g_elev;       
       
        gluLookAt(g_eye[0],g_eye[1],g_eye[2],g_look[0],g_look[1],g_look[2],0.0,1.0,0.0);

但是在以上代码里面的观察坐标系与世界坐标系没有旋转

在我的osg代码中我也仿造上面
_yaw += ((ea.getX() - _oldMousePosX) * 0.2);
_pitch +=((ea.getY() -oldMousePosY) * 0.2);
_oldMousePosX = ea.getX();
_oldMousePosY = ea.getY();
                       
osg::Vec3d lookAtVector;
lookAtVector[0] = 10*cos(osg^DegreesToRadians(_yaw));
lookAtVector[1] = 0;
lookAtVector[2] = 10 * sin(osg^DegreesToRadians(_yaw));

//getMatrix()是操作器里面重载的一个函数用来得到世界坐标系到观察坐标系的Matrix
               
lookAtVector = lookAtVector * getMatrix();
osg::Matrix mat = osg::Matrix::lookAt(_eye, lookAtVector, (osg::Vec3d)osg::Y_AXIS);

osg::Matrixd inverseMat = osg::Matrix::inverse(mat);
//自定义操作器类里面有_eye和_rotate记录相机的位置和姿态
_rotation = inverseMat.getRotate();


但是运行的时候场景却没有按照预期的那样去旋转,不知道什么原因?

该用户从未签到

发表于 2012-12-14 08:28:52 | 显示全部楼层
操作器的这个函数getInverseMatrix 要重载的,update更新中 就是通过这个函数设置camera的viewmatrix

该用户从未签到

 楼主| 发表于 2012-12-14 09:39:04 | 显示全部楼层
那个函数我有重载
  1. osg::Matrixd DriveManipulator3::getMatrix() const
  2. {
  3.         return osg::Matrixd::rotate(_rotation)*osg::Matrixd::translate(_eye);
  4. }

  5. osg::Matrixd DriveManipulator3::getInverseMatrix() const
  6. {
  7.         return osg::Matrixd::inverse(getMatrix());
  8. }
复制代码
不过上面那个问题我自己解决了,我在局部坐标系下算出新的center的坐标值,然后将它换算到世界坐标中,调用computePosition函数算出新的ViewMatrix。总之还是谢谢楼主的回复~
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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