From Jan Peciva, "I am sending four fixes to obj plugin:

- materialName used to be not stripped of whitespace, making number of models
fail to load materials; now fixed
- stripping was considering spaces only, thus models using tabs had problems
to load correctly; fixed
- fixed references to textures; they did not performed conversion to native
directory separators
- make d (dissolve) takes precedence over Tr (transparency); there seems to be
a confusion about the Tr item - some claiming 1 to be opaque and 0
transparent, while number of models uses exactly the opposite. d (dissolve),
if present in the model, does not suffer from this confusion, thus using it
instead fixes the problem for many many models.

I put many comments to the file concerning d and Tr item as others may further
investigate. Let me know in the case of any problems."
This commit is contained in:
Robert Osfield
2014-04-07 14:17:57 +00:00
parent 64979a0c1a
commit 391ab02573

View File

@@ -31,7 +31,8 @@ using namespace obj;
static std::string strip( const std::string& ss )
{
std::string result;
result.assign( ss.begin() + ss.find_first_not_of( ' ' ), ss.begin() + 1 + ss.find_last_not_of( ' ' ) );
result.assign( std::find_if( ss.begin(), ss.end(), std::not1( std::ptr_fun< int, int >( isspace ) ) ),
std::find_if( ss.rbegin(), ss.rend(), std::not1( std::ptr_fun< int, int >( isspace ) ) ).base() );
return( result );
}
@@ -107,7 +108,7 @@ static Material::Map parseTextureMap( const std::string& ss, Material::Map::Text
s = strip(s.substr(n));
}
map.name = s;
map.name = osgDB::convertFileNameToNativeStyle(s);
map.type = type;
return map;
}
@@ -220,6 +221,7 @@ bool Model::readMTL(std::istream& fin)
const int LINE_SIZE = 4096;
char line[LINE_SIZE];
float r = 1.0f, g = 1.0f, b = 1.0f, a = 1.0f;
bool usingDissolve = false;
Material* material = 0;// &(materialMap[""]);
std::string filename;
@@ -236,9 +238,11 @@ bool Model::readMTL(std::istream& fin)
{
if (strncmp(line,"newmtl ",7)==0)
{
std::string materialName(line+7);
// get material name and left- and right-trim all the white-space
std::string materialName(strip(line+7));
material = & materialMap[materialName];
material->name = materialName;
usingDissolve = false;
}
else if (material)
{
@@ -405,19 +409,52 @@ bool Model::readMTL(std::istream& fin)
if (fieldsRead==1) material->Ni = Ni;
}
//
// Tr - transparency
//
// Seems that the world did not agreed about the specification of the item.
//
// Some thinks that value of 1 means opaque material and 0 transparent material,
// such as http://people.sc.fsu.edu/~jburkardt/data/mtl/mtl.html .
//
// However, 3ds Max export uses the opposite: 0 means opaque material and
// 1 completely transparent material. These 3ds Max exported files
// carry the following signature as the first line in the file (*.obj, *.mtl):
// # 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
//
// Moreover, at least one model uses Tr followed by two numbers.
// Such model can be downloaded from http://graphics.cs.williams.edu/data/meshes/cube.zip
// (part of the following collection: http://graphics.cs.williams.edu/data/meshes.xml).
//
// Current solution: As we do not know what is the correct interpretation of
// the value 0 and value 1 for Tr, we will rely on d (dissolve) parameter instead
// whenever it is present. This seems to fix the problem on large number of models.
//
else if (strncmp(line,"Tr ",3)==0)
{
float alpha=1.0f;
unsigned int fieldsRead = sscanf(line+3,"%f", &alpha);
if (fieldsRead==1)
if( !usingDissolve )
{
material->ambient[3] = alpha;
material->diffuse[3] = alpha;
material->specular[3] = alpha;
material->emissive[3] = alpha;
float alpha=1.0f;
unsigned int fieldsRead = sscanf(line+3,"%f", &alpha);
if (fieldsRead==1)
{
material->ambient[3] = alpha;
material->diffuse[3] = alpha;
material->specular[3] = alpha;
material->emissive[3] = alpha;
}
}
}
//
// d - dissolve (pseudo-transparency)
//
// Dissolve of value 1 means completely opaque material
// and value of 0 results in completely transparent material.
//
// To be compatible with 3D Max obj exporter,
// d takes precedence over Tr (handled through usingDissolve variable).
//
else if (strncmp(line,"d ",2)==0)
{
float alpha=1.0f;
@@ -429,6 +466,7 @@ bool Model::readMTL(std::istream& fin)
material->diffuse[3] = alpha;
material->specular[3] = alpha;
material->emissive[3] = alpha;
usingDissolve = true;
}
}
else if (strncmp(line,"map_Ka ",7)==0)