|
@@ -0,0 +1,147 @@
|
|
|
+/*
|
|
|
+Open Asset Import Library (assimp)
|
|
|
+----------------------------------------------------------------------
|
|
|
+
|
|
|
+Copyright (c) 2006-2017, assimp team
|
|
|
+
|
|
|
+All rights reserved.
|
|
|
+
|
|
|
+Redistribution and use of this software in source and binary forms,
|
|
|
+with or without modification, are permitted provided that the
|
|
|
+following conditions are met:
|
|
|
+
|
|
|
+* Redistributions of source code must retain the above
|
|
|
+copyright notice, this list of conditions and the
|
|
|
+following disclaimer.
|
|
|
+
|
|
|
+* Redistributions in binary form must reproduce the above
|
|
|
+copyright notice, this list of conditions and the
|
|
|
+following disclaimer in the documentation and/or other
|
|
|
+materials provided with the distribution.
|
|
|
+
|
|
|
+* Neither the name of the assimp team, nor the names of its
|
|
|
+contributors may be used to endorse or promote products
|
|
|
+derived from this software without specific prior
|
|
|
+written permission of the assimp team.
|
|
|
+
|
|
|
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
+
|
|
|
+----------------------------------------------------------------------
|
|
|
+*/
|
|
|
+
|
|
|
+#include "EmbedTexturesProcess.h"
|
|
|
+#include "ParsingUtils.h"
|
|
|
+#include "ProcessHelper.h"
|
|
|
+
|
|
|
+#include <fstream>
|
|
|
+
|
|
|
+using namespace Assimp;
|
|
|
+
|
|
|
+EmbedTexturesProcess::EmbedTexturesProcess()
|
|
|
+: BaseProcess() {
|
|
|
+}
|
|
|
+
|
|
|
+EmbedTexturesProcess::~EmbedTexturesProcess() {
|
|
|
+}
|
|
|
+
|
|
|
+bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const {
|
|
|
+ return (pFlags & aiProcess_EmbedTextures) != 0;
|
|
|
+}
|
|
|
+
|
|
|
+void EmbedTexturesProcess::SetupProperties(const Importer* pImp) {
|
|
|
+ mRootPath = pImp->GetPropertyString("sourceFilePath");
|
|
|
+ mRootPath = mRootPath.substr(0, mRootPath.find_last_of("\\/") + 1u);
|
|
|
+}
|
|
|
+
|
|
|
+void EmbedTexturesProcess::Execute(aiScene* pScene) {
|
|
|
+ if (pScene == nullptr || pScene->mRootNode == nullptr) return;
|
|
|
+
|
|
|
+ aiString path;
|
|
|
+
|
|
|
+ uint32_t embeddedTexturesCount = 0u;
|
|
|
+
|
|
|
+ for (auto matId = 0u; matId < pScene->mNumMaterials; ++matId) {
|
|
|
+ auto material = pScene->mMaterials[matId];
|
|
|
+
|
|
|
+ for (auto ttId = 1u; ttId < AI_TEXTURE_TYPE_MAX; ++ttId) {
|
|
|
+ auto tt = static_cast<aiTextureType>(ttId);
|
|
|
+ auto texturesCount = material->GetTextureCount(tt);
|
|
|
+
|
|
|
+ for (auto texId = 0u; texId < texturesCount; ++texId) {
|
|
|
+ material->GetTexture(tt, texId, &path);
|
|
|
+ if (path.data[0] == '*') continue; // Already embedded
|
|
|
+
|
|
|
+ // Indeed embed
|
|
|
+ if (addTexture(pScene, path.data)) {
|
|
|
+ auto embeddedTextureId = pScene->mNumTextures - 1u;
|
|
|
+ ::ai_snprintf(path.data, 1024, "*%u", embeddedTextureId);
|
|
|
+ material->AddProperty(&path, AI_MATKEY_TEXTURE(tt, texId));
|
|
|
+ embeddedTexturesCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ char stringBuffer[128];
|
|
|
+ ::ai_snprintf(stringBuffer, 128, "EmbedTexturesProcess finished. Embedded %u textures.", embeddedTexturesCount);
|
|
|
+ DefaultLogger::get()->info(stringBuffer);
|
|
|
+}
|
|
|
+
|
|
|
+bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
|
|
|
+ uint32_t imageSize = 0;
|
|
|
+ std::string imagePath = path;
|
|
|
+
|
|
|
+ // Test path directly
|
|
|
+ std::ifstream file(imagePath, std::ios::binary | std::ios::ate);
|
|
|
+ if ((imageSize = file.tellg()) == -1u) {
|
|
|
+ DefaultLogger::get()->warn("EmbedTexturesProcess: Cannot find image: " + imagePath + ". Will try to find it in root folder.");
|
|
|
+
|
|
|
+ // Test path in root path
|
|
|
+ imagePath = mRootPath + path;
|
|
|
+ file.open(imagePath, std::ios::binary | std::ios::ate);
|
|
|
+ if ((imageSize = file.tellg()) == -1u) {
|
|
|
+ // Test path basename in root path
|
|
|
+ imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u);
|
|
|
+ file.open(imagePath, std::ios::binary | std::ios::ate);
|
|
|
+ if ((imageSize = file.tellg()) == -1u) {
|
|
|
+ DefaultLogger::get()->error("EmbedTexturesProcess: Unable to embed texture: " + path + ".");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ aiTexel* imageContent = new aiTexel[1u + imageSize / sizeof(aiTexel)];
|
|
|
+ file.seekg(0, std::ios::beg);
|
|
|
+ file.read(reinterpret_cast<char*>(imageContent), imageSize);
|
|
|
+
|
|
|
+ // Enlarging the textures table
|
|
|
+ auto textureId = pScene->mNumTextures++;
|
|
|
+ auto oldTextures = pScene->mTextures;
|
|
|
+ pScene->mTextures = new aiTexture*[pScene->mNumTextures];
|
|
|
+ memmove(pScene->mTextures, oldTextures, sizeof(aiTexture*) * (pScene->mNumTextures - 1u));
|
|
|
+
|
|
|
+ // Add the new texture
|
|
|
+ auto pTexture = new aiTexture();
|
|
|
+ pTexture->mHeight = 0; // Means that this is still compressed
|
|
|
+ pTexture->mWidth = imageSize;
|
|
|
+ pTexture->pcData = imageContent;
|
|
|
+
|
|
|
+ auto extension = path.substr(path.find_last_of('.') + 1u);
|
|
|
+ std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
|
|
+ if (extension == "jpeg") extension = "jpg";
|
|
|
+ strcpy(pTexture->achFormatHint, extension.c_str());
|
|
|
+
|
|
|
+ pScene->mTextures[textureId] = pTexture;
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|