VMD to Xsi Script Maerker について

2012.05.26 現在バグフィックス中です。
2010.05.25 v2.0リリース [DOWNLOAD]http://www.mediafire.com/?tddlbiydggv
2010.05.06 v1.9リリース [DOWNLOAD]http://www.mediafire.com/?hzjzjymoxjq
2010.04.15 v1.8リリース [DOWNLOAD]http://www.mediafire.com/?gjnjyyrmiym <ちょっと直した。
2010.04.04 v1.6リリース [DOWNLOAD]http://www.mediafire.com/?mmezgmqyyzw
2010.03.26 v1.5リリース [DOWNLOAD]http://www.mediafire.com/?byjqqtrjdgm
2010.03.20 v1.4リリース [DOWNLOAD]http://www.mediafire.com/?ywgz2fidfza
2010.03.14 v1.3リリース
2010.03.11 v1.2リリース
2010.03.08 v1.1リリース
2010.03.07 v1.0リリース

このプログラムはmikumikuDanceで利用されているVMDファイルからモーションデータを取り出し
Xsi用のスクリプトを吐き出すプログラムです。

 

動作確認環境 windows/XP SP3
コンパイラ VC++V6.0
MikuMikuDance V522a
Xsi fnd V5.11

[Xsiv5.11sceneSample] http://www.mediafire.com/?mgw4zyuknln

【使い方】

1.Xsi側でリファレンスのリグを作成しこれにモーションをつけます。

2.実際に動かすリグはリファレンスを参照するようにします。

3.リファレンスリグはスクリプトを走らせる前にニュートラルの設定が必要です。
   VtxsにVMDを読み込ませた後[nutral script]ボタンを押すとニュートラル設定に必要なスクリプトを吐き出します。

4.モーフに使用する為のリファレンスオブジェクトを用意します。
  VMDのモーフィングについてはxsi側のヌルオブジェクトのY方向(local)に移動させます。
  Xsi側ではその値を参照するようアクションクリップのウェィトにエクスプレッションを書くなどで対応してください。
  VtxsにVMDファイルを読み込ませた後[MorphModelScript]ボタンを押すとモーフに使う参照モデルを作成する
  スクリプトを吐き出しますので必要に応じてXsiで実行してください。

5.VtxsにVMDファイルをD&Dするとスクリプトを同名のテキストファイルとして作成しますので
  Xsiで読み込ませ実行してみてください。

 

【PMDモデルのボーンとXsiボーンの対応を作成する】

1.mikumikuDanceで使用するPMDモデルを読み込み各ボーンがXsiのどのボーンに対応するか調べます。

2.Vtxs.iniの<RIGNAME>にXsiのリグの名称を書きます。または、Xsi側でリグの名称を変えても構いません。

3.PMDモデルの各ボーンの移動方向、回転方向がXsiのリグと同じになるよう一つ一つXYZ方向を移動させて確認し
  その対応をVtxs.iniの[CONNECT]に記述します。
4.Xsiで使わないボーンについては記述不要です。

5.VMDファイルがどのボーンを使っているのか確認するためVtxsの[空のタグを作成]にチェックをしVMDファイルを読み込ませると
  Vtxs.iniに未対応のダクが branch として登録されますので必要に応じてボーンを追加してください。その際はVtxs.ini内の
  branchに対応したボーンの名称を書き換える必要があります。

branch になっているボーン、モーフ用オブジェクトについてはXsi用のスクリプトには反映されません。

iniファイルをモデルによって変更したい場合はそのiniファイルをD&Dすると以降のデフォルトとして設定されます。
iniファイルの名称は拡張子がiniであればVtxs.iniでなくても構いません。

< サンプルムービー >色々な意味で苦情が来そうだ。
http://www.mediafire.com/?enixzl32y3v

 

ポザから応援を頼んでみた。
FourBRATUKUSの振り付けはエクサプライズ様パルメパラパラをお借りいたしました。

【変更歴】

2010.05.25 v2.0 Y角がうまく回転しなくなったためMMDで使っている(はず)のクォータニオン<->オイラー変換を元に戻しました。

2010.05.06 v1.9 倍率計算の割り当てミスを修正。

2010.04.15 v1.8 MMDで使っている(はず)のクォータニオン<->オイラー変換を組み込みました。

2010.04.04 v1.6 スポットで角度補正できる機能を追加しました。

2010.03.26 v1.5 X軸、Z軸が一挙に180度または−180度に回転する動作を制限しました。
          結果としてモーションがヌルくなりますので必要に応じてxsi側でキーを修正してください。

2010.03.20 v1.4 キーフレームの設定数を1ボーン当たり3000から30000に拡大。テキストエリアを10kから30kに拡大。
           iniファイル内のボーンについてrotXYZを0にし、カレントフレームでキーをセットするスクリプトを吐く処理を追加。
           [rotXYZ=0]のボタンに割り当て。

