3D Model 貼圖呈現 - 程式撰寫

摘要:3D Model 貼圖呈現 - 程式撰寫

修改新增 : 範例程式增加

準備好XNA的C#邊及專案以後,接下來的工作就是將美術人員給我們的3D模型資訊檔案(FBX),加入到程式中。

首先,我們要先加入一個Model的物件,這代表著就是你現在要代表3D模型的變數。
Model : 呈現一個3D Model由多個ModelMesh物件的單元所組成。
Model FD;

接下來就是使用Content Pipeline的方式載入FBX檔案。
FD = Content.Load<Model>(@".\mesh\FD");
這邊可能用@,這樣就可以直接輸入路徑,而不需要再\\來指定。
因為我現在要匯出的當案型態為Model,所以在Content.Load<T>的T就要用Model。
這樣在執行期間,在LoadGraphicsContent的時候,Content就會用PIPELINE的方式載入所需要的檔案。

再下來就是進入到DRAW()的函式,在這個函式中,我用一個函數來繪製模型,而傳入的參數就是剛剛載入的Model。
protected override void Draw(GameTime gameTime)
 {
     graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

     DrawModel(FD);

     base.Draw(gameTime);
}

接下來就是來寫DrawModel函式的內容。

將一個3D世界中的物體,轉換成在2D我們螢幕畫面時,需要經過三個矩陣的轉換
World : 世界轉換矩陣,這個矩陣可以由三個部分組成。
             S : Size,表示放大的倍率,可以針對XYZ軸分別放大。用Matrix的CreateScale函數指定XYZ分別的放大倍率。
             R : Rotation,旋轉,這邊XNA的Matrix類別,提供幾個方建的旋轉函數。CreateRotationX(針對X軸旋轉)、 CreateRotationY(針對Y軸旋轉)、CreateRotationZ(針對Z軸旋轉)。
             T : Translation,平移,這邊可以說成是,3D Model在3D世界中的位置。用Matrix的CreateTranslation就可以指定位置。
             全部設定好以後Matrix world結果是寫成S*R*T的計算結果值。
View : 一個觀察者在一個3D空間中的位置,用Matrix的CreateLookAt函數設定就好,這個函式需要四個參數。
             Position : 觀看者的位置,也就是攝影機現在在的位置,可以用一個Vector3的方式可以完成指定座標位置就好。
             LookAt : 觀看者現在要看的位置,就是觀看者現在要看哪個點,也是用一個Vector3就可以描述完成。一般來說我們都會把物體放在原點上面,所以觀看位置都是填入 000,在XNA中,Vector提供了一個方式,這樣就不用特別的再填入那些數值,用Vector3.Zero就可以。
             Up : 向上的向量,一般都不會特別設定他,都直接用Vector3.Up代表010,這邊要注意的是,在匯出FBX的時候,他會問你說Up Vector是在哪個軸,在預設的3D Max中Z軸向上,所以在匯出的時候大家記得把Y軸改成Z軸。同時大家也可以把Vector3.Up改成Vector3.Down這樣會發現上下會顛倒。
             Matrix.CreateLookAt(位置,觀看的位置,Up)
Projection : 投影矩陣,用Matrix所提供的CreatePerspectiveFieldOfView來建置。
             這個參數需要四個參數:
             視野參數 : 眼睛所能看到的最大角度
             aspectRatio : 解析度的比值
             近平面 : 最近所能看到的距離。
             遠平面 : 最遠所能看到的距離。
                   這邊有個概念就是近平面與遠平面,所圍成的立體椎體,稱為平頭椎體。這個在3D圖學有自己的獨特的意義,就是說在這個椎體內的東西,才會畫出來,而超過這些椎體的範圍都不會匯出。

以上三個重要的矩陣設定好以後,接下來就是進行匯出的準備。

我們需要一個Matrix陣列用來儲存,目前那個3D Model有多少的元件(物件)。
Matrix[] transforms = new Matrix[FD.bone.count];

接下來就是將FD Model的東西放入transforms中
FD.CopyAbsoluteBoneTransformsTo(transforms);
這種複製不是單純的複製陣列或是物件,他會記錄所有物件與父類別的相對位置等等。

這些準備完成以後接下來就是,針對這個矩陣陣列來做WVP轉換。
用兩層FOREACH迴圈來完成,轉換動作
foreach (ModelMesh mesh in FD.Meshes)
{
       foreach (BasicEffect effect in mesh.Effects)
       {
             //預設光源
            effect.EnableDefaultLighting();

            effect.World = transforms[mesh.ParentBone.Index] * World;
            effect.View = View;
            effect.Projection = Projection;
        }
        mesh.Draw();
}

完成以後大家就可以編譯這個檔案,就會發現3D模型的呈現。



範例程式:
140.126.21.8/~b09402129/XNA/example4.rar

最後有一點要提醒, 這點美術人員應該要特別注意。
建議你把所有物件的中心點都設置在原點的位置,有些人有自己的特殊喜好,但是會帶改程式人員很大的困擾,因為程式人員需要尋找你那張圖片在哪裡。
再來美術人員需要把你現在3D模型的長寬高都告訴,程式人員,這樣可以減少程式人員在那邊尋找哪邊是最好的視野位置。