Re: フレームを回転させたい ( No.1 ) |
- 名前:softya(ソフト屋) 日時:2012/01/27 10:28
MV1SetFrameUserLocalMatrixではだめなのでしょか?
「DXライブラリ置き場 3D関係関数リファレンスページ」
ttp://homepage2.nifty.com/natupaji/DxLib/function/dxfunc_3d.html#R6N11
|
Re: フレームを回転させたい ( No.2 ) |
- 名前:mina 日時:2012/01/27 14:51
MV1SetFrameUserLocalMatrixは座標を変えることしか出来ないと思うのですが、
MV1SetFrameUserLocalMatrixでフレームを回転させることは出来るのでしょうか?
|
Re: フレームを回転させたい ( No.3 ) |
- 名前:いっち 日時:2012/01/27 20:07
> MV1SetFrameUserLocalMatrixでフレームを回転させることは出来るのでしょうか?
フレーム単体での姿勢の変更(自転)は可能ですが、
ローカル座標が設定されているフレーム(ボーンのあるフレームはたぶん設定されていると思います)や
中心が原点(0,0,0)で定義されているフレームで無い限り現実的には難しいです。
> そこでやりたい事があるのですが、それは「キャラクターの目線を常にカメラに向ける」ということです。
場合によっては、眼球に設定されているテクスチャをアニメーションさせることで
類似した結果を得ることが出来るかもしれません。
ちなみに SimpleModel.mqo の1つのフレームを無理やり自転させると以下のようになります。
ただし、MV1GetFrameAvgVertexLocalPosition はシンメトリックな形状のフレームで使わないと中心座標が分かりません。
//- 以下、テストコード ("SimpleModel.mqo"を使用)-//
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
ChangeWindowMode( TRUE );
SetWindowText( "DxLib:" DXLIB_VERSION_STR );
if ( DxLib_Init( ) == -1 ) return -1;
int white = GetColor( 255, 255, 255 );
int mh = MV1LoadModel( "SimpleModel.mqo" );
MV1SetPosition( mh, VGet( 320.0f, 240.0f, 800.0f ) );
VECTOR v = MV1GetFrameAvgVertexLocalPosition( mh, 2 );
MATRIX m1 = MGetTranslate( VGet( v.x, v.y, v.z ) );
MATRIX m2 = MGetTranslate( VGet( -v.x, -v.y, -v.z ) );
int angle = 0;
SetDrawScreen( DX_SCREEN_BACK );
while ( ProcessMessage( ) == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) {
ClearDrawScreen( );
DrawFormatString( 0, 0, white, "TEST" );
MV1SetFrameUserLocalMatrix( mh, 2, MMult( MMult( m2, MGetRotY( ((2 * PHI_F) / 60) * (angle++ % 60) )), m1) );
MV1DrawModel( mh );
ScreenFlip( );
}
DxLib_End( );
return 0;
}
|
Re: フレームを回転させたい ( No.4 ) |
- 名前:mina 日時:2012/01/28 22:39
いっちさん
サンプルソースまで書いて頂いてありがとうございます。
実は、ここ一週間ずっとMV1SetFrameUserLocalMatrix(しか実装出来そうな関数が無かったので)を使用して試行錯誤していたのですが、
どうやっても目的のフレームとは違う座標を軸として公転してしまうので、
MV1SetFrameUserLocalMatrixは座標を変えずに回転(自転)するのは無理だと思ってました。
いっちさんから教えて貰ったとおりモデルデータを調整して、
MV1GetFrameAvgVertexLocalPositionを使用したところ、
なんとか自転をさせる事が出来ました。
しかし、まだ最終目的には達する事が出来ません…。
今のところ実装できたのが「1つの軸方向に対しての自転」でして、
最終的にはXYZと3つの軸方向全てに対して自転したいのです。
一応、今のソースの関連箇所を抜粋したソースは以下の通りです。
以下、初期処理より
// フレームインデックス取得
eye_frame_index[0] = MV1SearchFrame( model_hdl, "eye_left" ); // model_hdl:モデルのハンドル、"eye_left":左眼球のフレーム名
eye_frame_index[1] = MV1SearchFrame( model_hdl, "eye_right" ); // "eye_right":右眼球のフレーム名
for( i = 0; i < 2; i++ ){ // i=0:左眼球、i=1:右眼球
eye_info = MV1GetFrameAvgVertexLocalPosition( model_hdl, eye_frame_index[i] );
eye_matrix_1[i] = MGetTranslate( VGet( eye_info.x, eye_info.y, eye_info.z ) );
eye_matrix_2[i] = MGetTranslate( VGet( -eye_info.x, -eye_info.y, -eye_info.z ) );
}
以下、描写ループ内より
for( i = 0; i < 2; i++ ){ // i=0:左眼球、i=1:右眼球
// camera_position:カメラの位置(VECTOR型)
MV1SetFrameUserLocalMatrix( model_hdl, eye_frame_index[i], MMult( MMult( eye_matrix_2[i], MGetRotY( atan( camera_position.x / camera_position.z ) ) ), eye_matrix_1[i] ) );
}
MV1DrawModel( model_hdl );
以上のソースだと、Y軸方向のみきちんとカメラに対し視線を向けます。
しかし、それにX軸方向を追加したいので以下の様にしますと、
// 眼球動作
for( i = 0; i < 2; i++ ){ // i=0:左眼球、i=1:右眼球
// camera_position:カメラの位置(VECTOR型)
MV1SetFrameUserLocalMatrix( model_hdl, eye_frame_index[i], MMult( MMult( eye_matrix_2[i], MGetRotY( atan( camera_position.x / camera_position.z ) ) ), eye_matrix_1[i] ) );
MV1SetFrameUserLocalMatrix( model_hdl, eye_frame_index[i], MMult( MMult( eye_matrix_2[i], MGetRotX( -( atan( camera_position.y / camera_position.z ) ) ) ), eye_matrix_1[i] ) );
}
MV1DrawModel( model_hdl );
X軸方向の自転はする様になるのですが、Y軸方向の自転をしなくなります。
さらにZ軸方向の処理も追加すると、
// 眼球動作
for( i = 0; i < 2; i++ ){ // i=0:左眼球、i=1:右眼球
// camera_position:カメラの位置(VECTOR型)
MV1SetFrameUserLocalMatrix( model_hdl, eye_frame_index[i], MMult( MMult( eye_matrix_2[i], MGetRotY( atan( camera_position.x / camera_position.z ) ) ), eye_matrix_1[i] ) );
MV1SetFrameUserLocalMatrix( model_hdl, eye_frame_index[i], MMult( MMult( eye_matrix_2[i], MGetRotX( -( atan( camera_position.y / camera_position.z ) ) ) ), eye_matrix_1[i] ) );
MV1SetFrameUserLocalMatrix( model_hdl, eye_frame_index[i], MMult( MMult( eye_matrix_2[i], MGetRotZ( atan( camera_position.x / camera_position.z ) ) ), eye_matrix_1[i] ) );
}
MV1DrawModel( model_hdl );
こうすると、眼球が全く動かなくなってしまいました。
たぶんそれぞれの軸方向の処理がお互いを相殺しているのかなと思っているのですが、
3軸方向全てが上手くカメラに向く回転になるにはどうしたらいいのでしょうか?
|
Re: フレームを回転させたい ( No.5 ) |
- 名前:いっち 日時:2012/01/28 23:36
> こうすると、眼球が全く動かなくなってしまいました。
> たぶんそれぞれの軸方向の処理がお互いを相殺しているのかなと思っているのですが、
違います。
1つのフレームに対して設定できる行列は1つだけなので最後のZ軸回転だけが有効になっているのだと思います。
> 3軸方向全てが上手くカメラに向く回転になるにはどうしたらいいのでしょうか?
以下のように行列を合成すると出来ると思います(この場合回転順序はY->X->Zになると思います)。
> MATRIX my = MMult( MMult( eye_matrix_2[i], MGetRotY( atan( camera_position.x / camera_position.z ) ) ), eye_matrix_1[i] );
> MATRIX mx = MMult( MMult( eye_matrix_2[i], MGetRotX( -( atan( camera_position.y / camera_position.z ) ) ) ), eye_matrix_1[i] );
> MATRIX mz = MMult( MMult( eye_matrix_2[i], MGetRotZ( atan( camera_position.x / camera_position.z ) ) ), eye_matrix_1[i] );
> MV1SetFrameUserLocalMatrix( model_hdl, eye_frame_index[i], MMult( MMult( my, mx ), mz ) );
それと、カメラを目線で追う程度でしたら2軸の回転で問題ないのではないでしょうか?
|
Re: フレームを回転させたい ( No.6 ) |
- 名前:mina(解決) 日時:2012/01/29 11:15
いっちさん
なるほど、それぞれの軸の行列で上書きしていたのですね…。
あとご指摘通り、目線の動きはXYの2軸でいいみたいです。
Zを考慮してしまうと眼球がキリモミ回転してしまいました。
今回初めて3Dゲームを製作でして、
その為に必要な行列計算を勉強したのですが、
まだ行列計算がプログラムにきちんとリンクしていないみたいで四苦八苦しています。
ご教示ありがとうございました。
|
|