プロジェクト演習 Ⅳ インタラクティブゲーム 制作 プログラミング 4
DESCRIPTION
プロジェクト演習 Ⅳ インタラクティブゲーム 制作 プログラミング 4. 2011/11/29 当たり 判定 総復習. 今日の内容. 当たり判定の素材を整理しよう 基礎となる計算の整理 座標系の正規化 球ベース判定 角張系判定 戻し方で苦労 しよう 速度 分解 ゲームの特性に合わせた戻し方. 覚えておいて欲しい計算. 距離を算出できると判定に使える 点と点 まさかこれが出来ないという人はおる まいね ? 点と線 & 線と線 fk_Math クラス参照 点と平面 & 線と平面 「 三次元幾何要素表現と交差交線計算 」参照 - PowerPoint PPT PresentationTRANSCRIPT
プロジェクト演習Ⅳインタラクティブゲーム制作
プログラミング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の順に判定できればいいが、そうならなかったらどうする?
真上から見た図
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;