if ((catA & maskB) != 0 && (catB & maskA) != 0)
它在Box2d 的手册:6.2中,用于检查两个对象是否应该碰撞(过滤后)
它检查 catA 至少有一个与 maskB 相同的“1”位,并且 catB 至少有一个与 maskA 相同的“1”位。
例如,如果 catA 为 3(二进制 00000011)且 maskB 为 10101010),则 (catA & maskB) != 0 为真,因为 catA & maskB 为 00000010。
这称为掩码,这意味着只保留感兴趣的位。
你经常有这种结构:
#define READ 1
#define WRITE 2
#define READWRITE (READ|WRITE)
#define DIRECTORY 4
int i=getFileInfo("myfile");
if(i & READWRITE)puts("you can read or write in myfile");
if(i & DIRECTORY)puts("myfile is a directory");
顺便说一句,“i & DIRECTORY”的含义与“(i & DIRECTORY) != 0”相同
该符号&
是按位与运算符。因此,声明
(catA & maskB) != 0
检查这两个项目中是否有任何位重叠。它查看是否先检查 A 和 B,然后检查 B 和 A。
catA 是对象 A 的碰撞类别的位字段 maskA 是对象 A 可以碰撞的类别的位字段。
例如:
catA = 100010000010010 // Object A is in 4 collision categories
maskA = 001010000000000 // Object A can collide with too different categories
catB = 000010001000001 // Object B is in 3 collision categories
maskB = 100000000000000 // Object B can only collide with the category represented by the highest bit
catA & maskB 表示 catA 和 maskB 中均为 1 的位,因此1000000000000000
. 它不是 0,因为对象 B 可以与最高位的对象发生碰撞,并且对象 A 设置了该位。
catB & maskA 表示在 catB 和 maskA 中均为 1 的位,因此0000100000000000
. 它也不为零,因为对象 A 可以与第 5 位最高位类别中的对象发生碰撞,而对象 B 属于该类别。
所以这两个物体可以碰撞。
我知道许多 C/C++ 程序员喜欢简洁,但我发现通过将此测试移到函数中可以使这种类型的代码更具可读性(如果需要,可以内联它)。他们也可以通过将代码移动到一个命名良好的方法来摆脱注释。
if (FixturesCanCollide() )
{
}
实际上,您可以放弃与 !=0 的比较(尽管为了清楚起见,您可能更喜欢它,但无论哪种方式,它都可能编译为相同的代码。
inline bool FixturesCanCollide()
{
return (catA & maskB) && (catB & maskA);
}