Chipmunk 碰撞对:cpArbiter

优质
小牛编辑
130浏览
2023-12-01

Chipmunk的cpArbiter结构封装了一对碰撞的形状和关于他们的所有碰撞数据。

为什么称之为仲裁者?简短来说,我一直用的是“仲裁”来形容碰撞解决的方式,然后早在2006年当我在看Box2D的求解器的时候看到了Box2D居然叫他们仲裁者。仲裁者就像是一个法官,有权力来解决两个人之间的纠纷。这是有趣的,使用了合适的名字并且输入比我以前用的CollisionPair要短。它最初只是被设定为一个私有的内部结构,但却在回调中变得有用。

内存管理

属性

触点集

通过触点集我们得到接触信息变得更为容易。

  1. cpContactPointSet cpArbiterGetContactPointSet(const cpArbiter *arb)

从仲裁者中得到的触点集结构域。

你可能通过下面的方式来得到并且处理一个触点集:

  1. cpContactPointSet set = cpArbiterGetContactPointSet(arbiter);
  2. for(int i=0; i<set.count; i++){
  3. // 得到并使用正常的触点集和穿透距离
  4. set.points[i].point
  5. set.points[i].normal
  6. set.points[i].dist
  7. }
  1. void cpArbiterSetContactPointSet(cpArbiter *arb, cpContactPointSet *set)

帮助函数

  1. void cpArbiterGetShapes(cpArbiter *arb, cpShape **a, cpShape **b)
  2. void cpArbiterGetBodies(const cpArbiter *arb, cpBody **a, cpBody **b)

得到在仲裁者关联的碰撞处理中所定义的形状(或者刚体)。如果你定义了一个处理函数如cpSpaceAddCollisionHandler(space, 1, 2, …),你会发现a->collision_type == 1并且b->collision_type == 2。便捷的宏为你定义并且初始化了两个形状变量。默认的碰撞处理函数不会使用碰撞类型,所以顺序是未定义的。

  1. #define CP_ARBITER_GET_SHAPES(arb, a, b) cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b)
  2. #define CP_ARBITER_GET_BODIES(arb, a, b) cpBody *a, *b; cpArbiterGetBodies(arb, &a, &b);

定义变量并且从仲裁者中检索形状/刚体所用的缩略宏。

  1. cpVect cpArbiterTotalImpulseWithFriction(cpArbiter *arb);
  2. cpVect cpArbiterTotalImpulse(cpArbiter *arb);

返回为解决碰撞而施加于此步骤的冲量。这些函数应该只在postStep()cpBodyEachArbiter()回调中被调用,否则结果将不可确定。如有疑问要不知道要使用哪个函数,使用cpArbiterTotalImpulseWithFriction()

  1. cpFloat cpArbiterTotalKE(const cpArbiter *arb);

计算在碰撞中的能量损失值包括静摩擦不包括动摩擦。这个函数应该在postSolve(), postStep()或者cpBodyEachArbiter()回调中被调用。