From Ulrich Hertlein, "attached are some fixes and tweaks I made to the .obj loader:

- Material class contained both 'shininess' and 'Ns' member variables
- 'Ns' and 'Ni' are initialized to 0 ('Ni' is unused at the moment)
- only 'Ns' was read from .mtl file but 'shininess' was used for osg::Material
- 'illum' was read from .mtl file but never used; it is now used as follows
-- illum==0 -> no osg::Material created/attached therefore no lighting
-- illum==1 -> osg::Material specular is set to black
-- illum==2 (default) -> specular read from .mtl file is used
- 'map_Kd' and 'map_Ks' may contain additional arguments (e.g. '-s 1 1 1'),
these are now skipped over and the texture filename is properly extracted
"
This commit is contained in:
Robert Osfield
2007-12-10 20:27:06 +00:00
parent d0cc647986
commit 9d260213f7
3 changed files with 27 additions and 24 deletions

View File

@@ -3,7 +3,7 @@
/*
* Wavefront OBJ loader for Open Scene Graph
*
* Copyright (C) 2001 Ulrich Hertlein <u.hertlein@web.de>
* Copyright (C) 2001,2007 Ulrich Hertlein <u.hertlein@sandbox.de>
*
* Modified by Robert Osfield to support per Drawable coord, normal and
* texture coord arrays, bug fixes, and support for texture mapping.
@@ -213,14 +213,20 @@ void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToSt
bool isTransparent = false;
// handle material colors
// http://java3d.j3d.org/utilities/loaders/obj/sun.html
if (material.illum != 0)
{
osg::Material* osg_material = new osg::Material;
stateset->setAttribute(osg_material);
osg_material->setAmbient(osg::Material::FRONT_AND_BACK,material.ambient);
osg_material->setDiffuse(osg::Material::FRONT_AND_BACK,material.diffuse);
osg_material->setSpecular(osg::Material::FRONT_AND_BACK,material.specular);
osg_material->setShininess(osg::Material::FRONT_AND_BACK,(material.shininess/1000.0f)*128.0f ); // note OBJ shiniess is 0..1000.
if (material.illum == 2) {
osg_material->setSpecular(osg::Material::FRONT_AND_BACK,material.specular);
} else {
osg_material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,1));
}
osg_material->setShininess(osg::Material::FRONT_AND_BACK,(material.Ns/1000.0f)*128.0f ); // note OBJ shiniess is 0..1000.
if (material.ambient[3]!=1.0 ||
material.diffuse[3]!=1.0 ||

View File

@@ -112,6 +112,16 @@ bool Model::readline(std::istream& fin, char* line, const int LINE_SIZE)
}
std::string Model::lastComponent(const char* linep)
{
std::string line = std::string(linep);
int space = line.find_last_of(" ");
if (space >= 0) {
line = line.substr(space+1);
}
return line;
}
bool Model::readMTL(std::istream& fin)
{
osg::notify(osg::INFO)<<"Reading MTL file"<<std::endl;
@@ -213,13 +223,6 @@ bool Model::readMTL(std::istream& fin)
if (fieldsRead==1) material->Ni = Ni;
}
else if (strncmp(line,"illum ",6)==0)
{
int illum = 0;
unsigned int fieldsRead = sscanf(line+6,"%d", &illum);
if (fieldsRead==1) material->illum = illum;
}
else if (strncmp(line,"Tr ",3)==0)
{
float alpha=1.0f;
@@ -253,13 +256,11 @@ bool Model::readMTL(std::istream& fin)
}
else if (strncmp(line,"map_Kd ",7)==0)
{
std::string filename(line+7);
material->map_Kd = filename;
material->map_Kd = lastComponent(line+7);
}
else if (strncmp(line,"map_Ks ",7)==0)
{
std::string filename(line+7);
material->map_Ks = filename;
material->map_Ks = lastComponent(line+7);
}
else if (strcmp(line,"refl")==0 || strncmp(line,"refl ",5)==0)
{

View File

@@ -39,10 +39,11 @@ public:
diffuse(0.8f,0.8f,0.8f,1.0f),
specular(0.0f,0.0f,0.0f,1.0f),
emissive(0.0f,0.0f,0.0f,1.0f),
shininess(0.0f),
sharpness(0.0f),
illum(0),
illum(2),
Tf(0.0f,0.0f,0.0f,1.0f),
Ni(0),
Ns(0),
textureReflection(false),
alpha(1.0f),
uScale(1.0f),
@@ -56,13 +57,12 @@ public:
osg::Vec4 diffuse;
osg::Vec4 specular;
osg::Vec4 emissive;
float shininess;
float sharpness;
int illum;
osg::Vec4 Tf;
int Ni;
int Ns;
int Ns; // shininess 0..1000
std::string map_Ka;
std::string map_Kd;
@@ -73,9 +73,8 @@ public:
float vScale;
float uOffset;
float vOffset;
protected:
protected:
};
class Element : public osg::Referenced
@@ -158,6 +157,7 @@ public:
void setDatabasePath(const std::string& path) { databasePath = path; }
const std::string& getDatabasePath() const { return databasePath; }
std::string lastComponent(const char* linep);
bool readMTL(std::istream& fin);
bool readOBJ(std::istream& fin, const osgDB::ReaderWriter::Options* options);
@@ -195,8 +195,4 @@ public:
}
#endif