• nape.dynamics.InteractionGroup


    (转载http://tomyail.com/blog/1123)

    说明:

    Filter只是Shape的属性,Nape为Interactor类提供了group属性,这个属性是一个InteractionGroup类型.Shape,Body和Compound都是Interactor的子类,所以它们都能使用InteractionGroup的一些特性.

    过滤规则:

    把需要一起控制的对象指向同一个group,并且改变这个group的ignore(布尔值)属性来控制这些对象是否需要交互,true是不交互,false(默认)是交互.

    group版本小球碰撞的源码:

    private function testSimpleGroup():void
            {
                var group:InteractionGroup = new InteractionGroup();
                var ball:Body = createCircleBody(BodyType.DYNAMIC, 60, 40, 30);
                ball.shapes.at(0).material = new Material(Number.POSITIVE_INFINITY);
                var box:Body = createRectBody(BodyType.KINEMATIC,110, 150, 200,20);
                ball.group = box.group = group;
                var btn:PushButton = new PushButton(this, 400, 100, "group.ignore=false(交互)", clickCallback);
                btn.width = 200;
                function clickCallback(e:MouseEvent):void
                {
                    group.ignore = !group.ignore;
                    if (group.ignore) btn.label = "group.ignore=true(不交互)";
                    if (!group.ignore) btn.label = "group.ignore=false(交互)";
                }
            }

    控制三组对象碰撞关系的group版本源码:

    private function testMultiGroup():void
            {
                var groupA:InteractionGroup = new InteractionGroup(true);
                var groupB:InteractionGroup = new InteractionGroup(false);
                var groupC:InteractionGroup = new InteractionGroup(true);
                
                var groupAB:InteractionGroup = new InteractionGroup(false);
                var groupBC:InteractionGroup = new InteractionGroup(true);
                var groupAC:InteractionGroup = new InteractionGroup(false);
                
                groupA.group = groupAB;
                groupA.group = groupAC;
                
                groupB.group = groupAB;
                groupB.group = groupBC;
                
                groupC.group = groupAC;
                groupC.group = groupBC;
                
                var Ba1:Body = createCircleBody(BodyType.DYNAMIC,50,100,120);
                var Ba2:Body = createCircleBody(BodyType.DYNAMIC,150,100,120);
                Ba1.group = groupA;
                Ba2.group = groupA;
                
                var Bb1:Body = createCircleBody(BodyType.DYNAMIC,250,100,80);
                var Bb2:Body = createCircleBody(BodyType.DYNAMIC,250,100,80);
                Bb1.group = groupB;
                Bb2.group = groupB;
                
                var Bc1:Body = createCircleBody(BodyType.DYNAMIC,300,100,30);
                var Bc2:Body = createCircleBody(BodyType.DYNAMIC,300,100,30);
                Bc1.group = groupC;
                Bc2.group = groupC;
            }

    图示:

    ABC交互关系
      A(a1a2) B(b1b2) C(c1c2)
    A(a1a2) 0 1 1
    B(b1b2) 1 1 0
    C(c1c2) 1 0 0

    0代表不交互:group.ignore=true;

    1代表不交互:group.ignore=false;

    比如:MRCA(a1,b2)==groupAB,而groupAB.ignore=false,这样a1,b2就有交互;(由大到小对应abc)

    在这个例子中用到了InteractionGroup的一个树结构的特征.也就是任何InteractionGroup都有一个group属性说明这个group的父group是什么.这个group是一个列表所以支持

    groupA.group = groupAB;

    groupA.group = groupAC;

    这种多重赋值,意思就是groupA有两个父节点分别是groupAB和groupAC.

    对于多次嵌套树结构,需要通过查找他们的最近共同祖先(MRCA)来确定是属于哪一个group的.这里拿官方手册上的例子好了.

               Group1
              /   |
             /  Group2      Group3
            /    |           |
        Body1   /      Cmp1   |
       /      /      /      |
    Shp1   Shp2   Body2     Cmp2
                    |         |
                   Shp3     Body3
                              |
                            Shp4

    这是它们的原始结构关系,这里着重看看shape之间的关系.

      shape4 shape3 shape2 shape1
    shape4 g3(单独) 无共同组 无共同组 无共同组
    shape3 无共同组 g2 g2 g1
    shape2 无共同组 g2 g2 同一刚体
    shape1 无共同组 g1 同一刚体 g1

    要确定两两shape的关系.

    1:先要确定每个shape属于哪一个group,所以

    Shp1依次往上递归得到碰到的第一个group是G1.

    Shp2依次往上递归得到碰到的第一个group是G2.

    Shp3依次往上递归得到碰到的第一个group是G2.

    Shp4依次往上递归得到碰到的第一个group是G3.

    2:结合这几个Group的关系就能确定最终得到的Group关系图:

            Group1
            /              Group3
        Shp1    Group2        |
                /          Shp4
             Shp2    Shp3

    Shp1和Shp2属于同一个刚体,所以他们是一起运动的也就不存在交互作用了.

    MRCA(Shp1, Shp3) == Group1;

    MRCA(Shp2, Shp3) == Group2;

    Shp4是孤立的,所以不存在Shp1和Shp4之类的交互控制,所以Shp4和所有其他对象默认都是发生碰撞的.

    在确定了各个Shape的MRCA之后就能很容易的看出他们的碰撞关系了.

    比如

    Group1.ignore = true && Group2.ignore = false就能得出:Shp1和Shp3不会交互,Shp2和Shp3会交互.由大到小对应shp4、shp3、shp2、shp1

    Group1.ignore = false&& Group2.ignore = true就能得出:Shp1和Shp3会交互,Shp2和Shp3不会交互.由大到小对应shp4、shp3、shp2、shp1

    总结

    1:Filter是Shape的属性,在一开始就创建好了,Group是所有Interactor的属性,但默认是null的.需要自己new

    2:创建的数量区别,filter很多,但是group是无限的

    3:Filter有特定类型的Filter,比如Collision有对应的group和mask,Sensor又有对应的group和mask,但Group是不需要这么指定的.

    4:Filter的操作更加底层,需要熟悉位运。

  • 相关阅读:
    【BZOJ2138】stone
    【ARC076F】 Exhausted
    [SDOI2018]战略游戏
    CF536D Tavas in Kansas
    [JSOI2018]战争
    ###学习《C++ Primer》- 5
    ###学习《C++ Primer》- 4
    ###Linux基础
    ###Linux基础
    ###Linux基础
  • 原文地址:https://www.cnblogs.com/ddw1997/p/3166805.html
Copyright © 2020-2023  润新知