衝突判定に手を出すか
うーん、やっとこさ衝突判定のための仕組みを入れられました。
なんとも下らんクラスを作ってしまいました。
もっと良い方法があればいいんだけどなぁ。
objectとobjectの型を示すid、そのobjectのAABB(Axis Aligned Bounding Box)だけを持つクラスを作り、AABB同士での衝突判定をした後に、双方のidをindexにして関数ポインタのテーブルCoolideTableから、詳細な衝突判定と衝突処理を行う関数を呼び出す・・・という手筈。
class CollideTarget { public: explicit CollideTarget(void* object, unsigned int id, const Rect& bbox) : object_(object), id_(id), bbox_(bbox), collide_(false) {} public: void* object() {return object_;} const void* object() const {return object_;} Rect bbox() {return bbox_;} const Rect& bbox() const {return bbox_;} unsigned int id() const {return id_;} /* 衝突したかどうか */ void collide() {collide_ = true;} bool isCollide() const {return collide_;} private: void* object_; // 衝突対象 unsigned int id_; // 型を示すID Rect bbox_; // AABB bool collide_; // 既に衝突したかどうか }; // 衝突処理上の関数 typedef bool (*Collide)(CollideTarget& lhs, CollideTarget& rhs); // 関数ポインタのテーブル extern Collide CollideTable[]; // 衝突処理関数・・・の一部 void collide() { typedef std::vector< CollideTarget >::iterator Iterator; for (Iterator p = collideList_.begin(), pend = collideList_.end(); p != pend - 1; ++p) { // 衝突している場合は除く if (p->isCollide() == true) continue; Rect p_rect = p->bbox(); unsigned int p_id = p->id(); for (Iterator q = p + 1; q != pend; ++q) { // 既に衝突している場合は次へ if (q->isCollide() == true) continue; Rect q_rect = q->bbox(); unsigned int q_id = q->id(); // 衝突していないなら次へ if (p_rect.overlap(q_rect) == false) continue; // 衝突関数を見つけ処理 bool result; if (p_id <= q_id) result = CollideTable[p_id * ID_END + q_id](*p, *q); else result = CollideTable[q_id * ID_END + p_id](*q, *p); // 実際に衝突していた場合には後の処理中止 if (result == true) { p->collide(); q->collide(); break; } } } }
さてと今はN x Nの衝突判定を行っていますがさすがに遅くなりそうなので、まともな枝刈りをしないとね。
最初はRDC(Recursive Dimension Clustering)を試そうと思ったけれど、GameDevで調べる限りあんまり速くないみたいなので、sort-and-sweepでも勉強しますか。