码迷,mamicode.com
首页 > 其他好文 > 详细

OSG漫游:实现按键控制的操作器

时间:2015-08-03 21:00:24      阅读:320      评论:0      收藏:0      [点我收藏+]

标签:

OSG提供了几种manipulator(操作器),已经能胜任很多场合了。但玩过射击类游戏的都比较熟悉使用按键的方式控制人物角色的移动,自己也想来实现一个,于是参考了OSG程序设计 一书,进行实现。

功能:

  • W或者↑箭头:前进
  • S或者↓箭头:后退
  • A或者←箭头:向左
  • D或者→箭头:向右
  • Q:左旋转
  • E:右旋转
  • 鼠标左键拖动:左右视角
  • 鼠标右键拖动:上下视角
  • 鼠标中键:放大或者缩小
  • +:加速移动
  • -:减速移动

关键点

1、视口矩阵的运算方式:

osg::Matrixd CustomManipulator::getMatrix() const
{
    // 返回视口的矩阵
    osg::Matrixd mat;
    mat.makeRotate(m_vecRotation._v[0], osg::Vec3d(1.0, 0.0, 0.0),
        m_vecRotation._v[1], osg::Vec3d(0.0, 1.0, 0.0),
        m_vecRotation._v[2], osg::Vec3d(0.0, 0.0, 1.0));

    return mat * osg::Matrixd::translate(m_vecPosition);
}

2、视口矩阵的逆矩阵:这个就比较好求了,直接对视口矩阵求逆

osg::Matrixd CustomManipulator::getInverseMatrix() const
{
    osg::Matrixd mat;
    mat.makeRotate(m_vecRotation._v[0], osg::Vec3d(1.0, 0.0, 0.0),
        m_vecRotation._v[1], osg::Vec3d(0.0, 1.0, 0.0),
        m_vecRotation._v[2], osg::Vec3d(0.0, 0.0, 1.0));
    // 返回视口的逆矩阵
    return osg::Matrixd::inverse(mat * osg::Matrixd::translate(m_vecPosition));
}

3、移动过程中的碰撞检测
使用的是比较简单的十字交叉方式进行碰撞检测,在实际运用中,我们需要使用包围盒的方式,也就是需要十二条线进行碰撞检测。

osg::Vec3d newPos = m_vecPosition + delta;
        osgUtil::IntersectVisitor iv;
        osg::ref_ptr<osg::LineSegment> lineWidth = new osg::LineSegment(newPos, m_vecPosition);
        osg::ref_ptr<osg::LineSegment> lineHeight = new osg::LineSegment(
            newPos + osg::Vec3d(0, 0, m_dSpeed), newPos - osg::Vec3d(0, 0, m_dSpeed));
        iv.addLineSegment(lineWidth);
        iv.addLineSegment(lineHeight);
        m_pCollisionNode->accept(iv);
        if (!iv.hits())
        {
            // 碰撞检测失败,可以移动
            m_vecPosition += delta;
        }

代码如下:

所有完整代码已上传到我的GitHub, 传送门在此OSG漫游
PS:里面不光有漫游的代码,也有前面博客中提及的所有代码。

版权声明:本文为博主原创文章,未经博主允许不得转载。

OSG漫游:实现按键控制的操作器

标签:

原文地址:http://blog.csdn.net/chlk118/article/details/47261543

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!