回転と移動のアニメーション

X-FILE から回転と移動の情報を取得してアニメーションします。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. X-FILE から回転と移動の情報を取得して、自作の Interpolator でアニメーションをします。
    DirectX 3D で Form を表示する に習って、空のプロジェクトから作成します。
    次のファイルを格納して、プロジェクトに取り込んで下さい。
    Main Program です。
    /*********************************************/
    /*★ 回転と移動のアニメーション    前田 稔 ★*/
    /*********************************************/
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using Microsoft.DirectX;
    using Microsoft.DirectX.Direct3D;
    using Direct3D=Microsoft.DirectX.Direct3D;
    using System.Collections;
    using System.IO;
    
    namespace Anime
    {
        public class Meshes : Form
        {
            Device device = null;       // Our rendering device
            Mesh mesh = null;           // Our mesh object in sysmem
            Direct3D.Material[] meshMaterials;      // Materials for our mesh
            Texture[] meshTextures;                 // Textures for our mesh
            PresentParameters presentParams = new PresentParameters();
            bool pause = false;
            InterRot    interrot;       //Interpolator の定義
            InterMov    intermov;       //Interpolator の定義
            X_Loader    x_load;         //X-File Load Class の定義
    
            InterRotDat[]   Rot;        //回転情報の定義
            InterMovDat[]   Mov;        //移動情報の定義
            int     tim= 0;
            Matrix  mat;
    
            //Constructor
            public Meshes()
            {   // Set the initial size of our form
                this.ClientSize = new System.Drawing.Size(400, 400);
                this.Text = "Direct3D Teapot";
            }
    
            //D3DDevice の取得
            bool InitializeGraphics()
            {
                try
                {   presentParams.Windowed = true;
                    presentParams.SwapEffect = SwapEffect.Discard;
                    presentParams.EnableAutoDepthStencil = true;
                    presentParams.AutoDepthStencilFormat = DepthFormat.D16;
    
                    // Create the D3DDevice
                    device = new Device(0, DeviceType.Hardware, this,
                        CreateFlags.SoftwareVertexProcessing, presentParams);
                    device.DeviceReset += new System.EventHandler(this.OnResetDevice);
                    this.OnResetDevice(device, null);
                    pause = false;
                }
                catch (DirectXException)
                {   return false;  }
                return true;
            }
    
            //Direct3D の初期化
            public void OnResetDevice(object sender, EventArgs e)
            {
                ExtendedMaterial[] materials = null;
                Directory.SetCurrentDirectory(@"c:\data\xfile\");
    
                Device dev = (Device)sender;
                dev.RenderState.ZBufferEnable = true;
                dev.RenderState.Ambient = System.Drawing.Color.White;
                mesh = Mesh.FromFile("Cube_Men4.x", MeshFlags.SystemMemory, device, out materials);
    
                meshMaterials = new Material[materials.Length];
                meshTextures = new Texture[materials.Length];
                for(int i = 0; i < meshMaterials.Length; i++)
                {   meshMaterials[i] = materials[i].Material3D;
                    meshMaterials[i].AmbientColor = meshMaterials[i].DiffuseColor;
                    if ((materials[i].TextureFilename != null) && (materials[i].TextureFilename.Length > 0))
                    {   meshTextures[i] = TextureLoader.FromFile(dev, materials[i].TextureFilename);  }
                }
    
                // 法線情報がなければ計算して作成
                if ((mesh.VertexFormat & VertexFormats.Normal) == 0)
                {   Mesh temporaryMesh = mesh.Clone(mesh.Options.Value,
                        mesh.VertexFormat | VertexFormats.Normal, device);
                    // 法線を計算
                    temporaryMesh.ComputeNormals();
                    // 古いメッシュを破棄し、置き換える
                    mesh.Dispose();
                    mesh = temporaryMesh;
                }
    
                // アニメーションデータの入力
                x_load = new X_Loader(@"c:\data\xfile\Cube_Men4.x");
                // 回転 Interpolator の設定
                Rot = x_load.LoadRot();
                interrot = new InterRot(Rot);
                // 移動 Interpolator の設定
                Mov = x_load.LoadMov();
                intermov = new InterMov(Mov);
            }
    
            //描画環境の設定
            void SetupMatrices()
            {
                device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f,1.0f,-5.0f),
                    new Vector3(0.0f,0.0f,0.0f), new Vector3(0.0f,1.0f,0.0f));
                device.Transform.Projection = Matrix.PerspectiveFovLH((float)(Math.PI/4),
                    1.0f,1.0f,500.0f);
            }
    
            //ライトの設定
            private void SetupLights()
            {   System.Drawing.Color col = System.Drawing.Color.White;
                Direct3D.Material mtrl = new Direct3D.Material();
                mtrl.Diffuse = col;
                mtrl.Ambient = col;
                device.Material = mtrl;
                
                device.Lights[0].Type = LightType.Directional;
                device.Lights[0].Diffuse = System.Drawing.Color.FromArgb(0xF0F020);
                device.Lights[0].Direction = new Vector3(50.0f, -40.0f, 100.0f);
                device.Lights[0].Enabled = true;
                device.RenderState.Ambient = System.Drawing.Color.FromArgb(0x202020);
            }
    
            //モデルの描画
            private void Render()
            {   if (device == null) return;
                if (pause)          return;
    
                device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Gray, 1.0f, 0);
                device.BeginScene();
                SetupLights();
                SetupMatrices();
                for(int i=0; i<meshMaterials.Length; i++)
                {
                    if (i<6)    mat = interrot.GetMat(Environment.TickCount*4);
                    else        mat = intermov.GetMat(Environment.TickCount * 4);
                    device.Transform.World = mat;
                    device.Material = meshMaterials[i];
                    device.SetTexture(0, meshTextures[i]);
                    mesh.DrawSubset(i);
                }
                device.EndScene();
                device.Present();
            }
    
            //マウスのクリックを検出
            protected override void OnMouseDown(MouseEventArgs e)
            {   tim+= 20;  }        //アニメーションの間隔
    
            protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
            {   this.Render();  }
            protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
            {   if ((int)(byte)e.KeyChar == (int)System.Windows.Forms.Keys.Escape)
                    this.Dispose(); // Esc was pressed
            }
    
            protected override void OnResize(System.EventArgs e)
            {   pause = ((this.WindowState == FormWindowState.Minimized) || !this.Visible);  }
    
            //☆ Main() メソッド
            static void Main()
            {   using (Meshes frm = new Meshes())
                {   if (!frm.InitializeGraphics()) // Initialize Direct3D
                    {   MessageBox.Show("Could not initialize Direct3D.  This tutorial will exit.");
                        return;
                    }
                    frm.Show();
    
                    // While the form is still valid, render and process messages
                    while (frm.Created)
                    {   frm.Render();
                        Application.DoEvents();
                    }
                }
            }
        }
    }
    
    回転のインタープローラです。
    /*******************************************/
    /*★ Interpolator Class(回転)    前田 稔 ★*/
    /*******************************************/
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using Microsoft.DirectX;
    using Microsoft.DirectX.Direct3D;
    using Direct3D=Microsoft.DirectX.Direct3D;
    using System.Collections;
    
    namespace Anime
    {
        //Rotation Interpolator Data
        class InterRotDat
        {
            public int  Tim;
            public Quaternion Qt;
    
            //InterRotDat Constructor
            public InterRotDat(int tim, Quaternion qt)
            {   Tim= tim;
                //Qt= Quaternion.Normalize(qt);
                Qt= qt;
            }
            public void Print()
            {
                Console.WriteLine("Time={0}  {1},{2},{3},{4}", Tim, Qt.X, Qt.Y, Qt.Z, Qt.W);
            }
        }
    
        //☆Interpolator Class
        class InterRot
        {
            InterRotDat[]   Rot;
            int         Leng;
    
            //InterRot Constructor
            public InterRot(InterRotDat[] rot)
            {   Rot= rot;
                Leng= Rot.GetLength(0)-1;
            }
    
            //tim の Matrix を計算
            public Matrix GetMat(int tim)
            {   int     wk,i;
                float   rate;
                Quaternion wqt;
                wk= tim % Rot[Leng].Tim;
                for(i=0; i<Leng && Rot[i].Tim<wk; i++);
                if (Rot[i].Tim==wk) return Matrix.RotationQuaternion(Rot[i].Qt);
                rate= (float)(wk-Rot[i-1].Tim)/(float)(Rot[i].Tim-Rot[i-1].Tim);
                wqt = Quaternion.Slerp(Rot[i-1].Qt, Rot[i].Qt, rate);
                return Matrix.RotationQuaternion(wqt);
            }
        }
    }
    
    移動のインタープローラです。
    /*******************************************/
    /*★ Interpolator Class(移動)    前田 稔 ★*/
    /*******************************************/
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using Microsoft.DirectX;
    using Microsoft.DirectX.Direct3D;
    using Direct3D=Microsoft.DirectX.Direct3D;
    using System.Collections;
    
    namespace Anime
    {
        //Moving Interpolator Data
        class InterMovDat
        {
            public int      Tim;
            public Vector3  V3;
    
            //InterMovDat Constructor
            public InterMovDat(int tim, Vector3 v3)
            {   Tim= tim;
                V3= v3;
            }
            public void Print()
            {
                Console.WriteLine("Time={0}  {1},{2},{3}", Tim, V3.X, V3.Y, V3.Z);
            }
        }
    
        //☆Interpolator Class
        class InterMov
        {
            InterMovDat[]   Mov;
            int     Leng;
    
            //Interpolator Constructor
            public InterMov(InterMovDat[] mov)
            {   Mov= mov;
                Leng= Mov.GetLength(0)-1;
            }
    
            //tim の Matrix を計算
            public Matrix GetMat(int tim)
            {   int     wk,i;
                float   rate;
                Vector3 wv3;
    
                wk= tim % Mov[Leng].Tim;
                for(i=0; i<Leng && Mov[i].Tim<wk; i++);
                if (i==0 || Mov[i].Tim==wk) return Matrix.Translation(Mov[i].V3);
                rate= (float)(wk-Mov[i-1].Tim)/(float)(Mov[i].Tim-Mov[i-1].Tim);
                wv3 = Vector3.Lerp(Mov[i-1].V3, Mov[i].V3, rate);
                return Matrix.Translation(wv3);
            }
        }
    }
    
    X_Loader Ver-2 です。
    /****************************************************/
    /*★ X-FILE の回転(移動)情報を入力する    前田 稔 ★*/
    /****************************************************/
    using System;
    using System.IO;    // for File, StreamReader
    using System.Text;  // for Encoding
    using System.Windows.Forms;
    using System.Drawing;
    using Microsoft.DirectX;
    
    namespace Anime
    {
        //X-File Load Class
        class X_Loader : IDisposable
        {
            StreamReader reader;
            public string   BUF;        //文字列入力領域
            int             LT,RT;      //Index Left,Right
            InterRotDat[]   _Rot;       //回転情報の定義
            InterMovDat[]   _Mov;       //移動情報の定義
    
            //Constructor
            public X_Loader(string x_file)
            {
                if (!File.Exists(x_file))
                {   MessageBox.Show("X-File が見つかりません",x_file);
                    return;
                }
                reader = new StreamReader(x_file,Encoding.GetEncoding("Shift_JIS"));
            }
    
            //Destructor
            ~X_Loader()
            {   Dispose();  }
    
            //Dispose() 関数
            public void  Dispose()
            {   reader.Close();
                GC.SuppressFinalize(this);
            }
    
            //回転アニメーションデータを入力
            public InterRotDat[] LoadRot()
            {   int     val=0,tim,i;
                float[] fval;
                //Skip("AnimationSet ");
                while(Skip("AnimationKey "))
                {   NextRead();
                    val = Val();
                    if (val==0) break;
                }
                if (val!=0)
                {   MessageBox.Show("回転データが見つかりません");
                    return  null;
                }
    
                NextRead();
                val = Val();    //テーブルの件数
                _Rot= new InterRotDat[val];
                for(i=0; i<val; i++)
                {
                    NextRead();
                    tim = Val();    //Time を入力
                    fval= OneLine();
                    _Rot[i] = new InterRotDat(tim, new Quaternion(fval[0], fval[1], fval[2], fval[3]));
    _Rot[i].Print();
                }
                return _Rot;
            }
    
            //移動アニメーションデータを入力
            public InterMovDat[] LoadMov()
            {   int     val=0,tim,i;
                float[] fval;
                //Skip("AnimationSet ");
                while(Skip("AnimationKey "))
                {   NextRead();
                    val = Val();
                    if (val==2) break;
                }
                if (val!=2)
                {   MessageBox.Show("移動データが見つかりません");
                    return  null;
                }
    
                NextRead();
                val = Val();    //テーブルの件数
                _Mov= new InterMovDat[val];
                for(i=0; i<val; i++)
                {
                    NextRead();
                    tim = Val();    //Time を入力
                    fval= OneLine();
                    _Mov[i] = new InterMovDat(tim, new Vector3(fval[0], fval[1], fval[2]));
    _Mov[i].Print();
                }
                return _Mov;
            }
    
            //一件のデータ(回転,移動)を設定
            public float[] OneLine()
            {   int     val,i;
                float[] fval;
    
                fval= new float[4];
                val = Val();        //個数を入力
                for(i=0; i<val; i++)
                {   fval[i] = FVal();   }
                return fval;
            }
    
            //次の有効な行を入力(/ はコメント行)
            public bool NextRead()
            {   int i;
                while((BUF=reader.ReadLine()) != null)
                {   for(i=0; i<BUF.Length && (BUF[i]==' ' || BUF[i]=='\t'); i++);
                    if (i<BUF.Length && BUF[i]!='/')
                    {
                        RT = 0;
                        return true;
                    }
                }
                return false;
            }
    
            //key の行まで読み飛ばす
            public bool Skip(string key)
            {
                while((BUF=reader.ReadLine()) != null)
                {   LT = BUF.IndexOf(key);
                    if (LT!=-1)
                    {   RT= LT+key.Length;
    //Console.WriteLine(BUF);
                        return true;
                    }
                }
                return false;
            }
    
            //BUF[RT] から次の int を取得
            public int Val()
            {
                string wk;
                while (true)
                {
                    for(LT=RT; LT<BUF.Length && BUF[LT]!='-' && (BUF[LT]<'0' || BUF[LT]>'9'); LT++);
                    if (LT<BUF.Length)
                    {
                        for (RT=LT+1; RT<BUF.Length && (BUF[RT]>='0' && BUF[RT]<='9'); RT++);
                        wk = BUF.Substring(LT, RT-LT);
                        return int.Parse(wk);
                    }
                    if (NextRead()==false)  return -1;
                }
            }
    
            //BUF[RT] から次の float を取得
            public float FVal()
            {
                string wk;
                while (true)
                {
                    for(LT=RT; LT<BUF.Length && BUF[LT]!='-' && (BUF[LT]<'0' || BUF[LT]>'9'); LT++);
                    if (LT<BUF.Length)
                    {
                        for(RT=LT+1; (RT<BUF.Length && (BUF[RT]>='0' && BUF[RT]<='9') || BUF[RT]=='.'); RT++);
                        wk = BUF.Substring(LT, RT-LT);
                        return float.Parse(wk);
                    }
                    if (NextRead()==false)  return -1.0f;
                }
            }
    
            //Printout() 関数
            public void  Print()
            {   while((BUF=reader.ReadLine()) != null)
                {   Console.WriteLine(BUF);  }
            }
        }
    }
    
    このプログラムで入力する X-FILE です。
    xof 0303txt 0064
    
    Header {
     1;
     0;
     1;
    }
    
    //※長方体
    Frame Frame_World
    {
      Frame Anim_MatrixFrame_Box
      {
      }
      Frame Frame_ModelDef
      {
    
    Mesh {
     8;
     -1.0;-1.0;-1.0;,
     -1.0;0.0;1.0;,
     -1.0;0.0;-1.0;,
     -1.0;-1.0;1.0;,
     1.0;-1.0;-1.0;,
     1.0;0.0;1.0;,
     1.0;0.0;-1.0;,
     1.0;-1.0;1.0;;
    
     6;
     4;0,3,1,2;,
     4;4,0,2,6;,
     4;6,2,1,5;,
     4;5,1,3,7;,
     4;7,3,0,4;,
     4;4,6,5,7;;
    
     MeshMaterialList {
      6;
      6;
      0,
      1,
      2,
      3,
      4,
      5;
    
      Material {
       0.0;1.0;1.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
      Material {
       1.0;0.0;1.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
      Material {
       0.0;0.0;1.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
      Material {
       1.0;1.0;0.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
      Material {
       1.0;0.0;0.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
      Material {
       0.0;1.0;0.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
     }
    
     MeshNormals {
      6;
      -1.000000;0.000000;0.000000;,
      0.000000;0.000000;-1.000000;,
      0.000000;1.000000;0.000000;,
      0.000000;0.000000;1.000000;,
      0.000000;-1.000000;0.000000;,
      1.000000;0.000000;0.000000;;
    
      6;
      4;0,0,0,0;,
      4;1,1,1,1;,
      4;2,2,2,2;,
      4;3,3,3,3;,
      4;4,4,4,4;,
      4;5,5,5,5;;
      }
    
        XSkinMeshHeader {
            4;
            3;
            1;
        }
    
        SkinWeights {
            "Anim_MatrixFrame_Box";
            24;
            0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23;;
            1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,
            1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,
            1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0;;
            -0.99995, 0.00999, 0.0, 0.0, 
            -0.00999, -0.99995, 0.0, 0.0, 
            0.0, 0.0, 1.0, 0.0, 
            0.0, 0.0, 0.0, 1.0;;
        }
    
      } // End of Mesh
     } // End of "ModelDef" frame
    } // End of "World" frame
    
    //※四面体
    Frame Frame_World
    {
      Frame Anim_MatrixFrame_Men4
      {
      }
      Frame Frame_ModelDef
      {
    
    Mesh {
     12;
     -1.0; -0.40825; 0.57735;,
      1.0; -0.40825; 0.57735;,
      0.0;  1.22474; 0.0;,
      0.0; -0.40825; -1.1547;,
      0.0;  1.22474; 0.0;,
      1.0; -0.40825; 0.57735;,
      0.0;  1.22474; 0.0;,
      0.0; -0.40825; -1.1547;,
     -1.0; -0.40825; 0.57735;,
      1.0; -0.40825; 0.57735;,
     -1.0; -0.40825; 0.57735;,
      0.0; -0.40825; -1.1547;;
     4;
     3;0,1,2;,
     3;3,4,5;,
     3;6,7,8;,
     3;9,10,11;;
    
     MeshMaterialList {
      4;
      4;
      0,
      1,
      2,
      3;
    
      Material {
       1.0;0.0;0.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
      Material {
       1.0;1.0;0.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
      Material {
       0.0;0.0;1.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
      Material {
       0.0;1.0;0.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
     }
    
     MeshNormals {
      12;
      -0.82;-0.33;0.47;,
      0.82;-0.33;0.47;,
      0.00;1.00;-0.00;,
      0.00;-0.33;-0.94;,
      0.00;1.00;-0.00;,
      0.82;-0.33;0.47;,
      0.00;1.00;-0.00;,
      0.00;-0.33;-0.94;,
      -0.82;-0.33;0.47;,
      0.82;-0.33;0.47;,
      -0.82;-0.33;0.47;,
      0.00;-0.33;-0.94;;
      4;
      3;0,1,2;,
      3;3,4,5;,
      3;6,7,8;,
      3;9,10,11;;
     }
    
        XSkinMeshHeader {
            4; // nMaxSkinWeightsPerVertex
            3; // nMaxSkinWeightsPerFace
            1; // nBones
        }  // End of XSkinMeshHeader
    
        SkinWeights {
            "Anim_MatrixFrame_Men4";
            12;
            0,1,2,3,4,5,6,7,8,9,10,11;;
            1.000000,1.000000,1.000000,1.000000,
            1.000000,1.000000,1.000000,1.000000,
            1.000000,1.000000,1.000000,1.000000;
            1.0, 0.0, 0.0, 0.0, 
            0.0, 1.0, 0.0, 0.0, 
            0.0, 0.0, 1.0, 0.0, 
            0.0, 0.0, 0.0, 1.0;;
        }  // End of SkinWeights
    } // End of Mesh
     } // End of "ModelDef" frame
    } // End of "World" frame
    
    AnimationSet AnimationSet0 {
        Animation Animation0 {
            {Anim_MatrixFrame_Box}
            AnimationKey {
                0;  // Rotation
                5;
                0;4; 0.00,  0.72,  0.00,  0.70;;
                2000;4; 0.00,  0.00,  0.00,  1.00;;
                4000;4; 0.00, -0.72,  0.00,  0.70;;
                6000;4; 0.00,  0.00,  0.00,  1.00;;
                8000;4; 0.00,  0.72,  0.00,  0.70;;
            }
        }
    
        Animation Animation1 {
            {Anim_MatrixFrame_Men4}
            AnimationKey {
                2;  // Position
                9;
                   0;3; 0.00,1.11,0.0;;,
                 840;3; 0.22,2.97,0.00;;,
                1260;3; 0.32,2.88,0.00;;,
                2160;3; 0.18,2.34,0.00;;,
                2580;3; 0.09,1.23,0.00;;,
                3900;3;-0.23,0.42,0.00;;,
                4980;3;-0.21,1.00,0.00;;,
                5820;3;-0.08,0.45,0.00;;,
                8700;3; 0.00,0.40,0.00;;;
            }
        }
    }
    
  2. 今回入力する X-FILE(Cube_Men4.x)は、このプログラムのために作成した特別仕様です。
    @"c:\data\xfile\Cube_Men4.x" に格納して下さい。
    Cube_Men4.x は、ファイルの先頭から次の情報が順に記述されています。
    ・長方体モデルの定義
    ・四面体モデルの定義
    ・長方体の回転アニメーションデータ
    ・四面体の移動アニメーションデータ
    長方体と四面体は、各面に色を設定したカラーモデルで、ボーンは設定されていません。
    DirectX の Viewer で起動して、長方体の上に四面体が落下することを確認して下さい。
  3. 描画は DirectX に任せて、回転・移動アニメーションのみ自作します。
    次のソースコードは Material を設定してポリゴンを描画する部分です。
        for(int i=0; i<meshMaterials.Length; i++)
        {   device.Material = meshMaterials[i];
            device.SetTexture(0, meshTextures[i]);
            mesh.DrawSubset(i);
        }
    
    今回の X-FILE では i の値が 0~5 が長方体で、6~9 が四面体です。
    ルール違反かも知れませんが、これを利用してアニメーションすることにします。 (^_^;)
    念のために申し添えますが、Material を設定しないと DrawSubset(0) で全体が描画されるので i は意味を持ちません。
    長方体には回転アニメーションが、四面体には移動アニメーションが設定されています。
  4. 回転アニメーションのプログラムは X-FILE を入力して回転する を参照して下さい。
    移動アニメーションも回転アニメーションと同じ要領です。
    今回の X_Loader は、回転に加えて移動データも入力できるようにバージョンアップしています。
        InterRot    interrot;       //Interpolator の定義
        InterMov    intermov;       //Interpolator の定義
        X_Loader    x_load;         //X-File Load Class の定義
        InterRotDat[]   Rot;        //回転情報の定義
        InterMovDat[]   Mov;        //移動情報の定義
    
        x_load = new X_Loader(@"c:\data\xfile\Cube_Men4.x");
        // 回転 Interpolator の設定
        Rot = x_load.LoadRot();
        interrot = new InterRot(Rot);
        // 移動 Interpolator の設定
        Mov = x_load.LoadMov();
        intermov = new InterMov(Mov);
    
  5. 肝心の移動と回転のアニメーションの設定です。
    i の値が 0~5 には回転を、6~9 には移動のインタープローラを設定します。
    詳細はソースコードを参照して下さい。
        for(int i=0; i<meshMaterials.Length; i++)
        {
            if (i<6)    mat = interrot.GetMat(Environment.TickCount * 4);
            else        mat = intermov.GetMat(Environment.TickCount * 4);
            device.Transform.World = mat;
            device.Material = meshMaterials[i];
            device.SetTexture(0, meshTextures[i]);
            mesh.DrawSubset(i);
        }
    

超初心者のプログラム入門(C# Frame Work)