From Doug McCorkle, "Attached is patch that corrects/improves the following issues with the OBJ loader:
1. Added options to control wether the osgUtil::Tessellator or osgUtil::TriStripVisitor are run. By default they still run just as before. 2. Added support for the Emissive material. The data was being read from the mtl file but was never being applied to the model. 3. This is the main bug addressed, when a model is read in with an alpha value specified like: newmtl Material__8 Ns 24 d 0.33 illum 2 Kd 0.204 0.204 0.204 Ks 0 0 0 Ka 0.153 0.153 0.153 where the alpha value is d. The loader would then overwrite the alpha value when reading the diffuse, specular, and ambient colors. I have changed all the material color readers to only set the values they read and to use the default colors specified in the constructor of the obj class. With these changes, the obj reader now handles opacity correctly if the alpha value is specified before the material colo"
This commit is contained in:
parent
ccb50019e4
commit
4ca61c38f0
@ -122,7 +122,8 @@ protected:
|
||||
|
||||
osg::Geometry* convertElementListToGeometry(obj::Model& model, obj::Model::ElementList& elementList, bool& rotate) const;
|
||||
|
||||
osg::Node* convertModelToSceneGraph(obj::Model& model, bool& rotate) const;
|
||||
osg::Node* convertModelToSceneGraph(obj::Model& model, bool& rotate,
|
||||
bool& noTesselateLargePolygons, bool& noTriStripPolygons) const;
|
||||
|
||||
inline osg::Vec3 transformVertex(const osg::Vec3& vec, const bool rotate) const ;
|
||||
inline osg::Vec3 transformNormal(const osg::Vec3& vec, const bool rotate) const ;
|
||||
@ -267,6 +268,8 @@ void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToSt
|
||||
|
||||
osg_material->setAmbient(osg::Material::FRONT_AND_BACK,material.ambient);
|
||||
osg_material->setDiffuse(osg::Material::FRONT_AND_BACK,material.diffuse);
|
||||
osg_material->setEmission(osg::Material::FRONT_AND_BACK,material.emissive);
|
||||
|
||||
if (material.illum == 2) {
|
||||
osg_material->setSpecular(osg::Material::FRONT_AND_BACK,material.specular);
|
||||
} else {
|
||||
@ -276,7 +279,8 @@ void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToSt
|
||||
|
||||
if (material.ambient[3]!=1.0 ||
|
||||
material.diffuse[3]!=1.0 ||
|
||||
material.specular[3]!=1.0)
|
||||
material.specular[3]!=1.0||
|
||||
material.emissive[3]!=1.0)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Found transparent material"<<std::endl;
|
||||
isTransparent = true;
|
||||
@ -292,8 +296,13 @@ void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToSt
|
||||
load_material_texture( model, material, stateset.get(), material.map_Kd, TEXTURE_UNIT_KD );
|
||||
load_material_texture( model, material, stateset.get(), material.map_opacity, TEXTURE_UNIT_OPACITY );
|
||||
|
||||
materialToStateSetMap[material.name] = stateset.get();
|
||||
if (isTransparent)
|
||||
{
|
||||
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
}
|
||||
|
||||
materialToStateSetMap[material.name] = stateset.get();
|
||||
}
|
||||
}
|
||||
|
||||
@ -550,7 +559,8 @@ osg::Geometry* ReaderWriterOBJ::convertElementListToGeometry(obj::Model& model,
|
||||
return geometry;
|
||||
}
|
||||
|
||||
osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model, bool& rotate) const
|
||||
osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model,
|
||||
bool& rotate, bool& noTesselateLargePolygons, bool& noTriStripPolygons) const
|
||||
{
|
||||
|
||||
if (model.elementStateMap.empty()) return 0;
|
||||
@ -579,18 +589,24 @@ osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model, bool& ro
|
||||
geometry->setStateSet(stateset);
|
||||
|
||||
// tesseleate any large polygons
|
||||
if (!noTesselateLargePolygons)
|
||||
{
|
||||
osgUtil::Tessellator tessellator;
|
||||
tessellator.retessellatePolygons(*geometry);
|
||||
}
|
||||
|
||||
// tri strip polygons to improve graphics peformance
|
||||
if (!noTriStripPolygons)
|
||||
{
|
||||
osgUtil::TriStripVisitor tsv;
|
||||
tsv.stripify(*geometry);
|
||||
}
|
||||
|
||||
// if no normals present add them.
|
||||
if (!geometry->getNormalArray() || geometry->getNormalArray()->getNumElements()==0)
|
||||
{
|
||||
osgUtil::SmoothingVisitor tsv;
|
||||
tsv.smooth(*geometry);
|
||||
osgUtil::SmoothingVisitor sv;
|
||||
sv.smooth(*geometry);
|
||||
}
|
||||
|
||||
|
||||
@ -641,14 +657,32 @@ osgDB::ReaderWriter::ReadResult ReaderWriterOBJ::readNode(const std::string& fil
|
||||
model.setDatabasePath(osgDB::getFilePath(fileName.c_str()));
|
||||
model.readOBJ(fin, local_opt.get());
|
||||
|
||||
// code for checking the noRotation
|
||||
// code for checking the nonRotation, noTesselateLargePolygons,
|
||||
// and noTriStripPolygons
|
||||
bool rotate = true;
|
||||
if ((options!=NULL) && (options->getOptionString() == "noRotation"))
|
||||
bool noTesselateLargePolygons = false;
|
||||
bool noTriStripPolygons = false;
|
||||
|
||||
if (options!=NULL)
|
||||
{
|
||||
if (options->getOptionString() == "noRotation")
|
||||
{
|
||||
rotate = false;
|
||||
}
|
||||
|
||||
osg::Node* node = convertModelToSceneGraph(model,rotate);
|
||||
if (options->getOptionString() == "noTesselateLargePolygons")
|
||||
{
|
||||
noTesselateLargePolygons = true;
|
||||
}
|
||||
|
||||
if (options->getOptionString() == "noTriStripPolygons")
|
||||
{
|
||||
noTesselateLargePolygons = true;
|
||||
}
|
||||
}
|
||||
|
||||
osg::Node* node = convertModelToSceneGraph(model,rotate,
|
||||
noTesselateLargePolygons,noTriStripPolygons);
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -662,14 +696,32 @@ osgDB::ReaderWriter::ReadResult ReaderWriterOBJ::readNode(std::istream& fin, con
|
||||
obj::Model model;
|
||||
model.readOBJ(fin, options);
|
||||
|
||||
// code for checking the nonRotation
|
||||
// code for checking the nonRotation, noTesselateLargePolygons,
|
||||
// and noTriStripPolygons
|
||||
bool rotate = true;
|
||||
if ((options!=NULL) && (options->getOptionString() == "noRotation"))
|
||||
bool noTesselateLargePolygons = false;
|
||||
bool noTriStripPolygons = false;
|
||||
|
||||
if (options!=NULL)
|
||||
{
|
||||
if (options->getOptionString() == "noRotation")
|
||||
{
|
||||
rotate = false;
|
||||
}
|
||||
|
||||
osg::Node* node = convertModelToSceneGraph(model,rotate);
|
||||
if (options->getOptionString() == "noTesselateLargePolygons")
|
||||
{
|
||||
noTesselateLargePolygons = true;
|
||||
}
|
||||
|
||||
if (options->getOptionString() == "noTriStripPolygons")
|
||||
{
|
||||
noTesselateLargePolygons = true;
|
||||
}
|
||||
}
|
||||
|
||||
osg::Node* node = convertModelToSceneGraph(model,rotate,
|
||||
noTesselateLargePolygons,noTriStripPolygons);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -155,46 +155,136 @@ bool Model::readMTL(std::istream& fin)
|
||||
{
|
||||
unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
|
||||
|
||||
if (fieldsRead==1) material->ambient.set(r,0.0f,0.0f,1.0f);
|
||||
else if (fieldsRead==2) material->ambient.set(r,g,0.0f,1.0f);
|
||||
else if (fieldsRead==3) material->ambient.set(r,g,b,1.0f);
|
||||
else if (fieldsRead==4) material->ambient.set(r,g,b,a);
|
||||
if (fieldsRead==1)
|
||||
{
|
||||
material->ambient[ 0 ] = r;
|
||||
}
|
||||
else if (fieldsRead==2)
|
||||
{
|
||||
material->ambient[ 0 ] = r;
|
||||
material->ambient[ 1 ] = g;
|
||||
}
|
||||
else if (fieldsRead==3)
|
||||
{
|
||||
material->ambient[ 0 ] = r;
|
||||
material->ambient[ 1 ] = g;
|
||||
material->ambient[ 2 ] = b;
|
||||
}
|
||||
else if (fieldsRead==4)
|
||||
{
|
||||
material->ambient[ 0 ] = r;
|
||||
material->ambient[ 1 ] = g;
|
||||
material->ambient[ 2 ] = b;
|
||||
material->ambient[ 3 ] = a;
|
||||
}
|
||||
}
|
||||
else if (strncmp(line,"Kd ",3)==0)
|
||||
{
|
||||
unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
|
||||
|
||||
if (fieldsRead==1) material->diffuse.set(r,0.0f,0.0f,1.0f);
|
||||
else if (fieldsRead==2) material->diffuse.set(r,g,0.0f,1.0f);
|
||||
else if (fieldsRead==3) material->diffuse.set(r,g,b,1.0f);
|
||||
else if (fieldsRead==4) material->diffuse.set(r,g,b,a);
|
||||
if (fieldsRead==1)
|
||||
{
|
||||
material->diffuse[ 0 ] = r;
|
||||
}
|
||||
else if (fieldsRead==2)
|
||||
{
|
||||
material->diffuse[ 0 ] = r;
|
||||
material->diffuse[ 1 ] = g;
|
||||
}
|
||||
else if (fieldsRead==3)
|
||||
{
|
||||
material->diffuse[ 0 ] = r;
|
||||
material->diffuse[ 1 ] = g;
|
||||
material->diffuse[ 2 ] = b;
|
||||
}
|
||||
else if (fieldsRead==4)
|
||||
{
|
||||
material->diffuse[ 0 ] = r;
|
||||
material->diffuse[ 1 ] = g;
|
||||
material->diffuse[ 2 ] = b;
|
||||
material->diffuse[ 3 ] = a;
|
||||
}
|
||||
}
|
||||
else if (strncmp(line,"Ks ",3)==0)
|
||||
{
|
||||
unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
|
||||
|
||||
if (fieldsRead==1) material->specular.set(r,0.0f,0.0f,1.0f);
|
||||
else if (fieldsRead==2) material->specular.set(r,g,0.0f,1.0f);
|
||||
else if (fieldsRead==3) material->specular.set(r,g,b,1.0f);
|
||||
else if (fieldsRead==4) material->specular.set(r,g,b,a);
|
||||
if (fieldsRead==1)
|
||||
{
|
||||
material->specular[ 0 ] = r;
|
||||
}
|
||||
else if (fieldsRead==2)
|
||||
{
|
||||
material->specular[ 0 ] = r;
|
||||
material->specular[ 1 ] = g;
|
||||
}
|
||||
else if (fieldsRead==3)
|
||||
{
|
||||
material->specular[ 0 ] = r;
|
||||
material->specular[ 1 ] = g;
|
||||
material->specular[ 2 ] = b;
|
||||
}
|
||||
else if (fieldsRead==4)
|
||||
{
|
||||
material->specular[ 0 ] = r;
|
||||
material->specular[ 1 ] = g;
|
||||
material->specular[ 2 ] = b;
|
||||
material->specular[ 3 ] = a;
|
||||
}
|
||||
}
|
||||
else if (strncmp(line,"Ke ",3)==0)
|
||||
{
|
||||
unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
|
||||
|
||||
if (fieldsRead==1) material->emissive.set(r,0.0f,0.0f,1.0f);
|
||||
else if (fieldsRead==2) material->emissive.set(r,g,0.0f,1.0f);
|
||||
else if (fieldsRead==3) material->emissive.set(r,g,b,1.0f);
|
||||
else if (fieldsRead==4) material->emissive.set(r,g,b,a);
|
||||
if (fieldsRead==1)
|
||||
{
|
||||
material->emissive[ 0 ] = r;
|
||||
}
|
||||
else if (fieldsRead==2)
|
||||
{
|
||||
material->emissive[ 0 ] = r;
|
||||
material->emissive[ 1 ] = g;
|
||||
}
|
||||
else if (fieldsRead==3)
|
||||
{
|
||||
material->emissive[ 0 ] = r;
|
||||
material->emissive[ 1 ] = g;
|
||||
material->emissive[ 2 ] = b;
|
||||
}
|
||||
else if (fieldsRead==4)
|
||||
{
|
||||
material->emissive[ 0 ] = r;
|
||||
material->emissive[ 1 ] = g;
|
||||
material->emissive[ 2 ] = b;
|
||||
material->emissive[ 3 ] = a;
|
||||
}
|
||||
}
|
||||
else if (strncmp(line,"Tf ",3)==0)
|
||||
{
|
||||
unsigned int fieldsRead = sscanf(line+3,"%f %f %f %f", &r, &g, &b, &a);
|
||||
|
||||
if (fieldsRead==1) material->Tf.set(r,0.0f,0.0f,1.0f);
|
||||
else if (fieldsRead==2) material->Tf.set(r,g,0.0f,1.0f);
|
||||
else if (fieldsRead==3) material->Tf.set(r,g,b,1.0f);
|
||||
else if (fieldsRead==4) material->Tf.set(r,g,b,a);
|
||||
if (fieldsRead==1)
|
||||
{
|
||||
material->Tf[ 0 ] = r;
|
||||
}
|
||||
else if (fieldsRead==2)
|
||||
{
|
||||
material->Tf[ 0 ] = r;
|
||||
material->Tf[ 1 ] = g;
|
||||
}
|
||||
else if (fieldsRead==3)
|
||||
{
|
||||
material->Tf[ 0 ] = r;
|
||||
material->Tf[ 1 ] = g;
|
||||
material->Tf[ 2 ] = b;
|
||||
}
|
||||
else if (fieldsRead==4)
|
||||
{
|
||||
material->Tf[ 0 ] = r;
|
||||
material->Tf[ 1 ] = g;
|
||||
material->Tf[ 2 ] = b;
|
||||
material->Tf[ 3 ] = a;
|
||||
}
|
||||
}
|
||||
else if (strncmp(line,"sharpness ",10)==0)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user