スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[DirectX9.0]ヘルパー関数で床との当たり判定

3Dアクションゲームを作ることになったので、いろいろメモ用にブログを使う。

・やりたいこと

ステージの判定メッシュの上にキャラクターを立たせたい。
ステージの判定メッシュの坂に沿ってキャラクターを移動させたい。

・やったこと

地面メッシュの作成。メタセコイヤで50x50で分割した平面を作り、でこぼこさせて、xファイルに出力。

地面メッシュを表示。D3DXLoadMeshFromX関数からパパパっと。

20141218_当たり判定1
いしのなかにいる

ゲームプログラム制作日記 ~レイ(光線)でのあたり判定~
こちらを参考にD3DXIntersect関数を使って、地形と当たったかは判定出来た。
レイは真下に飛ばした。

あとは当たったポリゴンの情報を使って、地面に沿わせるようにキャラのY座標を調整する。

ここで、Xファイルのメッシュから頂点の構造体の中身を得る方法が分からないので調べる。

[ゲームつくろ~質問箱]D3DXMESHからskinweightsとボーンオフセット行列を取得したいのですが
ID3DXMesh::GetDeclarationメソッドで、頂点構造体の情報を得られるらしい。

		D3DVERTEXELEMENT9 aElements[ MAX_FVF_DECL_SIZE ];
pLandMesh->GetDeclaration( aElements );


上記のコードを書き、ブレークを挟んで数値をチェック。

20141220_当たり判定2
GetDeclarationメソッドで受け取った、D3DVERTEXELEMENT9型配列。

MSDNを使って調べたところ。TypeとUsageが、頂点構造体の型や意味を表してるようです。
1つめは、float3つで「Position」。つまり頂点位置。
2つめは、float3つで「Normal」。法線。
3つめは、D3DCOLOR型で「Color」。色。
4つめは、float2つで「TexCoord」。テクスチャ座標(u,v)
5つめはオフセットが0だったりと、ちぐはぐなので、たぶん終了でしょう。なので、上記4つが頂点構造体の中身っぽいです。
メタセコイヤで作ったxファイルなので、同じようにメタセコイヤで作ったxファイルはこの構造体を流用出来るはず。

頂点構造体を新しく作り、調べるのに使ったコードは削除。

[ゲームつくろ~質問箱]DirectX9での、「フェイスを表す頂点のインデックスの列」の取得方法

あとは、ここの>>2416を参考にして、レイの命中座標を算出。それを、キャラクターのY座標にセット。

すると、山部分は相変わらずめり込むが、凹んでいる場所はうまく地面に沿ってくれた。
いろいろ試すと、キャラ座標から真下に飛ばしていたレイを真上に飛ばすように変更すると、山部分に沿ってキャラクターが移動するように。凹んでいる部分はキャラクターに重力を設定することで、落ちるように。



図を描くと、納得。

20141220_当たり判定3

今回書いた地形判定と地形に沿わせるコードを抜粋。

	// 地形判定
BOOL bIsHit = false;
float fLandDistance;
LPD3DXMESH pLandMesh = GetLandMesh();
DWORD dwHitIndex = -1;
float fHitU;
float fHitV;

D3DXIntersect( pLandMesh, &g_player.pos, &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) , &bIsHit, &dwHitIndex, &fHitU, &fHitV, &fLandDistance, NULL, NULL );

// ----- 接地時処理 -----
if( bIsHit )
{

// ----- キャラY座標補正 -----
// 当たったインデックスバッファ取得
WORD dwHitVertexNo[ 3 ];
WORD *pIndex;
HRESULT hr = pLandMesh->LockIndexBuffer( 0, (void**)&pIndex );

for( int nIdxIdx = 0; nIdxIdx < 3; nIdxIdx ++ )
{
dwHitVertexNo[ nIdxIdx ] = pIndex[ dwHitIndex * 3 + nIdxIdx ];
}

pLandMesh->UnlockIndexBuffer();

// 当たったポリゴン取得
VERTEX *pVertex;
hr = pLandMesh->LockVertexBuffer( 0, (void**)&pVertex );

// 地面の高さに合わせる
g_player.pos.y = pVertex[ dwHitVertexNo[ 0 ] ].pos.y +
fHitU * ( pVertex[ dwHitVertexNo[ 1 ] ].pos.y - pVertex[ dwHitVertexNo[ 0 ] ].pos.y ) +
fHitV * ( pVertex[ dwHitVertexNo[ 2 ] ].pos.y - pVertex[ dwHitVertexNo[ 0 ] ].pos.y );

pLandMesh->UnlockVertexBuffer();

// Y移動量を0に
g_player.move.y = 0.0f;

}

