XFILE Animation Model

XFILE の Animation Model を作成します。
アニメーションモデルの詳しい説明は 前田稔の超初心者のプログラム入門 から
「DirectX9/VertexBuffer のプログラム/アニメーション X-FILE を作成する」を参照して下さい。

前田稔の超初心者のプログラム入門

立方体モデル

  1. XFILE で最も魅力があるのは、ファイルに組み込まれているアニメーション機能でしょう。
    プログラムの作成に取りかかる前に、テストで使うアニメーションモデルを作成します。
    Frame Animation Model では Frame Animation に使う専用のモデルを作成しましたが、今回は一般的なモデルを作成します。
    出回っている XFILE Animation Model の構成は多種多様で、中には文法的におかしい物もあります。
    DirectX の Viewer は結構柔軟で、少しぐらいおかしくても描画してくれるようです。
    ここではプログラミングを意識して、多少の制限を設けながらモデルを作成します。
  2. 立方体が複雑に回転するモデル(BoxAnime.x)です。
    DirectX SDK November 2008 の Viewer でアニメーションの実行を確認しました。
    xof 0303txt 0064
    
    Header {
     1;
     0;
     1;
    }
    
    // Top-most frame encompassing the 'World'
    Frame Frame_World
    {
      Frame Anim_MatrixFrame_Box
      {
      } // End animation 'Box' frame
      Frame Frame_ModelDef
      {
    
    Mesh {
     24;
     -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;,
     -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;,
     -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;;
    
     6;
     4;3,2,1,0;,
     4;4,5,6,7;,
     4;11,10,9,8;,
     4;12,13,14,15;,
     4;19,18,17,16;,
     4;20,21,22,23;;
    
     MeshMaterialList {
      6;
      6;
      0,
      1,
      2,
      3,
      4,
      5;
    
      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;;
      }
      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 {
       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;;
      }
     }
    
     MeshNormals {
      24;
      0.0;1.0;0.0;,
      0.0;1.0;0.0;,
      0.0;1.0;0.0;,
      0.0;1.0;0.0;,
      0.0;-1.0;0.0;,
      0.0;-1.0;0.0;,
      0.0;-1.0;0.0;,
      0.0;-1.0;0.0;,
      -1.0;0.0;0.0;,
      -1.0;0.0;0.0;,
      -1.0;0.0;0.0;,
      -1.0;0.0;0.0;,
      1.0;0.0;0.0;,
      1.0;0.0;0.0;,
      1.0;0.0;0.0;,
      1.0;0.0;0.0;,
      0.0;0.0;-1.0;,
      0.0;0.0;-1.0;,
      0.0;0.0;-1.0;,
      0.0;0.0;-1.0;;
      0.0;0.0;1.0;,
      0.0;0.0;1.0;,
      0.0;0.0;1.0;,
      0.0;0.0;1.0;;
    
      6;
      4;0,1,2,3;,
      4;4,5,6,7;,
      4;8,9,10,11;,
      4;12,13,14,15;,
      4;16,17,18,19;,
      4;20,21,22,23;;
     } // End of MeshNormals
    
        XSkinMeshHeader {
            4; // nMaxSkinWeightsPerVertex
            3; // nMaxSkinWeightsPerFace
            1; // nBones
        }  // End of XSkinMeshHeader
    
        SkinWeights {
            "Anim_MatrixFrame_Box";
            24; // nWeights  頂点と法線の Index 番号を指定する
            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;;
            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;1.0,0.0,0.0,0.0;;,
                4000;4;0.556201,0.198899,0.788152,-0.172904;;
                8000;4;0.194614,0.361892,0.907646,-0.085662;;
                12000;4;0.111571,-0.136411,0.983987,0.026705;;
                16000;4;0.038249,0.002162,0.999266,0.000730;;
            }
        }
    }
    

モデルの説明

  1. XFILE の基本的な形式は XFILE Loader の基礎 を参照して下さい。
    アニメーションの基本モデルは Frame Animation Model を参照して下さい。
  2. XFILE の構成です。
    腕を回せば、上腕、肘、掌、指が付いてくるように、親子孫の関係を Frame 階層構造で定義します。
  3. Mesh(モデル)は、例えば Frame_ModelDef の中で一括して定義します。
  4. XSkinMeshHeader と SkinWeights で、各 Frame 構造の中でモデルのどのポリゴン(頂点 Index)が動くかを設定します。
        XSkinMeshHeader {
          4; // nMaxSkinWeightsPerVertex
          3; // nMaxSkinWeightsPerFace
          1; // nBones
        }  // End of XSkinMeshHeader
    
        SkinWeights {
            "Anim_MatrixFrame_Box";
            24; // nWeights  頂点と法線の Index 番号を指定する
            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;;
            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
        
  5. 頂点の定義では、各頂点毎に座標と法線ベクトルを対で定義します。
    頂点と法線ベクトルの個数と Index 番号は一致させて下さい。
    Mesh {
     24;
     -1.0;1.0;-1.0;,
       ・・・・・
     -1.0;1.0;1.0;;
    
     6;
     4;3,2,1,0;,
     4;4,5,6,7;,
     4;11,10,9,8;,
     4;12,13,14,15;,
     4;19,18,17,16;,
     4;20,21,22,23;;
    
     MeshMaterialList {
      6;
      6;
      0,
      1,
      2,
      3,
      4,
      5;
    
      Material {
       1.0;0.0;0.0;1.0;;
       21.3;
       0.0;0.0;0.0;;
       0.0;0.0;0.0;;
      }
      Material {
       ・・・・・
      }
     }
    
     MeshNormals {
      24;
      0.0;1.0;0.0;,
       ・・・・・
      0.0;0.0;1.0;;
    
      6;
      4;0,1,2,3;,
      4;4,5,6,7;,
      4;8,9,10,11;,
      4;12,13,14,15;,
      4;16,17,18,19;,
      4;20,21,22,23;;
     } // End of MeshNormals
    

正四面体モデル

  1. 中心座標を 0,0,0 に置いて、正四面体(正四面体に近い)モデルです。
    DirectX では頂点座標の定義で、座標, 法線, マテリアルなどを対にして定義しています。
    その関係なのでしょうか、四面体の場合は12個の頂点を設定しなければならないようです。
    DirectX SDK November 2008 の Viewer でアニメーションの実行を確認しました。
    xof 0303txt 0032
    
    Header {
     1;
     0;
     1;
    }
    
    // Top-most frame encompassing the 'World'
    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.000000, 0.0, 0.0, 0.0, 
            0.0, 1.000000, 0.0, 0.0, 
            0.0, 0.0, 1.000000, 0.0, 
            0.0, 0.0, 0.0, 1.000000;;
        }  // End of SkinWeights
    } // End of Mesh
     } // End of "ModelDef" frame
    } // End of "World" frame
    
    AnimationSet AnimationSet0 {
        Animation Animation0 {
            {Anim_MatrixFrame_Men4}
            AnimationKey {
                0;  // Rotation
                5;
                0;4;1.0,0.0,0.0,0.0;;,
                4000;4;0.556201,0.198899,0.788152,-0.172904;;
                8000;4;0.194614,0.361892,0.907646,-0.085662;;
                12000;4;0.111571,-0.136411,0.983987,0.026705;;
                16000;4;0.038249,0.002162,0.999266,0.000730;;
            }
        }
    }
    

超初心者のプログラム入門(Java2)