2010.03.14 v1.3 [COMMENT]タグ内のスペース、タブが自由に使えるようになりました。
           スクリプト作成時、ボーン用かMorph用またはイニシャライズのみの選択をできるようにしました。

2010.03.11 v1.2 スクリプトウィンドーを[CTRL+A][CTRL+C]のコピペに対応させました。

2010.03.08 v1.1でセルフテスト用のVMD_TEST.VMDを作成するように追加しました。
      VMD_TEST.VMDファイルはVMD_BASE.VMDをD&Dすると使っているiniファイルに書かれている[CONNECT]の順に
      VMDのボーンに対応したXYZのローテーションをそれぞれ30度と−30度のキーを追加してD&Dしたディレクトリに
      作成されます。 30度の角度を変えたい場合はVMD_BASE.VMDをMMDに読み込み適宜変更してください。
      このVMD_TEST.VMDをD&Dする事でXsi用のScriptが作成されますのでスクリプト実行後の動作がMMDと違う
      場合、原因を調べてiniファイルを修正し、再度VMD_TEST.vmdをD&DしScriptを実行した後、動作を再確認して
      ください。

 

 

 

※使用した結果、動作については保証しかねますのでご了解ください。<(_ _)>
/*///////////////////////////////////////
バグ、不明点、ご要望、ご質問などありましたらメールください。
master@goriman.com 五莉 満
///////////////////////////////////////*/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2010.03.10
クォータニオンの変換でハマってた部分

VMDではボーンの回転をクオータニオンで表している。Xsiにスクリプトを吐くときはこれから角度を求めなくてはならない。
私にとってはクオータニオンが何であるかなどどうでもいい。ただ単にクオータニオンを渡して角度が得られればそれで
完璧なのだ。

ところが…

これが無いのである。

仕方なしにウェブを彷徨っていると

http://www.pineappledesign.org/Kanaya/Quaternion.html のPDFによると

