Here's what I'm doing so far (just deals with normals):
// vector for our triangles vector <Triangle> triangles; // get all the triangles, positions, texCoords, normals, tangents, binormals int triCount = mesh->GetPolygonCount(); KFbxVector4 * positions = mesh->GetControlPoints(); for (int i = 0; i < triCount; ++i) { // add a triangle triangles.push_back( Triangle() ); // get a reference to it Triangle & tri = triangles.back(); // for each vertex in the triangle for (int v = 0; v < 3; ++v) { // get a reference to it Vertex & vert = tri.vertices[v]; // set its position int positionIndex = mesh->GetPolygonVertex( i, v ); for (int p = 0; p < 3; ++p) vert.position = (float)positions[positionIndex]; } } bool texCoordsFound = false; bool normalsFound = false; bool tangentsFound = false; bool binormalsFound = false; bool error = false; for (int l = 0; l < mesh->GetLayerCount(); ++l) { KFbxLayerElementUV * texCoords = texCoordsFound ? NULL : mesh->GetLayer( l )->GetUVs(); KFbxLayerElementNormal * normals = normalsFound ? NULL : mesh->GetLayer( l )->GetNormals(); KFbxLayerElementTangent * tangents = tangentsFound ? NULL : mesh->GetLayer( l )->GetTangents(); KFbxLayerElementBinormal * binormals = binormalsFound ? NULL : mesh->GetLayer( l )->GetBinormals(); // loop through triangles for (int i = 0; i < triCount; ++i) { // get a reference to it Triangle & tri = triangles; // for each vertex in the triangle for (int v = 0; v < 3; ++v) { // get a reference to it Vertex & vert = tri.vertices[v]; int positionIndex = mesh->GetPolygonVertex( i, v ); //... //... get tex coords here (works) //... // set its normal if (normals != NULL) { normalsFound = true; if (normals->GetMappingMode() == KFbxLayerElement::eBY_POLYGON_VERTEX) { switch (normals->GetReferenceMode()) { case KFbxLayerElement::eDIRECT: for (int p = 0; p < 3; ++p) vert.normal = (float)normals->GetDirectArray().GetAt( positionIndex ); break; case KFbxLayerElement::eINDEX_TO_DIRECT: { int index = normals->GetIndexArray().GetAt( positionIndex ); for (int p = 0; p < 3; ++p) vert.normal = (float)normals->GetDirectArray().GetAt( index ); } break; default: cout << " Error: invalid normal reference mode\n"; error = true; } } else { cout << " Error: invalid normal mapping mode\n"; error = true; } } //... //... get tangents/binormals here (probably doesn't work, haven't tested though, but similar to normals) //... if (error) break; } if (error) break; } if (error) break; } if (error) continue;
This seems to be what the FBX examples are doing to get the normals.
The actual normals I'm getting seem to be correct - that is, for an object like a box, I get a bunch of (0, 0, +-1), (0, +-1, 0), (+-1, 0, 0) for the normals. The issue seems to be that I'm not using the correct indices. Here is a screenshot of what I mean:
Each face should be "flat shaded" and should have a solid color on the entire face. It appears that there are only around 6 unique colors (+-1 in directions x, y, z), which is correct, but that they're applied to the wrong vertices.
Can anyone see anything I'm doing wrong in extracting the normal indices?