トップページ > 過去ログ > 記事閲覧
3Dモデルアニメーションの鏡像化
名前:ガラス草 日時: 2011/07/30 23:13

モデルはそのままで、アニメーションだけ鏡像をとることはできないでしょうか。具体的には、 ・x座標が0のフレームは移動回転をzy平面に対する面対象のものに変換 ・"左○○"と"右○○"と名前が付けられたフレームの移動回転を交換 ・それ以外のフレームは、元のアニメーションの座標変換情報をそのまま適用するか否かを選べる 格闘ゲームで2P側は行動が反転しますが、 モデルはそのままでアニメーションだけ鏡像をとりたいです。何か方法はないでしょうか。

Page: 1 |

Re: 3Dモデルアニメーションの鏡像化 ( No.1 )
名前:いっち 日時:2011/07/31 00:01

私は3Dに疎いので、ガラス草さんの仰りたいことが良く分からないのですが、 以下のスレッドの情報はご参考になりませんでしょうか? > ://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=1984 私の中の理解では、「右利きのキャラを左利きにする」といった感じなのですが、 できれば、画像などで具体的な例示を頂けると助かります。 (もしかしたら、3Dゲームでは常識的な処理なのかもしれませんが・・・)
Re: 3Dモデルアニメーションの鏡像化 ( No.2 )
名前:ガラス草 日時:2011/07/31 01:41

>>1 その方法ではモデルそのものを反転していますが、 今回の場合ではモーションだけを反転させたいです。 例えば髪型がサイドテールのキャラの場合、そちらのやり方ではテールの位置まで反転してしまいます。 画像の件はこんな感じです↓ ://skydrive.live.com/?sa=794782492#!/?cid=6da4faf0fb09f590&sc=documents&uc=1&id=6DA4FAF0FB09F590%21129!cid=6DA4FAF0FB09F590&id=6DA4FAF0FB09F590%21130&sc=documents ポーズは反転していますが、サイドテールの位置はそのままです。
Re: 3Dモデルアニメーションの鏡像化 ( No.3 )
名前:クラスクラス 日時:2011/07/31 10:42

感想です。 プログラムでやるより、MMDで反転のモーションにした方が速いような気がします… 非対称なモデルのモーションは、全体を変えても変になると思いますが、一部を変えてても変になると思いますよ。 それでも変換したいなら、とても強力なモーション変換プログラムが要ると思われ… (非対称部分にモーションがない場合は除く)
Re: 3Dモデルアニメーションの鏡像化 ( No.4 )
名前:いっち 日時:2011/07/31 12:55

ガラス草さん> 画像を拝見しました。ありがとうございます。 今のところDXライブラリでは方法は無いと思います。
Re: 3Dモデルアニメーションの鏡像化 ( No.5 )
名前:ガラス草 日時:2011/08/01 00:27

>>3 ゲームそのものではなく、拡張性のあるエンジンとして 開発したいのでわざわざファイルを2倍用意しなきゃならなくなると辛いのです。 >>4 せめて左○○⇔右○○の変換さえできれば後の部分は自作できるのですが…。 それと話は別ですが、>>1で紹介された方法もあまりうまくいかないです。 こちらで妥協しなければならない可能性も視野に入れているのでどうにかならないでしょうか
Re: 3Dモデルアニメーションの鏡像化 ( No.6 )
名前:いっち 日時:2011/08/01 19:20

どうしてもと仰るのであれば、メモリ上でモデルファイルを編集して、 MV1LoadModelFromMem を使ってロードする事で実現できるかもしれません。 (もちろん、ファイル上で編集しても同じことではありますが) MV1LoadModelFromMem の使い方は以下のスレッドのレスNo.2729にあります。 > ://hpcgi2.nifty.com/natupaji/aska.cgi > それと話は別ですが、>>1で紹介された方法もあまりうまくいかないです。 どのようにうまくいかないのでしょうか?
Re: 3Dモデルアニメーションの鏡像化 ( No.7 )
名前:yasi 日時:2011/08/02 01:20

