物理エンジンライブラリ Box2DFlashAS3 衝突判定と衝突のグループ・カテゴリ分け

Box2Dの衝突判定と、衝突のグループ・カテゴリ分けをする方法のメモです。

衝突判定

Box2Dでは、衝突が起こった物体同士のリストが作成させるので、そのリストを取得して、衝突判定をします。
衝突の起こった物体同士は、b2Worldクラスのm_contactList(ContactListクラス)にb2Contactオブジェクトとして入れられます。
このm_contactListを、Box2Dの演算時に、順次取り出して、衝突時の処理をします。

衝突のグループ・カテゴリ分け

Box2Dで作った物体は、デフォルトでは全ての物体と衝突するようになっています。
これを、ある物体とは衝突するけどある物体とは衝突しないような、グループ分けをするには、b2ShapeDefクラスのfilter(b2FilterDataクラス)の値を変更します。

衝突のグループ・カテゴリ分けの方法

下記の二種類があって、両方を併用することもできます。

  1. groupIndex を使用する
  2. categoryBit と maskBit を使用する

1.groupIndexを使用する

groupIndexを0以外の値を指定して、グループを作る。値が正負かによって、処理が異なる。

  • の同じ値のグループ内の物体は、maskBit・categoryBitの値が何であれ、必ず衝突する
  • の同じ値のグループ内の物体は、maskBit・categoryBitの値が何であれ、必ず衝突しない

別の値のグループとは、maskBit・categoryBitの値によって、衝突判定が決まる。

2.categoryBit と maskBit を使用する

16進数4桁(2進数16桁)の categoryBit を指定。(0x0001)
maskBitも同じく16進数4桁をつける
categoryBitとmaskBitを論理積(AND)で演算して、0にならない物体同士は衝突。

Aグループ:
categoryBit=0x0001(0000 0000 0000 0001)
Bグループ:
categoryBit=0x0002(0000 0000 0000 0010)
Cグループ:
categoryBit=0x0004(0000 0000 0000 0100)
各グループ内の物体同士を衝突させる
A
maskBit=0x0003(0000 0000 0000 0011)
B
maskBit=0x0003(0000 0000 0000 0011)
C
maskBit=0x0003(0000 0000 0000 0100)
各グループ内の物体同士と、AとBグループの物体同士を衝突させる
AとB
maskBit=0x0006(0000 0000 0000 0011)
C
maskBit=0x0006(0000 0000 0000 0100)

maskBit・categoryBitのみで衝突のグループ分けしたい場合は、groupIndexをデフォルトの0のままにしておく

Body作成後に、m_filterの値を変えた場合は、b2WorldクラスのRefilterメソッドを使って、フィルターを再設定してやる必要があるようです。
変えなくてもフィルター設定反映されたのですが、念のため。

サンプルコード

実行結果(きのこと箱)
きのこと箱

※Box2Dのまとめたクラス(Box2DBase)を作って、基本クラスで使ってます。ソースは物理エンジンライブラリ Box2DFlashAS3(基本)にあります。

マウスジョイントの辺りは、Box2Dの付属コード、TestBedのTest.asのサンプルからほぼコピペです。