地形との衝突判定

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
fulls
記事: 72
登録日時: 14年前
住所: 埼玉

地形との衝突判定

#1

投稿記事 by fulls » 13年前

DirectX9で3Dのフライトシューティングゲームを作ろうと思っています。
で、地形(山)との衝突判定で詰まっています。
衝突判定をどうやるかネットでいろいろ探したところ「ゲームつくろー」というサイトに出会い、そこの記述を参考に自分ですこし考えてみました。

1.地形のXファイルからメッシュを得る。
2.得たメッシュから座標データを取り出す。
3.抜き取った座標データから表面の三角ポリゴンを作る。
4.三角ポリゴンと自機の位置関係を調べる。

で、これをやろうと思ったのですがメッシュから座標データを取り出し三角ポリゴンを作ることに苦戦しています。
ID3DXBaseMesh::GetVertexBufferをつかったのですが、どの頂点の組み合わせで三角ポリゴンを作ればいいのかわかりません。
頂点インデックスが関係して来るのかと思いいろいろ探し回っているのですが、なかなか見つかりません。
GetVertexBufferで頂点データを得たあとの処理をおしえてください。
また、地形との衝突判定の方法についてもっといい方法があったら教えてください。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: 地形との衝突判定

#2

投稿記事 by ISLe » 13年前

メッシュとの当たり判定なら、D3DXIntersectを使うと楽かもしれません。
yucky001 さんが書きました:で、これをやろうと思ったのですがメッシュから座標データを取り出し三角ポリゴンを作ることに苦戦しています。
ID3DXBaseMesh::GetVertexBufferをつかったのですが、どの頂点の組み合わせで三角ポリゴンを作ればいいのかわかりません。
頂点インデックスが関係して来るのかと思いいろいろ探し回っているのですが、なかなか見つかりません。
頂点インデックスはID3DXBaseMesh::LockIndexBufferを使ってポインタを取得できます。

頂点データは頂点フォーマットによってサイズが異なります。
ID3DXBaseMesh::GetFVFで得られる頂点フォーマットコードを使ってD3DXGetFVFVertexSizeを呼び出すと頂点データ一個分のサイズを求めることができます。

fulls
記事: 72
登録日時: 14年前
住所: 埼玉

Re: 地形との衝突判定

#3

投稿記事 by fulls » 13年前

ISLeさん、返信ありがとうございます。
教えていただいたD3DXIntersectなのですが、msdnを見ていて10個目の引数に
pCountOfHits
[out] ppAllHits 配列内のエントリ数を格納する DWORD へのポインタ。
とあったのですが、これは何ですか?

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: 地形との衝突判定

#4

投稿記事 by ISLe » 13年前

yucky001 さんが書きました:
pCountOfHits
[out] ppAllHits 配列内のエントリ数を格納する DWORD へのポインタ。
とあったのですが、これは何ですか?
9番目の引数(ppAllHits)でレイに交差するすべてのポリゴンの情報を持つID3DXBufferオブジェクトへのポインタを取得できますが、それがポリゴン何個分の情報なのかを変数に取得するため、変数のポインタを指定することができます。
レイの始点から最も近いポリゴンは除きます。

地形との当たり判定なら最も近いポリゴンだけが分かれば良いと思います。
取得する必要がない出力パラメータにはNULLを指定することができます。

fulls
記事: 72
登録日時: 14年前
住所: 埼玉

Re: 地形との衝突判定

#5

投稿記事 by fulls » 13年前

ISLeさん、返信ありがとうございます。
D3DXIntersectを使って衝突判定用の関数を作ってみましたがうまく動作しません。

コード:

int GetCollisionJudge(LPD3DXMESH mesh,D3DXVECTOR3 point,D3DXVECTOR3 direction){
	float dis;
	BOOL judge;
	D3DXIntersect(mesh,&point,&direction,&judge,NULL,NULL,NULL,&dis,NULL,NULL);
	if(judge){
		if(dis<0){
			return 1;
		}else{
			return 0;
		}
	}else{
		return 0;
	}
}
この関数で衝突判定を行うと地面にぶつかっているのに返り値として1が返ってきません。
少しD3DXIntersectについて調べていたらメッシュを移動・拡大している場合うまく動作しないと書いてあったのですが、自分は移動も拡大も行っています。
原因は移動・拡大でしょうか?

アバター
うしお
記事: 56
登録日時: 14年前

Re: 地形との衝突判定

#6

投稿記事 by うしお » 13年前

D3DXIntersect 関数は、モデルをローカル座標で計算します(当然といえば当然ですが)

モデルに移動、拡大を行っている場合、
レイに対して(レイの始点、向き両方に対して)、
モデルを描画する時に使用しているワールド行列の逆行列を、あらかじめ掛け算しておく必要があります。

注意点としては、向きは平行移動されると困るので、D3DXVec3TransformCoordを使用するところでしょうか
(始点と終点で計算する場合は普通に掛け算するだけでよいですが)

【蛇足】
別なアプローチでは、描画用メッシュとは別に、ポリゴン数を減らしたコリジョン用ポリゴンデータを用意し、
それを読み込んで衝突判定を行う方法もあります。
モデラーでwavefront objなどの読みやすい形式で保存し、
そこからポリゴンデータだけ抽出し、独自形式にでも変換すればよいでしょう。
こちらは少し手間が増えますが、柔軟なアプローチではないかと思います。

【追記】
関数名を修正しました
最後に編集したユーザー うしお on 2011年9月07日(水) 10:27 [ 編集 1 回目 ]

fulls
記事: 72
登録日時: 14年前
住所: 埼玉

Re: 地形との衝突判定

#7

投稿記事 by fulls » 13年前

うしおさん、返信ありがとうございます。
教えていただいた通り逆行列をかけて判定をしたところ、なんとも言えない結果になりました。
途中までは正しく動作するのですが、機体がある一線を越えると常に当たっていると判定されてしまいます。
何故でしょうか?


書き換えた関数です。↓

コード:

int GetCollisionJudge(LPD3DXMESH mesh,D3DXVECTOR3 point,D3DXVECTOR3 direction,D3DXMATRIX mat,float distance){
	float dis;
	BOOL judge;
	D3DXMATRIX matI;
	D3DXMatrixInverse(&matI,NULL,&mat);
	D3DXVECTOR3 pointI,directionI;
	D3DXVec3TransformCoord(&pointI,&point,&matI);
	D3DXVec3TransformCoord(&directionI,&direction,&matI);
	D3DXIntersect(mesh,&pointI,&directionI,&judge,NULL,NULL,NULL,&dis,NULL,NULL);
	if(judge){
		if(dis<distance){
			return 1;
		}else{
			return 0;
		}
	}else{
		return 0;
	}
}

アバター
うしお
記事: 56
登録日時: 14年前

Re: 地形との衝突判定

#8

投稿記事 by うしお » 13年前

向きは平行移動されると困るので、D3DXVec3TransformCoordを使用する必要があります。
ご注意ください。

fulls
記事: 72
登録日時: 14年前
住所: 埼玉

Re: 地形との衝突判定

#9

投稿記事 by fulls » 13年前

無事できたので解決です。
皆さんありがとうございました。

sas

Re: 地形との衝突判定

#10

投稿記事 by sas » 13年前

(現在地のx-y座標を取得して
その地点の高さをzとして
機体の高さから引いてマイナスになったら衝突してるって判断すると
楽?)

閉鎖

“C言語何でも質問掲示板” へ戻る