From Auelien Albert, "I'm working on an application which use 3ds file format as input and use the name of the material to "map" specific data with 3d geometry.
The osg 3ds plugin modify the exported materials name in the same way it modifies the node names. I've added an option to preserve originals materials names, with the assurance of unique material names are preserved." git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14283 16af8721-9629-0410-8352-f15c8da7e697
This commit is contained in:
parent
a2db511c99
commit
aac0a5fbe2
@ -238,6 +238,7 @@ ReaderWriter3DS::ReaderWriter3DS()
|
||||
//supportsOption("OutputTextureFiles","Write out the texture images to file");
|
||||
//supportsOption("flipTexture", "flip texture upside-down");
|
||||
supportsOption("extended3dsFilePaths", "(Write option) Keeps long texture filenames (not 8.3) when exporting 3DS, but can lead to compatibility problems.");
|
||||
supportsOption("preserveMaterialNames", "(Write option) Preserve original material names, up to 64 characters. This can lead to compatibility problems.");
|
||||
supportsOption("noMatrixTransforms", "(Read option) Set the plugin to apply matrices into the mesh vertices (\"old behaviour\") instead of restoring them (\"new behaviour\"). You may use this option to avoid a few rounding errors.");
|
||||
supportsOption("checkForEspilonIdentityMatrices", "(Read option) If not set, then consider \"almost identity\" matrices to be identity ones (in case of rounding errors).");
|
||||
supportsOption("restoreMatrixTransformsNoMeshes", "(Read option) Makes an exception to the behaviour when 'noMatrixTransforms' is not set for mesh instances. When a mesh instance has a transform on it, the reader creates a MatrixTransform above the Geode. If you don't want the hierarchy to be modified, then you can use this option to merge the transform into vertices.");
|
||||
|
@ -360,7 +360,7 @@ void PrimitiveIndexWriter::drawArrays(GLenum mode,GLint first,GLsizei count)
|
||||
|
||||
|
||||
|
||||
WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg::StateSet * stateset, osg::Material* mat, osg::Texture* tex, int index) :
|
||||
WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg::StateSet * stateset, osg::Material* mat, osg::Texture* tex, bool preserveName, int index) :
|
||||
index(index),
|
||||
diffuse(1,1,1,1),
|
||||
ambient(0.2,0.2,0.2,1),
|
||||
@ -387,7 +387,14 @@ WriterNodeVisitor::Material::Material(WriterNodeVisitor & writerNodeVisitor, osg
|
||||
//shininess = mat->getShininess(osg::Material::FRONT) <= 0 ? 0 : log( mat->getShininess(osg::Material::FRONT) ) / log(2.f) / 10.f;
|
||||
|
||||
transparency = 1-diffuse.w();
|
||||
name = writerNodeVisitor.getUniqueName(mat->getName(),true,"mat");
|
||||
if (preserveName == false)
|
||||
{
|
||||
name = writerNodeVisitor.getUniqueName(mat->getName(),true,"mat");
|
||||
}
|
||||
else
|
||||
{
|
||||
name = writerNodeVisitor.getMaterialName(mat->getName());
|
||||
}
|
||||
osg::StateAttribute * attribute = stateset->getAttribute(osg::StateAttribute::CULLFACE);
|
||||
if (!attribute)
|
||||
{
|
||||
@ -458,7 +465,8 @@ WriterNodeVisitor::WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & f
|
||||
_cur3dsNode(NULL),
|
||||
_options(options),
|
||||
_imageCount(0),
|
||||
_extendedFilePaths(false)
|
||||
_extendedFilePaths(false),
|
||||
_preserveMaterialNames(false)
|
||||
{
|
||||
if (!fileName.empty())
|
||||
_directory = options->getDatabasePathList().empty() ? osgDB::getFilePath(fileName) : options->getDatabasePathList().front();
|
||||
@ -471,6 +479,8 @@ WriterNodeVisitor::WriterNodeVisitor(Lib3dsFile * file3ds, const std::string & f
|
||||
{
|
||||
if (opt == "extended3dsFilePaths" || opt == "extended3DSFilePaths")
|
||||
_extendedFilePaths = true;
|
||||
if (opt == "preserveMaterialNames")
|
||||
_preserveMaterialNames = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -717,6 +727,53 @@ std::string WriterNodeVisitor::getUniqueName(const std::string& _defaultValue, b
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
std::string WriterNodeVisitor::getMaterialName(const std::string& inputMaterialName)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
// Search in map if this material name already exists
|
||||
MaterialNameMap::const_iterator mapIter=_materialNameMap.find(inputMaterialName);
|
||||
|
||||
if (mapIter!=_materialNameMap.end())
|
||||
{
|
||||
// Found, use it !
|
||||
result = mapIter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not found, create a new (unique) entry mapped to this material name
|
||||
std::string resultPrefix = inputMaterialName.substr(0, 60); // Up to 64 characters : truncate to 60 characters : 60 + "_" + number
|
||||
result = resultPrefix;
|
||||
|
||||
NameMap::const_iterator setIter=_materialNameSet.find(result);
|
||||
int suffixValue=-1;
|
||||
while (setIter!=_materialNameSet.end())
|
||||
{
|
||||
if (suffixValue < 0)
|
||||
{
|
||||
// First add of the suffix
|
||||
resultPrefix = resultPrefix + "_";
|
||||
suffixValue++;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << resultPrefix << suffixValue;
|
||||
|
||||
result = ss.str();
|
||||
|
||||
setIter=_materialNameSet.find(result);
|
||||
suffixValue++;
|
||||
}
|
||||
|
||||
// Add entry in map
|
||||
_materialNameMap[inputMaterialName] = result;
|
||||
}
|
||||
|
||||
std::cout << "getMaterialName : " << inputMaterialName << " => " << result << std::endl;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int WriterNodeVisitor::processStateSet(osg::StateSet* ss)
|
||||
{
|
||||
MaterialMap::const_iterator itr = _materialMap.find(ss);
|
||||
@ -732,7 +789,7 @@ int WriterNodeVisitor::processStateSet(osg::StateSet* ss)
|
||||
if (mat || tex)
|
||||
{
|
||||
int matNum = _lastMaterialIndex;
|
||||
_materialMap.insert(std::make_pair(osg::ref_ptr<osg::StateSet>(ss), Material(*this, ss, mat, tex, matNum) ));
|
||||
_materialMap.insert(std::make_pair(osg::ref_ptr<osg::StateSet>(ss), Material(*this, ss, mat, tex, _preserveMaterialNames, matNum) ));
|
||||
++_lastMaterialIndex;
|
||||
return matNum;
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ class WriterNodeVisitor: public osg::NodeVisitor
|
||||
///\todo Add support for 2nd texture, opacity_map, bump_map, specular_map, shininess_map, self_illum_map, reflection_map.
|
||||
class Material {
|
||||
public:
|
||||
Material(WriterNodeVisitor & writerNodeVisitor, osg::StateSet * stateset, osg::Material* mat, osg::Texture* tex, int index=-1);
|
||||
Material(WriterNodeVisitor & writerNodeVisitor, osg::StateSet * stateset, osg::Material* mat, osg::Texture* tex, bool preserveName, int index=-1);
|
||||
|
||||
int index; ///< Index in the 3DS file
|
||||
osg::Vec4 diffuse, ambient, specular;
|
||||
@ -191,6 +191,7 @@ class WriterNodeVisitor: public osg::NodeVisitor
|
||||
int processStateSet(osg::StateSet* stateset);
|
||||
|
||||
std::string getUniqueName(const std::string& defaultvalue, bool isNodeName, const std::string & defaultPrefix = "", int currentPrefixLen = -1);
|
||||
std::string getMaterialName(const std::string& inputMaterialName);
|
||||
std::string export3DSTexture(const osg::Image * image, const std::string & fileName);
|
||||
|
||||
typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack;
|
||||
@ -210,6 +211,9 @@ class WriterNodeVisitor: public osg::NodeVisitor
|
||||
typedef std::set<std::string> NameMap;
|
||||
NameMap _nodeNameMap;
|
||||
NameMap _imageNameMap;
|
||||
typedef std::map<std::string, std::string> MaterialNameMap;
|
||||
MaterialNameMap _materialNameMap;
|
||||
NameMap _materialNameSet;
|
||||
MaterialMap _materialMap;
|
||||
unsigned int _lastMaterialIndex;
|
||||
unsigned int _lastMeshIndex;
|
||||
@ -217,6 +221,7 @@ class WriterNodeVisitor: public osg::NodeVisitor
|
||||
const osgDB::ReaderWriter::Options* _options;
|
||||
unsigned int _imageCount;
|
||||
bool _extendedFilePaths;
|
||||
bool _preserveMaterialNames;
|
||||
typedef std::map<osg::Image*, std::string> ImageSet;
|
||||
ImageSet _imageSet; ///< Map used to avoid renaming and writing twice an image
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user