// 位置移動
g_player.pos += g_player.move;

// 重力
g_player.move.y -= 0.1f;


・参考ページ

ゲームプログラム制作日記 ~レイ(光線)でのあたり判定~
D3DXIntersect関数

2-1-1.D3DXIntersect関数
D3DXIntersect関数。引数について。

サンプルプログラム 3Dアクション基本
衝突応答関係

[ゲームつくろ~質問箱]DirectX9での、「フェイスを表す頂点のインデックスの列」の取得方法
衝突面の法線の取得、及び重心座標の使い方

[ゲームつくろ~質問箱]D3DXMESHからskinweightsとボーンオフセット行列を取得したいのですが
ID3DXMesh::GetDeclarationメソッド。
頂点構造体の取得に使う。

[DirectX9]行列とドット絵[備忘録]

がっこの課題でDirectX9を触っているので、この前の土日の備忘録

・行列
DirectX9では行列ヘルパ関数があり、固定機能パイプラインなるものを通して、設定された頂点が設定された行列変換されます。

この時、行列変換の対象となるのは変換済みでない頂点になります。
自前で計算しない限り、変換済みの頂点なんてないと思いますが、頂点フォーマットでXYZRHWを指定している場合は別です。
その頂点フォーマットの頂点は、変換済みと見なされ、行列が全く適用されません
これに気付くのに4時間掛かりました。

・ドット絵
そんなわけで、めでたく行列変換が可能になったんですが、今度はテクスチャのドット絵がボヤける問題が。

これの解決方法は

1.テクスチャの拡縮時の補正をD3DTEXF_POINTにする

pD3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_POINT ); // テクスチャ拡大時の補間設定
pD3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_POINT ); // テクスチャ縮小時の補間設定

2.テクスチャ生成時、画像補正をD3DX_FILTER_POINTにする

D3DXCreateTextureFromFileEx( pDevice, szFilepass, m_nTexWidth, m_nTexHeight, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,D3DX_FILTER_POINT, D3DX_FILTER_POINT, 0, NULL, NULL, &m_pTexture

3.テクスチャ生成時、テクスチャのサイズを画像サイズより大きい最小の2のべき乗の数にする
4.描画時、変換済み頂点の座標を(-0.5,-0.5,0.0)ずらす

の4つです(おいらの環境では)

変換済みの頂点をずらすのは、移動行列に渡す座標を加工すれば出来ました。

ただ、テクスチャのUV座標を弄る場合、頂点のロックが入るので、少し重くなります。一つの画像にスプライトをまとめている時のゲームの動作を最適化する時は考えものです。
ドット絵は自前で行列変換を行い、DrawPrimitiveUPで描画が良いのでしょうか。

・結論
DirectX9でドット絵、というか2Dゲームはめんどくさすぎです。他にいろいろ手段がある現在、無理して生のDirectXを触って2Dゲーム作るのは、モチベーションのコストパフォーマンスが悪いです。
少なくとも、行列ヘルパ関数とドット絵は共存は出来ないでしょう。

おいらがよく見に行くまるぺけさんのサイトでは、自作シェーダを使っていました。
その3 スクリーン座標にテクスチャの一部を2D描画する仕組み

・これからのプログラミングについて
DirectXに「普通これすれば、こうなるだろう」という、理想の動きを全く期待しないほうがいいので、デバッグ作業はトップダウンで。いろいろ弄る前に、自分のコードでのDirectXの設定と、DirectXについての解説しているサイトをみまくる。

・参考サイト
DirectXにおける2D描画

DrawPrimitive周り

続きを読む

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
プロフィール

ぴお

Author:ぴお
ようこそ

自分のゲーム制作での備忘録や製作記録を書き留めておくブログです。

■やってるサービス
Twitter:piorimumu

Pixiv
http://www.pixiv.net/member.php?id=1126385

Twitter
このページのトップへ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。