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];
|
||||
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
|
||||
result.data[0] = '*';
|
||||
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;
|
||||
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 )
|
||||
|
@ -1776,6 +1764,8 @@ unsigned int Converter::ConvertVideo( const Video& video )
|
|||
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 );
|
||||
}
|
||||
|
||||
|
@ -1810,17 +1800,21 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
|
|||
textures_converted[media] = index;
|
||||
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
|
||||
if (doc.Settings().useLegacyEmbeddedTextureNaming) {
|
||||
if (textureReady) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 );
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ struct ImportSettings
|
|||
, readWeights(true)
|
||||
, preservePivots(true)
|
||||
, optimizeEmptyAnimationCurves(true)
|
||||
, searchEmbeddedTextures(false)
|
||||
, useLegacyEmbeddedTextureNaming(false)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -139,9 +139,9 @@ struct ImportSettings
|
|||
* The default value is true. */
|
||||
bool optimizeEmptyAnimationCurves;
|
||||
|
||||
/** search for embedded loaded textures, where no embedded texture data is provided.
|
||||
* The default value is false. */
|
||||
bool searchEmbeddedTextures;
|
||||
/** use legacy naming for embedded textures eg: (*0, *1, *2)
|
||||
**/
|
||||
bool useLegacyEmbeddedTextureNaming;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
|
|||
settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
|
||||
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.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;
|
||||
}
|
||||
|
||||
//! 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
|
||||
|
||||
/** Internal data, do not touch */
|
||||
|
|
|
@ -179,6 +179,12 @@ struct aiTexture
|
|||
*/
|
||||
C_STRUCT aiTexel* pcData;
|
||||
|
||||
/** Texture original filename
|
||||
*
|
||||
* Used to get the texture reference
|
||||
*/
|
||||
C_STRUCT aiString mFilename;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
//! For compressed textures (mHeight == 0): compare the
|
||||
|
|
Loading…
Reference in New Issue