让鼠标点选更加人性化

        以前做的鼠标框选和点选系统虽然实现了基本的功能,但是使用起来感觉总是那么别扭,如果一棵大树里面有一棵小树的话,那么这棵小树是永远选不到的,因为OGRE的射线查询是根据物体的包围盒来判断的。如果想使点选系统更接近用户的意图的话,我开始考虑了以下几个方案:

      1.射线与模型的三角面进行精确检测。(效率太低)

      2.按ctrl键点模型,选中第一个被查到的物体,如果不松手在点一下,选中第二个被查到的物体,以此类推,这样用户可以选到想选的物体。(程序实现和用户操作都会很复杂)

      3.做筛选列表,用户把想选到的物体加入筛选列表,这样不想选择的物体就不做检测。(更复杂)

      以上三种不是效率太低,就是实现和操作起来过于复杂。

      后来我终于想到个又简单,又操作方便的方案,那就是永远选择包围盒最小的物体,具观察,包围盒越大的物体越容易被选到,所以用户不需要为包围盒大的物体考虑如何选他,稍微换一换角度,总是可以选到的,但是包围盒越小的物体就越难被选中,大部分是跟本无法被单独选中的。所以一条射线查询查询到的所有物体中,最应该被选中的是包围盒最小的物体。于是我按照取小优先的原则试了试,效果还不错,很人性化。

      部分源码:

    //跟据用户框选的范围大小,判断是框选还是点选
    if ((right - left) * (bottom - top) < 0.0001)
    {
        Ray selectRay = m_pCamera->getCameraToViewportRay(left, top);
        m_pRaySceneQuery->setRay(selectRay);
        m_pRaySceneQuery->setSortByDistance(true);

        RaySceneQueryResult result = m_pRaySceneQuery->execute();
        deselectObjects();
        RaySceneQueryResult::iterator itr;
        MovableObject* pObject=NULL;
        for ( itr = result.begin(); itr != result.end(); itr++ )
        {
            //筛选掉一些非物体结点
            if (CheckSubString("/Object/" , itr->movable->getName()))
            {
                //是不是第一个物体
                if (pObject==NULL)
                {
                    pObject=itr->movable;
                }
                else //如果不是第一个物体,那么判断它与之前的物体包围盒,那个更小
                {
                    float fCurrent=itr->movable->getParentSceneNode()->_getWorldAABB().getSize().length();
                    float fLast=pObject->getParentSceneNode()->_getWorldAABB().getSize().length();
                    if(fCurrent
                    {
                         pObject=itr->movable;
                    }
                }
            }
        }
        if (pObject!=NULL)
        {
            selectObject(pObject);     //选中这个物体
        }

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值