Search code examples
c++directxvertex-buffervertices

Non coherent Vertex Buffer with X file


I'm trying to understand how to manipulate a mesh from a .X file. I started by testing out with a pyramid (5 vertices). I load the .X with the classic D3DX function

D3DXLoadMeshFromX( path.c_str(), D3DXMESH_DYNAMIC, pDevice->GetDeviced3d(), NULL, &pMaterialBuffer, NULL, &m_numMaterials, &m_pMesh);

Everything looks fine in the renderer.But I notice that the GetNumVertices() return 16... When I get the vertex buffer with GetMesh()->LockVertexBuffer(0(void**)&pVerts); and print all 16 vertices I get this output :

0 1 -1
1 0 -1
0 -1 -1
0.13477 0.180836 1.34715
-1 0 -1
0.13477 0.180836 1.34715
0 1 -1
0.13477 0.180836 1.34715
-1 0 -1
0 -1 -1
0.13477 0.180836 1.34715
1 0 -1
-1 0 -1
0 -1 -1
1 0 -1
0 1 -1

From the folowing X file :

Frame Root {
  FrameTransformMatrix {
     1.000000, 0.000000, 0.000000, 0.000000,
     0.000000,-0.000000, 1.000000, 0.000000,
     0.000000, 1.000000, 0.000000, 0.000000,
     0.000000, 0.000000, 0.000000, 1.000000;;
  }
  Frame Cone {
    FrameTransformMatrix {
       1.000000, 0.000000, 0.000000, 0.000000,
       0.000000, 1.000000, 0.000000, 0.000000,
       0.000000, 0.000000, 1.000000, 0.000000,
       0.000000, 0.000000, 0.000000, 1.000000;;
    }
    Mesh { // Cone mesh
      5;
       0.000000; 1.000000;-1.000000;,
       1.000000;-0.000000;-1.000000;,
      -0.000000;-1.000000;-1.000000;,
       0.134770; 0.180836; 1.347146;,
      -1.000000; 0.000000;-1.000000;;
      5;
      3;4,3,2;,
      3;1,3,0;,
      3;0,3,4;,
      3;2,3,1;,
      4;4,2,1,0;;
      MeshNormals { // Cone normals
        5;
        -0.657358;-0.657358; 0.368458;,
         0.692540; 0.692540; 0.201935;,
        -0.679600; 0.679600; 0.276205;,
         0.674410;-0.674410; 0.300568;,
         0.000000; 0.000000;-1.000000;;
        5;
        3;0,0,0;,
        3;1,1,1;,
        3;2,2,2;,
        3;3,3,3;,
        4;4,4,4,4;;
      } // End of Cone normals
    } // End of Cone mesh
  } // End of Cone
} // End of Root

So how is it possible to have these 16 vertices if the file only contains 5? My goal is being able to edit the vertex XYZ coord.

Thanks alot!


Solution

  • This is because each vertex can only have a single position and a single vertex normal. The model is specified as having face normals (i.e. each face has a unique normal) which requires vertex duplication to be specified as per-vertex normals.

    The first face is 4,3,2 for position but 0,0,0 for normal so it has to create 3 vertex instances that combine them and no other faces in the mesh are actually identical.

    Face 0:
    Vertex A [ position:-1.000000; 0.000000;-1.000000;
               normal:-0.657358;-0.657358; 0.368458; ]
    Vertex B [ position: 0.134770; 0.180836; 1.347146;
               normal:-0.657358;-0.657358; 0.368458; ]
    Vertex C [ position: -0.000000;-1.000000;-1.000000
               normal:-0.657358;-0.657358; 0.368458; ]
    

    Even though the original 4 and 3 position is reused in the 3rd face, the normals are different than in Face 0 so this has to be done by duplicating (aka splitting) the vertex.

    Face normals are usually a 'worst-case' here since each each vertex can be unique. Most models containing 'smooth' per-vertex normals only need the vertex splitting to happen on sharp edges/creases.

    You might want to take a look at the DirectXMesh library for example code for processing mesh information.