0

基于 short int 的掩码如何在 c++ 中工作(例如Bullet中的掩码)?

看子弹

CollisionFilterGroups { 
  DefaultFilter = 1, 
  StaticFilter = 2, 
  KinematicFilter = 4, 
  DebrisFilter = 8, 
  SensorTrigger = 16, 
  CharacterFilter = 32, 
  AllFilter = -1 
}

并看到所有值都是 2 的度数,我知道

short 是有符号整数,需要 2 个字节来存储,从 -32,768 到 +32,767。

但是如何创建我自己的组:如何计算掩码交叉点?

例如,除了 CollisionFilterGroups 之外,如何创建类似:

MyCollisionFilterGroups { 
  Cubes= ?,
  Boxes= ?, 
  Spheres= ?
}

在哪里

  • 我们希望“planes”不与“planes”、“boxes”和“spheres”发生碰撞(“see”)
  • 我们希望“盒子”与其他“盒子”和“球体”发生碰撞
  • 我们希望“球体”不与“球体”碰撞,但与“盒子”碰撞
4

3 回答 3

2

基本上,如果它是 2 的幂,这意味着比二进制表示中只有一个 1 位,其余为 0,如下所示:1 = 1, 2 = 10, 4 = 100, 8 = 1000, 16 = 10000 以此类推。现在让我们说 a = 1, b = 2, c = 4, d = 8, e = 16, f = 32。如果你有一个数字并且你想看看它是否有 a 和 e 你做一个这样的面具: a|b(or)...这将导致 10001 二进制表示。

假设您要测试 a 和 e 的数字是 X。仅当 X 包含 a 和 e 时,以下语句才成立:X&(a|e) == X,即 X 并且(a 或 e)等于 X。

对于第一个示例,X 是 11001,即包含 a 和 e。11001 & 10001 将是 10001,所以这是真的,因此您发现 X 包含 a 和 e。

第二个例子:X 是 100111,即包含 a,但不包含 e。当你用 a|e(10001)“和”它时,它会得到 000001,它不等于 X,因此 X 不包含。

现在初始化,如果你想要一个数字包含 a,c,e 你写: X=a|c|e

这一切都归结为数字的二进制表示。在您编写的示例中,还有一个 -1,在二进制表示中是 1111..11,这意味着它涵盖了所有内容。

希望这可以帮助

于 2012-11-05T13:04:49.143 回答
1

您的问题尚不清楚,但我认为您正在寻找为模拟中的对象设置类别和掩码位:

MyCollisionFilterGroups { 
    Plane= 64,
    Box= 128, 
   Sphere= 256
}

平面,类别位 = 平面,掩码 = 0

Box,类别位 = Box,掩码 = Box + Sphere(或 Box | Sphere)

球体,类别位 = 球体,掩码 = 框

简而言之,为每个过滤器组创建 2 的幂,将每个对象的类别掩码设置为组枚举,并将其掩码设置为您希望它与之碰撞的对象类型的枚举(或 0 表示不碰撞) .

于 2012-11-05T20:52:08.873 回答
0

不确定 Bullet 具体是如何工作的,但想法是这样的:

每个对象都有一个碰撞组标志和一个碰撞掩码。碰撞组是对象的分类器(什么样的对象)。碰撞掩码是您的对象与之碰撞的所有组(分类器)(通常它以 0xffff 开头,这意味着它与所有东西碰撞)

在碰撞测试中,它是这样的:

if( obj->group & otherObj->mask
    &&
    obj->mask & otherObj->group )
 ..check collision..

如果您想创建新组,(我不知道项目符号如何工作或允许这样做),创建一个只设置一个位的组,并且尚未设置(您在帖子中显示的那些),我不喜欢用整数,很混乱,我更喜欢位移:

DefaultFilter = 1 equals (1<<0)
StaticFilter = 2, equals (1<<1)
KinematicFilter = 4, equals (1<<2)
DebrisFilter = 8, equals (1<<3)
SensorTrigger = 16, equals (1<<4)
CharacterFilter = 32, equals (1<<5)
AnewGroup_Box = (1<<6),
AnewGroup_Sphere = (1<<7)

最多短的位数(主要是 16 位)。要设置您的对象(不是组)与哪些组发生冲突,只需将掩码中的组组合起来:

myObj->mask = AnewGroup_Box | StaticFilter | DebrisFilter; // groups obj will collide

我不确定 Bullet 是如何工作的,你..

希望这会有所帮助,如果我错了,请纠正我。

于 2012-11-06T22:11:48.470 回答