From 4ca61c38f0b87b90cebfedd7f7719ee8d3945b09 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 12 Jul 2008 12:00:58 +0000 Subject: [PATCH] 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" --- src/osgPlugins/obj/ReaderWriterOBJ.cpp | 96 +++++++++++++----- src/osgPlugins/obj/obj.cpp | 130 +++++++++++++++++++++---- 2 files changed, 184 insertions(+), 42 deletions(-) diff --git a/src/osgPlugins/obj/ReaderWriterOBJ.cpp b/src/osgPlugins/obj/ReaderWriterOBJ.cpp index 1c407ece2..403ccd780 100644 --- a/src/osgPlugins/obj/ReaderWriterOBJ.cpp +++ b/src/osgPlugins/obj/ReaderWriterOBJ.cpp @@ -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"<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 - osgUtil::Tessellator tessellator; - tessellator.retessellatePolygons(*geometry); - + if (!noTesselateLargePolygons) + { + osgUtil::Tessellator tessellator; + tessellator.retessellatePolygons(*geometry); + } + // tri strip polygons to improve graphics peformance - osgUtil::TriStripVisitor tsv; - tsv.stripify(*geometry); - + 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) { - rotate = false; + if (options->getOptionString() == "noRotation") + { + rotate = false; + } + + if (options->getOptionString() == "noTesselateLargePolygons") + { + noTesselateLargePolygons = true; + } + + if (options->getOptionString() == "noTriStripPolygons") + { + noTesselateLargePolygons = true; + } } - - osg::Node* node = convertModelToSceneGraph(model,rotate); + + 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) { - rotate = false; + if (options->getOptionString() == "noRotation") + { + rotate = false; + } + + if (options->getOptionString() == "noTesselateLargePolygons") + { + noTesselateLargePolygons = true; + } + + if (options->getOptionString() == "noTriStripPolygons") + { + noTesselateLargePolygons = true; + } } - - osg::Node* node = convertModelToSceneGraph(model,rotate); + + osg::Node* node = convertModelToSceneGraph(model,rotate, + noTesselateLargePolygons,noTriStripPolygons); return node; } diff --git a/src/osgPlugins/obj/obj.cpp b/src/osgPlugins/obj/obj.cpp index 39cd6a0ea..8e4d90a28 100644 --- a/src/osgPlugins/obj/obj.cpp +++ b/src/osgPlugins/obj/obj.cpp @@ -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) {