diff options
Diffstat (limited to 'src/3rdparty/assimp/code/OgreMaterial.cpp')
-rw-r--r-- | src/3rdparty/assimp/code/OgreMaterial.cpp | 1023 |
1 files changed, 513 insertions, 510 deletions
diff --git a/src/3rdparty/assimp/code/OgreMaterial.cpp b/src/3rdparty/assimp/code/OgreMaterial.cpp index a85741f18..f9da9d584 100644 --- a/src/3rdparty/assimp/code/OgreMaterial.cpp +++ b/src/3rdparty/assimp/code/OgreMaterial.cpp @@ -2,11 +2,11 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2012, assimp team +Copyright (c) 2006-2016, 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 +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 @@ -23,32 +23,35 @@ following conditions are met: 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 +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 +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 +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 +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 "AssimpPCH.h" + #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER #include "OgreImporter.h" #include "TinyFormatter.h" - +#include <assimp/material.h> +#include <assimp/scene.h> +#include <assimp/DefaultLogger.hpp> #include "fast_atof.h" #include <vector> #include <sstream> +#include <memory> using namespace std; @@ -63,527 +66,527 @@ static const string partBlockEnd = "}"; void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, Mesh *mesh) { - std::vector<aiMaterial*> materials; - - // Create materials that can be found and parsed via the IOSystem. - for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i) - { - SubMesh *submesh = mesh->GetSubMesh(i); - if (submesh && !submesh->materialRef.empty()) - { - aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef); - if (material) - { - submesh->materialIndex = materials.size(); - materials.push_back(material); - } - } - } - - AssignMaterials(pScene, materials); + std::vector<aiMaterial*> materials; + + // Create materials that can be found and parsed via the IOSystem. + for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i) + { + SubMesh *submesh = mesh->GetSubMesh(i); + if (submesh && !submesh->materialRef.empty()) + { + aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef); + if (material) + { + submesh->materialIndex = materials.size(); + materials.push_back(material); + } + } + } + + AssignMaterials(pScene, materials); } void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, MeshXml *mesh) { - std::vector<aiMaterial*> materials; - - // Create materials that can be found and parsed via the IOSystem. - for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i) - { - SubMeshXml *submesh = mesh->GetSubMesh(i); - if (submesh && !submesh->materialRef.empty()) - { - aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef); - if (material) - { - submesh->materialIndex = materials.size(); - materials.push_back(material); - } - } - } - - AssignMaterials(pScene, materials); + std::vector<aiMaterial*> materials; + + // Create materials that can be found and parsed via the IOSystem. + for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i) + { + SubMeshXml *submesh = mesh->GetSubMesh(i); + if (submesh && !submesh->materialRef.empty()) + { + aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef); + if (material) + { + submesh->materialIndex = materials.size(); + materials.push_back(material); + } + } + } + + AssignMaterials(pScene, materials); } void OgreImporter::AssignMaterials(aiScene *pScene, std::vector<aiMaterial*> &materials) { - pScene->mNumMaterials = materials.size(); - if (pScene->mNumMaterials > 0) - { - pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; - for(size_t i=0;i<pScene->mNumMaterials; ++i) { - pScene->mMaterials[i] = materials[i]; - } - } + pScene->mNumMaterials = materials.size(); + if (pScene->mNumMaterials > 0) + { + pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; + for(size_t i=0;i<pScene->mNumMaterials; ++i) { + pScene->mMaterials[i] = materials[i]; + } + } } -aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSystem *pIOHandler, const std::string materialName) +aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSystem *pIOHandler, const std::string &materialName) { - if (materialName.empty()) { - return 0; - } - - // Full reference and examples of Ogre Material Script - // can be found from http://www.ogre3d.org/docs/manual/manual_14.html - - /*and here is another one: - - import * from abstract_base_passes_depth.material - import * from abstract_base.material - import * from mat_shadow_caster.material - import * from mat_character_singlepass.material - - material hero/hair/caster : mat_shadow_caster_skin_areject - { - set $diffuse_map "hero_hair_alpha_c.dds" - } - - material hero/hair_alpha : mat_char_cns_singlepass_areject_4weights - { - set $diffuse_map "hero_hair_alpha_c.dds" - set $specular_map "hero_hair_alpha_s.dds" - set $normal_map "hero_hair_alpha_n.dds" - set $light_map "black_lightmap.dds" - - set $shadow_caster_material "hero/hair/caster" - } - */ - - stringstream ss; - - // Scope for scopre_ptr auto release - { - /* There are three .material options in priority order: - 1) File with the material name (materialName) - 2) File with the mesh files base name (pFile) - 3) Optional user defined material library file (m_userDefinedMaterialLibFile) */ - std::vector<string> potentialFiles; - potentialFiles.push_back(materialName + ".material"); - potentialFiles.push_back(pFile.substr(0, pFile.rfind(".mesh")) + ".material"); - if (!m_userDefinedMaterialLibFile.empty()) - potentialFiles.push_back(m_userDefinedMaterialLibFile); - - IOStream *materialFile = 0; - for(size_t i=0; i<potentialFiles.size(); ++i) - { - materialFile = pIOHandler->Open(potentialFiles[i]); - if (materialFile) { - break; - } - DefaultLogger::get()->debug(Formatter::format() << "Source file for material '" << materialName << "' " << potentialFiles[i] << " does not exist"); - } - if (!materialFile) - { - DefaultLogger::get()->error(Formatter::format() << "Failed to find source file for material '" << materialName << "'"); - return 0; - } - - boost::scoped_ptr<IOStream> stream(materialFile); - if (stream->FileSize() == 0) - { - DefaultLogger::get()->warn(Formatter::format() << "Source file for material '" << materialName << "' is empty (size is 0 bytes)"); - return 0; - } - - // Read bytes - vector<char> data(stream->FileSize()); - stream->Read(&data[0], stream->FileSize(), 1); - - // Convert to UTF-8 and terminate the string for ss - BaseImporter::ConvertToUTF8(data); - data.push_back('\0'); - - ss << &data[0]; - } - - DefaultLogger::get()->debug("Reading material '" + materialName + "'"); - - aiMaterial *material = new aiMaterial(); - m_textures.clear(); - - aiString ts(materialName); - material->AddProperty(&ts, AI_MATKEY_NAME); - - // The stringstream will push words from a line until newline. - // It will also trim whitespace from line start and between words. - string linePart; - ss >> linePart; - - const string partMaterial = "material"; - const string partTechnique = "technique"; - - while(!ss.eof()) - { - // Skip commented lines - if (linePart == partComment) - { - NextAfterNewLine(ss, linePart); - continue; - } - if (linePart != partMaterial) - { - ss >> linePart; - continue; - } - - ss >> linePart; - if (linePart != materialName) - { - //DefaultLogger::get()->debug(Formatter::format() << "Found material '" << linePart << "' that does not match at index " << ss.tellg()); - ss >> linePart; - continue; - } - - NextAfterNewLine(ss, linePart); - if (linePart != partBlockStart) - { - DefaultLogger::get()->error(Formatter::format() << "Invalid material: block start missing near index " << ss.tellg()); - return material; - } - - DefaultLogger::get()->debug("material '" + materialName + "'"); - - while(linePart != partBlockEnd) - { - // Proceed to the first technique - ss >> linePart; - - if (linePart == partTechnique) - { - string techniqueName = SkipLine(ss); - ReadTechnique(Trim(techniqueName), ss, material); - } - - // Read informations from a custom material - /** @todo This "set $x y" does not seem to be a official Ogre material system feature. - Materials can inherit other materials and override texture units by using the (unique) - parent texture unit name in your cloned material. - This is not yet supported and below code is probably some hack from the original - author of this Ogre importer. Should be removed? */ - if (linePart=="set") - { - ss >> linePart; - if (linePart=="$specular")//todo load this values: - { - } - else if (linePart=="$diffuse") - { - } - else if (linePart=="$ambient") - { - } - else if (linePart=="$colormap") - { - ss >> linePart; - aiString ts(linePart); - material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); - } - else if (linePart=="$normalmap") - { - ss >> linePart; - aiString ts(linePart); - material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); - } - else if (linePart=="$shininess_strength") - { - ss >> linePart; - float Shininess = fast_atof(linePart.c_str()); - material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS_STRENGTH); - } - else if (linePart=="$shininess_exponent") - { - ss >> linePart; - float Shininess = fast_atof(linePart.c_str()); - material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS); - } - //Properties from Venetica: - else if (linePart=="$diffuse_map") - { - ss >> linePart; - if (linePart[0] == '"')// "file" -> file - linePart = linePart.substr(1, linePart.size()-2); - aiString ts(linePart); - material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); - } - else if (linePart=="$specular_map") - { - ss >> linePart; - if (linePart[0] == '"')// "file" -> file - linePart = linePart.substr(1, linePart.size()-2); - aiString ts(linePart); - material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0)); - } - else if (linePart=="$normal_map") - { - ss >> linePart; - if (linePart[0]=='"')// "file" -> file - linePart = linePart.substr(1, linePart.size()-2); - aiString ts(linePart); - material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); - } - else if (linePart=="$light_map") - { - ss >> linePart; - if (linePart[0]=='"') { - linePart = linePart.substr(1, linePart.size() - 2); - } - aiString ts(linePart); - material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, 0)); - } - } - } - ss >> linePart; - } - - return material; + if (materialName.empty()) { + return 0; + } + + // Full reference and examples of Ogre Material Script + // can be found from http://www.ogre3d.org/docs/manual/manual_14.html + + /*and here is another one: + + import * from abstract_base_passes_depth.material + import * from abstract_base.material + import * from mat_shadow_caster.material + import * from mat_character_singlepass.material + + material hero/hair/caster : mat_shadow_caster_skin_areject + { + set $diffuse_map "hero_hair_alpha_c.dds" + } + + material hero/hair_alpha : mat_char_cns_singlepass_areject_4weights + { + set $diffuse_map "hero_hair_alpha_c.dds" + set $specular_map "hero_hair_alpha_s.dds" + set $normal_map "hero_hair_alpha_n.dds" + set $light_map "black_lightmap.dds" + + set $shadow_caster_material "hero/hair/caster" + } + */ + + stringstream ss; + + // Scope for scopre_ptr auto release + { + /* There are three .material options in priority order: + 1) File with the material name (materialName) + 2) File with the mesh files base name (pFile) + 3) Optional user defined material library file (m_userDefinedMaterialLibFile) */ + std::vector<string> potentialFiles; + potentialFiles.push_back(materialName + ".material"); + potentialFiles.push_back(pFile.substr(0, pFile.rfind(".mesh")) + ".material"); + if (!m_userDefinedMaterialLibFile.empty()) + potentialFiles.push_back(m_userDefinedMaterialLibFile); + + IOStream *materialFile = 0; + for(size_t i=0; i<potentialFiles.size(); ++i) + { + materialFile = pIOHandler->Open(potentialFiles[i]); + if (materialFile) { + break; + } + DefaultLogger::get()->debug(Formatter::format() << "Source file for material '" << materialName << "' " << potentialFiles[i] << " does not exist"); + } + if (!materialFile) + { + DefaultLogger::get()->error(Formatter::format() << "Failed to find source file for material '" << materialName << "'"); + return 0; + } + + std::unique_ptr<IOStream> stream(materialFile); + if (stream->FileSize() == 0) + { + DefaultLogger::get()->warn(Formatter::format() << "Source file for material '" << materialName << "' is empty (size is 0 bytes)"); + return 0; + } + + // Read bytes + vector<char> data(stream->FileSize()); + stream->Read(&data[0], stream->FileSize(), 1); + + // Convert to UTF-8 and terminate the string for ss + BaseImporter::ConvertToUTF8(data); + data.push_back('\0'); + + ss << &data[0]; + } + + DefaultLogger::get()->debug("Reading material '" + materialName + "'"); + + aiMaterial *material = new aiMaterial(); + m_textures.clear(); + + aiString ts(materialName); + material->AddProperty(&ts, AI_MATKEY_NAME); + + // The stringstream will push words from a line until newline. + // It will also trim whitespace from line start and between words. + string linePart; + ss >> linePart; + + const string partMaterial = "material"; + const string partTechnique = "technique"; + + while(!ss.eof()) + { + // Skip commented lines + if (linePart == partComment) + { + NextAfterNewLine(ss, linePart); + continue; + } + if (linePart != partMaterial) + { + ss >> linePart; + continue; + } + + ss >> linePart; + if (linePart != materialName) + { + //DefaultLogger::get()->debug(Formatter::format() << "Found material '" << linePart << "' that does not match at index " << ss.tellg()); + ss >> linePart; + continue; + } + + NextAfterNewLine(ss, linePart); + if (linePart != partBlockStart) + { + DefaultLogger::get()->error(Formatter::format() << "Invalid material: block start missing near index " << ss.tellg()); + return material; + } + + DefaultLogger::get()->debug("material '" + materialName + "'"); + + while(linePart != partBlockEnd) + { + // Proceed to the first technique + ss >> linePart; + + if (linePart == partTechnique) + { + string techniqueName = SkipLine(ss); + ReadTechnique(Trim(techniqueName), ss, material); + } + + // Read informations from a custom material + /** @todo This "set $x y" does not seem to be a official Ogre material system feature. + Materials can inherit other materials and override texture units by using the (unique) + parent texture unit name in your cloned material. + This is not yet supported and below code is probably some hack from the original + author of this Ogre importer. Should be removed? */ + if (linePart=="set") + { + ss >> linePart; + if (linePart=="$specular")//todo load this values: + { + } + else if (linePart=="$diffuse") + { + } + else if (linePart=="$ambient") + { + } + else if (linePart=="$colormap") + { + ss >> linePart; + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); + } + else if (linePart=="$normalmap") + { + ss >> linePart; + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); + } + else if (linePart=="$shininess_strength") + { + ss >> linePart; + float Shininess = fast_atof(linePart.c_str()); + material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS_STRENGTH); + } + else if (linePart=="$shininess_exponent") + { + ss >> linePart; + float Shininess = fast_atof(linePart.c_str()); + material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS); + } + //Properties from Venetica: + else if (linePart=="$diffuse_map") + { + ss >> linePart; + if (linePart[0] == '"')// "file" -> file + linePart = linePart.substr(1, linePart.size()-2); + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); + } + else if (linePart=="$specular_map") + { + ss >> linePart; + if (linePart[0] == '"')// "file" -> file + linePart = linePart.substr(1, linePart.size()-2); + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0)); + } + else if (linePart=="$normal_map") + { + ss >> linePart; + if (linePart[0]=='"')// "file" -> file + linePart = linePart.substr(1, linePart.size()-2); + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); + } + else if (linePart=="$light_map") + { + ss >> linePart; + if (linePart[0]=='"') { + linePart = linePart.substr(1, linePart.size() - 2); + } + aiString ts(linePart); + material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, 0)); + } + } + } + ss >> linePart; + } + + return material; } bool OgreImporter::ReadTechnique(const std::string &techniqueName, stringstream &ss, aiMaterial *material) { - string linePart; - ss >> linePart; - - if (linePart != partBlockStart) - { - DefaultLogger::get()->error(Formatter::format() << "Invalid material: Technique block start missing near index " << ss.tellg()); - return false; - } - - DefaultLogger::get()->debug(" technique '" + techniqueName + "'"); - - const string partPass = "pass"; - - while(linePart != partBlockEnd) - { - ss >> linePart; - - // Skip commented lines - if (linePart == partComment) - { - SkipLine(ss); - continue; - } - - /// @todo Techniques have other attributes than just passes. - if (linePart == partPass) - { - string passName = SkipLine(ss); - ReadPass(Trim(passName), ss, material); - } - } - return true; + string linePart; + ss >> linePart; + + if (linePart != partBlockStart) + { + DefaultLogger::get()->error(Formatter::format() << "Invalid material: Technique block start missing near index " << ss.tellg()); + return false; + } + + DefaultLogger::get()->debug(" technique '" + techniqueName + "'"); + + const string partPass = "pass"; + + while(linePart != partBlockEnd) + { + ss >> linePart; + + // Skip commented lines + if (linePart == partComment) + { + SkipLine(ss); + continue; + } + + /// @todo Techniques have other attributes than just passes. + if (linePart == partPass) + { + string passName = SkipLine(ss); + ReadPass(Trim(passName), ss, material); + } + } + return true; } bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMaterial *material) { - string linePart; - ss >> linePart; - - if (linePart != partBlockStart) - { - DefaultLogger::get()->error(Formatter::format() << "Invalid material: Pass block start missing near index " << ss.tellg()); - return false; - } - - DefaultLogger::get()->debug(" pass '" + passName + "'"); - - const string partAmbient = "ambient"; - const string partDiffuse = "diffuse"; - const string partSpecular = "specular"; - const string partEmissive = "emissive"; - const string partTextureUnit = "texture_unit"; - - while(linePart != partBlockEnd) - { - ss >> linePart; - - // Skip commented lines - if (linePart == partComment) - { - SkipLine(ss); - continue; - } - - // Colors - /// @todo Support alpha via aiColor4D. - if (linePart == partAmbient || linePart == partDiffuse || linePart == partSpecular || linePart == partEmissive) - { - float r, g, b; - ss >> r >> g >> b; - const aiColor3D color(r, g, b); - - DefaultLogger::get()->debug(Formatter::format() << " " << linePart << " " << r << " " << g << " " << b); - - if (linePart == partAmbient) - { - material->AddProperty(&color, 1, AI_MATKEY_COLOR_AMBIENT); - } - else if (linePart == partDiffuse) - { - material->AddProperty(&color, 1, AI_MATKEY_COLOR_DIFFUSE); - } - else if (linePart == partSpecular) - { - material->AddProperty(&color, 1, AI_MATKEY_COLOR_SPECULAR); - } - else if (linePart == partEmissive) - { - material->AddProperty(&color, 1, AI_MATKEY_COLOR_EMISSIVE); - } - } - else if (linePart == partTextureUnit) - { - string textureUnitName = SkipLine(ss); - ReadTextureUnit(Trim(textureUnitName), ss, material); - } - } - return true; + string linePart; + ss >> linePart; + + if (linePart != partBlockStart) + { + DefaultLogger::get()->error(Formatter::format() << "Invalid material: Pass block start missing near index " << ss.tellg()); + return false; + } + + DefaultLogger::get()->debug(" pass '" + passName + "'"); + + const string partAmbient = "ambient"; + const string partDiffuse = "diffuse"; + const string partSpecular = "specular"; + const string partEmissive = "emissive"; + const string partTextureUnit = "texture_unit"; + + while(linePart != partBlockEnd) + { + ss >> linePart; + + // Skip commented lines + if (linePart == partComment) + { + SkipLine(ss); + continue; + } + + // Colors + /// @todo Support alpha via aiColor4D. + if (linePart == partAmbient || linePart == partDiffuse || linePart == partSpecular || linePart == partEmissive) + { + float r, g, b; + ss >> r >> g >> b; + const aiColor3D color(r, g, b); + + DefaultLogger::get()->debug(Formatter::format() << " " << linePart << " " << r << " " << g << " " << b); + + if (linePart == partAmbient) + { + material->AddProperty(&color, 1, AI_MATKEY_COLOR_AMBIENT); + } + else if (linePart == partDiffuse) + { + material->AddProperty(&color, 1, AI_MATKEY_COLOR_DIFFUSE); + } + else if (linePart == partSpecular) + { + material->AddProperty(&color, 1, AI_MATKEY_COLOR_SPECULAR); + } + else if (linePart == partEmissive) + { + material->AddProperty(&color, 1, AI_MATKEY_COLOR_EMISSIVE); + } + } + else if (linePart == partTextureUnit) + { + string textureUnitName = SkipLine(ss); + ReadTextureUnit(Trim(textureUnitName), ss, material); + } + } + return true; } bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstream &ss, aiMaterial *material) { - string linePart; - ss >> linePart; - - if (linePart != partBlockStart) - { - DefaultLogger::get()->error(Formatter::format() << "Invalid material: Texture unit block start missing near index " << ss.tellg()); - return false; - } - - DefaultLogger::get()->debug(" texture_unit '" + textureUnitName + "'"); - - const string partTexture = "texture"; - const string partTextCoordSet = "tex_coord_set"; - const string partColorOp = "colour_op"; - - aiTextureType textureType = aiTextureType_NONE; - std::string textureRef; - int uvCoord = 0; - - while(linePart != partBlockEnd) - { - ss >> linePart; - - // Skip commented lines - if (linePart == partComment) - { - SkipLine(ss); - continue; - } - - if (linePart == partTexture) - { - ss >> linePart; - textureRef = linePart; - - // User defined Assimp config property to detect texture type from filename. - if (m_detectTextureTypeFromFilename) - { - size_t posSuffix = textureRef.find_last_of("."); - size_t posUnderscore = textureRef.find_last_of("_"); - - if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) - { - string identifier = Ogre::ToLower(textureRef.substr(posUnderscore, posSuffix - posUnderscore)); - DefaultLogger::get()->debug(Formatter::format() << "Detecting texture type from filename postfix '" << identifier << "'"); - - if (identifier == "_n" || identifier == "_nrm" || identifier == "_nrml" || identifier == "_normal" || identifier == "_normals" || identifier == "_normalmap") - { - textureType = aiTextureType_NORMALS; - } - else if (identifier == "_s" || identifier == "_spec" || identifier == "_specular" || identifier == "_specularmap") - { - textureType = aiTextureType_SPECULAR; - } - else if (identifier == "_l" || identifier == "_light" || identifier == "_lightmap" || identifier == "_occ" || identifier == "_occlusion") - { - textureType = aiTextureType_LIGHTMAP; - } - else if (identifier == "_disp" || identifier == "_displacement") - { - textureType = aiTextureType_DISPLACEMENT; - } - else - { - textureType = aiTextureType_DIFFUSE; - } - } - else - { - textureType = aiTextureType_DIFFUSE; - } - } - // Detect from texture unit name. This cannot be too broad as - // authors might give names like "LightSaber" or "NormalNinja". - else - { - string unitNameLower = Ogre::ToLower(textureUnitName); - if (unitNameLower.find("normalmap") != string::npos) - { - textureType = aiTextureType_NORMALS; - } - else if (unitNameLower.find("specularmap") != string::npos) - { - textureType = aiTextureType_SPECULAR; - } - else if (unitNameLower.find("lightmap") != string::npos) - { - textureType = aiTextureType_LIGHTMAP; - } - else if (unitNameLower.find("displacementmap") != string::npos) - { - textureType = aiTextureType_DISPLACEMENT; - } - else - { - textureType = aiTextureType_DIFFUSE; - } - } - } - else if (linePart == partTextCoordSet) - { - ss >> uvCoord; - } - /// @todo Implement - else if(linePart == partColorOp) - { - /* - ss >> linePart; - if("replace"==linePart)//I don't think, assimp has something for this... - { - } - else if("modulate"==linePart) - { - //TODO: set value - //material->AddProperty(aiTextureOp_Multiply) - } - */ - } - } - - if (textureRef.empty()) - { - DefaultLogger::get()->warn("Texture reference is empty, ignoring texture_unit."); - return false; - } - if (textureType == aiTextureType_NONE) - { - DefaultLogger::get()->warn("Failed to detect texture type for '" + textureRef + "', ignoring texture_unit."); - return false; - } - - unsigned int textureTypeIndex = m_textures[textureType]; - m_textures[textureType]++; - - DefaultLogger::get()->debug(Formatter::format() << " texture '" << textureRef << "' type " << textureType - << " index " << textureTypeIndex << " UV " << uvCoord); - - aiString assimpTextureRef(textureRef); - material->AddProperty(&assimpTextureRef, AI_MATKEY_TEXTURE(textureType, textureTypeIndex)); - material->AddProperty(&uvCoord, 1, AI_MATKEY_UVWSRC(textureType, textureTypeIndex)); - - return true; + string linePart; + ss >> linePart; + + if (linePart != partBlockStart) + { + DefaultLogger::get()->error(Formatter::format() << "Invalid material: Texture unit block start missing near index " << ss.tellg()); + return false; + } + + DefaultLogger::get()->debug(" texture_unit '" + textureUnitName + "'"); + + const string partTexture = "texture"; + const string partTextCoordSet = "tex_coord_set"; + const string partColorOp = "colour_op"; + + aiTextureType textureType = aiTextureType_NONE; + std::string textureRef; + int uvCoord = 0; + + while(linePart != partBlockEnd) + { + ss >> linePart; + + // Skip commented lines + if (linePart == partComment) + { + SkipLine(ss); + continue; + } + + if (linePart == partTexture) + { + ss >> linePart; + textureRef = linePart; + + // User defined Assimp config property to detect texture type from filename. + if (m_detectTextureTypeFromFilename) + { + size_t posSuffix = textureRef.find_last_of("."); + size_t posUnderscore = textureRef.find_last_of("_"); + + if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) + { + string identifier = Ogre::ToLower(textureRef.substr(posUnderscore, posSuffix - posUnderscore)); + DefaultLogger::get()->debug(Formatter::format() << "Detecting texture type from filename postfix '" << identifier << "'"); + + if (identifier == "_n" || identifier == "_nrm" || identifier == "_nrml" || identifier == "_normal" || identifier == "_normals" || identifier == "_normalmap") + { + textureType = aiTextureType_NORMALS; + } + else if (identifier == "_s" || identifier == "_spec" || identifier == "_specular" || identifier == "_specularmap") + { + textureType = aiTextureType_SPECULAR; + } + else if (identifier == "_l" || identifier == "_light" || identifier == "_lightmap" || identifier == "_occ" || identifier == "_occlusion") + { + textureType = aiTextureType_LIGHTMAP; + } + else if (identifier == "_disp" || identifier == "_displacement") + { + textureType = aiTextureType_DISPLACEMENT; + } + else + { + textureType = aiTextureType_DIFFUSE; + } + } + else + { + textureType = aiTextureType_DIFFUSE; + } + } + // Detect from texture unit name. This cannot be too broad as + // authors might give names like "LightSaber" or "NormalNinja". + else + { + string unitNameLower = Ogre::ToLower(textureUnitName); + if (unitNameLower.find("normalmap") != string::npos) + { + textureType = aiTextureType_NORMALS; + } + else if (unitNameLower.find("specularmap") != string::npos) + { + textureType = aiTextureType_SPECULAR; + } + else if (unitNameLower.find("lightmap") != string::npos) + { + textureType = aiTextureType_LIGHTMAP; + } + else if (unitNameLower.find("displacementmap") != string::npos) + { + textureType = aiTextureType_DISPLACEMENT; + } + else + { + textureType = aiTextureType_DIFFUSE; + } + } + } + else if (linePart == partTextCoordSet) + { + ss >> uvCoord; + } + /// @todo Implement + else if(linePart == partColorOp) + { + /* + ss >> linePart; + if("replace"==linePart)//I don't think, assimp has something for this... + { + } + else if("modulate"==linePart) + { + //TODO: set value + //material->AddProperty(aiTextureOp_Multiply) + } + */ + } + } + + if (textureRef.empty()) + { + DefaultLogger::get()->warn("Texture reference is empty, ignoring texture_unit."); + return false; + } + if (textureType == aiTextureType_NONE) + { + DefaultLogger::get()->warn("Failed to detect texture type for '" + textureRef + "', ignoring texture_unit."); + return false; + } + + unsigned int textureTypeIndex = m_textures[textureType]; + m_textures[textureType]++; + + DefaultLogger::get()->debug(Formatter::format() << " texture '" << textureRef << "' type " << textureType + << " index " << textureTypeIndex << " UV " << uvCoord); + + aiString assimpTextureRef(textureRef); + material->AddProperty(&assimpTextureRef, AI_MATKEY_TEXTURE(textureType, textureTypeIndex)); + material->AddProperty(&uvCoord, 1, AI_MATKEY_UVWSRC(textureType, textureTypeIndex)); + + return true; } } // Ogre |