OSG碰撞检测

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

http://bbs.vrchina.net/viewthread.php?tid=5196&extra=page%3D1
OSG
碰撞检测
碰撞检测涉及到虚拟仿真的各个方面,这里我主要介绍两方面的应用:
一 判断摄像机是否与前面的物体相撞
基本原理如下图:
首先确定摄像机的旧位置和新位置(此处的新位置是假设前方没有障碍物所行进到的新位置),然后利用两点创建一条线段,然后判断这条线段与模型是否有交点,如果存在交点,则取交点作为新位置(或者取交点稍前面的一点作为新位置)。

1.jpg (16.32 KB)
2008-1-27 07:07 PM

   











二 摄像机按照地形来进行漫游:
如果不进行碰撞检测的话,可能会出现一下两种情况:
第一种情况,摄像机穿地形而过:

2.JPG (11.76 KB)
2008-1-27 07:12 PM








第二种情况, 摄像机处于悬空状态

3.JPG (9.14 KB)
2008-1-27 07:12 PM










对于第一种情况,摄像机肯定会与地形发生碰撞,但检测到碰撞之后,摄像机到达的位置
是否位于地形法线上方的合适高度,需要进行另一次碰撞检测,如下图所示:

4.JPG (9.3 KB)
2008-1-27 07:12 PM






       


绿色代表摄像机移动到的最终位置,从而保证了摄像机与地形之间的高度是固定的。
对于第二种情况,可能在第一种情况的碰撞检测中检测不到碰撞,那么需要进行在一次碰撞检测,

5.JPG (10.57 KB)
2008-1-27 07:12 PM



       

       





绿色代表摄像机移动到的最终位置,从而保证了摄像机与地形之间的高度是固定的。

三 重要的类和函数

osg::LineSegmen
表示一个线段的类,包括一个起点和一个终点
osgUtil::IntersectVisiotr
接受线段的类,用于判别与节点的交集。
其中的函数addLineSegment(line.get())用来添加一条线段到列表当中
osgUtil::IntersectVisitor::HitList
可以得到相交点的具体位置,从而计算出距离

四 代码示例
bool DriveManipulator::calcMovement()
{
    //如果少于两个事件则返回错误
    if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
    double dt = _ga_t0->getTime()-_ga_t1->getTime();

    if (dt<0.0f)
    {
        notify(INFO) << "warning dt = "<<dt<< std::endl;
        dt = 0.0f;
    }
    switch(_speedMode)
    {
        case(USE_MOUSE_Y_FOR_SPEED):
        {//切换到鼠标上下控制速度模式
            double dy = _ga_t0->getYnormalized();
            _velocity = _modelScale*0.2f*dy;
            break;
        }
        case(USE_MOUSE_BUTTONS_FOR_SPEED):
        {//切换到鼠标按键控制速度模式
            unsigned int buttonMask = _ga_t1->getButtonMask();
            if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON)
            {   //左键加速
                _velocity += dt*_modelScale*0.01;
            }
            else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
                buttonMask==(GUIEventAdapter::LEFT_MOUSE_BUTTON|GUIEventAdapter::RIGHT_MOUSE_BUTTON))
            {   //中键停止
                _velocity = 0.0;
            }
            else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON)
            {   //右键减速
                _velocity -= dt*_modelScale*0.01;
            }
            break;
        }
    }

    osg::CoordinateFrame cf=getCoordinateFrame(_eye);
    osg::Matrix rotation_matrix;
    rotation_matrix.makeRotate(_rotation);
    osg::Vec3d up = osg::Vec3d(0.0,1.0,0.0) * rotation_matrix;
    osg::Vec3d lv = osg::Vec3d(0.0,0.0,-1.0) * rotation_matrix;
    osg::Vec3d sv = osg::Vec3d(1.0,0.0,0.0) * rotation_matrix;

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值