来自XX的FBX的顶点信息,结果很奇怪

时间:2013-08-03 16:31:43

标签: 3d xna vertex-buffer fbx

我试图从fbx文件中获取顶点位置数据,为了测试我使用一个简单的平面,它位于xz平面,它的4个顶点是(+ / -1,0,+ / - 1)。顶点数据在Maya中确认,我用它来导出平面。

这是我的顶点提取代码:

void getVertices()
{
    foreach (ModelMesh mesh in model.Meshes)
        foreach (ModelMeshPart part in mesh.MeshParts)
        {
            nVerts = part.NumVertices;
            Vector3[] vec = new Vector3[nVerts * 2];

            part.VertexBuffer.GetData<Vector3>(vec);

            Console.WriteLine("#Vertices in Model: " + nVerts);
            for (int i = 0; i < vec.Length; i++)
            {
                Console.WriteLine(i + " " vec[i].ToString());
            }
        }
    }

由于有4个顶点,我得到8个Vector3s,每个顶点位置1个,每个顶点法线1个。对于平面MOST是正确的(我最初使用了更复杂的模型而且不太准确)。

以下是结果:所有法线都应该直接指向Y.

点数: (1,0,-1) (1,0,1) (1,0,1) (-1,0,1)

法线 (0,1,0) (0,1,0) (1,-1,0) (0,0,0)

第三点,(与第二点相同)和最后两个法线是错误的。我无法弄清楚为什么我没有得到正确的数据。我尝试过增加vector3数组,但它只有8个向量要发送,所以我不认为我错过了任何信息。

3 个答案:

答案 0 :(得分:1)

假设您通过内容管道加载FBX,它将为其分配一个框架标准顶点类型。但是没有顶点类型只有位置和正常信息。最有可能的是第3个元素会搞砸你的结果。这应该有效:

int vertexStride = model.Meshes[0].MeshParts[0].VertexDeclaration.VertexStride;
VertexBuffer vb = model.Meshes[0].MeshParts[0].VertexBuffer;
List<Vector3> vertexPositions = new List<Vector3>();


for(int i = 0; i < vb.VertexCount; i++)
{
   Vector3 vec;
   vb.GetData<Vector3>(i*vertexStride, vec, i, 1, vertexStride);//3rd param should either be i or 0
   vertexPositions.Add(vec);
}

答案 1 :(得分:0)

模型可以有不同的顶点结构,所以最好考虑它的信息来读取数据,如果你想要纹理或正常,最好是使用正确的VertexElementUsage来检查它是否存在以及数据的偏移量是多少。 / p>

var vertices = new float[  meshPart.VertexBuffer.VertexCount 
                         * meshPart.VertexBuffer.VertexDeclaration.VertexStride / 4];

meshPart.VertexBuffer.GetData<float>( vertices );

var vertexElements = meshPart.VertexBuffer.VertexDeclaration.GetVertexElements( );

int vertexOffset = vertexElements
        .First( e => e.VertexElementUsage == VertexElementUsage.Position )
        .Offset / 4;

for (int i = meshPart.VertexOffset; 
         i < meshPart.VertexOffset + meshPart.NumVertices; i++ {
    int baseIndex = i * (meshPart.VertexBuffer.VertexDeclaration.VertexStride / 4);

    var X = vertices[baseIndex + vertexOffset] ;
    var Y = vertices[baseIndex + vertexOffset + 1];
    var Z = vertices[baseIndex + vertexOffset + 2];
}

答案 2 :(得分:0)

我的最终答案,基于我从Steve H获得的帮助,包括索引数据:

    VertexBuffer vertexBuffer;
    VertexPositionColor[] verts;
    IndexBuffer indexBuffer;
    short[] indices;
    int nVerts;

    void getVertices()
        {
            int vertexStride = model.Meshes[0].MeshParts[0].VertexBuffer.VertexDeclaration.VertexStride;
            vertexBuffer = model.Meshes[0].MeshParts[0].VertexBuffer;
            nVerts = vertexBuffer.VertexCount;

            indexBuffer = model.Meshes[0].MeshParts[0].IndexBuffer;
            int nInts = indexBuffer.IndexCount;

            indices = new short[nInts];

            indexBuffer.GetData<short>(indices);

            verts = new VertexPositionColor[vertexBuffer.VertexCount];

            for (int i = 0; i < vertexBuffer.VertexCount; i++)
            {
                Vector3[] vertData = new Vector3[vertexBuffer.VertexCount];
                vertexBuffer.GetData<Vector3>(i * vertexStride, vertData, i, 1, vertexStride);

                verts[i].Position = vertData[i];
            }

            vertexBuffer = new VertexBuffer(device, typeof(VertexPositionColor), nVerts, BufferUsage.WriteOnly);
            indexBuffer = new IndexBuffer(device, typeof(short), nVerts / 4 * 6, BufferUsage.WriteOnly);

            vertexBuffer.SetData(verts);
            indexBuffer.SetData(indices);

        }