詳しく検証して調べている時間が無いので机上の空論的な話で申し訳ないのですが、 以下のような手順でできないでしょうか? 1.キャラクタのフレーム情報を予め解析しておく。 (どれが差換え対象なのか(腕、足等)、どれが差換え無しの反転処理対象なのか(背骨、首等)) 2.MV1SetAttachAnimTime後、MV1GetFrameLocalMatrixで対象フレームのローカル行列を全て取得する。 3.取得した行列に全て反転処理を行う。 4.処理後の行列をMV1SetFrameUserLocalMatrixで首等は同じフレームへ、 腕等は左右逆のフレームへセットして描画する。 恐らく反転処理に関しては何らかの行列を乗算するだけでできると思いますが 自分は詳しくないので調べてみてください。 この方法は上手く行ったとしても解析の関係上、 モデルデータ作成時に予め決まった名前の付け方が必要になります。 又、処理コスト的にも一般的なモデルでどの程度掛かるか不明です。
Re: 3Dモデルアニメーションの鏡像化 ( No.8 )
名前:ガラス草 日時:2011/08/02 01:34

>>6 今試しているモデルではカリング計算がうまくいっていないのか、 表示されないメッシュが発生します。 >>7 反転処理対象のフレームを検出するアルゴリズムはできました。 処理量的にもたいした量ではないと思います。 しかし、肝心の反転行列がわかりません。 MMDの反転コピー機能がどのような行列を使っているのかがわかれば解決するのですが…
Re: 3Dモデルアニメーションの鏡像化 ( No.9 )
名前:いっち 日時:2011/08/03 19:37

ガラス草さん> > 今試しているモデルではカリング計算がうまくいっていないのか、表示されないメッシュが発生します。 ご使用のモデルをご提供いただけますか?
Re: 3Dモデルアニメーションの鏡像化 ( No.10 )
名前:yasi 日時:2011/08/04 16:07

簡単な検証しかしていない事と、専門では無いのでこれがスマートな方法か判りませんが、 以下の行列処理でできないでしょうか。 // コピー元フレーム(例:右腕)のローカル行列取得 MATRIX FrameM = MV1GetFrameLocalMatrix( MH, BaseFI ); // YZ面反転用行列作成 MATRIX MirrorM = MGetIdent(); MirrorM.m[0][0] = -1.0f; // 反転処理 FrameM = MMult( MMult( MirrorM, FrameM ), MirrorM ); // コピー先(例:左腕)へセット MV1SetFrameUserLocalMatrix( MH, TargetFI, FrameM ); 上記のコードは元になるフレーム(BaseFI)ローカル座標行列(FrameM)に対し、 X軸のY,Z要素と、Y,Z,PosのX要素を正負反転させて、 それをターゲットになるフレーム(TargetFI)にセットしています。 先にも書きましたが、簡単な検証しか行っていないため、 間違えている可能性もありますのでご了承ください。 又、もしお試しになるのでしたら後学のためにも結果をご報告いただけるとありがたいです。
Re: 3Dモデルアニメーションの鏡像化 ( No.11 )
名前:いっち 日時:2011/08/07 00:02

yasiさん> 私が試してみた範囲ではうまくいくようでした。 なんでかわかりませんが、アニメーション後も LocalMatrix は変化しないと思い込んでいたので、 大変助かりました。(以前、確認したはずなんですが・・・) ガラス草さん&管理人さん> 「方法が無い」なんて嘘言ってすみませんでした。 せっかくなので、テストコードを載せておきます。 //- 以下、テストコード ("DxChara.x"を使用) -// #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ); if ( DxLib_Init() < 0 ) return -1; int ModelHandle = MV1LoadModel( "DxChara.x" ); int DuplicateHandle = MV1DuplicateModel( ModelHandle ); SetDrawScreen( DX_SCREEN_BACK ); MV1SetPosition( ModelHandle, VGet( 160.0f, -300.0f, 600.0f ) ); MV1SetPosition( DuplicateHandle, VGet( 480.0f, -300.0f, 600.0f ) ); int AttachIndex = MV1AttachAnim( ModelHandle, 0, -1, FALSE ); float TotalTime = MV1GetAttachAnimTotalTime( ModelHandle, AttachIndex ); float PlayTime = 0.0f; MATRIX mat; MATRIX MirrorM = MGetIdent(); MirrorM.m[0][0] = -1.0f; while ( ProcessMessage() == 0 ) { ClearDrawScreen(); PlayTime += 100.0f ; if ( PlayTime >= TotalTime ) PlayTime = 0.0f; // アニメーションと位置の固定 MV1ResetFrameUserLocalMatrix( ModelHandle, 2 ); MV1SetAttachAnimTime( ModelHandle, AttachIndex, PlayTime ); mat = MV1GetFrameLocalMatrix( ModelHandle, 2 ); mat.m[3][2] = 0.0f; MV1SetFrameUserLocalMatrix( ModelHandle, 2, mat ); for ( int src = 0, dst = 0, MaxIdx = MV1GetFrameNum( ModelHandle ); src < MaxIdx; src++, dst = src ) { mat = MV1GetFrameLocalMatrix( ModelHandle, src ); if ( !CheckHitKey( KEY_INPUT_SPACE ) ) { // スペースキーで反転 if ( 4 <= src && src <= 11 ) { // 両足を入れ替え mat = MMult( MMult( MirrorM, mat ), MirrorM ); dst = src + (src <= 7 ? 4 : -4); } } MV1SetFrameUserLocalMatrix( DuplicateHandle, dst, mat ); } MV1DrawModel( ModelHandle ); MV1DrawModel( DuplicateHandle ); ScreenFlip(); } DxLib_End(); return 0 ; }
Re: 3Dモデルアニメーションの鏡像化 ( No.12 )
名前:yasi 日時:2011/08/07 17:16

