diff --git a/code/Collada/ColladaHelper.h b/code/Collada/ColladaHelper.h index ffab6226d..66cff2d20 100644 --- a/code/Collada/ColladaHelper.h +++ b/code/Collada/ColladaHelper.h @@ -580,15 +580,11 @@ struct Image { std::string mFileName; - /** If image file name is zero, embedded image data - */ + /** Embedded image data */ std::vector mImageData; - /** If image file name is zero, file format of - * embedded image data. - */ + /** File format hint ofembedded image data */ std::string mEmbeddedFormat; - }; /** An animation channel. */ diff --git a/code/Collada/ColladaLoader.cpp b/code/Collada/ColladaLoader.cpp index 40b2b0811..bcf6b1c60 100644 --- a/code/Collada/ColladaLoader.cpp +++ b/code/Collada/ColladaLoader.cpp @@ -235,6 +235,9 @@ void ColladaLoader::InternReadFile(const std::string& pFile, aiScene* pScene, IO // store all materials StoreSceneMaterials(pScene); + // store all textures + StoreSceneTextures(pScene); + // store all lights StoreSceneLights(pScene); @@ -927,8 +930,7 @@ void ColladaLoader::StoreSceneLights(aiScene* pScene) void ColladaLoader::StoreSceneTextures(aiScene* pScene) { pScene->mNumTextures = static_cast(mTextures.size()); - if (mTextures.size() > 0) - { + if (mTextures.size() > 0) { pScene->mTextures = new aiTexture*[mTextures.size()]; std::copy(mTextures.begin(), mTextures.end(), pScene->mTextures); mTextures.clear(); @@ -1728,7 +1730,7 @@ void ColladaLoader::BuildMaterials(ColladaParser& pParser, aiScene* /*pScene*/) mat->AddProperty(&colSpecular, 1, AI_MATKEY_COLOR_SPECULAR); const ai_real specExp = 5.0; mat->AddProperty(&specExp, 1, AI_MATKEY_SHININESS); - } +} #endif } @@ -1766,14 +1768,19 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser& pParse } // if this is an embedded texture image setup an aiTexture for it - if (imIt->second.mFileName.empty()) + if (!imIt->second.mImageData.empty()) { - if (imIt->second.mImageData.empty()) { - throw DeadlyImportError("Collada: Invalid texture, no data or file reference given"); - } - aiTexture* tex = new aiTexture(); + // Store embedded texture name reference + tex->mFilename.Set(imIt->second.mFileName.c_str()); + result.Set(imIt->second.mFileName); + + // TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING" +// result.data[0] = '*'; +// result.length = 1 + ASSIMP_itoa10(result.data + 1, static_cast(MAXLEN - 1), static_cast(mTextures.size())); + + // setup format hint if (imIt->second.mEmbeddedFormat.length() > 3) { ASSIMP_LOG_WARN("Collada: texture format hint is too long, truncating to 3 characters"); @@ -1786,20 +1793,15 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser& pParse 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 through 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())); - // and add this texture to the list mTextures.push_back(tex); } else { + if (imIt->second.mFileName.empty()) { + throw DeadlyImportError("Collada: Invalid texture, no data or file reference given"); + } + result.Set(imIt->second.mFileName); ConvertPath(result); } diff --git a/code/Collada/ColladaLoader.h b/code/Collada/ColladaLoader.h index ad606ea74..92f390f17 100644 --- a/code/Collada/ColladaLoader.h +++ b/code/Collada/ColladaLoader.h @@ -100,14 +100,14 @@ protected: /** Return importer meta information. * See #BaseImporter::GetInfo for the details */ - const aiImporterDesc* GetInfo () const; + const aiImporterDesc* GetInfo () const override; - void SetupProperties(const Importer* pImp); + void SetupProperties(const Importer* pImp) override; /** Imports the given file into the given scene structure. * See BaseImporter::InternReadFile() for details */ - void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); + void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override; /** Recursively constructs a scene node for the given parser node and returns it. */ aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode); diff --git a/code/Collada/ColladaParser.cpp b/code/Collada/ColladaParser.cpp index 560c0cc9d..20a881860 100644 --- a/code/Collada/ColladaParser.cpp +++ b/code/Collada/ColladaParser.cpp @@ -132,7 +132,7 @@ ColladaParser::ColladaParser(IOSystem* pIOHandler, const std::string& pFile) // read embedded textures if (zip_archive && zip_archive->isOpen()) { - // TODO + ReadEmbeddedTextures(*zip_archive); } } @@ -3056,6 +3056,26 @@ void ColladaParser::ReadMaterialVertexInputBinding(Collada::SemanticMappingTable } } +void Assimp::ColladaParser::ReadEmbeddedTextures(ZipArchiveIOSystem& zip_archive) +{ + // Attempt to load any undefined Collada::Image in ImageLibrary + for (ImageLibrary::iterator it = mImageLibrary.begin(); it != mImageLibrary.end(); ++it) { + Collada::Image &image = (*it).second; + + if (image.mImageData.empty()) { + std::unique_ptr image_file(zip_archive.Open(image.mFileName.c_str())); + if (image_file) { + image.mImageData.resize(image_file->FileSize()); + image_file->Read(image.mImageData.data(), image_file->FileSize(), 1); + image.mEmbeddedFormat = BaseImporter::GetExtension(image.mFileName); + if (image.mEmbeddedFormat == "jpeg") { + image.mEmbeddedFormat = "jpg"; + } + } + } + } +} + // ------------------------------------------------------------------------------------------------ // Reads a mesh reference in a node and adds it to the node's mesh list void ColladaParser::ReadNodeGeometry(Node* pNode) diff --git a/code/Collada/ColladaParser.h b/code/Collada/ColladaParser.h index 7c77013f6..a2c9a4ff2 100644 --- a/code/Collada/ColladaParser.h +++ b/code/Collada/ColladaParser.h @@ -239,6 +239,9 @@ namespace Assimp // Processes bind_vertex_input and bind elements void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl); + /** Reads embedded textures from a ZAE archive*/ + void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive); + protected: /** Aborts the file reading with an exception */ AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;