トップページ > 過去ログ > 記事閲覧
3Dモデルの左腕を曲げたい
名前:SEIRYU 日時: 2012/07/05 20:08

MV1SetFrameUserLocalMatrixを使って左腕を曲げているのですが、 位置がおかしくなっています。 左腕が本来の位置から離れて体の中心にくっついているように見えます。 理由がわからないので、どなたか教えていただけませんでしょうか。 ソースプログラムは次の通りです。 #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int ModelHandle ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) { // エラーが発生したら直ちに終了 return -1 ; } // 3Dモデルの読み込み ModelHandle = MV1LoadModel( "初音ミク.pmd" ) ; // 描画先を裏画面にする SetDrawScreen(DX_SCREEN_BACK); // ESCキーが押されるかウインドウが閉じられるまでループ while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { // 画面をクリア ClearDrawScreen(); MV1SetScale(ModelHandle, VGet(2, 2, 2)); int MaterialNum = MV1GetMaterialNum(ModelHandle); for(int i=0; i<MaterialNum; i++) { // マテリアルの元々の輪郭線の太さを取得 float dotwidth = MV1GetMaterialNum( ModelHandle ); // マテリアルの輪郭線の太さを5分の1にする MV1SetMaterialOutLineDotWidth( ModelHandle, i, dotwidth / 100.0f ); } // 画面に映る位置に3Dモデルを移動 MV1SetPosition( ModelHandle, VGet( 320.0f, 225.0f, -350.0f ) ) ; int RightHandFrameNo; RightHandFrameNo = MV1SearchFrame(ModelHandle, "左肩");     MV1SetFrameUserLocalMatrix( ModelHandle, RightHandFrameNo, MGetRotZ(PHI_F / 4.0f)); // 3Dモデルの描画 MV1DrawModel( ModelHandle ) ; // 裏画面の内容を表画面に反映 ScreenFlip(); } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }

Page: 1 |

Re: 3Dモデルの左腕を曲げたい ( No.1 )
名前:SEIRYU 日時:2012/07/05 20:50

説明だけではわかりづらいと思いますので、 写真を載せます。 ttp://photozou.jp/photo/show/2680852/141989174 フレーム番号は 上体---左肩---左腕---左ひじ---左手首 の順になっていますが、 この場合左肩を曲げようとしたら、上体の位置になっています。 左手首を曲げると左ひじの位置になっているので、親のフレームで回転しているように見えます。
Re: 3Dモデルの左腕を曲げたい ( No.2 )
名前:SEIRYU 日時:2012/07/08 12:04

原因がわかり、解決できました。 またわからないところがあると思いますのでよろしくお願いします。
Re: 3Dモデルの左腕を曲げたい ( No.3 )
名前:管理人 日時:2012/07/08 17:22

既に解決されたということですが、一応私も対処の解説をさせていただきます フレームの行列には回転要素の他に位置要素も含まれていますので、 MGetRotZ の戻り値である回転要素だけに置き換えてしまうと位置要素が欠落して フレームの位置がおかしくなってしまいます なのでフレームの位置を変更せずに回転する場合は回転の行列に位置の行列を 掛け合わせてあげる必要があります 具体的には MV1SetFrameUserLocalMatrix( ModelHandle, RightHandFrameNo, MGetRotZ(PHI_F / 4.0f)); こちらを MATRIX LocalMatrix ; VECTOR LocalPosition ; // 「左肩」フレームに設定した独自行列情報をリセット MV1ResetFrameUserLocalMatrix( ModelHandle, RightHandFrameNo ) ; // 「左肩」フレームの元々の行列を取得 LocalMatrix = MV1GetFrameLocalMatrix( ModelHandle, RightHandFrameNo ) ; // 「左肩」フレームの位置情報を取得( 行列の [ 3 ][ 0 ] が x、[ 3 ][ 1 ] が y、[ 3 ][ 2 ] が z となっています ) LocalPosition = VGet( LocalMatrix.m[ 3 ][ 0 ], LocalMatrix.m[ 3 ][ 1 ], LocalMatrix.m[ 3 ][ 2 ] ); // 回転行列に元々の位置情報を行列に変換したものを掛け合わせた行列を「左肩」フレームにセット MV1SetFrameUserLocalMatrix( ModelHandle, RightHandFrameNo, MMult( MGetRotZ( PHI_F / 4.0f ), MGetTranslate( LocalPosition ) ) ); こんな感じにします

Page: 1 |