FBX Embedding Fix
FBX files may use a texture reference from an embedded texture that hasn't been loaded yet. This patch fixes this issue, storing all texture filenames, that can be acessed later via "scene::GetEmbeddedTexture", when all textures are already loaded. Some warnings have been added to other file formats that uses embedded data.pull/1645/head
parent
5ddc281c4b
commit
4623c2f14c
|
@ -1778,6 +1778,11 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
|
||||||
tex->pcData = (aiTexel*)new char[tex->mWidth];
|
tex->pcData = (aiTexel*)new char[tex->mWidth];
|
||||||
memcpy(tex->pcData,&imIt->second.mImageData[0],tex->mWidth);
|
memcpy(tex->pcData,&imIt->second.mImageData[0],tex->mWidth);
|
||||||
|
|
||||||
|
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
||||||
|
// In FBX files textures are now stored internally by Assimp with their filename included
|
||||||
|
// Now Assimp can lookup thru the loaded textures after all data is processed
|
||||||
|
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
|
||||||
|
// This may occur on this case too, it has to be studied
|
||||||
// setup texture reference string
|
// setup texture reference string
|
||||||
result.data[0] = '*';
|
result.data[0] = '*';
|
||||||
result.length = 1 + ASSIMP_itoa10(result.data+1,static_cast<unsigned int>(MAXLEN-1),static_cast<int32_t>(mTextures.size()));
|
result.length = 1 + ASSIMP_itoa10(result.data+1,static_cast<unsigned int>(MAXLEN-1),static_cast<int32_t>(mTextures.size()));
|
||||||
|
|
|
@ -436,18 +436,6 @@ private:
|
||||||
|
|
||||||
aiScene* const out;
|
aiScene* const out;
|
||||||
const FBX::Document& doc;
|
const FBX::Document& doc;
|
||||||
|
|
||||||
bool FindTextureIndexByFilename(const Video& video, unsigned int& index) {
|
|
||||||
index = 0;
|
|
||||||
const char* videoFileName = video.FileName().c_str();
|
|
||||||
for (auto texture = textures_converted.begin(); texture != textures_converted.end(); ++texture) {
|
|
||||||
if (!strcmp(texture->first->FileName().c_str(), videoFileName)) {
|
|
||||||
index = texture->second;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Converter::Converter( aiScene* out, const Document& doc )
|
Converter::Converter( aiScene* out, const Document& doc )
|
||||||
|
@ -1776,6 +1764,8 @@ unsigned int Converter::ConvertVideo( const Video& video )
|
||||||
memcpy( out_tex->achFormatHint, ext.c_str(), ext.size() );
|
memcpy( out_tex->achFormatHint, ext.c_str(), ext.size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out_tex->mFilename.Set(video.FileName().c_str());
|
||||||
|
|
||||||
return static_cast<unsigned int>( textures.size() - 1 );
|
return static_cast<unsigned int>( textures.size() - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1810,15 +1800,19 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
|
||||||
textures_converted[media] = index;
|
textures_converted[media] = index;
|
||||||
textureReady = true;
|
textureReady = true;
|
||||||
}
|
}
|
||||||
else if (doc.Settings().searchEmbeddedTextures) { //try to find the texture on the already-loaded textures by the filename, if the flag is on
|
|
||||||
textureReady = FindTextureIndexByFilename(*media, index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready
|
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready
|
||||||
if (textureReady) {
|
if (doc.Settings().useLegacyEmbeddedTextureNaming) {
|
||||||
path.data[0] = '*';
|
if (textureReady) {
|
||||||
path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
|
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
||||||
|
// In FBX files textures are now stored internally by Assimp with their filename included
|
||||||
|
// Now Assimp can lookup thru the loaded textures after all data is processed
|
||||||
|
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
|
||||||
|
// This may occur on this case too, it has to be studied
|
||||||
|
path.data[0] = '*';
|
||||||
|
path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ struct ImportSettings
|
||||||
, readWeights(true)
|
, readWeights(true)
|
||||||
, preservePivots(true)
|
, preservePivots(true)
|
||||||
, optimizeEmptyAnimationCurves(true)
|
, optimizeEmptyAnimationCurves(true)
|
||||||
, searchEmbeddedTextures(false)
|
, useLegacyEmbeddedTextureNaming(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,9 +139,9 @@ struct ImportSettings
|
||||||
* The default value is true. */
|
* The default value is true. */
|
||||||
bool optimizeEmptyAnimationCurves;
|
bool optimizeEmptyAnimationCurves;
|
||||||
|
|
||||||
/** search for embedded loaded textures, where no embedded texture data is provided.
|
/** use legacy naming for embedded textures eg: (*0, *1, *2)
|
||||||
* The default value is false. */
|
**/
|
||||||
bool searchEmbeddedTextures;
|
bool useLegacyEmbeddedTextureNaming;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
|
||||||
settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
|
settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
|
||||||
settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
|
settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
|
||||||
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
|
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
|
||||||
settings.searchEmbeddedTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES, false);
|
settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -366,6 +366,27 @@ struct aiScene
|
||||||
return mAnimations != NULL && mNumAnimations > 0;
|
return mAnimations != NULL && mNumAnimations > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Returns a short filename from a full path
|
||||||
|
static const char* GetShortFilename(const char* filename) {
|
||||||
|
const char* lastSlash = strrchr(filename, '/');
|
||||||
|
if (lastSlash == '\0') {
|
||||||
|
lastSlash = strrchr(filename, '\\');
|
||||||
|
}
|
||||||
|
const char* shortFilename = lastSlash != '\0' ? lastSlash + 1 : filename;
|
||||||
|
return shortFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Returns an embedded texture
|
||||||
|
const aiTexture* GetEmbeddedTexture(const char* filename) {
|
||||||
|
const char* shortFilename = GetShortFilename(filename);
|
||||||
|
for (unsigned int i = 0; i < mNumTextures; i++) {
|
||||||
|
const char* shortTextureFilename = GetShortFilename(mTextures[i]->mFilename.C_Str());
|
||||||
|
if (strcmp(shortTextureFilename, shortFilename) == 0) {
|
||||||
|
return mTextures[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
/** Internal data, do not touch */
|
/** Internal data, do not touch */
|
||||||
|
|
|
@ -179,6 +179,12 @@ struct aiTexture
|
||||||
*/
|
*/
|
||||||
C_STRUCT aiTexel* pcData;
|
C_STRUCT aiTexel* pcData;
|
||||||
|
|
||||||
|
/** Texture original filename
|
||||||
|
*
|
||||||
|
* Used to get the texture reference
|
||||||
|
*/
|
||||||
|
C_STRUCT aiString mFilename;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
//! For compressed textures (mHeight == 0): compare the
|
//! For compressed textures (mHeight == 0): compare the
|
||||||
|
|
Loading…
Reference in New Issue