Fix FBXBaker not properly handling textures with the same name

This commit is contained in:
Ryan Huffman 2017-09-21 13:40:39 -07:00 committed by GitHub
parent 84786ac8e3
commit abbe263142
6 changed files with 54 additions and 38 deletions

View file

@ -1165,10 +1165,11 @@ void AssetServer::handleFailedBake(QString originalAssetHash, QString assetPath,
void AssetServer::handleCompletedBake(QString originalAssetHash, QString originalAssetPath, QVector<QString> bakedFilePaths) {
bool errorCompletingBake { false };
QString errorReason;
qDebug() << "Completing bake for " << originalAssetHash;
for (auto& filePath: bakedFilePaths) {
for (auto& filePath : bakedFilePaths) {
// figure out the hash for the contents of this file
QFile file(filePath);
@ -1184,6 +1185,7 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina
} else {
// stop handling this bake, couldn't hash the contents of the file
errorCompletingBake = true;
errorReason = "Failed to finalize bake";
break;
}
@ -1194,6 +1196,7 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina
if (!file.copy(_filesDirectory.absoluteFilePath(bakedFileHash))) {
// stop handling this bake, couldn't copy the bake file into our files directory
errorCompletingBake = true;
errorReason = "Failed to copy baked assets to asset server";
break;
}
}
@ -1220,12 +1223,14 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina
qDebug() << "Failed to set mapping";
// stop handling this bake, couldn't add a mapping for this bake file
errorCompletingBake = true;
errorReason = "Failed to finalize bake";
break;
}
} else {
qDebug() << "Failed to open baked file: " << filePath;
// stop handling this bake, we couldn't open one of the files for reading
errorCompletingBake = true;
errorReason = "Failed to finalize bake";
break;
}
}
@ -1235,6 +1240,10 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina
writeMetaFile(originalAssetHash);
} else {
qWarning() << "Could not complete bake for" << originalAssetHash;
AssetMeta meta;
meta.failedLastBake = true;
meta.lastBakeErrors = errorReason;
writeMetaFile(originalAssetHash, meta);
}
_pendingBakes.remove(originalAssetHash);
@ -1246,7 +1255,6 @@ void AssetServer::handleAbortedBake(QString originalAssetHash, QString assetPath
}
static const QString BAKE_VERSION_KEY = "bake_version";
static const QString APP_VERSION_KEY = "app_version";
static const QString FAILED_LAST_BAKE_KEY = "failed_last_bake";
static const QString LAST_BAKE_ERRORS_KEY = "last_bake_errors";
@ -1273,18 +1281,15 @@ std::pair<bool, AssetMeta> AssetServer::readMetaFile(AssetHash hash) {
auto root = doc.object();
auto bakeVersion = root[BAKE_VERSION_KEY].toInt(-1);
auto appVersion = root[APP_VERSION_KEY].toInt(-1);
auto failedLastBake = root[FAILED_LAST_BAKE_KEY];
auto lastBakeErrors = root[LAST_BAKE_ERRORS_KEY];
if (bakeVersion != -1
&& appVersion != -1
&& failedLastBake.isBool()
&& lastBakeErrors.isString()) {
AssetMeta meta;
meta.bakeVersion = bakeVersion;
meta.applicationVersion = appVersion;
meta.failedLastBake = failedLastBake.toBool();
meta.lastBakeErrors = lastBakeErrors.toString();
@ -1303,7 +1308,6 @@ bool AssetServer::writeMetaFile(AssetHash originalAssetHash, const AssetMeta& me
QJsonObject metaFileObject;
metaFileObject[BAKE_VERSION_KEY] = meta.bakeVersion;
metaFileObject[APP_VERSION_KEY] = meta.applicationVersion;
metaFileObject[FAILED_LAST_BAKE_KEY] = meta.failedLastBake;
metaFileObject[LAST_BAKE_ERRORS_KEY] = meta.lastBakeErrors;

View file

@ -34,7 +34,6 @@ struct AssetMeta {
}
int bakeVersion { 0 };
int applicationVersion { 0 };
bool failedLastBake { false };
QString lastBakeErrors;
};

View file

@ -583,29 +583,17 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
QString fbxTextureFileName { textureChild.properties.at(0).toByteArray() };
QFileInfo textureFileInfo { fbxTextureFileName.replace("\\", "/") };
if (textureFileInfo.suffix() == BAKED_TEXTURE_EXT.mid(1)) {
// re-baking an FBX that already references baked textures is a fail
// so we add an error and return from here
handleError("Cannot re-bake a file that references compressed textures");
return;
}
// make sure this texture points to something and isn't one we've already re-mapped
if (!textureFileInfo.filePath().isEmpty()) {
if (textureFileInfo.suffix() == BAKED_TEXTURE_EXT.mid(1)) {
// re-baking an FBX that already references baked textures is a fail
// so we add an error and return from here
handleError("Cannot re-bake a file that references compressed textures");
return;
}
// construct the new baked texture file name and file path
// ensuring that the baked texture will have a unique name
// even if there was another texture with the same name at a different path
auto bakedTextureFileName = createBakedTextureFileName(textureFileInfo);
QString bakedTextureFilePath {
_bakedOutputDir + "/" + bakedTextureFileName
};
_outputFiles.push_back(bakedTextureFilePath);
qCDebug(model_baking).noquote() << "Re-mapping" << fbxTextureFileName
<< "to" << bakedTextureFileName;
// check if this was an embedded texture we have already have in-memory content for
auto textureContent = _textureContent.value(fbxTextureFileName.toLocal8Bit());
@ -613,10 +601,29 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
auto urlToTexture = getTextureURL(textureFileInfo, fbxTextureFileName,
!textureContent.isNull());
QString bakedTextureFileName;
if (_remappedTexturePaths.contains(urlToTexture)) {
bakedTextureFileName = _remappedTexturePaths[urlToTexture];
} else {
// construct the new baked texture file name and file path
// ensuring that the baked texture will have a unique name
// even if there was another texture with the same name at a different path
bakedTextureFileName = createBakedTextureFileName(textureFileInfo);
_remappedTexturePaths[urlToTexture] = bakedTextureFileName;
}
qCDebug(model_baking).noquote() << "Re-mapping" << fbxTextureFileName
<< "to" << bakedTextureFileName;
QString bakedTextureFilePath {
_bakedOutputDir + "/" + bakedTextureFileName
};
// write the new filename into the FBX scene
textureChild.properties[0] = bakedTextureFileName.toLocal8Bit();
if (!_bakingTextures.contains(urlToTexture)) {
_outputFiles.push_back(bakedTextureFilePath);
// grab the ID for this texture so we can figure out the
// texture type from the loaded materials
@ -624,7 +631,7 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
auto textureType = textureTypes[textureID];
// bake this texture asynchronously
bakeTexture(urlToTexture, textureType, _bakedOutputDir, textureContent);
bakeTexture(urlToTexture, textureType, _bakedOutputDir, bakedTextureFileName, textureContent);
}
}
}
@ -644,10 +651,10 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
}
void FBXBaker::bakeTexture(const QUrl& textureURL, image::TextureUsage::Type textureType,
const QDir& outputDir, const QByteArray& textureContent) {
const QDir& outputDir, const QString& bakedFilename, const QByteArray& textureContent) {
// start a bake for this texture and add it to our list to keep track of
QSharedPointer<TextureBaker> bakingTexture {
new TextureBaker(textureURL, textureType, outputDir, textureContent),
new TextureBaker(textureURL, textureType, outputDir, bakedFilename, textureContent),
&TextureBaker::deleteLater
};

View file

@ -71,7 +71,7 @@ private:
QUrl getTextureURL(const QFileInfo& textureFileInfo, QString relativeFileName, bool isEmbedded = false);
void bakeTexture(const QUrl& textureURL, image::TextureUsage::Type textureType, const QDir& outputDir,
const QByteArray& textureContent = QByteArray());
const QString& bakedFilename, const QByteArray& textureContent = QByteArray());
QUrl _fbxURL;
@ -91,6 +91,7 @@ private:
QMultiHash<QUrl, QSharedPointer<TextureBaker>> _bakingTextures;
QHash<QString, int> _textureNameMatchCount;
QHash<QUrl, QString> _remappedTexturePaths;
TextureBakerThreadGetter _textureThreadGetter;

