スポンサーサイト

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

"クォータニオン"を学んでみた

3Dモデルの回転などでは、 クォータニオンを使ったりすると思うのですが、
実は、 自分はまだ使ったことがありませんでした。
(基本動作は完成している自作ゲーム"立体倉庫番"は、平行移動しかしてない。

で、 クォータニオンって何?と思うのですが、
------------------------------------------------------------------------
●クォータニオンとは1つの実部(実数)と3つの虚部(虚数)で構成されている
任意の回転軸を中心とした、オブジェクトの回転を表現できる
●クォータニオンの真価は、合成と補間で発揮される

------------------------------------------------------------------------
大体こんな感じらしいです。

"回転"といえばD3DXMatrixRotationXD3DXMatrixRotationYD3DXMatrixRotationZ
とかの関数を使うと思うのですが、
これはそれぞれX軸、Y軸、Z軸を中心とした回転しか出来ず
オブジェクトを中心とした回転は出来ない んですよね。

【参考画像】
回転
D3DXMatrixRotationYを使った場合は、画像の上段ではなく、下段の様な状態になります。
その場で回転させたいのですが、あくまでもY軸を中心に回転するので、
座標も変なところへ行きます。

下記の様に例える事も出来ますね。
-----------------------------------------
画像上段 = 地球自体が回転
画像下段 = 太陽を中心に、地球が回転

-----------------------------------------

オブジェクトを中心とした回転をしたい場合はどうすれば良いかというと、
(X、Y、Z)軸中心に回転、その後 平行移動という形になります。

オブジェクトが(2,0,2)にあるとした場合、まず(0,0,0)で回転。
その後、X軸に2、Z軸に2平行移動、みたいな。

これは行列の合成をすれば良いのですが、
いかんせん行列はfloat型が4×4の16個もあるので、
処理が大変になってしまいます。

ここで、優位なのが、クォータニオンという訳です。
(クォータニオンはfloat値が4つです。要素が少ないので処理も当然早くなります。

で、クォータニオンを使った物体の回転が端的に載ってるサイトはなかなか見つからなくて
困った
ので、自分は端的に書きたいと思います。
----------------------------------------------------------------------
void QuaternionTest(void)
{
D3DXQUATERNION q(0,0,0,1); // 単位クォータニオン'q'を生成
D3DXMATRIX TurnMat; // 回転行列
D3DXMATRIX mat; //平行移動行列
D3DXVECTOR3 NAxis( 0, 0, 1); // 任意の中心軸

//何もしない行列を作る
D3DXMatrixIdentity(&mat);
D3DXMatrixIdentity(&TurnMat);

//x座標に3、z座標に3移動する行列
D3DXMatrixTranslation(&mat,3,0,3);

//z軸を中心に 45度 回転するクォータニオン'q'を生成
D3DXQuaternionRotationAxis( &q, &NAxis, D3DXToRadian(45));

//クォータニオンをマトリックスに変換
D3DXMatrixRotationQuaternion(&TurnMat, &q);

//行列をかける(回転させた後、行列'mat'で平行移動させる)
TurnMat*=mat;

//回転マトリックスをパイオプラインにセット
g_pd3dDevice->SetTransform( D3DTS_WORLD, &TurnMat);

//オブジェクトvtx2(ただの正方形ポリゴン)の描画
g_pd3dDevice->SetFVF(D3DFVF_VERTEX);
g_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,vtx2,sizeof(D3DVERTEXCOR));
}

----------------------------------------------------------------------

ついでに、クォータニオンの補間はD3DXQuaternionSlerp関数を使います。
クォータニオンq1とq2のちょうど中間の状態をq3に入れる場合は、
下記の様にします。
------------------------------------------------------------
D3DXQuaternionSlerp(&q3, &q1, &q2, 0.5);
※最後のfloat型は0~1までの範囲。
q    中間   q2
0  ← 0.5 →  1

------------------------------------------------------------
一応ソースコード全部です。
クォータニオン補間
スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

コメント
コメントの投稿
管理者にだけ表示を許可する



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