diff --git a/code/ColladaLoader.cpp b/code/ColladaLoader.cpp index d2141c374..d41f4a999 100644 --- a/code/ColladaLoader.cpp +++ b/code/ColladaLoader.cpp @@ -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(MAXLEN-1),static_cast(mTextures.size())); diff --git a/code/FBXConverter.cpp b/code/FBXConverter.cpp index 24bdfdd11..66f541f17 100644 --- a/code/FBXConverter.cpp +++ b/code/FBXConverter.cpp @@ -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( textures.size() - 1 ); } @@ -1810,15 +1800,19 @@ 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 (textureReady) { - path.data[0] = '*'; - path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index); + 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); + } } } diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index 9592bf31f..54f18b191 100644 --- a/code/FBXDocument.cpp +++ b/code/FBXDocument.cpp @@ -619,10 +619,10 @@ std::vector Document::GetConnectionsBySourceSequenced(uint64_ } // ------------------------------------------------------------------------------------------------ -std::vector Document::GetConnectionsBySourceSequenced(uint64_t dest, const char* classname) const +std::vector Document::GetConnectionsBySourceSequenced(uint64_t src, const char* classname) const { const char* arr[] = {classname}; - return GetConnectionsBySourceSequenced(dest, arr,1); + return GetConnectionsBySourceSequenced(src, arr,1); } // ------------------------------------------------------------------------------------------------ diff --git a/code/FBXImportSettings.h b/code/FBXImportSettings.h index 53fa64ec6..84129cd4a 100644 --- a/code/FBXImportSettings.h +++ b/code/FBXImportSettings.h @@ -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; }; diff --git a/code/FBXImporter.cpp b/code/FBXImporter.cpp index 51e41b8f4..37d7cc4be 100644 --- a/code/FBXImporter.cpp +++ b/code/FBXImporter.cpp @@ -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); } // ------------------------------------------------------------------------------------------------ diff --git a/code/FIReader.hpp b/code/FIReader.hpp index 5f4e5bb48..e142a571b 100644 --- a/code/FIReader.hpp +++ b/code/FIReader.hpp @@ -62,6 +62,7 @@ namespace Assimp { struct FIValue { virtual const std::string &toString() const = 0; + virtual ~FIValue() {} }; struct FIStringValue: public FIValue { @@ -121,6 +122,7 @@ struct FICDATAValue: public FIStringValue { struct FIDecoder { virtual std::shared_ptr decode(const uint8_t *data, size_t len) = 0; + virtual ~FIDecoder() {} }; struct FIQName { diff --git a/code/MDCLoader.cpp b/code/MDCLoader.cpp index 21aca53ff..8af18992d 100644 --- a/code/MDCLoader.cpp +++ b/code/MDCLoader.cpp @@ -283,9 +283,8 @@ void MDCImporter::InternReadFile( pcMesh->mNumVertices = pcMesh->mNumFaces * 3; // store the name of the surface for use as node name. - // FIX: make sure there is a 0 termination - const_cast(pcSurface->ucName[AI_MDC_MAXQPATH-1]) = '\0'; - pcMesh->mTextureCoords[3] = (aiVector3D*)pcSurface->ucName; + pcMesh->mName.Set(std::string(pcSurface->ucName + , strnlen(pcSurface->ucName, AI_MDC_MAXQPATH - 1))); // go to the first shader in the file. ignore the others. if (pcSurface->ulNumShaders) @@ -294,8 +293,8 @@ void MDCImporter::InternReadFile( pcMesh->mMaterialIndex = (unsigned int)aszShaders.size(); // create a new shader - aszShaders.push_back(std::string( pcShader->ucName, std::min( - ::strlen(pcShader->ucName),sizeof(pcShader->ucName)) )); + aszShaders.push_back(std::string( pcShader->ucName, + ::strnlen(pcShader->ucName, sizeof(pcShader->ucName)) )); } // need to create a default material else if (UINT_MAX == iDefaultMatIndex) @@ -432,7 +431,7 @@ void MDCImporter::InternReadFile( else if (1 == pScene->mNumMeshes) { pScene->mRootNode = new aiNode(); - pScene->mRootNode->mName.Set(std::string((const char*)pScene->mMeshes[0]->mTextureCoords[3])); + pScene->mRootNode->mName = pScene->mMeshes[0]->mName; pScene->mRootNode->mNumMeshes = 1; pScene->mRootNode->mMeshes = new unsigned int[1]; pScene->mRootNode->mMeshes[0] = 0; @@ -447,17 +446,13 @@ void MDCImporter::InternReadFile( { aiNode* pcNode = pScene->mRootNode->mChildren[i] = new aiNode(); pcNode->mParent = pScene->mRootNode; - pcNode->mName.Set(std::string((const char*)pScene->mMeshes[i]->mTextureCoords[3])); + pcNode->mName = pScene->mMeshes[i]->mName; pcNode->mNumMeshes = 1; pcNode->mMeshes = new unsigned int[1]; pcNode->mMeshes[0] = i; } } - // make sure we invalidate the pointer to the mesh name - for (unsigned int i = 0; i < pScene->mNumMeshes;++i) - pScene->mMeshes[i]->mTextureCoords[3] = NULL; - // create materials pScene->mNumMaterials = (unsigned int)aszShaders.size(); pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; diff --git a/code/MMDPmxParser.h b/code/MMDPmxParser.h index 989cffed6..a26eddb04 100644 --- a/code/MMDPmxParser.h +++ b/code/MMDPmxParser.h @@ -87,6 +87,7 @@ namespace pmx { public: virtual void Read(std::istream *stream, PmxSetting *setting) = 0; + virtual ~PmxVertexSkinning() {} }; class PmxVertexSkinningBDEF1 : public PmxVertexSkinning diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 9f3bdef97..e1a084d62 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -264,8 +264,12 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile { unsigned int meshId = pObject->m_Meshes[ i ]; aiMesh *pMesh = createTopology( pModel, pObject, meshId ); - if( pMesh && pMesh->mNumFaces > 0 ) { - MeshArray.push_back( pMesh ); + if( pMesh ) { + if (pMesh->mNumFaces > 0) { + MeshArray.push_back( pMesh ); + } else { + delete pMesh; + } } } @@ -317,7 +321,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj return NULL; } - aiMesh* pMesh = new aiMesh; + std::unique_ptr pMesh(new aiMesh); if( !pObjMesh->m_name.empty() ) { pMesh->mName.Set( pObjMesh->m_name ); } @@ -382,9 +386,9 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj } // Create mesh vertices - createVertexArray(pModel, pData, meshIndex, pMesh, uiIdxCount); + createVertexArray(pModel, pData, meshIndex, pMesh.get(), uiIdxCount); - return pMesh; + return pMesh.release(); } // ------------------------------------------------------------------------------------------------ diff --git a/code/Q3BSPFileImporter.cpp b/code/Q3BSPFileImporter.cpp index 9d6d8e870..0cdafae42 100644 --- a/code/Q3BSPFileImporter.cpp +++ b/code/Q3BSPFileImporter.cpp @@ -447,6 +447,7 @@ void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, pMesh->mTextureCoords[ 0 ][ rVertIdx ].Set( pVertex->vTexCoord.x, pVertex->vTexCoord.y, 0.0f ); pMesh->mTextureCoords[ 1 ][ rVertIdx ].Set( pVertex->vLightmap.x, pVertex->vLightmap.y, 0.0f ); + ai_assert( m_pCurrentFace ); m_pCurrentFace->mIndices[ idx ] = rVertIdx; rVertIdx++; diff --git a/include/assimp/config.h.in b/include/assimp/config.h.in index 1dabae7cf..ad08a04b6 100644 --- a/include/assimp/config.h.in +++ b/include/assimp/config.h.in @@ -642,13 +642,13 @@ enum aiComponent "IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES" // --------------------------------------------------------------------------- -/** @brief Set whether the fbx importer will search for embedded loaded textures, where no embedded texture data is provided. +/** @brief Set whether the fbx importer will use the legacy embedded texture naming. * * The default value is false (0) * Property type: bool */ -#define AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES \ - "IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES" +#define AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING \ + "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING" // --------------------------------------------------------------------------- /** @brief Set the vertex animation keyframe to be imported diff --git a/include/assimp/scene.h b/include/assimp/scene.h index 342c316d6..00fa42142 100644 --- a/include/assimp/scene.h +++ b/include/assimp/scene.h @@ -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 == nullptr) { + lastSlash = strrchr(filename, '\\'); + } + const char* shortFilename = lastSlash != nullptr ? 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 */ diff --git a/include/assimp/texture.h b/include/assimp/texture.h index c09ef2cbe..ec65e4655 100644 --- a/include/assimp/texture.h +++ b/include/assimp/texture.h @@ -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