▼XNA Game Studioメモ▼
3Dモデルを表示する


3Dモデルを表示するプログラムを作成する。



リソースの追加
今回のプログラムには3Dモデルを1つとテクスチャ1枚とエフェクトファイル1つを使用する。
モデルとテクスチャはXNA Creators ClubのVideo Tutorial 1のサンプルから拝借。
フォルダ構成は次の通り。

  1. プロジェクトを生成。
  2. プロジェクト名を右クリックし、「追加⇒新しいフォルダ」を選択し「Contentフォルダ」を生成し、その下に同じように「Modelsフォルダ」「Texturesフォルダ」を生成。
  3. 「Modelsフォルダ」を右クリックし、「追加⇒既存の項目」を選択し「p1_wedge.fbx」を追加。
  4. 「Texturesフォルダ」を右クリックし、「追加⇒既存の項目」を選択し「wedge_p1_diff_v1.tga」を追加。プログラムから読み込まないので、ソリューションエクスプローラからは消しておく。「wedge_p1_diff_v1.tga」を右クリックし、「プロジェクトから削除」を選択する(ディレクトリには配置されたまま。「削除」とは異なる)。


Modelクラス
モデル情報を保持する。
ModelMeshCollection Meshes メッシュ情報

ModelMeshCollectionクラス
メッシュ情報を複数保持する。

ModelMeshクラス
メッシュ情報を保持する。
ModelBone ParentBone 親ボーン
ModelEffectCollection Effects 複数の効果情報
void Draw(); 描画

ModelEffectCollectionクラス
効果情報を複数保持する。

BasicEffectクラス
基本的な効果情報を保持する。
Matrix World ワールド変換行列
Matrix View ビュー変換行列
Matrix Projection 射影変換行列
void EnableDefaultLighting() デフォルトライトの指定

ParentBoneクラス
親ボーンの情報を保持する。
Matrix Transform 位置・回転・拡縮

Matrixクラス
行列情報を保持する。
M11,M12,M13,M14
M21,M22,M23,M24
M31,M32,M33,M34
M41,M42,M43,M44
Matrix CreateTranslation(float,float,float) 平行移動
Matrix CreateTranslation(Vector3) 平行移動
static Matrix CreateRotationX(float) X軸回転
static Matrix CreateRotationY(float) Y軸回転
static Matrix CreateRotationZ(float) Z軸回転
static Matrix CreateLookAt(Vector3,Vector3,Vector3) ビュー変換行列
static Matrix CreatePerspectiveFieldOfView(float,float,float,float) 射影変換行列

MathHelperクラス
算術演算を行う。
static float ToDegrees(float) ラジアン⇒度
static float ToRadians(float) 度⇒ラジアン


ソースコードの編集
Game1.csを編集。

Game1.cs
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;

//3Dモデルの表示
namespace ModelEx {
    public class Game1 : Microsoft.Xna.Framework.Game {
        //グラフィックス
        private GraphicsDeviceManager graphics;//グラフィックス
        private ContentManager        content; //コンテント

        //モデル
        private Model   model;                  //モデル
        private Vector3 modelPos = Vector3.Zero;//モデルの位置
        private float   modelRot = 0.0f;        //モデルの回転

        //カメラ
        private float   aspectRatio;//アスペクト比
        private Vector3 cameraPos;  //カメラ位置

        //コンストラクタ
        public Game1() {
            //グラフィックス
            graphics = new GraphicsDeviceManager(this);
            content  = new ContentManager(Services);

            //画面サイズ
            graphics.PreferredBackBufferWidth  = 853;
            graphics.PreferredBackBufferHeight = 480;
        }

        //初期化
        protected override void Initialize() {
            base.Initialize();
        }

        //グラフィックコンテントのロード
        protected override void LoadGraphicsContent(bool loadAllContent) {
            if (loadAllContent) {
                //モデルの読み込み
                model = content.Load<Model>("Content\\Models\\p1_wedge");
            }

            //カメラの初期化
            aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width /
                graphics.GraphicsDevice.Viewport.Height;  //アスペクト比
            cameraPos = new Vector3(0.0f, 50.0f, 5000.0f);//カメラ
        }

        //グラフィクスコンテントの解放
        protected override void UnloadGraphicsContent(bool unloadAllContent) {
            if (unloadAllContent) content.Unload();
        }

        //更新
        protected override void Update(GameTime gameTime) {
            //アプリの終了
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) {
                this.Exit();
            }

            //モデルの回転
            modelRot += (float)gameTime.ElapsedGameTime.TotalMilliseconds * 
                MathHelper.ToRadians(0.1f);

            //ベースの更新
            base.Update(gameTime);
        }

        //描画
        protected override void Draw(GameTime gameTime) {
            //背景色の指定
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            //親トランスフォームのコピー
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);

            //モデルの描画
            foreach (ModelMesh mesh in model.Meshes) {
                //エフェクトの指定
                foreach (BasicEffect effect in mesh.Effects) {
                    //ライティング
                    effect.EnableDefaultLighting();

                    //ワールド変換行列
                    effect.World = 
                        transforms[mesh.ParentBone.Index] * 
                        Matrix.CreateRotationY(modelRot) * //モデルY軸回転
                        Matrix.CreateTranslation(modelPos);//モデル位置
                    
                    //ビュー変換行列
                    effect.View = Matrix.CreateLookAt(
                        cameraPos,   //カメラ位置
                        Vector3.Zero,//参照点
                        Vector3.Up); //UPベクトル
                    
                    //射影変換行列
                    effect.Projection = Matrix.CreatePerspectiveFieldOfView(
                        MathHelper.ToRadians(45.0f),//視野角(ラジアン単位)
                        aspectRatio,                //アスペクト比
                        1.0f,                       //ニアクリップ面の距離
                        10000.0f);                  //ファークリップ面の距離
                }
                //描画
                mesh.Draw();
            }

            //ベースの描画
            base.Draw( gameTime );
        }
    }
}



−戻る−