From Ulrich Hertlein, "as I hinted at on osg-users in the "obj loader: map_* only reads last component" thread, this submission broke material/texture loading for some files I have that specify texture matrix scaling.

The following link shows a very comprehensive list of .mtl file options:
http://local.wasp.uwa.edu.au/~pbourke/dataformats/mtl/

Attached is a patch that should fix spacey filenames and optional texture scale/offset.  I have tested it with files I have that I modified to contain spaces in the texture filenames."
This commit is contained in:
Robert Osfield 2008-07-25 15:45:40 +00:00
parent 55199b8e38
commit d8d2bc4193
3 changed files with 93 additions and 13 deletions

View File

@ -163,7 +163,7 @@ inline osg::Vec3 ReaderWriterOBJ::transformNormal(const osg::Vec3& vec, const bo
// register with Registry to instantiate the above reader/writer.
REGISTER_OSGPLUGIN(obj, ReaderWriterOBJ)
void load_material_texture( obj::Model &model,
static void load_material_texture( obj::Model &model,
obj::Material &material,
osg::StateSet *stateset,
const std::string & filename,
@ -174,7 +174,7 @@ void load_material_texture( obj::Model &model,
osg::ref_ptr< osg::Image > image;
if ( !model.getDatabasePath().empty() )
{
// first try with databasr path of parent.
// first try with database path of parent.
image = osgDB::readImageFile(model.getDatabasePath()+'/'+filename);
}
@ -208,6 +208,26 @@ void load_material_texture( obj::Model &model,
}
}
}
if (material.uScale != 1.0f || material.vScale != 1.0f ||
material.uOffset != 0.0f || material.vOffset != 0.0f)
{
osg::Matrix mat;
if (material.uScale != 1.0f || material.vScale != 1.0f)
{
osg::notify(osg::DEBUG_INFO) << "Obj TexMat scale=" << material.uScale << "," << material.vScale << std::endl;
mat *= osg::Matrix::scale(material.uScale, material.vScale, 1.0);
}
if (material.uOffset != 0.0f || material.vOffset != 0.0f)
{
osg::notify(osg::DEBUG_INFO) << "Obj TexMat offset=" << material.uOffset << "," << material.uOffset << std::endl;
mat *= osg::Matrix::translate(material.uOffset, material.vOffset, 0.0);
}
osg::TexMat* texmat = new osg::TexMat;
texmat->setMatrix(mat);
stateset->setTextureAttributeAndModes( texture_unit,texmat,osg::StateAttribute::ON );
}
}

View File

@ -26,13 +26,76 @@
using namespace obj;
std::string strip( const std::string& ss )
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( ' ' ) );
return( result );
}
/*
* parse a subset of texture options, following
* http://local.wasp.uwa.edu.au/~pbourke/dataformats/mtl/
*/
static std::string parseTexture( const std::string& ss, Material& mat)
{
std::string s(ss);
for (;;)
{
if (s[0] != '-')
break;
int n;
if (s[1] == 's' || s[1] == 'o')
{
float x, y, z;
if (sscanf(s.c_str(), "%*s %f %f %f%n", &x, &y, &z, &n) != 3)
{
break;
}
if (s[1] == 's')
{
// texture scale
mat.uScale = x;
mat.vScale = y;
}
else if (s[1] == 'o')
{
// texture offset
mat.uOffset = x;
mat.vOffset = y;
}
}
else if (s[1] == 'm' && s[2] == 'm')
{
// texture color offset and gain
float base, gain;
if (sscanf(s.c_str(), "%*s %f %f%n", &base, &gain, &n) != 2)
{
break;
}
// UNUSED
}
else if (s[1] == 'b' && s[2] == 'm')
{
// blend multiplier
float mult;
if (sscanf(s.c_str(), "%*s %f%n", &mult, &n) != 2)
{
break;
}
// UNUSED
}
else
break;
s = strip(s.substr(n));
}
return s;
}
bool Model::readline(std::istream& fin, char* line, const int LINE_SIZE)
{
if (LINE_SIZE<1) return false;
@ -141,6 +204,7 @@ bool Model::readMTL(std::istream& fin)
float r = 1.0f, g = 1.0f, b = 1.0f, a = 1.0f;
Material* material = 0;// &(materialMap[""]);
std::string filename;
while (fin)
{
@ -351,23 +415,19 @@ bool Model::readMTL(std::istream& fin)
}
else if (strncmp(line,"map_Ka ",7)==0)
{
std::string filename(line+7);
material->map_Ka = filename;
material->map_Ka = parseTexture(strip(line+7), *material);
}
else if (strncmp(line,"map_Kd ",7)==0)
{
material->map_Kd = strip(line+7);
osg::notify(osg::INFO)<< "map_Kd:\'" << material->map_Kd << "\'" << std::endl;
material->map_Kd = parseTexture(strip(line+7), *material);
}
else if (strncmp(line,"map_Ks ",7)==0)
{
material->map_Ks = strip(line+7);
osg::notify(osg::INFO)<< "map_Ks:\'" << material->map_Kd << "\'" << std::endl;
material->map_Ks = parseTexture(strip(line+7), *material);
}
else if (strncmp(line,"map_opacity ",7)==0)
{
material->map_opacity = strip(line+7);
osg::notify(osg::INFO)<< "map_opacity:\'" << material->map_Kd << "\'" << std::endl;
material->map_opacity = parseTexture(strip(line+7), *material);
}
else if (strcmp(line,"refl")==0 || strncmp(line,"refl ",5)==0)
{

View File

@ -48,8 +48,8 @@ public:
alpha(1.0f),
uScale(1.0f),
vScale(1.0f),
uOffset(1.0f),
vOffset(1.0f) {}
uOffset(0.0f),
vOffset(0.0f) {}
std::string name;