スライド 1

プロジェクト演習Ⅳ
インタラクティブゲーム制作
プログラミング4
2011/11/29
当たり判定総復習
今日の内容
• 当たり判定の素材を整理しよう
– 基礎となる計算の整理
– 座標系の正規化
– 球ベース判定
– 角張系判定
• 戻し方で苦労しよう
– 速度分解
– ゲームの特性に合わせた戻し方
覚えておいて欲しい計算
• 距離を算出できると判定に使える
– 点と点
• まさかこれが出来ないという人はおるまいね?
– 点と線&線と線
• fk_Mathクラス参照
– 点と平面&線と平面
• 「三次元幾何要素表現と交差交線計算」参照
• 線と平面の交差判定は、パラメータu,vを算出する
ことで三角形との衝突判定になるので重要
座標系の正規化とは
• こういう計算よりは
• こういう計算の方が
楽そうだよね
球ベース判定の傾向と対策
• 球
– 球だけで押し通すのは厳しいが、他の判定と併用
することも多い
• 複雑な判定の前に球ベースで判定しておくなど
– 球の中心を「点」から「線分」に拡張することに
より、「カプセル」へと進化する
• カプセル
– 球よりボリュームの広いエリアをカバー
– 球の弾丸貫通問題対策としても使用
– ボーンのように組み合わせれば人型キャラの判定
は十分作れる
球とカプセル
• 中心間の距離が、お
互いの半径の合計よ
り小さかったら衝突
• 球がうぞぞぞぞっと
動いた軌跡
• 組み合わせて人型に
したり、弾丸貫通
問題への対処に使う
• 線分と線分(点)の距離
で判定ができる
真の衝突判定とは
• ある瞬間にぶつかってるかどうか、を
調べるだけでは「干渉判定」でしかない
• 「これくらい動く予定なんだけど、
どこかでぶつかっちゃう?」を調べる
!!!!
!
?
!
角張り系判定
• 球VS球では安定した接地が難しいため、乗っかる
ことを前提とした物体は角張り系の判定が必要
– 直方体
• XYZ軸に平行に配置された直方体はAABB、
自由に回転が許されたものはOBBと呼ぶ
• 球やカプセルとの判定も可能で、
その場合は座標系の正規化を使って処理を行う
– 凸包
• 対球に関しては最強レベルの判定素材
• 凸包同士や、その他の判定素材との連携が困難
– 三角形メッシュ集合体
• DirectXやXNAではデフォルトでサポートしている
• 点や線との判定は容易だが、閉じた形状は表せないので運用
に注意が必要
凸包とは
• 凹んだ部位のない
立体
• n角柱、n角錐なども
凸包に含まれる
• 点(球)との内外判定が
べらぼうに簡単
– 衝突検出になると
難しいが。。。
三角形と線分の判定を駆使
• 理論上はどんなポリ
ゴンモデルでも対応
可能
– 破綻無く判定するのが
困難だが…
• どこでぶつかったの
か、を明確に判断で
きるのは線分系の判
定なので、それをひ
たすら駆使する
用途に応じて使い分け
• キャラクターは球
– 見た目はゴージャスに
作った形状でもいい
– それらを覆うような球
を当たり判定用に用意
して、親子関係を結べ
ばいい
• entry()しなければ表示
されない
• マップはブロック
– 球だとつるつるすべっ
て操作性に難がある
とりあえずおすすめは
• キャラ&可動障害物
– 球(カプセル)、OBB
• 地形
– 全てをOBB
– 地面はポリゴンで、
障害物はOBB
• 乗っかれる必要が
あるデカキャラなど
– OBB
• 視界判定
– ベクトルの内積による
角度判定&距離
• 攻撃判定
– 球、カプセル
戻し方
• 動物体の次フレームでの位置を仮定する
• その動きを阻害する可能性のある物体全
てと衝突判定を行う
• 戻しベクトルが発生したら動物体に適用
する
• 全物体と判定を終えたら終了…
ではない
以下のようなシチュを考える
• 右図のような状況の
場合、Aに衝突して発
生した戻しベクトル
によって、Bに衝突す
る危険性がある
• A→Bの順に判定でき
ればいいが、そうな
らなかったらどうす
る?
真上から見た図
解決案
• 候補の物体と判定して、 do {
「戻しベクトルが発生
戻しベクトル初期化
しなかったら」判定終
for(障害物候補全部) {
了とする
当たり判定する
• 色々効率化の余地はあ
戻しベクトル加算
るだろうが、とりあえ
}
ずはこうしておこう
動物体に適用
} while(適用したベクト
ルがゼロじゃなかった
らもう1回ループ);
重力の扱い
• 基本的には常時下向
きの力を働かせる
• そうすると、同じ高
さで並べたブロック
でつっかかる
– 足下のブロックから先
に判定できればいいが、
そうもいかない
• 速度をXZ方向とY方
向に分解して2回判定
真横から見た図
A
B
どちらが好ましいか?
• ぶつかった時点で
止まるタイプ
• 壁擦れするタイプ
効率的な判定のためテクニック
• 距離で刈り込む
– OBBの判定より距離の判定の方が軽い
– 具体的な距離の値が要らない(距離内かどう
かだけが知りたい)場合は、ベクトルの長さ
の2乗と判定距離の2乗で比較しよう
• if(vec.dist2() < d*d) のように判定
• クラスタで刈り込む
– 常時全物体と判定するのはナンセンスの極み
クラスタリングって?
• モノの分類や、
グループ分けのこと
– マップを領域ごとに分
割する
– 領域ごとに「どの物体
が存在しているか」の
リストを持つ
– 判定したくなったら、
自分が居る領域のリス
トに問い合わせて判定
真上から見た図
クラスタリングに必要な部品
• 座標→クラスターIDへの変換
– (x, z)の座標値を、一定間隔ごとの整数値に
変換する必要がある
• 配列の配列
– クラスターIDで問い合わせると、対応する領
域の物体情報が取れるようにしたい
– vector< vector<int> >などを使う
• 本当はlistなどに出来ればした方がよい
当たり判定クラスの設計方針
• 現状のfkutシリーズ
ではまだまだです
• 共通の基底クラスを
持たせて、個別の判
定クラスはそれを継
承して作るようにす
べき
• チームを超えて設計
して、共通のクラス
を開発するのもgood!
• こうなるよりは…
vector<fkut_OBB *>
obbArray;
vector<fkut_Capsule *> capArray;
vector<fkut_... *>
otherArray;
• この方がいい
vector<fkut_Collision *>
colArray;