2013-05-01 30 views
1

我正在嘗試使用C#和XNA 4.0遍歷FBX模型的頂點。我認爲,如果我可以訪問頂點,那麼我就可以自己訪問其他部分,如臉部法線,邊緣,PolygonVertexIndex等。使用XNA 4.0從fbx模型中提取頂點

我發現喬恩Watte的一篇文章討論瞭如何使用XNA 3.0, Extracting Vertices and Triangles from an XNA Model 但他使用似乎並沒有在4.0存在的3.0結構來做到這一點。

尤其是他訪問的頂點是這樣的:

Vector3[] a = new Vector3[myModelMeshPart.NumVertices]; 
myModelMesh.VertexBuffer.GetData<Vector3>(myModelMeshPart.StreamOffset + myModelMeshPart.BaseVertex * myModelMeshPart.VertexStride, 
      a, 0, myModelMeshPart.NumVertices, myModelMeshPart.VertexStride); 

但在XNA 4,VertexBuffer似乎並沒有成爲MeshModel屬性。

任何人都可以請指導我的Model的頂點的基本迭代?

謝謝。

@ user2340634謝謝您的迴應。
我的嘗試使用了比實際#個vert更少的嘗試。
我想我不知道如何使用VertexBuffer。您能否對此代碼發表評論?

private void getVerts(Model mdl) 
{ 
    foreach (ModelMesh mm in mdl.Meshes) 
    { 
     foreach (ModelMeshPart mp in mm.MeshParts) 
     { 
      VertexBuffer vb = mp.VertexBuffer; 
      short[] s = new short[mp.PrimitiveCount * 3]; 
      IndexBuffer ib = mp.IndexBuffer; 
      ib.GetData<short>(mp.StartIndex * 2, s, 0, mp.PrimitiveCount * 3); 

      Vector3[] v = new Vector3[4]; 
      VertexPositionNormalTexture[] vert = new VertexPositionNormalTexture[4]; 
      mp.VertexBuffer.GetData<VertexPositionNormalTexture>(vert, 0, mp.NumVertices); 
      for (int i = 0; i < v.Length; i++) 
      { 
       v[i] = vert[i].Position; 
       trace("(" + v[i].X.ToString() + ", " + v[i].Y.ToString() + ", " + v[i].Z.ToString() + ")"); 
      } 
     } 
    } 
} 

你有一個工作樣本,迭代通過verts,請嗎?

回答

0
modModel = Content.Load<Model>("Cube1"); 
foreach (ModelMesh modmModel in modModel.Meshes) 
{ 
    foreach (ModelMeshPart mmpModel in modmModel.MeshParts) 
    { 
     modelExtractor = new ModelExtractor(mmpModel, new Vector3[mmpModel.NumVertices * 2], new VertexPositionColor[mmpModel.NumVertices]); 
     modelExtractor.ExtractVertices(); 
    } 
} 
for (int a = 0; a < modelExtractor.ArrVectors.Length; a++) 
{ 
    Console.WriteLine(modelExtractor.ArrVectors[a]); 
} 
vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), modelExtractor.VpcVertices.Length, BufferUsage.None); 
vertexBuffer.SetData(modelExtractor.VpcVertices); 

這是來自主類。這就是我將模型轉換爲ModelMeshPart的方式。直到我從.fbx中提取數據後,才創建頂點緩衝區。 for循環(及其內部的代碼行)通過將提取的頂點數據寫入控制檯窗口,爲您提供了一個列表。

private ModelMeshPart mmpModel; 
private Vector3[] arrVectors; 
private VertexPositionColor[] vpcVertices; 

這些是我的ModelExtractor類的字段。它們被以下方法使用。

public void ExtractVertices() 
{ 
    this.mmpModel.VertexBuffer.GetData<Vector3>(this.arrVectors); 
    for (int a = 0; a < vpcVertices.Length; a += 2) 
    { 
     this.vpcVertices[a].Position.X = arrVectors[a].X; 
     this.vpcVertices[a].Position.Y = arrVectors[a].Y; 
     this.vpcVertices[a].Position.Z = arrVectors[a].Z; 
    } 
} 

我提取了「Vector3」類型的數據。 .fbx中的每個頂點都有一個用於位置的Vector3和另一個用於法線的頂點。只有這樣,我才能將位置組件從Vector3s數組中的組件移到VertexPositionColors數組中。請注意,for循環會將「a」增加2而不是1.這樣我可以跳過法線的Vector3s。

+0

謝謝,這讓我得到了頂點。太糟糕了,其他數據沒有相應的緩衝區。 – user2340426 2013-05-04 07:51:23

+0

就好像你確實需要一個正常向量的緩衝區。緩衝區真的只是繪畫。 – user2340634 2013-05-06 04:14:15

2

「Model」沒有「VertexBuffer」。 「ModelMesh」也沒有「VertexBuffer」。但是,我發現「ModelMeshPart」確實有「VertexBuffer」。我也是第一次從.fbx進行數據提取。我們包含在項目中的任何模型都必須存儲在ModelMeshPart中。這並不壞。 .fbx中的整個網格可以被認爲是一個部分。

+0

。我拼湊在一起的代碼示例並不能給出我在fbx文件中看到的頂點。我認爲這是我使用VertexBuffer缺乏技巧。你有一個基本的迭代例子,你可以告訴我嗎? – user2340426 2013-05-02 17:17:03

+0

看到我的新答案。 – user2340634 2013-05-03 06:00:23

0

這是我的解決方案(如果該模型有你通過他們必須循環過程中的幾個部分),我需要使用VertexBuffer幫助

public static void ModelData(Model model) 
{ 
    ModelMeshPart part = model.Meshes[0].MeshParts[0]; 

    VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[part.VertexBuffer.VertexCount]; 
    part.VertexBuffer.GetData<VertexPositionNormalTexture>(vertices); 

    ushort[] drawOrder = new ushort[part.IndexBuffer.IndexCount]; 
    part.IndexBuffer.GetData<ushort>(drawOrder); 

}