0

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 つあるため、頂点位置ごとに 1 つ、頂点法線ごとに 1 つ、計 8 つの Vector3 を取得します。飛行機の場合、ほとんどが正しいです (最初はより複雑なモデルを使用しましたが、精度は低くなりました)。

結果は次のとおりです。すべての法線が 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)

3 番目のポイント (2 番目と同じ) と最後の 2 つの法線が間違っています。正しいデータを取得できない理由がわかりません。vector3 配列を増やしてみましたが、送信するベクトルが 8 つしかないため、情報が欠落しているとは思いません。

4

3 に答える 3

1

コンテンツ パイプラインを介して FBX をロードしたと仮定すると、フレームワークの標準頂点タイプの 1 つが割り当てられます。しかし、位置情報と法線情報だけを持つ頂点タイプはありません。ほとんどの場合、結果を台無しにしている 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);
}
于 2013-08-03T19:05:54.430 に答える
0

モデルはさまざまな頂点構造を持つことができるため、その情報を考慮してデータを読み取るのが最善です。テクスチャまたは法線を使用する場合は、適切な VertexElementUsage を使用して存在するかどうか、およびデータのオフセットを確認するのが最善です。

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];
}
于 2013-08-04T00:25:40.440 に答える
0

スティーブ 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);

        }
于 2013-08-04T00:41:24.497 に答える