سؤال

I'm trying to grab the vertex position data from an fbx file, for testing I'm using a simple plane, it lies in the xz plane and it's 4 vertices are (+/-1, 0, +/-1). The vertex data is confirmed in Maya, which I used to export the plane.

Here's my vertex extraction code:

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());
            }
        }
    }

Since there are 4 vertices, I get 8 Vector3s, 1 for each vertex position and one for each vertex normal. For the plane MOST are correct (I used more complicated models at first and it was less accurate).

Here are the results: all the normals should point straight up in Y.

Points: (1,0,-1) (1,0,1) (1,0,1) (-1,0,1)

Normals (0,1,0) (0,1,0) (1,-1,0) (0,0,0)

The third point, (the same as the 2nd) and the final 2 normals are wrong. I can't figure out why I am not getting the right data. I've tried increasing the vector3 array, but it only has 8 vectors to send, so i don't think I'm missing any info.

هل كانت مفيدة؟

المحلول

Assuming you loaded the FBX through the content pipeline, it would have assigned it one of the frameworks standard vertex types. But there is no vertex type that has only position and normal information. Most likely there is a 3rd element that is screwing up your results. This should work:

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);
}

نصائح أخرى

Models can have different vertex structures, so the best is consider its info to read the data, if you wnat textures or normal the best is using the right VertexElementUsage to check if it exists and what is the offset where data is.

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];
}

My final answer, based on the help I got from Steve H, and including index data:

    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);

        }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top