[C#][XNA][AR]MikuMikuDance for XNAを使用してARを行う(4)


「7.Game1.csの編集を行い実装を行っています。」の続きです。
(2)MikuMikuDanceの動作を追加します。
  
■MikuMikuDance for XNAの名前空間を追加します。

//MikumikuDance XNA -> mmdの再生に使用
using MikuMikuDance.Core.Model;
using MikuMikuDance.Core;
using MikuMikuDance.Core.Motion;
using MikuMikuDance.Core.Misc;
using MikuMikuDance.XNA;
using MikuMikuDance.XNA.Misc;
using MikuMikuDance.Core.Accessory;
using MikuMikuDance.XNA.Accessory;

■MikuMikuDance for XNAの動作に必要なメンバ変数を追加します。

//MMDモデル
MMDModel model;
//MMDモーション
MMDMotion motion;
//前回のキーボードの入力を保持
KeyboardState beforeState;
GamePadButtons beforeButtons;

■MikuMikuDance for XNAで使用するモデル/モーションデータの読み込みを行います。

protected override void LoadContent()
{
<省略>
//モデルをパイプラインより読み込み
model = MMDXCore.Instance.LoadModel("Miku", Content);
//サンプルモデルはカリングを行わない。(他のモデルはカリングを行う)
model.Culling = false;
//モーションをパイプラインより読み込み
motion = MMDXCore.Instance.LoadMotion("TrueMyHeart", Content);
//モデルにモーションをセット
model.AnimationPlayer.AddMotion("TrueMyHeart", motion, MMDMotionTrackOptions.UpdateWhenStopped);
<省略>
}

アプリケーション終了時の処理を追加します。

protected override void Dispose(bool disposing)
{
<省略>
//MMDの破棄処理を実行
model.Dispose();
MMDXCore.Instance.Dispose();
<省略>
}

■Updateハンドラの処理を追加します。
 Updateハンドラではキー入力、MMDインスタンスの更新処理を追加します。

protected override void Update(GameTime gameTime)
{
<省略>
//////////////////////////////////////////////////////////////////
//MikuMikuDanceの処理
//エンターを入力すると
if ((!beforeState.IsKeyDown(Keys.Enter) && Keyboard.GetState().IsKeyDown(Keys.Enter)) ||
(GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Pressed))
{
//再生した後ならリセットをかける
if (model.AnimationPlayer["TrueMyHeart"].NowFrame > 0)
{
//停止
model.AnimationPlayer["TrueMyHeart"].Stop();
//巻き戻し
model.AnimationPlayer["TrueMyHeart"].Reset();
//剛体位置のリセット
model.PhysicsManager.Reset();
}
//モーションの再生
model.AnimationPlayer["TrueMyHeart"].Start();
}
//MMDのUpdateを呼び出す
MMDXCore.Instance.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
<省略>
}

■DrawハンドラにARマーカーの座標取得および、取得した座標からMMDXのカメラの位置設定を行います。
 ALVARMarkerTrackerから取得できる変換行列は、カメラから見たARマーカーの位置を表すようです。
 このため以下の手順で変換を行います。

  1. 逆行列を求める

  2. X軸方向に-90度回転する(使用したARマーカーARDominoALVAR.txtに依存していると思われますがX軸に90度回転した変換行列が得られています。)


   
 計算された変換行列から回転/位置の情報を取得しMMDXのカメラに設定します。

protected override void Draw(GameTime gameTime)
{
<省略>
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
//モデルを描画する
if (tracker.FindMarker(markerID))
{
//マーカーの姿勢行列を得る
Matrix matrix = Matrix.Invert(tracker.GetMarkerTransform());
matrix = matrix * Matrix.CreateRotationX((float)-1.570796326794);
Vector3 traslat = new Vector3();
Vector3 scale = new Vector3();
Quaternion rotation = Quaternion.Identity;
matrix.Decompose(out scale, out rotation, out traslat);
//カメラの位置を設定する
MMDXCore.Instance.Camera.SetRotation(rotation);
MMDXCore.Instance.Camera.Position = traslat;
//モデルを描画する
model.Draw();
}
<省略>
}


0 件のコメント :

コメントを投稿