zoukankan      html  css  js  c++  java
  • 使用filter筛选刚体碰撞

      有时候需要避免刚体间的碰撞,那么可以使用filter。它是框架的一个属性,提供了碰撞筛选功能。用法比较有意思,经过了多次的试错,才找到其规则,因此有必要进行一些总结。

      filter有三个属性,可以从引擎源代码得知:

    struct b2Filter
    {
        b2Filter()
        {
            categoryBits = 0x0001;
            maskBits = 0xFFFF;
            groupIndex = 0;
        }
    
        /// The collision category bits. Normally you would just set one bit.
        uint16 categoryBits;
    
        /// The collision mask bits. This states the categories that this
        /// shape would accept for collision.
        uint16 maskBits;
    
        /// Collision groups allow a certain group of objects to never collide (negative)
        /// or always collide (positive). Zero means no collision group. Non-zero group
        /// filtering always wins against the mask bits.
        int16 groupIndex;
    };

      这三个属性都是uint16类型的,其中categoryBits和maskBits用二进制来表示(用十六进制初始化,但是是二进制用法)。关于每个属性的意义,虽然英文注释已经说明了很多了,但只有经过了实践,方才真正理解。在查阅了BOX2D手册后,得知filter有两种碰撞筛选策略。

    1.categoryBits和maskBits组合判断

      categoryBits代表该刚体所属的种族,它的值要设置成2的N次方,这是因为其16位二进制数只能有一位是1,其余都是0。maskBits代表该刚体被允许碰撞的刚体种群(即另一个刚体的categoryBits)。根据这两个属性,引擎给出了一个碰撞筛选规则:

    uint16 catA = fixtureA.filter.categoryBits;
    uint16 maskA = fixtureA.filter.maskBits;
    uint16 catB = fixtureB.filter.categoryBits;
    uint16 maskB = fixtureB.filter.maskBits;
    if ((catA & maskB) != 0 && (catB & maskA) != 0)
    {
     // fixtures can collide
    }

      可以看出,两个刚体要相撞,必须是“你情我愿”的,一方不愿意,那么就撞不了了。又从maskBits默认值0xFFFF得知,默认情况下,一个刚体是被允许和任意刚体发生碰撞的,当然这个刚体必须是动态刚体。

      那么,如何设置刚体的maskBits的值使其允许和一个以上的刚体发生碰撞呢?那就是使用按位或操作:|,这样该刚体的maskBits和要碰撞的刚体的categoryBits做&操作后,就都不会为0了,满足了碰撞筛选规则。如下代码所示,cat_b2代表的刚体,被允许和和cat_ground刚体以及cat_b1刚体都发生碰撞:

    fixturedef.filter.categoryBits = cat_b2;
    fixturedef.filter.maskBits = cat_ground | cat_b1;

    2.group分组判断

      这个比较简单,但要使其生效,那么两个刚体的groupIndex属性值必须一致且不为0。接下来再判断其值的正负,正一定相撞,负一定不相撞。且一旦满足了group分组判断策略,categoryBits和maskBits组合判断策略就无效了。也就是说该判断策略的优先级要高。如下代码所示,fixture1和fixture2是一定相撞的(相等、不为0,正),而fixture3和fixture4是一定不相撞的(相等,不为0,负):

    fixture1Def.filter.groupIndex = 1;
    fixture2Def.filter.groupIndex = 1;
    fixture3Def.filter.groupIndex = -1;
    fixture4Def.filter.groupIndex = -1;

    动态地改变刚体的碰撞规则

      除了通过初始化filter的各种属性来指定碰撞规则,还可以通过b2Fixture::SetFilterData函数随时改变刚体框架的filter,从而根据游戏逻辑需求动态地改变刚体的碰撞规则。

  • 相关阅读:
    《快速软件开发》学习笔记 之一
    Python+常用模块(2).md
    Python语法 (1).md
    使用mysql导入txt文件
    Python+numpy(3).md
    笔试二(程序题)
    啦啦啦 我的博客开通了
    java面试笔试
    笔试三(面试二)
    笔试三(面试)
  • 原文地址:https://www.cnblogs.com/demon90s/p/4430525.html
Copyright © 2011-2022 走看看