3d XNA中FBX的顶点信息,奇怪的结果

3d XNA中FBX的顶点信息,奇怪的结果,3d,xna,vertex-buffer,fbx,3d,Xna,Vertex Buffer,Fbx,我试图从fbx文件中获取顶点位置数据,为了测试,我使用了一个简单的平面,它位于xz平面上,它的4个顶点是(+/-1,0,+/-1)。顶点数据在Maya中确认,我使用Maya导出平面 以下是我的顶点提取代码: void getVertices() { foreach (ModelMesh mesh in model.Meshes) foreach (ModelMeshPart part in mesh.MeshParts) { nVe

我试图从fbx文件中获取顶点位置数据,为了测试,我使用了一个简单的平面,它位于xz平面上,它的4个顶点是(+/-1,0,+/-1)。顶点数据在Maya中确认,我使用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());
            }
        }
    }
void getVertices()
{
foreach(model.mesh中的ModelMesh网格)
foreach(网格中的ModelMeshPart零件。MeshParts)
{
nVerts=part.num证书;
Vector3[]vec=新的Vector3[nVerts*2];
part.VertexBuffer.GetData(vec);
Console.WriteLine(“#模型中的顶点:+nVerts”);
对于(int i=0;i
因为有4个顶点,我得到了8个向量,每个顶点位置1个,每个顶点法线1个。对于飞机来说,大多数都是正确的(起初我使用了更复杂的模型,但精确度较低)

结果如下:所有法线都应该在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个向量要发送,所以我不认为我遗漏了任何信息

假设您通过内容管道加载FBX,它会将其指定为框架标准顶点类型之一。但是没有一种顶点类型只有位置和法线信息。最有可能的是有第三个因素正在破坏你的结果。这应该起作用:

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);
}
int vertexStride=model.mesh[0].MeshParts[0].VertexDeclaration.vertexStride;
VertexBuffer vb=model.mesh[0]。MeshParts[0]。VertexBuffer;
List vertexPositions=新列表();
对于(int i=0;i

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

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];
}
var顶点=新浮点[meshPart.VertexBuffer.VertexCount
*meshPart.VertexBuffer.VertexDeclaration.VertexStride/4];
meshPart.VertexBuffer.GetData(顶点);
var vertexElements=meshPart.VertexBuffer.VertexDeclaration.GetVertexElements();
int vertexOffset=顶点元素
.First(e=>e.VertexElementUsage==VertexElementUsage.Position)
.抵销额/4;
对于(int i=meshPart.VertexOffset;
i
我的最终答案基于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);

        }
VertexBuffer-VertexBuffer;
VertexPositionColor[]顶点;
IndexBuffer IndexBuffer;
短期[]指数;
国际投资;
void getVertices()
{
int vertexStride=model.mesh[0]。MeshParts[0]。VertexBuffer.VertexDeclaration.vertexStride;
vertexBuffer=model.mesh[0]。MeshParts[0]。vertexBuffer;
nVerts=vertexBuffer.VertexCount;
indexBuffer=model.mesh[0]。MeshParts[0]。indexBuffer;
int nInts=indexBuffer.IndexCount;
指数=新的短期[nInts];
indexBuffer.GetData(索引);
verts=新的VertexExpositionColor[vertexBuffer.VertexCount];
对于(int i=0;i
这很有效,非常感谢!我发现索引缓冲区会改变每个模型,即使它来自同一个程序,这是我没有想到的,并且有一些小的语法错误,因此我将在下面发布我最后得到的完整性。再次感谢。如果你想访问其他模型,将数据作为Vector3是个坏主意呃数据…纹理坐标是矢量2,颜色是矢量4…虽然它解决了你的需要…我认为最好是以浮点形式检索数据,并使用VertexElementUsage来检测你想要的数据的正确偏移位置…是的,谢谢,直到我完成了我自己的答案,我才看到你的答案。一旦我让3d模型在我的粒子中运行良好系统,我将返回并按照您的方式实现它。