Merge pull request #1931 from ey6es/master

Fix for textures on Blender FBX exports (such as jellyrob_blue_blender.fbx).
This commit is contained in:
AndrewMeadows 2014-02-10 14:27:44 -08:00
commit c517675edb

View file

@ -601,6 +601,7 @@ public:
FBXMesh mesh;
QMultiHash<int, int> newIndices;
QVector<QHash<int, int> > blendshapeIndexMaps;
QVector<QPair<int, int> > partMaterialTextures;
};
class MeshData {
@ -667,6 +668,7 @@ void appendIndex(MeshData& data, QVector<int>& indices, int index) {
ExtractedMesh extractMesh(const FBXNode& object) {
MeshData data;
QVector<int> materials;
QVector<int> textures;
foreach (const FBXNode& child, object.children) {
if (child.name == "Vertices") {
data.vertices = createVec3Vector(getDoubleVector(child.properties, 0));
@ -703,19 +705,32 @@ ExtractedMesh extractMesh(const FBXNode& object) {
materials = getIntVector(subdata.properties, 0);
}
}
} else if (child.name == "LayerElementTexture") {
foreach (const FBXNode& subdata, child.children) {
if (subdata.name == "TextureId") {
textures = getIntVector(subdata.properties, 0);
}
}
}
}
// convert the polygons to quads and triangles
int polygonIndex = 0;
QHash<QPair<int, int>, int> materialTextureParts;
for (int beginIndex = 0; beginIndex < data.polygonIndices.size(); polygonIndex++) {
int endIndex = beginIndex;
while (data.polygonIndices.at(endIndex++) >= 0);
int materialIndex = (polygonIndex < materials.size()) ? materials.at(polygonIndex) : 0;
data.extracted.mesh.parts.resize(max(data.extracted.mesh.parts.size(), materialIndex + 1));
FBXMeshPart& part = data.extracted.mesh.parts[materialIndex];
QPair<int, int> materialTexture((polygonIndex < materials.size()) ? materials.at(polygonIndex) : 0,
(polygonIndex < textures.size()) ? textures.at(polygonIndex) : 0);
int& partIndex = materialTextureParts[materialTexture];
if (partIndex == 0) {
data.extracted.partMaterialTextures.append(materialTexture);
data.extracted.mesh.parts.resize(data.extracted.mesh.parts.size() + 1);
partIndex = data.extracted.mesh.parts.size();
}
FBXMeshPart& part = data.extracted.mesh.parts[partIndex - 1];
if (endIndex - beginIndex == 4) {
appendIndex(data, part.quadIndices, beginIndex++);
appendIndex(data, part.quadIndices, beginIndex++);
@ -1265,41 +1280,60 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
glm::mat4 modelTransform = getGlobalTransform(parentMap, models, modelID);
// look for textures, material properties
int partIndex = extracted.mesh.parts.size() - 1;
int materialIndex = 0;
int textureIndex = 0;
bool generateTangents = false;
foreach (const QString& childID, childMap.values(modelID)) {
if (partIndex < 0) {
break;
}
FBXMeshPart& part = extracted.mesh.parts[partIndex];
if (textureFilenames.contains(childID)) {
part.diffuseFilename = textureFilenames.value(childID);
continue;
}
if (!materials.contains(childID)) {
continue;
}
Material material = materials.value(childID);
part.diffuseColor = material.diffuse;
part.specularColor = material.specular;
part.shininess = material.shininess;
QString diffuseTextureID = diffuseTextures.value(childID);
if (!diffuseTextureID.isNull()) {
part.diffuseFilename = textureFilenames.value(diffuseTextureID);
QList<QString> children = childMap.values(modelID);
for (int i = children.size() - 1; i >= 0; i--) {
const QString& childID = children.at(i);
if (materials.contains(childID)) {
Material material = materials.value(childID);
QByteArray diffuseFilename;
QString diffuseTextureID = diffuseTextures.value(childID);
if (!diffuseTextureID.isNull()) {
diffuseFilename = textureFilenames.value(diffuseTextureID);
// FBX files generated by 3DSMax have an intermediate texture parent, apparently
foreach (const QString& childTextureID, childMap.values(diffuseTextureID)) {
if (textureFilenames.contains(childTextureID)) {
part.diffuseFilename = textureFilenames.value(childTextureID);
// FBX files generated by 3DSMax have an intermediate texture parent, apparently
foreach (const QString& childTextureID, childMap.values(diffuseTextureID)) {
if (textureFilenames.contains(childTextureID)) {
diffuseFilename = textureFilenames.value(childTextureID);
}
}
}
QByteArray normalFilename;
QString bumpTextureID = bumpTextures.value(childID);
if (!bumpTextureID.isNull()) {
normalFilename = textureFilenames.value(bumpTextureID);
generateTangents = true;
}
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
if (extracted.partMaterialTextures.at(j).first == materialIndex) {
FBXMeshPart& part = extracted.mesh.parts[j];
part.diffuseColor = material.diffuse;
part.specularColor = material.specular;
part.shininess = material.shininess;
if (!diffuseFilename.isNull()) {
part.diffuseFilename = diffuseFilename;
}
if (!normalFilename.isNull()) {
part.normalFilename = normalFilename;
}
}
}
materialIndex++;
} else if (textureFilenames.contains(childID)) {
QByteArray filename = textureFilenames.value(childID);
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
if (extracted.partMaterialTextures.at(j).second == textureIndex) {
extracted.mesh.parts[j].diffuseFilename = filename;
}
}
textureIndex++;
}
QString bumpTextureID = bumpTextures.value(childID);
if (!bumpTextureID.isNull()) {
part.normalFilename = textureFilenames.value(bumpTextureID);
generateTangents = true;
}
partIndex--;
}
// if we have a normal map (and texture coordinates), we must compute tangents