トップページ > 記事閲覧
衝突判定の負荷
名前:田中星人 日時: 2014/06/17 22:52

「DxLibModelViewerで開けないFBXファイル」の質問の時はありがとうございました。 また新しい疑問が2つほど生じたので質問させていただきます。 1.衝突の負荷について 現在、MV1CollCheck_Sphere()を使った球とモデルの衝突判定を行っています。そこで、前回の質問で用いた木のモデル(頂点数が多い)でも衝突判定を行ったのですが、MV1CollCheck_Sphere()の処理に高い負荷がかかってしまっています。 MV1SetupCollInfo()の仕様は、モデルを引数で指定した格子数で区切り、その格子を用いて衝突判定を行うものであると解釈しています。 もし、私の解釈が正しければ、MV1CollCheck_Sphere()に掛かる負荷はポリゴンの頂点数にかかわらず、MV1SetupCollInfo()で指定した格子数に比例するのではないかと思います。 そこで、なぜ少ない格子数にしたにもかかわらず、木のモデルとの衝突判定で高負荷がかかっているのか。 その理由をご教授いただけると幸いですm(_ _)m 2.境界球について  モデルを包む最小の球体である境界球やAABBを取得する関数はDXライブラリにありますでしょうか? 衝突判定に何かと必要のなので、教えていただきたいです。
メンテ

Page: 1 |

Re: 衝突判定の負荷 ( No.1 )
名前:管理人 日時:2014/06/17 23:06

> MV1SetupCollInfo()の仕様は、モデルを引数で指定した格子数で区切り、その格子を用いて衝突判定を行うものであると解釈しています。 いえ、違います 格子に区切って、各格子に接触しているしているポリゴンとの当たり判定を行います なので、ポリゴン・頂点の数はダイレクトに処理負荷に関わってきます 格子の意味ですが、不要なポリゴンとの当たり判定を無くす為の仕組みです 例えば幅と奥行きが1kmの巨大な街のモデルを作成したとします その街にキャラクターモデルを歩かせる場合は、当然キャラクターモデルは 街モデルのポリゴンと当たり判定を行い、壁や床にめり込まないようにします このとき、キャラクターが街モデルのどのポリゴンと接触しているかを判定するために 街モデルの全てのポリゴンと当たっているかを判定するのは非常に非効率です ( 幅、奥行き1kmの街モデルに対してキャラクターモデルは非常に小さいので、 街モデルと接触している可能性のあるポリゴンは街モデル全体のごく一部だけに 限られるため ) ここで格子区切りの仕組みを使います 例えば幅・奥行き各方向に対してそれぞれ10分割して100個の格子に区切ったとします この場合一つの格子は幅・奥行きは100mです この状態でキャラクターモデルが街モデルのどのポリゴンと接触しているかを 判定する場合は、まず格子とキャラクターモデルとの当たり判定を行います そして、接触している格子に接触している街モデルのポリゴンとのみキャラクターモデルとの 当たり判定を行います こうすれば、格子をキャラクターモデルが跨っていなければ幅・奥行き100m内に 存在するポリゴンとのみ当たり判定判定を行えば良いので、街モデル全体のポリゴンと当たり判定を 行った場合より判定の処理負荷は( 街全体のポリゴン密度が一定だとして )100分の1になります ( ただ、キャラクターモデルは最大で4つの格子を跨る可能性があるので、その場合は25分の1 ) 何個の格子に分けるのが最適か、ですが、判定を行いたい対象( この場合はキャラクターモデル )の 大きさの10倍〜20倍程度が良いのではないかと思います 上記の例も、1格子の幅・奥行き100mというのはまだまだキャラクターモデルに対しては 大きいので不要なポリゴン判定が頻発していると考えられます、なので1格子の幅・奥行き10m程度が 最適かもしれません 以上、格子分け機能と用途の説明でした なので、( 2度目になりますが )ポリゴンとの判定をしているのでポリゴン数・頂点数は処理負荷に影響します なので、描画用のハイポリゴンモデルとは別に当たり判定用のローポリゴンモデルを用意して、 当たり判定についてはそちらを使うのが一般的です 32bitアプリではメモリが足りなくなるくらいのハイポリゴンモデルをそのまま当たり判定に しようすると、処理負荷は大変なことになりそうですので、似たような単純形状の ローポリゴンモデルを作成して使用してください
メンテ
Re: 衝突判定の負荷 ( No.2 )
名前:管理人 日時:2014/06/17 23:38

> モデルを包む最小の球体である境界球やAABBを取得する関数はDXライブラリにありますでしょうか? 境界球を取得する関数はありません AABBを直接取得する関数もありませんが、関数 MV1GetReferenceMesh の引数 FrameIndex に -1 を 渡して返ってきた MV1_REF_POLYGONLIST 構造体のメンバ変数 MinPosition と MaxPosition が モデル中の全頂点の最小値と最大値となっていますので、この値を使用して AABB を取得できます
メンテ
Re: 衝突判定の負荷 ( No.3 )
名前:田中星人 日時:2014/06/18 01:14

回答有難うございます。 なるほどそういうことだったんですか。納得しました。 つまり、まず格子でアバウトな衝突判定を行い、さらに衝突した格子内にある頂点・面と詳細な衝突判定を行っていた、という感じであってるでしょうか……? 私もゲームを作るにあたって似たような方式(区画を区切って同じ区画内にある物体とのみ衝突確認を行うとか)は用いていたのですが、MV1SetupCollInfo()がそれだとは気づきませんでした。勉強不足ですいませんm(_ _)m >32bitアプリではメモリが足りなくなるくらいのハイポリゴンモデルをそのまま当たり判定に しようすると、処理負荷は大変なことになりそうですので、似たような単純形状の ローポリゴンモデルを作成して使用してください はい、そうしたいと思います。ありがとうございます。 >AABBを直接取得する関数もありませんが、関数 MV1GetReferenceMesh の引数 FrameIndex に -1 を 渡して返ってきた MV1_REF_POLYGONLIST 構造体のメンバ変数 MinPosition と MaxPosition が モデル中の全頂点の最小値と最大値となっていますので、この値を使用して AABB を取得できます おお、そんな方法が……。助かります。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存