// Copyright (C) 2009-2018, Panagiotis Christopoulos Charitos and contributors. // All rights reserved. // Code licensed under the BSD License. // http://www.anki3d.org/LICENSE #include "Exporter.h" #include const char* MATERIAL_TEMPLATE = R"( %parallaxInput% %diff% %spec% %roughness% %metallic% %normal% %emission% %subsurface% %height% )"; void Exporter::exportMaterial(const aiMaterial& mtl) const { aiString path; std::string name = getMaterialName(mtl); LOGI("Exporting material %s", name.c_str()); std::string xml = MATERIAL_TEMPLATE; // Diffuse texture if(mtl.GetTextureCount(aiTextureType_DIFFUSE) > 0) { if(mtl.GetTexture(aiTextureType_DIFFUSE, 0, &path) == AI_SUCCESS) { std::string diffTex = m_texrpath + getFilename(path.C_Str()); xml = replaceAllString(xml, "%diff%", ""); xml = replaceAllString(xml, "%diffTexMutator%", "1"); } else { ERROR("Failed to retrieve texture"); } } else { aiColor3D diffCol = {0.0, 0.0, 0.0}; mtl.Get(AI_MATKEY_COLOR_DIFFUSE, diffCol); xml = replaceAllString(xml, "%diff%", ""); xml = replaceAllString(xml, "%diffTexMutator%", "0"); } // Specular color if(mtl.GetTextureCount(aiTextureType_SPECULAR) > 0) { if(mtl.GetTexture(aiTextureType_SPECULAR, 0, &path) == AI_SUCCESS) { std::string specTex = m_texrpath + getFilename(path.C_Str()); xml = replaceAllString(xml, "%spec%", ""); xml = replaceAllString(xml, "%specTexMutator%", "1"); } else { ERROR("Failed to retrieve texture"); } } else { aiColor3D specCol = {0.0, 0.0, 0.0}; mtl.Get(AI_MATKEY_COLOR_SPECULAR, specCol); xml = replaceAllString(xml, "%spec%", ""); xml = replaceAllString(xml, "%specTexMutator%", "0"); } // Roughness if(mtl.GetTextureCount(aiTextureType_SHININESS) > 0) { if(mtl.GetTexture(aiTextureType_SHININESS, 0, &path) == AI_SUCCESS) { std::string shininessTex = m_texrpath + getFilename(path.C_Str()); xml = replaceAllString( xml, "%roughness%", ""); xml = replaceAllString(xml, "%roughnessTexMutator%", "1"); } else { ERROR("Failed to retrieve texture"); } } else { float shininess = 0.0; mtl.Get(AI_MATKEY_SHININESS, shininess); const float MAX_SHININESS = 511.0; shininess = std::min(MAX_SHININESS, shininess); if(shininess > MAX_SHININESS) { LOGW("Shininness exceeds %f", MAX_SHININESS); } shininess = shininess / MAX_SHININESS; xml = replaceAllString( xml, "%roughness%", ""); xml = replaceAllString(xml, "%roughnessTexMutator%", "0"); } // Metallic texture if(mtl.GetTextureCount(aiTextureType_REFLECTION) > 0) { if(mtl.GetTexture(aiTextureType_REFLECTION, 0, &path) == AI_SUCCESS) { std::string metallicTex = m_texrpath + getFilename(path.C_Str()); xml = replaceAllString(xml, "%metallic%", ""); xml = replaceAllString(xml, "%metalTexMutator%", "1"); } else { ERROR("Failed to retrieve texture"); } } else { float metallic = 0.0; if(mtl.mAnKiProperties.find("metallic") != mtl.mAnKiProperties.end()) { metallic = std::stof(mtl.mAnKiProperties.at("metallic")); } xml = replaceAllString( xml, "%metallic%", ""); xml = replaceAllString(xml, "%metalTexMutator%", "0"); } // Normal texture if(mtl.GetTextureCount(aiTextureType_NORMALS) > 0) { if(mtl.GetTexture(aiTextureType_NORMALS, 0, &path) == AI_SUCCESS) { std::string normTex = m_texrpath + getFilename(path.C_Str()); xml = replaceAllString(xml, "%normal%", ""); xml = replaceAllString(xml, "%normalTexMutator%", "1"); } else { ERROR("Failed to retrieve texture"); } } else { xml = replaceAllString(xml, "%normal%", ""); xml = replaceAllString(xml, "%normalTexMutator%", "0"); } // Emissive texture if(mtl.GetTextureCount(aiTextureType_EMISSIVE) > 0) { if(mtl.GetTexture(aiTextureType_EMISSIVE, 0, &path) == AI_SUCCESS) { std::string emissiveTex = m_texrpath + getFilename(path.C_Str()); xml = replaceAllString( xml, "%emission%", ""); xml = replaceAllString(xml, "%emissiveTexMutator%", "1"); } else { ERROR("Failed to retrieve texture"); } } else { aiColor3D emissionCol = {0.0, 0.0, 0.0}; mtl.Get(AI_MATKEY_COLOR_EMISSIVE, emissionCol); xml = replaceAllString(xml, "%emission%", ""); xml = replaceAllString(xml, "%emissiveTexMutator%", "0"); } // Subsurface { float subsurface = 0.0; if(mtl.mAnKiProperties.find("subsurface") != mtl.mAnKiProperties.end()) { subsurface = std::stof(mtl.mAnKiProperties.at("subsurface")); } xml = replaceAllString( xml, "%subsurface%", ""); } // Height texture if(mtl.GetTextureCount(aiTextureType_DISPLACEMENT) > 0) { if(mtl.GetTexture(aiTextureType_DISPLACEMENT, 0, &path) == AI_SUCCESS) { std::string dispTex = m_texrpath + getFilename(path.C_Str()); xml = replaceAllString(xml, "%height%", "\n" "\t\t"); xml = replaceAllString( xml, "%parallaxInput%", ""); xml = replaceAllString(xml, "%parallaxMutator%", "1"); } else { ERROR("Failed to retrieve texture"); } } else { xml = replaceAllString(xml, "%height%", ""); xml = replaceAllString(xml, "%parallaxInput%", ""); xml = replaceAllString(xml, "%parallaxMutator%", "0"); } // Replace texture extensions with .anki xml = replaceAllString(xml, ".tga", ".ankitex"); xml = replaceAllString(xml, ".png", ".ankitex"); xml = replaceAllString(xml, ".jpg", ".ankitex"); xml = replaceAllString(xml, ".jpeg", ".ankitex"); // Open and write file std::fstream file; file.open(m_outputDirectory + name + ".ankimtl", std::ios::out); file << xml; }