- クオータニオンを使ってボーンを回転させる - |
今回はボーンの動かし方を考えてみたいと思います。 ・制御をクォータニオンで このボーンを描いたときに使ったクォータニオンをQとします。 このQに、ボーンをある軸で回転させるクォータニオンqを合成すればよいわけです。 軸となるベクトルは、各座標系のクォータニオンを使って変換すれば求められます。 次の図は前回出てきた図です。 赤い座標系から緑の座標系に変換するクォータニオンをQgとします。 今、赤い座標系をクォータニオンQrを使って回転させたとします。 この回転のときに、緑の座標系・青の座標系が赤い座標系の回転とともに回転しないと、 ボーンがちぎれてしまい、腕のような動きになりません。 そこで、QgとQrを合成します。 この合成によって、緑の座標系にも赤い座標系の回転が加えられることになります。 同じように青のボーンのクォータニオンにもQrを合成すれば赤のボーンの回転と一緒についてきます。 #合成については前回を参照してください。 ・実際に動かす 前回のサンプルソースを使ってボーンを動かしてみます。 [実行したところ] 前回描画したボーンを曲げてみたところです。 赤→緑→青の順に親子関係が成り立っていて、 青のボーンには子が無く、赤のボーンの親座標系というのはOpenGLの空間を表す座標系です。 ・サンプルソース 前回のサンプルでデータを作成してあるものとします。 Vector drawBone; drawBone = b[0].position; //最初に描画するボーン位置を入れておく Quaternion quat; //上位ボーンの回転クォータニオンから下位ボーンの回転クォータニオンを合成したもの //単位クォータニオンで初期化 quat.t = 1.0; quat.x = 0.0; quat.y = 0.0; quat.z = 0.0; for(i = 0; i < 3; i++) { glTranslatef(drawBone.x, drawBone.y, drawBone.z); //最初のボーンはpositionから描画。次以降のボーンは前のボーンの先端から描画} 描画した時点で、b[i].boneVectorにボーンの初期姿勢のベクトルが格納されています。 そのベクトルをそのまま描くとボーンの初期状態が描くことができます。 今回はその初期姿勢を回転させて動かそうというものです。 QuaternionRotationAxis()で、各ボーンデータのb[i].axisVectorを回転軸として、指定した角度分回転させるクォータニオンを作成します。 そしてその次の行で回転クォータニオンを上位ボーンの回転クォータニオンと合成しています。 この合成によって上位ボーンの回転が、描画しようとするボーンに伝わった上で描画ボーンの回転をさせることができます。 つまり、描画するボーンより上位のボーンすべての回転クォータニオンを合成し、 そこに新たに描画ボーンの回転クォータニオンを合成するということです。 同じことを次々と下位ボーンにて行うことで、ボーンの回転ができます。 |