From 74f7ffcd32e96f088e89ca3898e22d2de9774ec6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 19 Nov 2009 12:54:52 +0000 Subject: [PATCH] From Ulrich Hertlein, "ttached are some tweaks to the Obj loader that allows a program supplied osgDB::Options object to be passed through the code. This allows for caching to be used with images. The patched loader also complains more loudly if a material library file wasn't found or if a referenced material wasn't found in the material library." --- src/osgPlugins/obj/ReaderWriterOBJ.cpp | 39 +++++++++++++++----------- src/osgPlugins/obj/obj.cpp | 12 ++++++-- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/osgPlugins/obj/ReaderWriterOBJ.cpp b/src/osgPlugins/obj/ReaderWriterOBJ.cpp index 4d6f67c19..ace791c08 100644 --- a/src/osgPlugins/obj/ReaderWriterOBJ.cpp +++ b/src/osgPlugins/obj/ReaderWriterOBJ.cpp @@ -146,11 +146,11 @@ protected: typedef std::map< std::string, osg::ref_ptr > MaterialToStateSetMap; - void buildMaterialToStateSetMap(obj::Model& model, MaterialToStateSetMap& materialToSetSetMapObj, ObjOptionsStruct& localOptions) const; + void buildMaterialToStateSetMap(obj::Model& model, MaterialToStateSetMap& materialToSetSetMapObj, ObjOptionsStruct& localOptions, const Options* options) const; osg::Geometry* convertElementListToGeometry(obj::Model& model, obj::Model::ElementList& elementList, ObjOptionsStruct& localOptions) const; - osg::Node* convertModelToSceneGraph(obj::Model& model, ObjOptionsStruct& localOptions) const; + osg::Node* convertModelToSceneGraph(obj::Model& model, ObjOptionsStruct& localOptions, const Options* options) 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 ; @@ -191,7 +191,8 @@ REGISTER_OSGPLUGIN(obj, ReaderWriterOBJ) static void load_material_texture( obj::Model &model, obj::Material::Map &map, osg::StateSet *stateset, - const unsigned int texture_unit ) + const unsigned int texture_unit, + const osgDB::Options* options) { std::string filename = map.name; if (!filename.empty()) @@ -200,13 +201,13 @@ static void load_material_texture( obj::Model &model, if ( !model.getDatabasePath().empty() ) { // first try with database path of parent. - image = osgDB::readRefImageFile(model.getDatabasePath()+'/'+filename); + image = osgDB::readRefImageFile(model.getDatabasePath()+'/'+filename, options); } if ( !image.valid() ) { // if not already set then try the filename as is. - image = osgDB::readRefImageFile(filename); + image = osgDB::readRefImageFile(filename, options); } if ( image.valid() ) @@ -268,7 +269,7 @@ static void load_material_texture( obj::Model &model, } -void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToStateSetMap& materialToStateSetMap, ObjOptionsStruct& localOptions) const +void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToStateSetMap& materialToStateSetMap, ObjOptionsStruct& localOptions, const Options* options) const { if (localOptions.fixBlackMaterials) { @@ -366,7 +367,7 @@ void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToSt break; } } - if(index>=0) load_material_texture( model, material.maps[index], stateset.get(), unit ); + if(index>=0) load_material_texture( model, material.maps[index], stateset.get(), unit, options ); } } // If the user has set no options, then we load them up in the order contained in the enum. This @@ -389,7 +390,7 @@ void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToSt } if(index>=0) { - load_material_texture( model, material.maps[index], stateset.get(), unit ); + load_material_texture( model, material.maps[index], stateset.get(), unit, options ); unit++; } } @@ -700,7 +701,7 @@ osg::Geometry* ReaderWriterOBJ::convertElementListToGeometry(obj::Model& model, return geometry; } -osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model, ObjOptionsStruct& localOptions) const +osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model, ObjOptionsStruct& localOptions, const Options* options) const { if (model.elementStateMap.empty()) return 0; @@ -708,8 +709,8 @@ osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model, ObjOptio osg::Group* group = new osg::Group; // set up the materials - MaterialToStateSetMap materialToSetSetMap; - buildMaterialToStateSetMap(model, materialToSetSetMap, localOptions); + MaterialToStateSetMap materialToStateSetMap; + buildMaterialToStateSetMap(model, materialToStateSetMap, localOptions, options); // go through the groups of related elements and build geometry from them. for(obj::Model::ElementStateMap::iterator itr=model.elementStateMap.begin(); @@ -724,8 +725,13 @@ osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model, ObjOptio if (geometry) { + MaterialToStateSetMap::const_iterator it = materialToStateSetMap.find(es.materialName); + if (it == materialToStateSetMap.end()) + { + osg::notify(osg::WARN) << "Obj unable to find material '" << es.materialName << "'" << std::endl; + } - osg::StateSet* stateset = materialToSetSetMap[es.materialName].get(); + osg::StateSet* stateset = materialToStateSetMap[es.materialName].get(); geometry->setStateSet(stateset); // tesseleate any large polygons @@ -867,11 +873,10 @@ osgDB::ReaderWriter::ReadResult ReaderWriterOBJ::readNode(const std::string& fil obj::Model model; model.setDatabasePath(osgDB::getFilePath(fileName.c_str())); model.readOBJ(fin, local_opt.get()); - + ObjOptionsStruct localOptions = parseOptions(options); - - - osg::Node* node = convertModelToSceneGraph(model,localOptions); + + osg::Node* node = convertModelToSceneGraph(model, localOptions, options); return node; } @@ -887,7 +892,7 @@ osgDB::ReaderWriter::ReadResult ReaderWriterOBJ::readNode(std::istream& fin, con ObjOptionsStruct localOptions = parseOptions(options); - osg::Node* node = convertModelToSceneGraph(model, localOptions); + osg::Node* node = convertModelToSceneGraph(model, localOptions, options); return node; } diff --git a/src/osgPlugins/obj/obj.cpp b/src/osgPlugins/obj/obj.cpp index aa73b7b0d..4fa96eceb 100644 --- a/src/osgPlugins/obj/obj.cpp +++ b/src/osgPlugins/obj/obj.cpp @@ -645,16 +645,22 @@ bool Model::readOBJ(std::istream& fin, const osgDB::ReaderWriter::Options* optio { std::string materialFileName = trim( line+7 ); std::string fullPathFileName = osgDB::findDataFile( materialFileName, options ); - osg::notify(osg::INFO) << "--" << line+7 << "--" << std::endl; - osg::notify(osg::INFO) << "--" << materialFileName << "--" << std::endl; - osg::notify(osg::INFO) << "--" << fullPathFileName << "--" << std::endl; if (!fullPathFileName.empty()) { osgDB::ifstream mfin( fullPathFileName.c_str() ); if (mfin) { + osg::notify(osg::INFO) << "Obj reading mtllib '" << fullPathFileName << "'\n"; readMTL(mfin); } + else + { + osg::notify(osg::WARN) << "Obj unable to load mtllib '" << fullPathFileName << "'\n"; + } + } + else + { + osg::notify(osg::WARN) << "Obj unable to find mtllib '" << materialFileName << "'\n"; } } else if (strncmp(line,"o ",2)==0)