トップページ > 過去ログ > 記事閲覧
モデルの3D回転について
名前:sagari 日時: 2010/07/12 00:23

 はじめまして、DXライブラリを用いて3Dゲームを作っているものです。モデルの3D回転の関数に関してお聞きしたいことがあります。  モデルに独自の軸を設定し、その軸に合わせて3D回転させ、モデルが回転した場合はその回転に合わせてモデルの軸も変更するという機能の実装を考えています。 そのため、対応キーを押したときに各軸の回転量を増減させ、その値をMV1SetRotationXYZ関数にいれてみましたが、X軸は希望どおりに動き、残りのYZ軸は回転軸がモデルの回転に追従してくれません。 これは、MV1SetRotationXYZ関数の回転軸の順番がX→Y→Zであることに関係しているのでしょうか?  また、前出のような機能の実装方法についてご存知でしたらご教授願います。

Page: 1 |

Re: モデルの3D回転について ( No.1 )
名前:管理人 日時:2010/07/15 09:14

なんとなく仰りたいことは分かったのですが、細部がちょっと把握できないので よろしければ独自の軸の3D回転+モデルの回転の参考となるプログラムをこちらに 書き込んでいただけないでしょうか? ( 独自の軸を使用した3D回転ではモデルの座標だけが変化して、モデルの向き自体は MV1SetRotationXYZ関数で行うということでしょうか? ) あと、曖昧な理解でも申し上げられることとしては意図した回転にならない原因が 回転軸の順番がX-Y-Zの順番ある可能性は高いです
Re: モデルの3D回転について ( No.2 )
名前:sagari 日時:2010/07/16 23:18

