fix load obj texture filename when has any option

This commit is contained in:
alemuntoni 2021-07-08 12:56:06 +02:00
parent a282947a72
commit 735f93c256
1 changed files with 130 additions and 130 deletions

View File

@ -960,135 +960,135 @@ public:
return ret; return ret;
} }
static bool LoadMaterials(const char * filename, std::vector<Material> &materials, std::vector<std::string> &textures) static bool LoadMaterials(const char * filename, std::vector<Material> &materials, std::vector<std::string> &textures)
{ {
// assumes we are in the right directory // assumes we are in the right directory
std::ifstream stream(filename); std::ifstream stream(filename);
if (stream.fail()) if (stream.fail())
return false; return false;
std::vector< std::string > tokens; std::vector< std::string > tokens;
std::string line; std::string line;
std::string header; std::string header;
materials.clear(); materials.clear();
Material currentMaterial; Material currentMaterial;
// Fill in some default values for the material // Fill in some default values for the material
currentMaterial.index = (unsigned int)(-1); currentMaterial.index = (unsigned int)(-1);
currentMaterial.Ka = Point3f(0.2, 0.2, 0.2); currentMaterial.Ka = Point3f(0.2, 0.2, 0.2);
currentMaterial.Kd = Point3f(1, 1, 1); currentMaterial.Kd = Point3f(1, 1, 1);
currentMaterial.Ks = Point3f(1, 1, 1); currentMaterial.Ks = Point3f(1, 1, 1);
currentMaterial.Tr = 1; currentMaterial.Tr = 1;
currentMaterial.Ns = 0; currentMaterial.Ns = 0;
currentMaterial.illum = 2; currentMaterial.illum = 2;
bool first = true; bool first = true;
while (!stream.eof()) while (!stream.eof())
{ {
tokens.clear(); tokens.clear();
TokenizeNextLine(stream, tokens, line, 0); TokenizeNextLine(stream, tokens, line, 0);
if (tokens.size() > 0) if (tokens.size() > 0)
{ {
header.clear(); header.clear();
header = tokens[0]; header = tokens[0];
if (header.compare("newmtl")==0) if (header.compare("newmtl")==0)
{ {
if (!first) if (!first)
{ {
materials.push_back(currentMaterial); materials.push_back(currentMaterial);
currentMaterial = Material(); currentMaterial = Material();
currentMaterial.index = (unsigned int)(-1); currentMaterial.index = (unsigned int)(-1);
} }
else else
first = false; first = false;
//strcpy(currentMaterial.name, tokens[1].c_str()); //strcpy(currentMaterial.name, tokens[1].c_str());
if(tokens.size() < 2) if(tokens.size() < 2)
return false; return false;
else if (tokens.size() == 2) else if (tokens.size() == 2)
currentMaterial.materialName = tokens[1]; //play it safe currentMaterial.materialName = tokens[1]; //play it safe
else else
currentMaterial.materialName = line.substr(7); //space in the name, get everything after "newmtl " currentMaterial.materialName = line.substr(7); //space in the name, get everything after "newmtl "
} }
else if (header.compare("Ka")==0) else if (header.compare("Ka")==0)
{ {
if (tokens.size() < 4) return false; if (tokens.size() < 4) return false;
currentMaterial.Ka = Point3fFrom3Tokens(tokens,1); currentMaterial.Ka = Point3fFrom3Tokens(tokens,1);
} }
else if (header.compare("Kd")==0) else if (header.compare("Kd")==0)
{ {
if (tokens.size() < 4) return false; if (tokens.size() < 4) return false;
currentMaterial.Kd = Point3fFrom3Tokens(tokens,1); currentMaterial.Kd = Point3fFrom3Tokens(tokens,1);
} }
else if (header.compare("Ks")==0) else if (header.compare("Ks")==0)
{ {
if (tokens.size() < 4) return false; if (tokens.size() < 4) return false;
currentMaterial.Ks = Point3fFrom3Tokens(tokens,1); currentMaterial.Ks = Point3fFrom3Tokens(tokens,1);
} }
else if ( (header.compare("d")==0) || else if ( (header.compare("d")==0) ||
(header.compare("Tr")==0) ) // alpha (header.compare("Tr")==0) ) // alpha
{ {
if (tokens.size() < 2) return false; if (tokens.size() < 2) return false;
currentMaterial.Tr = (float) atof(tokens[1].c_str()); currentMaterial.Tr = (float) atof(tokens[1].c_str());
} }
else if (header.compare("Ns")==0) // shininess else if (header.compare("Ns")==0) // shininess
{ {
if (tokens.size() < 2) return false; if (tokens.size() < 2) return false;
currentMaterial.Ns = float(atoi(tokens[1].c_str())); currentMaterial.Ns = float(atoi(tokens[1].c_str()));
} }
else if (header.compare("illum")==0) // specular illumination on/off else if (header.compare("illum")==0) // specular illumination on/off
{ {
if (tokens.size() < 2) return false; if (tokens.size() < 2) return false;
currentMaterial.illum = atoi(tokens[1].c_str());; currentMaterial.illum = atoi(tokens[1].c_str());;
} }
else if(header.compare("map_Kd")==0) // texture name else if(header.compare("map_Kd")==0) // texture name
{ {
std::string textureName; std::string textureName;
if (tokens.size() < 2) if (tokens.size() < 2)
return false; return false;
else if (tokens.size() == 2) else {
textureName = tokens[1]; //play it safe //the tex name is the last one (after any option)
else textureName = tokens[tokens.size()-1];
textureName = line.substr(7); //get everything after "map_Kd " }
currentMaterial.map_Kd=textureName; currentMaterial.map_Kd=textureName;
// adding texture name into textures vector (if not already present) // adding texture name into textures vector (if not already present)
// avoid adding the same name twice // avoid adding the same name twice
auto it = std::find(textures.begin(), textures.end(), textureName); auto it = std::find(textures.begin(), textures.end(), textureName);
if(it==textures.end()) { if(it==textures.end()) {
currentMaterial.index = textures.size(); currentMaterial.index = textures.size();
textures.push_back(textureName); textures.push_back(textureName);
} else { } else {
currentMaterial.index = std::distance(textures.begin(),it); currentMaterial.index = std::distance(textures.begin(),it);
} }
} }
// we simply ignore other situations // we simply ignore other situations
} }
} }
materials.push_back(currentMaterial); // add last read material materials.push_back(currentMaterial); // add last read material
stream.close(); stream.close();
// Sometimes some materials have texture and no texture // Sometimes some materials have texture and no texture
// in this case for sake of uniformity we just use the first texture. // in this case for sake of uniformity we just use the first texture.
if(!textures.empty()) if(!textures.empty())
{ {
for(size_t i=0;i<materials.size();++i) for(size_t i=0;i<materials.size();++i)
{ {
if(materials[i].map_Kd.empty()) if(materials[i].map_Kd.empty())
{ {
materials[i].map_Kd=textures[0]; materials[i].map_Kd=textures[0];
materials[i].index=0; materials[i].index=0;
} }
} }
} }
return true; return true;
} }
}; // end class }; // end class
} // end Namespace tri } // end Namespace tri