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,从而根据游戏逻辑需求动态地改变刚体的碰撞规则。

  • 相关阅读:
    x64 平台开发 Mapxtreme 编译错误
    hdu 4305 Lightning
    Ural 1627 Join(生成树计数)
    poj 2104 Kth Number(可持久化线段树)
    ural 1651 Shortest Subchain
    hdu 4351 Digital root
    hdu 3221 Bruteforce Algorithm
    poj 2892 Tunnel Warfare (Splay Tree instead of Segment Tree)
    hdu 4031 Attack(BIT)
    LightOJ 1277 Looking for a Subsequence
  • 原文地址:https://www.cnblogs.com/demon90s/p/4430525.html
Copyright © 2011-2022 走看看