Merge pull request #770 from rhabacker/3.4-obj-plugin-fixes
obj plugin fixes
This commit is contained in:
commit
b3569882c9
97
examples/osgobjectcache/osgobjectcache.cpp
Normal file
97
examples/osgobjectcache/osgobjectcache.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
/* OpenSceneGraph example, osgobjectcache.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
osg::Group* createObjectCache()
|
||||
{
|
||||
osg::Group* group = new osg::Group();
|
||||
|
||||
if (osgDB::Registry::instance()->getOptions()==0)
|
||||
osgDB::Registry::instance()->setOptions(new osgDB::Options());
|
||||
|
||||
osgDB::Registry::instance()->getOptions()->setObjectCacheHint(osgDB::Options::CACHE_ALL);
|
||||
|
||||
osg::ref_ptr<osgDB::Options> options1 = new osgDB::Options("a=1 b=2 c=3");
|
||||
options1->setObjectCacheHint(osgDB::Options::CACHE_ALL);
|
||||
|
||||
osg::ref_ptr<osgDB::Options> options2 = new osgDB::Options("a=6 b=7 c=8");
|
||||
options2->setObjectCacheHint(osgDB::Options::CACHE_ALL);
|
||||
|
||||
osg::ref_ptr<osgDB::Options> options3 = new osgDB::Options("b=7 a=6 c=8");
|
||||
options3->setObjectCacheHint(osgDB::Options::CACHE_ALL);
|
||||
|
||||
osg::ref_ptr<osg::Node> node1 = osgDB::readRefNodeFile("cessna.osg");
|
||||
osg::ref_ptr<osg::Node> node2 = osgDB::readRefNodeFile("cessna.osg");
|
||||
osg::ref_ptr<osg::Node> node3 = osgDB::readRefNodeFile("cessna.osg", options1.get());
|
||||
osg::ref_ptr<osg::Node> node4 = osgDB::readRefNodeFile("cessna.osg", options2.get());
|
||||
osg::ref_ptr<osg::Node> node5 = osgDB::readRefNodeFile("cessna.osg", options1.get());
|
||||
osg::ref_ptr<osg::Node> node6 = osgDB::readRefNodeFile("cessna.osg", options2.get());
|
||||
osg::ref_ptr<osg::Node> node7 = osgDB::readRefNodeFile("cessna.osg", options3.get());
|
||||
osg::ref_ptr<osg::Node> node8 = osgDB::readRefNodeFile("cessna.osg", options3.get());
|
||||
|
||||
// check that we really get the correct nodes
|
||||
if (node1 != node2)
|
||||
{
|
||||
fprintf(stderr, "error reading node from object cache using default options\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (node3 != node5)
|
||||
{
|
||||
fprintf(stderr, "error reading node from object cache stored with options '%s'\n", options1.get()->getOptionString().c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (node4 != node6)
|
||||
{
|
||||
fprintf(stderr, "error reading node from object cache stored with options '%s'\n", options2.get()->getOptionString().c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (node7 != node8)
|
||||
{
|
||||
fprintf(stderr, "error reading node from object cache stored with options '%s'\n", options3.get()->getOptionString().c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
group->addChild(node1);
|
||||
group->addChild(node2);
|
||||
group->addChild(node3);
|
||||
group->addChild(node4);
|
||||
group->addChild(node5);
|
||||
group->addChild(node6);
|
||||
return group;
|
||||
}
|
||||
|
||||
int main(int , char **)
|
||||
{
|
||||
// construct the viewer.
|
||||
osgViewer::Viewer viewer;
|
||||
|
||||
// add model to viewer.
|
||||
viewer.setSceneData(createObjectCache());
|
||||
|
||||
// create the windows and run the threads.
|
||||
return viewer.run();
|
||||
}
|
@ -50,16 +50,16 @@ class OSGDB_EXPORT ObjectCache : public osg::Referenced
|
||||
void addObjectCache(ObjectCache* object);
|
||||
|
||||
/** Add a filename,object,timestamp triple to the Registry::ObjectCache.*/
|
||||
void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0);
|
||||
void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0, const Options *options = NULL);
|
||||
|
||||
/** Remove Object from cache.*/
|
||||
void removeFromObjectCache(const std::string& fileName);
|
||||
void removeFromObjectCache(const std::string& fileName, const Options *options = NULL);
|
||||
|
||||
/** Get an Object from the object cache*/
|
||||
osg::Object* getFromObjectCache(const std::string& fileName);
|
||||
osg::Object* getFromObjectCache(const std::string& fileName, const Options *options = NULL);
|
||||
|
||||
/** Get an ref_ptr<Object> from the object cache*/
|
||||
osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName);
|
||||
osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName, const Options *options = NULL);
|
||||
|
||||
/** call rleaseGLObjects on all objects attached to the object cache.*/
|
||||
void releaseGLObjects(osg::State* state);
|
||||
@ -68,8 +68,15 @@ class OSGDB_EXPORT ObjectCache : public osg::Referenced
|
||||
|
||||
virtual ~ObjectCache();
|
||||
|
||||
typedef std::pair<std::string, osg::ref_ptr<const osgDB::Options> > FileNameOptionsPair;
|
||||
|
||||
class ClassComp {
|
||||
public:
|
||||
bool operator() (const ObjectCache::FileNameOptionsPair& lhs, const ObjectCache::FileNameOptionsPair& rhs);
|
||||
};
|
||||
|
||||
typedef std::pair<osg::ref_ptr<osg::Object>, double > ObjectTimeStampPair;
|
||||
typedef std::map<std::string, ObjectTimeStampPair > ObjectCacheMap;
|
||||
typedef std::map<FileNameOptionsPair, ObjectTimeStampPair, ClassComp> ObjectCacheMap;
|
||||
|
||||
ObjectCacheMap _objectCache;
|
||||
OpenThreads::Mutex _objectCacheMutex;
|
||||
|
@ -255,10 +255,12 @@ class OSGDB_EXPORT Options : public osg::Object
|
||||
/** Get the parentGroup observer_ptr, where the loaded model is intended to be added */
|
||||
const osg::observer_ptr<osg::Group>& getParentGroup() const { return _parentGroup; }
|
||||
|
||||
protected:
|
||||
|
||||
bool operator < (const Options &rhs) const;
|
||||
bool operator == (const Options &rhs) const;
|
||||
virtual ~Options() {}
|
||||
|
||||
protected:
|
||||
|
||||
std::string _str;
|
||||
FilePathList _databasePaths;
|
||||
|
||||
|
@ -452,16 +452,16 @@ class OSGDB_EXPORT Registry : public osg::Referenced
|
||||
void clearObjectCache();
|
||||
|
||||
/** Add a filename,object,timestamp triple to the Registry::ObjectCache.*/
|
||||
void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0);
|
||||
void addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp = 0.0, Options *options = NULL);
|
||||
|
||||
/** Remove Object from cache.*/
|
||||
void removeFromObjectCache(const std::string& fileName);
|
||||
void removeFromObjectCache(const std::string& fileName, Options *options = NULL);
|
||||
|
||||
/** Get an Object from the object cache*/
|
||||
osg::Object* getFromObjectCache(const std::string& fileName);
|
||||
osg::Object* getFromObjectCache(const std::string& fileName, Options *options = NULL);
|
||||
|
||||
/** Get an ref_ptr<Object> from the object cache*/
|
||||
osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName);
|
||||
osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName, Options *options = NULL);
|
||||
|
||||
|
||||
|
||||
|
@ -12,9 +12,30 @@
|
||||
*/
|
||||
|
||||
#include <osgDB/ObjectCache>
|
||||
#include <osgDB/Options>
|
||||
|
||||
using namespace osgDB;
|
||||
|
||||
bool ObjectCache::ClassComp::operator() (const ObjectCache::FileNameOptionsPair& lhs, const ObjectCache::FileNameOptionsPair& rhs)
|
||||
{
|
||||
// check if filename are the same
|
||||
if (lhs.first < rhs.first) return true;
|
||||
if (rhs.first < lhs.first) return false;
|
||||
|
||||
// check if Options pointers are the same.
|
||||
if (lhs.second == rhs.second) return false;
|
||||
|
||||
// need to compare Options pointers
|
||||
if (lhs.second.valid() && rhs.second.valid())
|
||||
{
|
||||
// lhs & rhs have valid Options objects
|
||||
return *lhs.second < *rhs.second;
|
||||
}
|
||||
|
||||
// finally use pointer comparison, expecting at least one will be NULL pointer
|
||||
return lhs.second < rhs.second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ObjectCache
|
||||
@ -39,34 +60,48 @@ void ObjectCache::addObjectCache(ObjectCache* objectCache)
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock1(_objectCacheMutex);
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock2(objectCache->_objectCacheMutex);
|
||||
|
||||
// OSG_NOTICE<<"Inserting objects to main ObjectCache "<<objectCache->_objectCache.size()<<std::endl;
|
||||
OSG_DEBUG<<"Inserting objects to main ObjectCache "<<objectCache->_objectCache.size()<<std::endl;
|
||||
|
||||
_objectCache.insert(objectCache->_objectCache.begin(), objectCache->_objectCache.end());
|
||||
}
|
||||
|
||||
|
||||
void ObjectCache::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp)
|
||||
void ObjectCache::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp, const Options *options)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
|
||||
_objectCache[filename]=ObjectTimeStampPair(object,timestamp);
|
||||
_objectCache[FileNameOptionsPair(filename, osg::clone(options))] = ObjectTimeStampPair(object,timestamp);
|
||||
OSG_DEBUG<<"Adding "<<filename<<" with options '"<<(options ? options->getOptionString() : "")<<"' to ObjectCache "<<this<<std::endl;
|
||||
}
|
||||
|
||||
osg::Object* ObjectCache::getFromObjectCache(const std::string& fileName)
|
||||
osg::Object* ObjectCache::getFromObjectCache(const std::string& fileName, const Options *options)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
|
||||
ObjectCacheMap::iterator itr = _objectCache.find(fileName);
|
||||
if (itr!=_objectCache.end()) return itr->second.first.get();
|
||||
ObjectCacheMap::iterator itr = _objectCache.find(FileNameOptionsPair(fileName, options));
|
||||
if (itr!=_objectCache.end())
|
||||
{
|
||||
osg::ref_ptr<const osgDB::Options> o = itr->first.second;
|
||||
if (o.valid())
|
||||
OSG_DEBUG<<"Found "<<fileName<<" with options '"<< o->getOptionString()<< "' in ObjectCache "<<this<<std::endl;
|
||||
else
|
||||
OSG_DEBUG<<"Found "<<fileName<<" in ObjectCache "<<this<<std::endl;
|
||||
return itr->second.first.get();
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Object> ObjectCache::getRefFromObjectCache(const std::string& fileName)
|
||||
osg::ref_ptr<osg::Object> ObjectCache::getRefFromObjectCache(const std::string& fileName, const Options *options)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
|
||||
ObjectCacheMap::iterator itr = _objectCache.find(fileName);
|
||||
ObjectCacheMap::iterator itr;
|
||||
itr = _objectCache.find(FileNameOptionsPair(fileName, options));
|
||||
if (itr!=_objectCache.end())
|
||||
{
|
||||
// OSG_NOTICE<<"Found "<<fileName<<" in ObjectCache "<<this<<std::endl;
|
||||
return itr->second.first;
|
||||
osg::ref_ptr<const osgDB::Options> o = itr->first.second;
|
||||
if (o.valid())
|
||||
OSG_DEBUG<<"Found "<<fileName<<" with options '"<< o->getOptionString()<< "' in ObjectCache "<<this<<std::endl;
|
||||
else
|
||||
OSG_DEBUG<<"Found "<<fileName<<" in ObjectCache "<<this<<std::endl;
|
||||
return itr->second.first.get();
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
@ -108,10 +143,10 @@ void ObjectCache::removeExpiredObjectsInCache(double expiryTime)
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectCache::removeFromObjectCache(const std::string& fileName)
|
||||
void ObjectCache::removeFromObjectCache(const std::string& fileName, const Options *options)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
|
||||
ObjectCacheMap::iterator itr = _objectCache.find(fileName);
|
||||
ObjectCacheMap::iterator itr = _objectCache.find(FileNameOptionsPair(fileName, options));
|
||||
if (itr!=_objectCache.end()) _objectCache.erase(itr);
|
||||
}
|
||||
|
||||
|
@ -56,3 +56,17 @@ void Options::parsePluginStringData(const std::string& str, char separator1, cha
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Options::operator <(const Options &rhs) const
|
||||
{
|
||||
// TODO add better compare
|
||||
//OSG_DEBUG << "comparing <'" << _str << "' with '" << rhs._str << "'" << std::endl;
|
||||
return _str.compare(rhs._str) < 0;
|
||||
}
|
||||
|
||||
bool Options::operator ==(const Options &rhs) const
|
||||
{
|
||||
// TODO add better compare
|
||||
//OSG_DEBUG << "comparing == '" << _str << "' with '" << rhs._str << "'" << std::endl;
|
||||
return _str.compare(rhs._str) == 0;
|
||||
}
|
||||
|
@ -1267,9 +1267,9 @@ ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFun
|
||||
if (useObjectCache)
|
||||
{
|
||||
// search for entry in the object cache.
|
||||
osg::ref_ptr<osg::Object> object = optionsCache ? optionsCache->getRefFromObjectCache(file) : 0;
|
||||
osg::ref_ptr<osg::Object> object = optionsCache ? optionsCache->getRefFromObjectCache(file, options) : 0;
|
||||
|
||||
if (!object && _objectCache.valid()) object = _objectCache->getRefFromObjectCache(file);
|
||||
if (!object && _objectCache.valid()) object = _objectCache->getRefFromObjectCache(file, options);
|
||||
|
||||
if (object.valid())
|
||||
{
|
||||
@ -1281,7 +1281,7 @@ ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFun
|
||||
if (rr.validObject())
|
||||
{
|
||||
// search AGAIN for entry in the object cache.
|
||||
object = _objectCache->getRefFromObjectCache(file);
|
||||
object = _objectCache->getRefFromObjectCache(file, options);
|
||||
if (object.valid())
|
||||
{
|
||||
if (readFunctor.isValid(object.get())) return ReaderWriter::ReadResult(object.get(), ReaderWriter::ReadResult::FILE_LOADED_FROM_CACHE);
|
||||
@ -1292,8 +1292,8 @@ ReaderWriter::ReadResult Registry::readImplementation(const ReadFunctor& readFun
|
||||
}
|
||||
|
||||
// update cache with new entry.
|
||||
if (optionsCache) optionsCache->addEntryToObjectCache(file, rr.getObject(), 0.0);
|
||||
else if (_objectCache.valid()) _objectCache->addEntryToObjectCache(file, rr.getObject(), 0.0);
|
||||
if (optionsCache) optionsCache->addEntryToObjectCache(file, rr.getObject(), 0.0, options);
|
||||
else if (_objectCache.valid()) _objectCache->addEntryToObjectCache(file, rr.getObject(), 0.0, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1673,19 +1673,19 @@ ReaderWriter::WriteResult Registry::writeScriptImplementation(const Script& imag
|
||||
return result;
|
||||
}
|
||||
|
||||
void Registry::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp)
|
||||
void Registry::addEntryToObjectCache(const std::string& filename, osg::Object* object, double timestamp, Options *options)
|
||||
{
|
||||
if (_objectCache.valid()) _objectCache->addEntryToObjectCache(filename, object, timestamp);
|
||||
if (_objectCache.valid()) _objectCache->addEntryToObjectCache(filename, object, timestamp, options);
|
||||
}
|
||||
|
||||
osg::Object* Registry::getFromObjectCache(const std::string& filename)
|
||||
osg::Object* Registry::getFromObjectCache(const std::string& filename, Options *options)
|
||||
{
|
||||
return _objectCache.valid() ? _objectCache->getFromObjectCache(filename) : 0;
|
||||
return _objectCache.valid() ? _objectCache->getFromObjectCache(filename, options) : 0;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Object> Registry::getRefFromObjectCache(const std::string& filename)
|
||||
osg::ref_ptr<osg::Object> Registry::getRefFromObjectCache(const std::string& filename, Options *options)
|
||||
{
|
||||
return _objectCache.valid() ? _objectCache->getRefFromObjectCache(filename) : 0;
|
||||
return _objectCache.valid() ? _objectCache->getRefFromObjectCache(filename, options) : 0;
|
||||
}
|
||||
|
||||
void Registry::updateTimeStampOfObjectsInCacheWithExternalReferences(const osg::FrameStamp& frameStamp)
|
||||
@ -1699,9 +1699,9 @@ void Registry::removeExpiredObjectsInCache(const osg::FrameStamp& frameStamp)
|
||||
if (_objectCache.valid()) _objectCache->removeExpiredObjectsInCache(expiryTime);
|
||||
}
|
||||
|
||||
void Registry::removeFromObjectCache(const std::string& filename)
|
||||
void Registry::removeFromObjectCache(const std::string& filename, Options *options)
|
||||
{
|
||||
if (_objectCache.valid()) _objectCache->removeFromObjectCache(filename);
|
||||
if (_objectCache.valid()) _objectCache->removeFromObjectCache(filename, options);
|
||||
}
|
||||
|
||||
void Registry::clearObjectCache()
|
||||
|
@ -370,7 +370,7 @@ void ObjPrimitiveIndexWriter::drawArrays(GLenum mode,GLint first,GLsizei count)
|
||||
|
||||
for(GLsizei i=0;i<count;++i)
|
||||
{
|
||||
writePoint(i);
|
||||
writePoint(first + i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -379,7 +379,7 @@ void ObjPrimitiveIndexWriter::drawArrays(GLenum mode,GLint first,GLsizei count)
|
||||
{
|
||||
for(GLsizei i=0;i<count;i+=2)
|
||||
{
|
||||
writeLine(i, i+1);
|
||||
writeLine(first + i, first + i+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -387,7 +387,7 @@ void ObjPrimitiveIndexWriter::drawArrays(GLenum mode,GLint first,GLsizei count)
|
||||
{
|
||||
for(GLsizei i=1;i<count;++i)
|
||||
{
|
||||
writeLine(i-1, i);
|
||||
writeLine(first + i-1, first + i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -395,9 +395,9 @@ void ObjPrimitiveIndexWriter::drawArrays(GLenum mode,GLint first,GLsizei count)
|
||||
{
|
||||
for(GLsizei i=1;i<count;++i)
|
||||
{
|
||||
writeLine(i-1, i);
|
||||
writeLine(first + i-1, first + i);
|
||||
}
|
||||
writeLine(count-1, 0);
|
||||
writeLine(first + count-1, first + 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -411,6 +411,7 @@ OBJWriterNodeVisitor::OBJMaterial::OBJMaterial(osg::Material* mat, osg::Texture*
|
||||
diffuse(1,1,1,1),
|
||||
ambient(0.2,0.2,0.2,1),
|
||||
specular(0,0,0,1),
|
||||
shininess(-1),
|
||||
image("")
|
||||
{
|
||||
static unsigned int s_objmaterial_id = 0;
|
||||
@ -423,6 +424,7 @@ OBJWriterNodeVisitor::OBJMaterial::OBJMaterial(osg::Material* mat, osg::Texture*
|
||||
diffuse = mat->getDiffuse(osg::Material::FRONT);
|
||||
ambient = mat->getAmbient(osg::Material::FRONT);
|
||||
specular = mat->getSpecular(osg::Material::FRONT);
|
||||
shininess = mat->getShininess(osg::Material::FRONT)*1000.0f/128.0f;
|
||||
}
|
||||
|
||||
if (tex) {
|
||||
@ -440,6 +442,8 @@ std::ostream& operator<<(std::ostream& fout, const OBJWriterNodeVisitor::OBJMate
|
||||
fout << " " << "Ka " << mat.ambient << std::endl;
|
||||
fout << " " << "Kd " << mat.diffuse << std::endl;
|
||||
fout << " " << "Ks " << mat.specular << std::endl;
|
||||
if (mat.shininess != -1)
|
||||
fout << " " << "Ns " << mat.shininess<< std::endl;
|
||||
|
||||
if(!mat.image.empty())
|
||||
fout << " " << "map_Kd " << mat.image << std::endl;
|
||||
|
@ -116,6 +116,7 @@ class OBJWriterNodeVisitor: public osg::NodeVisitor {
|
||||
OBJMaterial(osg::Material* mat, osg::Texture* tex);
|
||||
|
||||
osg::Vec4 diffuse, ambient, specular;
|
||||
float shininess;
|
||||
std::string image;
|
||||
std::string name;
|
||||
};
|
||||
|
@ -71,6 +71,7 @@ public:
|
||||
supportsOption("BUMP=<unit>", "Set texture unit for bumpmap texture");
|
||||
supportsOption("DISPLACEMENT=<unit>", "Set texture unit for displacement texture");
|
||||
supportsOption("REFLECTION=<unit>", "Set texture unit for reflection texture");
|
||||
supportsOption("NsIfNotPresent=<value>", "set specular exponent if not present");
|
||||
|
||||
}
|
||||
|
||||
@ -133,7 +134,8 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
struct ObjOptionsStruct {
|
||||
class ObjOptionsStruct {
|
||||
public:
|
||||
bool rotate;
|
||||
bool noTesselateLargePolygons;
|
||||
bool noTriStripPolygons;
|
||||
@ -144,6 +146,18 @@ protected:
|
||||
// otherwise overriden
|
||||
typedef std::vector< std::pair<int,obj::Material::Map::TextureMapType> > TextureAllocationMap;
|
||||
TextureAllocationMap textureUnitAllocation;
|
||||
int specularExponent;
|
||||
|
||||
ObjOptionsStruct()
|
||||
{
|
||||
rotate = true;
|
||||
noTesselateLargePolygons = false;
|
||||
noTriStripPolygons = false;
|
||||
generateFacetNormals = false;
|
||||
fixBlackMaterials = true;
|
||||
noReverseFaces = false;
|
||||
specularExponent = -1;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map< std::string, osg::ref_ptr<osg::StateSet> > MaterialToStateSetMap;
|
||||
@ -333,12 +347,13 @@ void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToSt
|
||||
osg_material->setDiffuse(osg::Material::FRONT_AND_BACK,material.diffuse);
|
||||
osg_material->setEmission(osg::Material::FRONT_AND_BACK,material.emissive);
|
||||
|
||||
if (material.illum == 2) {
|
||||
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.
|
||||
int ns = material.Ns != -1 ? material.Ns : localOptions.specularExponent != -1 ? localOptions.specularExponent : 0;
|
||||
osg_material->setShininess(osg::Material::FRONT_AND_BACK,(ns/1000.0f)*128.0f ); // note OBJ shiniess is 0..1000.
|
||||
|
||||
if (material.ambient[3]!=1.0 ||
|
||||
material.diffuse[3]!=1.0 ||
|
||||
@ -820,12 +835,6 @@ osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model, ObjOptio
|
||||
ReaderWriterOBJ::ObjOptionsStruct ReaderWriterOBJ::parseOptions(const osgDB::ReaderWriter::Options* options) const
|
||||
{
|
||||
ObjOptionsStruct localOptions;
|
||||
localOptions.rotate = true;
|
||||
localOptions.noTesselateLargePolygons = false;
|
||||
localOptions.noTriStripPolygons = false;
|
||||
localOptions.generateFacetNormals = false;
|
||||
localOptions.fixBlackMaterials = true;
|
||||
localOptions.noReverseFaces = false;
|
||||
|
||||
if (options!=NULL)
|
||||
{
|
||||
@ -868,6 +877,11 @@ ReaderWriterOBJ::ObjOptionsStruct ReaderWriterOBJ::parseOptions(const osgDB::Rea
|
||||
{
|
||||
localOptions.noReverseFaces = true;
|
||||
}
|
||||
else if (pre_equals == "NsIfNotPresent")
|
||||
{
|
||||
int value = atoi(post_equals.c_str());
|
||||
localOptions.specularExponent = value ;
|
||||
}
|
||||
else if (post_equals.length()>0)
|
||||
{
|
||||
obj::Material::Map::TextureMapType type = obj::Material::Map::UNKNOWN;
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
illum(2),
|
||||
Tf(0.0f,0.0f,0.0f,1.0f),
|
||||
Ni(0),
|
||||
Ns(0),
|
||||
Ns(-1),
|
||||
// textureReflection(false),
|
||||
alpha(1.0f) {}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user