いっちさん> 検証ありがとうございました。おつかれさまでした。 テストコードまで記載していただき感謝です。 今後の参考にさせていただきます。 しかしながら今回、自分で手段を提示しておきながら言うのもおかしな話ですが、 私の個人的な感想としてもやはり、いっちさんが仰られていたように、 MV1LoadModelされる前に事前にメモリ上、もしくはファイル上で VMDデータを解析して反転モーションデータを構築する方がベータではないかと思っています。 最終的にガラス草さんがリアルタイム描画のエンジンを作ってらっしゃるのかどうかは判りませんが、 リアルタイムの場合、今回の手法ではどうしても描画を行うユーザーが フレーム(ボーン)数分の反転処理に対する処理コストを 描画ごとに払う形になるため、低スペックPCでも軽く動作が行える物を作ろうと思えば 少しでも描画毎に掛かる処理を少なくする事は必要になると思いますので。 最近のMMDモデルはボーン数が多い物も増えていますからね・・・。 もう1つの懸念としてはクラスクラスさんが仰られていたように 対となる差換え対象が存在しない非対称部位の動きが不自然になるであろうという事ですね。 非対称部位の多くは3Dでは揺れ物と呼ばれるMMDでは物理演算処理に任せる部分だと思いますが、 これらの動きはその位置によってYZ面反転処理だけでは済まないと思いますので。 何れにしても100%を望む場合はちゃんと左右のモーションをデベロッパーが用意するのがいいと思います。 一応参考にVMDファイルの構造が分かるサイトへリンクが張られているMMD関連サイトのURLを残しておきます。 //w w w.geocities.jp/hatsune_no_mirai/ こちらの「6.外部へのリンク」にVMD関係があります。 長々と失礼しました。
Re: 3Dモデルアニメーションの鏡像化 ( No.13 )
名前:クラスクラス 日時:2011/08/10 18:15

>いっちさん 遅レスですが、ついさっきソース試してみました。 これ、腰が動いてないから破綻しない様に思いますが。 腰が右側が前、左側が後ろとか、右腰が上に上がり気味とかになったら破綻しませんか? いや、試してないけど、ちょっと疑問に思ったので。
Re: 3Dモデルアニメーションの鏡像化 ( No.14 )
名前:いっち 日時:2011/08/10 22:25

私も試していないのですが、おそらく、そういった場合 > 腰の行列 = X反転( 腰の行列 ); といった風にすればうまくいくのではないかと思います。 ただ、テストに使用したchara.xの場合、腰の子フレームに上半身も含まれているので、 波及的に上半身のフレームもすべて反転する必要が出てくるかもしれません。
Re: 3Dモデルアニメーションの鏡像化 ( No.15 )
名前:クラスクラス 日時:2011/08/11 07:23

返答ありがとうございます。 そうですよね、完全に対称な基本位置の部位のみを交換できるからといって。 それを理由に部位の交換が可能といっていいものか、私には疑問です^^; まてまて、基本位置の位置および角度も計算して部位の位置を… いや、それは単に高度なモーション変換プログラムを…(笑) 私なら素直に、MMDでモーション作る^^
Re: 3Dモデルアニメーションの鏡像化 ( No.16 )
名前:ガラス草 日時:2011/08/13 22:09

丁寧な回答ありがとうございました。 とりあえずテストしてみながら適した方法を選んでみたいと思います。

Page: 1 |