if ((catA & maskB) != 0 && (catB & maskA) != 0)
Box2d のマニュアル: 6.2にあり、2 つのオブジェクトが衝突するかどうかを確認するために使用されます (フィルタリング後) 。
if ((catA & maskB) != 0 && (catB & maskA) != 0)
Box2d のマニュアル: 6.2にあり、2 つのオブジェクトが衝突するかどうかを確認するために使用されます (フィルタリング後) 。
これは、catA が maskB と共通の「1」ビットを少なくとも 1 つ持ち、catB が maskA と共通の「1」ビットを少なくとも 1 つ持つことを確認します。
たとえば、catA が 3 (バイナリ 00000011) で maskB が 10101010 の場合、catA & maskB は 00000010 であるため、(catA & maskB) != 0 は true です。
これはマスキングと呼ばれ、関心のあるビットのみを保持することを意味します。
あなたはしばしばこの種の構造を持っています:
#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」と同じ意味です
記号&
はビットごとの AND 演算子です。したがって、ステートメント
(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
. オブジェクト B は最上位ビットのオブジェクトと衝突する可能性があり、オブジェクト A にはそのビットが設定されているため、0 ではありません。
catB & maskA は、catB と maskA の両方で 1 であるビットを意味するので、0000100000000000
. また、オブジェクト A は 5 番目に高いビット カテゴリのオブジェクトと衝突する可能性があり、オブジェクト B はそのカテゴリにあるため、ゼロではありません。
したがって、2 つのオブジェクトが衝突する可能性があります。
多くの C/C++ プログラマーが簡潔さを好むことは知っていますが、このタイプのコードは、このテストを関数に移動することではるかに読みやすくすることができます (必要に応じてインライン化できます)。コードを適切な名前のメソッドに移動することで、コメントを取り除くこともできたはずです。
if (FixturesCanCollide() )
{
}
!=0 との比較を実際に破棄することもできます (ただし、わかりやすくするためにそれを好むかもしれませんが、どちらの方法でもおそらく同じコードにコンパイルされます。
inline bool FixturesCanCollide()
{
return (catA & maskB) && (catB & maskA);
}