c++ - How to read in FBX 2014 indices properly for DirectX? -
i've been having annoying problem past weekend. have able to read in triangulated 2014 fbx file contains mesh exported maya , read in it's vertices , indices passed renderer (directx) drawindexed call.
so way have setup there tuniquevertex structure
struct tuniquevertex { xmfloat3 m_vposition, // vertex positions xmfloat3 m_vnormal, // vertex normals xmfloat2 m_uvs // vertex uvs int m_ncontrolpointindex, // control point index } this code here, load in fbxmesh cmesh class. holds mesh's vertices , indices.
class cmesh { ... vector<tuniquevertex> m_vvertices; vector<unsigned int> m_vindices; } the code load cmesh:
bool loadmesh(fbxmesh* pmesh, cmesh cmesh) { int polygoncount = pmesh->getpolygoncount(); fbxvector4* controlpoints = pmesh->getcontrolpoints(); int controlpointcount = pmesh->getcontrolpointscount(); int vertexid = 0; (int polygon = 0; polygon < polygoncount; polygon++) { int polyvertcount = pmesh->getpolygonsize(polygon); (int polyvert = 0; polyvert < polyvertcount; polyvert++) { cmesh::tuniquevertex uniquevert; int cpindex = pmesh->getpolygonvertex(polygon, polyvert); // grab our cp index our position information uniquevert.m_ncontrolpointindex = cpindex; uniquevert.m_vposition = xmfloat3((float)controlpoints[cpindex].mdata[0], (float)controlpoints[cpindex].mdata[1], (float)controlpoints[cpindex].mdata[2]); // grab uvs int uvelementcount = pmesh->getelementuvcount(); (int uvelement = 0; uvelement < uvelementcount; uvelement++) { fbxgeometryelementuv* geomelementuv = pmesh>getelementuv(uvelement); fbxlayerelement::emappingmode mapmode = geomelementuv->getmappingmode(); fbxlayerelement::ereferencemode refmode = geomelementuv->getreferencemode(); int directindex = -1; if (fbxgeometryelement::ebycontrolpoint == mapmode) { if (fbxgeometryelement::edirect == refmode) { directindex = cpindex; } else if (fbxgeometryelement::eindextodirect == refmode) { directindex = geomelementuv->getindexarray().getat(cpindex); } } else if (fbxgeometryelement::ebypolygonvertex == mapmode) { if (fbxgeometryelement::edirect == refmode || fbxgeometryelement::eindextodirect == refmode) { directindex = pmesh->gettextureuvindex(polygon, polyvert); } } // if got uv index if (directindex != -1) { fbxvector2 uv = geomelementuv->getdirectarray().getat(directindex); uniquevert.m_uvs = xmfloat2( (float)uv.mdata[0], (float)uv.mdata[1]); } } // grab normals int normelementcount = pmesh->getelementnormalcount(); (int normelement = 0; normelement < normelementcount; normelement++) { fbxgeometryelementnormal* geomelementnormal = pmesh->getelementnormal(normelement); fbxlayerelement::emappingmode mapmode = geomelementnormal->getmappingmode(); fbxlayerelement::ereferencemode refmode = geomelementnormal->getreferencemode(); int directindex = -1; if (fbxgeometryelement::ebypolygonvertex == mapmode) { if (fbxgeometryelement::edirect == refmode) { directindex = vertexid; } else if (fbxgeometryelement::eindextodirect == refmode) { directindex = geomelementnormal->getindexarray().getat(vertexid); } } // if got index if (directindex != 1) { fbxvector4 norm = geomelementnormal->getdirectarray().getat(directindex); uniquevert.m_vnormal = xmfloat3((float)norm.mdata[0], (float)norm.mdata[1], (float)norm.mdata[2]); } } // unique vertices stuff vector<cmesh::tuniquevertex>& uniqueverts = cmesh.getvertices(); size_t size = uniqueverts.size(); size_t i; (i = 0; < size; i++) { if (uniquevert == uniqueverts[i]) { break; } } if (i == size) { uniqueverts.push_back(uniquevert); } cmesh.getindices().push_back(i); ++vertexid; } } return true; } doing method loads in vertices, normals, , uvs correctly. however, when loading in indices , passing cmesh.getindices() count drawindexed call, indices out of order , looks in graphic debugger:

incase wondering, indices follows:
012, 023, 456, 657, 891, 081, 011, 121, 314, 121, 415, 161, 718, 171, 918, 202, 122, 212, 023
and here test .fbx i'm trying load information from:
if can me out this, i'd extremely grateful issue has caused me stress :d
are using left-handed view coordinates or right-handed view coordinates in application (see link)? if using left-handed view coordinates, need flip winding of each triangle in index buffer.
assert( (indices.size() % 3) == 0 ); for( auto = indices.begin(); != indices.end(); += 3 ) { std::swap( *it, *(it+2) ); } you may need flip texture coordinates well:
for( auto = vertices.begin(); != vertices.end(); ++it ) { it->texturecoordinate.x = ( 1.f - it->texturecoordinate.x ); } historically directx applications use left-handed view coordinates. xna game studio , opengl applications use right-handed view coordinates.
btw, why both -fliptriangles+ , -invertvtexcoord+ enabled default in samples content exporter sdkmesh.
Comments
Post a Comment