>よろしければ独自の軸の3D回転+モデルの回転の参考となるプログラムを >こちらに書き込んでいただけないでしょうか? 残念ながら、具体的に参考となるプログラムがありませんが、 イメージとしてはフライトシミュレータの飛行機の動きです。 一応、こちらでコーディングしたプログラムを記述しておきます。 (なお、MV1SetRotationZYAxis関数を使用していますが、MV1SetRotationXYZ関数と実現したい動作は変わりません。) void charactorFunction(void) { chara.Xaxis = VNorm(VGet(1.0f,0.0f,0.0f)); chara.Yaxis = VNorm(VGet(0.0f,1.0f,0.0f)); chara.Zaxis = VNorm(VGet(0.0f,0.0f,1.0f)); //キャラの操作//-------------------------------------- if(CheckHitKey(KEY_INPUT_UP) == 1) { chara.Xrot += CHARA_PITCH_SPEED; if(chara.Xrot > 360.0f) { chara.Xrot = 0.0f; } } if(CheckHitKey(KEY_INPUT_DOWN) == 1) { chara.Xrot -= CHARA_PITCH_SPEED; if(chara.Xrot < 0.0f) { chara.Xrot = 360.0f; } } if(CheckHitKey(KEY_INPUT_Z) == 1) { chara.Yrot += CHARA_YAW_SPEED; if(chara.Yrot < 0.0f) { chara.Yrot += 360.0f; } } if(CheckHitKey(KEY_INPUT_X) == 1) { chara.Yrot -= CHARA_YAW_SPEED; if(chara.Yrot > 360.0f) { chara.Yrot -= 360.0f; } } if(CheckHitKey(KEY_INPUT_LEFT) == 1) { chara.Zrot += CHARA_ROLL_SPEED; if(chara.Zrot > 360.0f) { chara.Zrot -= 360.0f; } } if(CheckHitKey(KEY_INPUT_RIGHT) == 1) { chara.Zrot -= CHARA_ROLL_SPEED; if(chara.Zrot < 0.0f) { chara.Zrot += 360.0f; } } chara.Zaxis = VTransform(chara.Zaxis, MGetRotX(chara.Xrot*TRANS_RAD)); chara.Zaxis = VTransform(chara.Zaxis, MGetRotY(chara.Yrot*TRANS_RAD)); chara.Yaxis = VTransform(chara.Yaxis, MGetRotX(chara.Xrot*TRANS_RAD)); chara.Yaxis = VTransform(chara.Yaxis, MGetRotZ(chara.Zrot*TRANS_RAD));     MV1SetRotationZYAxis(chara.modelHandle, chara.Zaxis, chara.Yaxis, chara.Zrot); // 3Dモデルの描画 MV1DrawModel(chara.modelHandle); >( 独自の軸を使用した3D回転ではモデルの座標だけが変化して、モデルの向き自体は >MV1SetRotationXYZ関数で行うということでしょうか? ) モデル独自の軸で3D回転させモデルの向きを変えます。 その時に、回転で使用しなかったモデル独自の軸の傾きも変わるはずなので、 それに合うようにモデル独自の軸も回転させてやりたいのです。
Re: モデルの3D回転について ( No.3 )
名前:PATOLE 日時:2010/07/18 01:23

同じ問題なのかはわからないですが、3Dモデルの回転について非常に困ってます。 回転の順番が、 X→Y→Zになっていますが、 Y→X→Zのように、順番を変えたいのです。 例えば、丸い円盤のようなモデルが、水平になっているとします。 これを、くるくると回転(Y軸回転)させながら、X軸方向に傾けたいとすると、 MV1SetRotationXYZ( モデルハンドル , VGet( 45 * PHI_F /180.0f , 回転角 * PHI_F /180.0f , 0.0f ) ) ; などになるんです。 そうしたら、変な回転方法になってしまいます。 これをなんとか解決する方法はないでしょうか……。
Re: モデルの3D回転について ( No.4 )
名前:いっち 日時:2010/07/18 02:52

> sagariさん もしかしたら、動き的にはこんな感じでしょうか? (MV1SetMatrixの実験用に書いたコードなので色々おかしいかもしれません・・・) > PATOLEさん PATOLEさんの場合、Y軸回転はモデル視点、X軸回転はカメラ視点なのかも? なんにしても、完全に的外れだったらごめんなさい。 //- 以下、テストコード ("DxChara.x"を使用) -// const float PITCH_RATE = TWO_PHI_F / 360.0f * 2.0f; const float YAW_RATE = TWO_PHI_F / 360.0f * 2.0f; const float ROLL_RATE = TWO_PHI_F / 360.0f * 2.0f; const float MOVE_RATE = 10.0f; void DrawMatrix( int x, int y, int color, const MATRIX& mt ) { for ( int l = 0; l < 4; l++ ) { DrawFormatString( x, y + 20 * l, color, "MATRIX%1d %f %6f %f %f", l, mt.m[l][0], mt.m[l][1], mt.m[l][2], mt.m[l][3] ); } return; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ); if ( DxLib_Init( ) == -1 ) return -1; SetDrawScreen( DX_SCREEN_BACK ); int StrColor = GetColor( 255, 255, 255 ); int mh = MV1LoadModel( "DxChara.x" ); MV1SetPosition( mh, VGet( 320.0f, -300.0f, 600.0f ) ); while ( ProcessMessage( ) == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { if ( CheckHitKey( KEY_INPUT_UP ) == 1 ) { MV1SetMatrix( mh, MMult( MGetRotAxis( VGet( 1.0f, 0.0f, 0.0f ), -PITCH_RATE ), MV1GetMatrix( mh ) ) ); } if ( CheckHitKey( KEY_INPUT_DOWN ) == 1 ) { MV1SetMatrix( mh, MMult( MGetRotAxis( VGet( 1.0f, 0.0f, 0.0f ), +PITCH_RATE ), MV1GetMatrix( mh ) ) ); } if ( CheckHitKey( KEY_INPUT_Z ) == 1 ) { MV1SetMatrix( mh, MMult( MGetRotAxis( VGet( 0.0f, 1.0f, 0.0f ), -YAW_RATE ), MV1GetMatrix( mh ) ) ); } if ( CheckHitKey( KEY_INPUT_X ) == 1 ) { MV1SetMatrix( mh, MMult( MGetRotAxis( VGet( 0.0f, 1.0f, 0.0f ), +YAW_RATE ), MV1GetMatrix( mh ) ) ); } if ( CheckHitKey( KEY_INPUT_LEFT ) == 1 ) { MV1SetMatrix( mh, MMult( MGetRotAxis( VGet( 0.0f, 0.0f, 1.0f ), -ROLL_RATE ), MV1GetMatrix( mh ) ) ); } if ( CheckHitKey( KEY_INPUT_RIGHT ) == 1 ) { MV1SetMatrix( mh, MMult( MGetRotAxis( VGet( 0.0f, 0.0f, 1.0f ), +ROLL_RATE ), MV1GetMatrix( mh ) ) ); } if ( CheckHitKey( KEY_INPUT_C ) == 1 ) { MV1SetMatrix( mh, MMult( MGetTranslate( VGet( 0.0f, 0.0f, -MOVE_RATE ) ), MV1GetMatrix( mh ) ) ); } if ( CheckHitKey( KEY_INPUT_V ) == 1 ) { MV1SetMatrix( mh, MMult( MGetTranslate( VGet( 0.0f, 0.0f, +MOVE_RATE ) ), MV1GetMatrix( mh ) ) ); } if ( CheckHitKey( KEY_INPUT_SPACE ) == 1 ) { MV1SetMatrix( mh, MGetIdent( ) ); } ClearDrawScreen( ); MV1DrawModel( mh ); DrawFormatString( 0, 0, StrColor, "test" ); DrawMatrix( 0, 40, StrColor, MV1GetMatrix( mh ) ); ScreenFlip( ); } DxLib_End( ); return 0; }
Re: モデルの3D回転について ( No.5 )
名前:管理人 日時:2010/07/18 04:20

いっちさんもご返信されていますが私も > sagariさん > モデル独自の軸で3D回転させモデルの向きを変えます。 > その時に、回転で使用しなかったモデル独自の軸の傾きも変わるはずなので、 > それに合うようにモデル独自の軸も回転させてやりたいのです。 書き込んで頂いたプログラムの中で「独自の軸」と「回転で使用しなかったモデル独自の軸」とは どれに当たるのでしょうか? あと   それに合うようにモデル独自の軸も回転させてやりたいのです。 こちらのご発言は、冗長さを避けずに表現すると   それに合うように回転で使用しなかったモデル独自の軸も回転させてやりたいのです。 となるのでしょうか? あと、「回転で使用しなかったモデル独自の軸」の回転ができた場合は MV1SetRotationXYZ を 使用する必要は無くなるのでしょうか? > PATOLEさん Y→X→Z の順番にされたい場合は MV1SetRotationXYZ の代わりに MV1SetMatrix を使用して、 回転に使用する行列を MGetRotX, MGetRotY, MGetRotZ, MMult を使用して自前で用意するように すると X, Y, Z の回転の順番を自由に決めることができます X→Y→Z の場合 MV1SetMatrix( MMult( MMult( MGetRotX( RotX ), MGetRotY( RotY ) ), MGetRotZ( RotZ ) ) ) ; Y→X→Z の場合 MV1SetMatrix( MMult( MMult( MGetRotY( RotY ), MGetRotX( RotX ) ), MGetRotZ( RotZ ) ) ) ; Z→Y→X の場合 MV1SetMatrix( MMult( MMult( MGetRotZ( RotZ ), MGetRotX( RotX ) ), MGetRotY( RotY ) ) ) ;
Re: モデルの3D回転について ( No.6 )
名前:PATOLE 日時:2010/07/18 16:24

いっちさん、管理人さん、ありがとうございました。 ページをよく見てなかったみたいですね……。 おかげ様で、解決できました。
Re: モデルの3D回転について ( No.7 )
名前:sagari 日時:2010/07/18 19:51

>いっちさん  わざわざコードを組んでいただき、ありがとうございます。 私が実現したかったのはまさにこの動きです。 MV1SetMatrix関数を用いて回転方向を指定する方法があったんですね。 もしよろしければ、こちらのコードをベースにプログラムで使用したいのですがよろしいでしょうか? >管理人さん  「独自の軸」とはchara.X〜Zaxisで指定しているベクトルです。 それぞれ独自のX〜Z軸に対応しています。  「回転に使用しなかったモデル独自の軸」は別に変数を用意しているのではなく、 「独自の軸」と同じ変数です。  また、冗長性を避けた表現としては管理人さんのもので間違いありません。  なお回転に使用する関数につきましては、機能の実装が可能であればMV1SetRotationXYZ関数にはこだわりません。 わかり難い表現で申し訳ありません。
Re: モデルの3D回転について ( No.8 )
名前:いっち 日時:2010/07/18 21:08

> もしよろしければ、こちらのコードをベースにプログラムで使用したいのですがよろしいでしょうか? もちろん構いません、というよりも、コードの品質にはまったく自信がないので恐縮してしまいます。
Re: モデルの3D回転について ( No.9 )
名前:sagari 日時:2010/07/19 18:34

それではありがたく使わせていただきます。 いっちさん、管理人さん、ありがとうございました。

Page: 1 |