View file

@ -26,15 +26,19 @@
const QString BAKED_TEXTURE_EXT = ".ktx";
TextureBaker::TextureBaker(const QUrl& textureURL, image::TextureUsage::Type textureType,
const QDir& outputDirectory, const QByteArray& textureContent) :
const QDir& outputDirectory, const QString& bakedFilename,
const QByteArray& textureContent) :
_textureURL(textureURL),
_originalTexture(textureContent),
_textureType(textureType),
_outputDirectory(outputDirectory)
_outputDirectory(outputDirectory),
_bakedTextureFileName(bakedFilename)
{
// figure out the baked texture filename
auto originalFilename = textureURL.fileName();
_bakedTextureFileName = originalFilename.left(originalFilename.lastIndexOf('.')) + BAKED_TEXTURE_EXT;
if (bakedFilename.isEmpty()) {
// figure out the baked texture filename
auto originalFilename = textureURL.fileName();
_bakedTextureFileName = originalFilename.left(originalFilename.lastIndexOf('.')) + BAKED_TEXTURE_EXT;
}
}
void TextureBaker::bake() {

View file

@ -28,7 +28,8 @@ class TextureBaker : public Baker {
public:
TextureBaker(const QUrl& textureURL, image::TextureUsage::Type textureType,
const QDir& outputDirectory, const QByteArray& textureContent = QByteArray());
const QDir& outputDirectory, const QString& bakedFilename = QString(),
const QByteArray& textureContent = QByteArray());
static const QStringList getSupportedFormats();