2014-09-29 28 views
0

我正在從使用SharpDX 2.6加載的模型中創建凸包和三角形網格。我發現了一些示例代碼,用於從模型中提取頂點和索引,但它們基於XNA和(看起來像)DirectX 9 - 我的程序使用SharpDX與DirectX 11(和SharpDX工具包,所以很多東西都與XNA相似)。從SharpDX工具包模型中提取頂點和三角形數據

的代碼我發現提取頂點和索引(三角形):

public void ExtractData(List<JVector> vertices, List<JOctree.TriangleVertexIndices> indices, Model model) 
    { 
     Matrix[] bones_ = new Matrix[model.Bones.Count]; 
     model.CopyAbsoluteBoneTransformsTo(bones_); 
     foreach (ModelMesh mm in model.Meshes) 
     { 
      Matrix xform = bones_[mm.ParentBone.Index]; 
      foreach (ModelMeshPart mmp in mm.MeshParts) 
      { 
       int offset = vertices.Count; 
       Vector3[] a = new Vector3[mmp.NumVertices]; 
       mm.VertexBuffer.GetData<Vector3>(mmp.StreamOffset + mmp.BaseVertex * mmp.VertexStride, 
        a, 0, mmp.NumVertices, mmp.VertexStride); 
       for (int i = 0; i != a.Length; ++i) 
        Vector3.Transform(ref a[i], ref xform, out a[i]); 

       for (int i = 0; i < a.Length; i++) vertices.Add(new JVector(a[i].X, a[i].Y, a[i].Z)); 

       if (mm.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits) 
        throw new Exception(
         String.Format("Model uses 32-bit indices, which are not supported.")); 
       short[] s = new short[mmp.PrimitiveCount * 3]; 
       mm.IndexBuffer.GetData<short>(mmp.StartIndex * 2, s, 0, mmp.PrimitiveCount * 3); 
       JOctree.TriangleVertexIndices[] tvi = new JOctree.TriangleVertexIndices[mmp.PrimitiveCount]; 
       for (int i = 0; i != tvi.Length; ++i) 
       { 
        tvi[i].I0 = s[i * 3 + 2] + offset; 
        tvi[i].I1 = s[i * 3 + 1] + offset; 
        tvi[i].I2 = s[i * 3 + 0] + offset; 
       } 
       indices.AddRange(tvi); 
      } 
     } 
    } 

這裏是我已經能夠將其返工成(支持DirectX 11與SharpDX工具輕鬆): 我已經將它推廣到簡單地從模型構建八叉樹,但是管道的主要部分仍然是相同的。我使用此代碼的變體(不包括三角形計算,只是頂點)以類似的方式創建一個凸包形狀。

我的問題是: 有沒有什麼辦法可以改進這段代碼?

該代碼是否正確/是否存在您立即發現可能錯誤的內容?

當我使用這種方法從盒子的模型中提取頂點(與Jitter教程中使用的模型相同)時,我得到的表示不是一個不完全均勻分佈的形狀網格細節的框,然後減慢碰撞比使用內置的BoxShape基元(使用BoxShape時爲60fps平坦,使用與靜態TerrainShape碰撞的單個盒子時約爲20-30)大得多。爲什麼會出現這種情況?

我覺得,雖然我重寫代碼會產生一些輸出,但它根本感覺不到最佳。

回答

1

不幸的是,您無法輕鬆提取數據。頂點緩衝區中的元素可以根據模型頂點結構而變化(請參閱compiler code,您可以有Vector4Vector3,Vector2甚至16位)。

要正確解碼它,您需要在運行時訪問佈局並使用它解碼頂點緩衝區。

+0

感謝您的回答xoofx, 如果您爲構建Jitter Physics的ConvexHullShape()而提出了構建頂點列表的任務,那麼您將如何去做? (我主要問的是實際開發SharpDX的人的洞察) 使用XNA的抖動示例如下鏈接: https://code.google.com/p/jitterphysics/source/browse/trunk /JitterDemo/JitterDemo/PhysicsObjects/ConvexHullObject.cs 你是否同意他們的做法,以及如何最好地將其轉換爲SharpDX解決方案? 謝謝 – lberezy 2014-09-30 01:11:37

+0

沒有時間寫出完整的解決方案,但這基本上是這個想法。與XNA版本的不同之處在於XNA GetData能夠獲得頂點流的一部分,而使用SharpDX則必須計算到正確頂點元素的偏移量,並迭代原始緩衝區來對其進行解碼。代碼編寫起來有點費勁。 – xoofx 2014-09-30 01:47:20

+0

當我寫我的解決方案時(我剛剛接觸3D圖形,請原諒我),偏移部分讓我感到困惑。 所以我想要遍歷模型中的每個網格的頂點緩衝區,對每個頂點應用適用的骨骼變換(對我來說是新的),然後將該緩衝區的頂點附加到有序的頂點列表 - 實質上是將許多網格壓縮到一個頂點列表中?抵消? 這就是創建凸包所需的全部內容,因爲可以從沒有任何頂點索引信息的點雲構建一個凸包,但要創建具有代表性的網格,我需要索引/ TriangleVertexElements。 – lberezy 2014-09-30 02:14:45

相關問題