元超複素数は環を 形成するように単位元を選ぶことができ,その ような組合せのうちのひとつがクォータニオン である.(なにそれ…

座標系の意味ではEinstein、Newton、Galilei…

ベクトル積とテンソル積って?

特殊相対論??

途中で寄り道も意味がない。

ブラの幾何学的解釈とは…女性の下着じゃない罠

リーマン(Riemann) 積分

ディラックのデルタ関数

ラプラス変換 <-ラブプラスじゃないぞ?

ユニタリ(Unitary) 行列

むむむ。きさま、ワシの脳を破壊するつもりかあぁぁぁ!?

5章になってまともになってきたと思ったら

リー(Lie) 代数、テイラー(Taylor) 展開

エルミート(Hermtie) 共役

ふぅ。おちつけ俺…

パウリ行列…ぉぃ

3 軸まわりにθ まわして…いや回さないでいいでつ。

ベーカー・ キャンベル・ハウスドルフ(Baker-Cambell- Housdorff) の公式として有名である. (知らないでつ…

クォータニオンがクォータニ オンらしく振舞うのはまさに3 次元ベクトルの
ベクトル積の特異性.ベクトルとベクトルのベ クトル積が再びベクトルになる.による.…べくとるべくとるべくとるうぅぅぅ

実のところ我々はベクトルRにはあまり興味があ るわけでなくクォータニオンV に興味があるので,(先生 ぼくは どっちも 興味 ありません。

スピノールからのベクトルとスカラの合成…もういい。もういいでつ…

1/2 階テンソルのようなもの…

リー代数、ウェッジ積の定義、外微分演算子の定義、ホッジ(Hodge) 演算子…あぁ、もうなにがなんだか…

ストークスの定理、ダランベール演算子、グリーンの公式…たのむ、終わってくれえぇぇ

これが阪大大学院基礎工学科の威力か…

だめだ。

完全に破壊された。

まあとにかくMMDが扱っているクォータニオンのデータはwebに転がっている変換方法では求まらない。
#自分が探し当てた変換プログラムが不完全なようで。。。<自分の能力不足なのは拭えないが。。。
 ただ、VMDに書かれているY軸のデータは、0から1の範囲である事には違いない。単純に求めよう
 と思うなら asin(Y軸)*2(このとき 0>wなら反転)でラジアンの近似値が出る。

VMDの角度はベクターの値を持っていない。なので回転を表す場合0から180と0から-180の
角度になる。図にするまでもないが
こうなっている。
ところでxsiに限らず3DCGのアプリはベクトルの値を持っているのでたとえば軸を回していくと
180度の次は181度になる。
VMDの181度は-179度であり、ストレートにデータコンバートしてしまうとアプリ側は360度逆回転
するハメになってしまう。

これを解決するにはプログラム側で直前の角度値を持ち次にきた値からどちらに回せば良いのか
選択し加減算すれば良いことになる。ロジックとしては前の値と今回の値が正と負と0の場合があり
ケースバイケースで判断が必要になる。

そもそも角度に正や負があるのはおかしいとは思うが一々考えてると進まないので。

static double old=0;//前の角度
void function hogehoge(double vmdY)
{
double syouYo=fmod(old,360);//回転数*360を引いた角度 (fmod()は剰余)
double syou=floor(old/360);//回転数 (floor()は切り捨て)
double rtn=0;
  if(0==vmdY){
    if(syouYo<180){//前回剰余角が180を超えている場合は回転を加算して0度になる
      rtn=(syou+1) * 360;
    }else{
     rtn=syou * 360;
    }
    if(0 > old ){//前の角度が-の場合
        rtn=rtn*-1;
    }
  }else //dondake〜
  if(0>old){//前の角度は-
    if(0>vmdY){//今回角度は-
*1)    if(180 > fabs(syouYo - vmdY)){//fabs()は絶対値を求める。=180度以内なら
         rtn=vmdY+(syou*360);
      }else{
        rtn= vmdY+((syou+1)*360);
      }
    }else{//今回角度は+なので上図左側になり角度は360からの差になる
      double fixradian=(360+vmdY)*-1;
      if(180 > fabs(syouYo - fixradian)){//fabs()は絶対値を求める。=180度以内なら
         rtn=fixradian+(syou*360);
      }else{
        rtn= fixradian+((syou+1)*360);
      }
    }
  }else
  if(0<old){//前の角度は+
    if(0>vmdY){//今回角度は(-)なので上図右側になる
      double fixradian=(360+vmdY);
      if(180 > fabs(syouYo - fixradian)){//fabs()は絶対値を求める。=180度以内なら
         rtn=fixradian+(syou*360);
      }else{
        rtn= fixradian+((syou+1)*360);
      }
    }else{//今回角度は+
      if(180 > fabs(syouYo - vmdY)){//fabs()は絶対値を求める。=180度以内なら
         rtn=vmdY+(syou*360);
      }else{
        rtn= vmdY+((syou+1)*360);
      }
    }
  }
return(rtn);
}

さくっと書いてこんな感じだがバグバグである。
double syouYo=fmod(old,360);  fmod()で得た値は符号付になるし
*1)ので if(180 > fabs(syouYo - vmdY)){ マイナスからマイナスを引くことは加算に等しい。
右回転は加算されるが左回りが無い。
前回角度のベクトルと今回角度が(+)か(-)かで比較、加算、減算の意味が異なるのが厄介だ。
では慎重に考えてと思うと余計にコンガラカルのである。
それよりも全てプラスにしてしまった方が楽である。
つまり

static double old=0;//前の角度(符号付ベクトル)
void function hogehoge(double vmdY)
{
double rtn=0;
double ABSsyouYo=fabs(fmod(old,360));//回転数*360を引いた角度 (fmod()は剰余) fabs()は絶対値
double syou=floor(old/360);//回転数 (floor()は切り捨て)
double ABSold=fabs(old);
double ABSvmdY;
BOOL bMainus=FALSE;
  if(0>old){//前の角度は-
     bMainus=TRUE;
    if(0>vmdY){//今回角度は-
       ABSvmdY=fabs(vmdY);
    }else{
      ABSvmdY=fabs(360 - vmdY);
    }
  }else
  if(0<old){//前の角度は+
    if(0>vmdY){//今回角度は-
       ABSvmdY=fabs(360 + vmdY);
    }else{
      ABSvmdY= vmdY;
    }
  }

  if(0==old){//前回角度=0
    rtn=vmdY;
  }else{
    if(0==vmdY){//今回角度=0
      if(ABSsyouYo>180){//前回剰余角が180を超えている場合は回転を加算する
        rtn=(syou+1) * 360;
      }else{
       rtn=syou * 360;
      }
    }else{//kondake〜
      if( ABSsyouYo < ABSvmdY){//今回位置は右側
        if(180 < fabs(ABSsyouYo-ABSvmdY)){//180度以上差がある
          rtn= ABSvmdY+((syou-1)*360);//1回転減算
        }else{
           rtn=ABSvmdY+(syou*360);
        }
      }else{//今回位置は左側または同じ
        if(180 < fabs(ABSsyouYo-ABSvmdY)){//180度以上差がある
          rtn= ABSvmdY+((syou+1)*360);//1回転加算
        }else{
           rtn=ABSvmdY+(syou*360);
        }
      }
    }
    if(bMainus){ //前の角度-
      rtn=rtn*-1;
    }
  }
return(rtn);
}

まぁステップ数は大して変わっていないが…以前に比べ肝心な部分がスッキリしてミスの無い
コードが書けたと思う。
(実際のfloor()については単純な切捨てではないので詳しくはお使いのコンパイラヘルプをご覧になってください。

 

SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送