From Sukender, I wrapped my change about non-empty texture units in an off-by-default option, so that it doesn't break any existing code. But AFAIK, other readers (except OSGx) generate contiguous texture units, so I guess this option to be useful for users.
Other changes in this sumbission include the added ability to tessellate polygons in Collada reader, with appropriate options. - No tessellation - Tessellate as triangle fan (previous behaviour, kept as default for backward-compatibility) - Full tessellation I also put auto_ptr<> for RAII of DAE structure (as discussed), and moved reader options in a structure, as for the writer. Code also make use of osgDB::ExternalFileWriter I submitted, so please merge this submission after the PluginImageWriter one.
This commit is contained in:
parent
b1d3763510
commit
c44ef1bfd9
@ -41,9 +41,28 @@ ReaderWriterDAE::readNode(const std::string& fname,
|
||||
bool bOwnDAE = false;
|
||||
DAE* pDAE = NULL;
|
||||
|
||||
if ( options )
|
||||
// Process options
|
||||
osgDAE::daeReader::Options pluginOptions;
|
||||
if( options )
|
||||
{
|
||||
pDAE = (DAE*)options->getPluginData("DAE");
|
||||
|
||||
pluginOptions.precisionHint = options->getPrecisionHint();
|
||||
|
||||
std::istringstream iss( options->getOptionString() );
|
||||
std::string opt;
|
||||
while (iss >> opt)
|
||||
{
|
||||
if( opt == "StrictTransparency") pluginOptions.strictTransparency = true;
|
||||
else if (opt == "daeTessellateNone") pluginOptions.tessellateMode = osgDAE::daeReader::TESSELLATE_NONE;
|
||||
else if (opt == "daeTessellatePolygonsAsTriFans") pluginOptions.tessellateMode = osgDAE::daeReader::TESSELLATE_POLYGONS_AS_TRIFAN;
|
||||
else if (opt == "daeTessellatePolygons") pluginOptions.tessellateMode = osgDAE::daeReader::TESSELLATE_POLYGONS;
|
||||
else if (opt == "daeUsePredefinedTextureUnits") pluginOptions.usePredefinedTextureUnits = true;
|
||||
else if (opt == "daeUseSequencedTextureUnits") pluginOptions.usePredefinedTextureUnits = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string ext( osgDB::getLowerCaseFileExtension(fname) );
|
||||
if( ! acceptsExtension(ext) ) return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
@ -57,10 +76,9 @@ ReaderWriterDAE::readNode(const std::string& fname,
|
||||
bOwnDAE = true;
|
||||
pDAE = new DAE;
|
||||
}
|
||||
std::auto_ptr<DAE> scopedDae(bOwnDAE ? pDAE : NULL); // Deallocates locally created structure at scope exit
|
||||
|
||||
osgDAE::daeReader daeReader(pDAE,
|
||||
options && options->getOptionString().find("StrictTransparency") != std::string::npos,
|
||||
options ? options->getPrecisionHint() : 0 ) ;
|
||||
osgDAE::daeReader daeReader(pDAE, &pluginOptions);
|
||||
|
||||
// Convert file name to URI
|
||||
std::string fileURI = ConvertFilePathToColladaCompatibleURI(fileName);
|
||||
@ -85,9 +103,6 @@ ReaderWriterDAE::readNode(const std::string& fname,
|
||||
*(domUpAxisType*)options->getPluginData("DAE-AssetUp_axis") = daeReader.getAssetUpAxis();
|
||||
}
|
||||
|
||||
if (bOwnDAE)
|
||||
delete pDAE;
|
||||
|
||||
osg::Node* rootNode( daeReader.getRootNode() );
|
||||
return rootNode;
|
||||
}
|
||||
@ -107,14 +122,7 @@ ReaderWriterDAE::writeNode( const osg::Node& node,
|
||||
if( ! acceptsExtension(ext) ) return WriteResult::FILE_NOT_HANDLED;
|
||||
|
||||
// Process options
|
||||
bool usePolygon(false); // Use plugin option "polygon" to enable
|
||||
bool googleMode(false); // Use plugin option "GoogleMode" to enable
|
||||
bool writeExtras(true); // Use plugin option "NoExtras" to disable
|
||||
bool earthTex(false); // Use plugin option "daeEarthTex" to enable
|
||||
bool zUpAxis(false); // Use plugin option "daeZUpAxis" to enable
|
||||
bool linkOrignialTextures(false);
|
||||
bool forceTexture(false);
|
||||
bool namesUseCodepage(false);
|
||||
osgDAE::daeWriter::Options pluginOptions;
|
||||
std::string srcDirectory( osgDB::getFilePath(node.getName().empty() ? fname : node.getName()) ); // Base dir when relativising images paths
|
||||
if( options )
|
||||
{
|
||||
@ -123,6 +131,12 @@ ReaderWriterDAE::writeNode( const osg::Node& node,
|
||||
const std::string & baseDir = options->getPluginStringData("baseImageDir"); // Rename "srcModelPath" (and call getFilePath() on it)?
|
||||
if (!baseDir.empty()) srcDirectory = baseDir;
|
||||
|
||||
const std::string & relativiseImagesPathNbUpDirs = options->getPluginStringData("DAE-relativiseImagesPathNbUpDirs");
|
||||
if (!relativiseImagesPathNbUpDirs.empty()) {
|
||||
std::istringstream iss(relativiseImagesPathNbUpDirs);
|
||||
iss >> pluginOptions.relativiseImagesPathNbUpDirs;
|
||||
}
|
||||
|
||||
// Sukender's note: I don't know why DAE seems to accept comma-sparated options instead of space-separated options as other ReaderWriters. However, to avoid breaking compatibility, here's a workaround:
|
||||
std::string optString( options->getOptionString() );
|
||||
for(std::string::iterator it=optString.begin(); it!=optString.end(); ++it) {
|
||||
@ -134,14 +148,14 @@ ReaderWriterDAE::writeNode( const osg::Node& node,
|
||||
//while (iss >> opt)
|
||||
while( std::getline( iss, opt, ',' ) )
|
||||
{
|
||||
if( opt == "polygon") usePolygon = true;
|
||||
else if (opt == "GoogleMode") googleMode = true;
|
||||
else if (opt == "NoExtras") writeExtras = false;
|
||||
else if (opt == "daeEarthTex") earthTex = true;
|
||||
else if (opt == "daeZUpAxis") zUpAxis = true;
|
||||
else if (opt == "daeLinkOriginalTexturesNoForce") { linkOrignialTextures = true; forceTexture = false; }
|
||||
else if (opt == "daeLinkOriginalTexturesForce") { linkOrignialTextures = true; forceTexture = true; }
|
||||
else if (opt == "daeNamesUseCodepage") namesUseCodepage = true;
|
||||
if( opt == "polygon") pluginOptions.usePolygons = true;
|
||||
else if (opt == "GoogleMode") pluginOptions.googleMode = true;
|
||||
else if (opt == "NoExtras") pluginOptions.writeExtras = false;
|
||||
else if (opt == "daeEarthTex") pluginOptions.earthTex = true;
|
||||
else if (opt == "daeZUpAxis") {} // Nothing (old option)
|
||||
else if (opt == "daeLinkOriginalTexturesNoForce") { pluginOptions.linkOrignialTextures = true; pluginOptions.forceTexture = false; }
|
||||
else if (opt == "daeLinkOriginalTexturesForce") { pluginOptions.linkOrignialTextures = true; pluginOptions.forceTexture = true; }
|
||||
else if (opt == "daeNamesUseCodepage") pluginOptions.namesUseCodepage = true;
|
||||
else if (!opt.empty())
|
||||
{
|
||||
OSG_NOTICE << std::endl << "COLLADA dae plugin: unrecognized option \"" << opt << std::endl;
|
||||
@ -154,13 +168,14 @@ ReaderWriterDAE::writeNode( const osg::Node& node,
|
||||
bOwnDAE = true;
|
||||
pDAE = new DAE;
|
||||
}
|
||||
std::auto_ptr<DAE> scopedDae(bOwnDAE ? pDAE : NULL); // Deallocates locally created structure at scope exit
|
||||
|
||||
// Convert file name to URI
|
||||
std::string fileURI = ConvertFilePathToColladaCompatibleURI(fname);
|
||||
|
||||
osg::NodeVisitor::TraversalMode traversalMode = writeExtras ? osg::NodeVisitor::TRAVERSE_ALL_CHILDREN : osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN;
|
||||
osg::NodeVisitor::TraversalMode traversalMode = pluginOptions.writeExtras ? osg::NodeVisitor::TRAVERSE_ALL_CHILDREN : osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN;
|
||||
|
||||
osgDAE::daeWriter daeWriter(pDAE, fileURI, osgDB::getFilePath(fname), srcDirectory, options, usePolygon, googleMode, traversalMode, writeExtras, earthTex, zUpAxis, linkOrignialTextures, forceTexture, namesUseCodepage);
|
||||
osgDAE::daeWriter daeWriter(pDAE, fileURI, osgDB::getFilePath(fname), srcDirectory, options, traversalMode, &pluginOptions);
|
||||
daeWriter.setRootNode( node );
|
||||
const_cast<osg::Node*>(&node)->accept( daeWriter );
|
||||
|
||||
@ -182,9 +197,6 @@ ReaderWriterDAE::writeNode( const osg::Node& node,
|
||||
}
|
||||
}
|
||||
|
||||
if (bOwnDAE)
|
||||
delete pDAE;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@ -246,7 +258,6 @@ std::string ReaderWriterDAE::ConvertFilePathToColladaCompatibleURI(const std::st
|
||||
std::string ReaderWriterDAE::ConvertColladaCompatibleURIToFilePath(const std::string& uri)
|
||||
{
|
||||
// Reciprocal of ConvertFilePathToColladaCompatibleURI()
|
||||
|
||||
#ifdef OSG_USE_UTF8_FILENAME
|
||||
std::string path( cdom::uriToNativePath( uri ) );
|
||||
#else
|
||||
|
@ -28,6 +28,11 @@ public:
|
||||
supportsOption("daeNamesUseCodepage", "(Write option) All names except filenames (materials, animation, geometries...) should be considered as encoded using current codepage (UTF8 if not). Filenames follow OSG_USE_UTF8_FILENAME.");
|
||||
|
||||
supportsOption("StrictTransparency", "(Read option) Undocumented");
|
||||
supportsOption("daeTessellateNone", "(Read option) Do not tessellate at all (Polygons are stored as GL_POLYGON - not suitable for concave polygons)");
|
||||
supportsOption("daeTessellatePolygonsAsTriFans", "(Read option) Tessellate the old way (default), interpreting polygons as triangle fans (faster, but does not work for concave polygons)");
|
||||
supportsOption("daeTessellatePolygons", "(Read option) Use full tessellation of polygons (slower, works for concave polygons)");
|
||||
supportsOption("daeUsePredefinedTextureUnits", "(Read option) Texture units have fixed uses (0: ambient occlusion, 1: main texture...). May create non contiguous units (default).");
|
||||
supportsOption("daeUsePredefinedTextureUnits", "(Read option) Texture units are created in sequence (contiguous units).");
|
||||
}
|
||||
|
||||
const char* className() const { return "COLLADA 1.4.x DAE reader/writer"; }
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include <osg/ShapeDrawable>
|
||||
#include <osg/Geometry>
|
||||
|
||||
#include <osgUtil/Tessellator>
|
||||
|
||||
#include <osgAnimation/MorphGeometry>
|
||||
#include <osgAnimation/RigGeometry>
|
||||
#include <osgAnimation/UpdateBone>
|
||||
@ -375,14 +377,14 @@ osg::Geode *daeReader::processMesh(domMesh* pDomMesh)
|
||||
domPolygons_Array polygonsArray = pDomMesh->getPolygons_array();
|
||||
for ( size_t i = 0; i < polygonsArray.getCount(); i++)
|
||||
{
|
||||
processPolygons<domPolygons>(pOsgGeode, pDomMesh, polygonsArray[i], sources);
|
||||
processPolygons<domPolygons>(pOsgGeode, pDomMesh, polygonsArray[i], sources, GL_POLYGON, _pluginOptions.tessellateMode);
|
||||
}
|
||||
|
||||
// 0..* <polylist>
|
||||
domPolylist_Array polylistArray = pDomMesh->getPolylist_array();
|
||||
for ( size_t i = 0; i < polylistArray.getCount(); i++)
|
||||
{
|
||||
processPolylist(pOsgGeode, pDomMesh, polylistArray[i], sources);
|
||||
processPolylist(pOsgGeode, pDomMesh, polylistArray[i], sources, _pluginOptions.tessellateMode);
|
||||
}
|
||||
|
||||
// 0..* <triangles>
|
||||
@ -396,7 +398,7 @@ osg::Geode *daeReader::processMesh(domMesh* pDomMesh)
|
||||
domTrifans_Array trifansArray = pDomMesh->getTrifans_array();
|
||||
for ( size_t i = 0; i < trifansArray.getCount(); i++)
|
||||
{
|
||||
processPolygons<domTrifans>(pOsgGeode, pDomMesh, trifansArray[i], sources);
|
||||
processPolygons<domTrifans>(pOsgGeode, pDomMesh, trifansArray[i], sources, GL_TRIANGLE_FAN, TESSELLATE_NONE);
|
||||
}
|
||||
|
||||
// 0..* <tristrips>
|
||||
@ -494,7 +496,7 @@ void daeReader::processMultiPPrimitive(osg::Geode* geode,
|
||||
}
|
||||
}
|
||||
|
||||
void daeReader::processPolylist(osg::Geode* geode, const domMesh* pDomMesh, const domPolylist *group, SourceMap &sources)
|
||||
void daeReader::processPolylist(osg::Geode* geode, const domMesh* pDomMesh, const domPolylist *group, SourceMap &sources, TessellateMode tessellateMode)
|
||||
{
|
||||
const domPolylist::domVcount* pDomVcount = group->getVcount();
|
||||
if (!pDomVcount)
|
||||
@ -515,52 +517,119 @@ void daeReader::processPolylist(osg::Geode* geode, const domMesh* pDomMesh, cons
|
||||
|
||||
const std::vector<GLuint>& vertexList = vertexLists.front();
|
||||
|
||||
osg::DrawElementsUInt* pDrawTriangles = new osg::DrawElementsUInt(GL_TRIANGLES);
|
||||
geometry->addPrimitiveSet(pDrawTriangles);
|
||||
|
||||
const domListOfUInts& vCount = pDomVcount->getValue();
|
||||
for (size_t i = 0, j = 0; i < vCount.getCount(); ++i)
|
||||
osg::DrawElementsUInt* pDrawTriangles(NULL);
|
||||
if (tessellateMode == TESSELLATE_POLYGONS_AS_TRIFAN)
|
||||
{
|
||||
size_t primitiveLength = vCount[i];
|
||||
if (j + primitiveLength > vertexList.size())
|
||||
// Produce triangles, interpreting polygons as fans (old way)
|
||||
pDrawTriangles = new osg::DrawElementsUInt(GL_TRIANGLES);
|
||||
geometry->addPrimitiveSet(pDrawTriangles);
|
||||
|
||||
const domListOfUInts& vCount = pDomVcount->getValue();
|
||||
for (size_t i = 0, j = 0; i < vCount.getCount(); ++i)
|
||||
{
|
||||
OSG_WARN << "Error: vertex counts are greater than the number of indices." << std::endl;
|
||||
return;
|
||||
size_t primitiveLength = vCount[i];
|
||||
if (j + primitiveLength > vertexList.size())
|
||||
{
|
||||
OSG_WARN << "Error: vertex counts are greater than the number of indices." << std::endl;
|
||||
return;
|
||||
}
|
||||
for (size_t k = 2; k < primitiveLength; ++k)
|
||||
{
|
||||
pDrawTriangles->push_back(vertexList[j]);
|
||||
pDrawTriangles->push_back(vertexList[j+k-1]);
|
||||
pDrawTriangles->push_back(vertexList[j+k]);
|
||||
}
|
||||
j += primitiveLength;
|
||||
}
|
||||
for (size_t k = 2; k < primitiveLength; ++k)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Produce polygons or well-tessellated polygons
|
||||
const domListOfUInts& vCount = pDomVcount->getValue();
|
||||
for (size_t i = 0, j = 0; i < vCount.getCount(); ++i)
|
||||
{
|
||||
pDrawTriangles->push_back(vertexList[j]);
|
||||
pDrawTriangles->push_back(vertexList[j+k-1]);
|
||||
pDrawTriangles->push_back(vertexList[j+k]);
|
||||
size_t primitiveLength = vCount[i];
|
||||
if (j + primitiveLength > vertexList.size())
|
||||
{
|
||||
OSG_WARN << "Error: vertex counts are greater than the number of indices." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(GL_POLYGON);
|
||||
geometry->addPrimitiveSet(pDrawElements);
|
||||
for (size_t k = 0; k < primitiveLength; ++k)
|
||||
{
|
||||
pDrawElements->push_back(vertexList[k+j]);
|
||||
}
|
||||
|
||||
j += primitiveLength;
|
||||
}
|
||||
|
||||
if (tessellateMode == TESSELLATE_POLYGONS)
|
||||
{
|
||||
osgUtil::Tessellator tessellator;
|
||||
tessellator.setTessellationType(osgUtil::Tessellator::TESS_TYPE_POLYGONS);
|
||||
tessellator.setWindingType(osgUtil::Tessellator::TESS_WINDING_POSITIVE);
|
||||
tessellator.retessellatePolygons(*geometry);
|
||||
}
|
||||
j += primitiveLength;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template< typename T >
|
||||
void daeReader::processPolygons(osg::Geode* geode,
|
||||
const domMesh* pDomMesh, const T *group, SourceMap& sources)
|
||||
const domMesh* pDomMesh, const T *group, SourceMap& sources, GLenum mode, TessellateMode tessellateMode)
|
||||
{
|
||||
osg::Geometry *geometry = new osg::Geometry();
|
||||
geometry->setName(group->getMaterial());
|
||||
geode->addDrawable(geometry);
|
||||
|
||||
osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(GL_TRIANGLES);
|
||||
geometry->addPrimitiveSet(pDrawElements);
|
||||
|
||||
std::vector<std::vector<GLuint> > indexLists;
|
||||
resolveMeshArrays(group->getP_array(), group->getInput_array(), pDomMesh,
|
||||
geometry, sources, indexLists);
|
||||
|
||||
for ( size_t i = 0; i < indexLists.size(); ++i)
|
||||
if (tessellateMode == TESSELLATE_POLYGONS_AS_TRIFAN)
|
||||
{
|
||||
const std::vector<GLuint>& indices = indexLists[i];
|
||||
// Produce triangles, interpreting polygons as fans (old way)
|
||||
osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(GL_TRIANGLES);
|
||||
geometry->addPrimitiveSet(pDrawElements);
|
||||
|
||||
for (size_t j = 2; j < indices.size(); ++j)
|
||||
std::vector<std::vector<GLuint> > indexLists;
|
||||
resolveMeshArrays(group->getP_array(), group->getInput_array(), pDomMesh,
|
||||
geometry, sources, indexLists);
|
||||
|
||||
for ( size_t i = 0; i < indexLists.size(); ++i)
|
||||
{
|
||||
pDrawElements->push_back(indices.front());
|
||||
pDrawElements->push_back(indices[j - 1]);
|
||||
pDrawElements->push_back(indices[j]);
|
||||
const std::vector<GLuint>& indices = indexLists[i];
|
||||
|
||||
for (size_t j = 2; j < indices.size(); ++j)
|
||||
{
|
||||
pDrawElements->push_back(indices.front());
|
||||
pDrawElements->push_back(indices[j - 1]);
|
||||
pDrawElements->push_back(indices[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Produce polygons or well-tessellated polygons
|
||||
for ( size_t i = 0; i < indexLists.size(); ++i)
|
||||
{
|
||||
const std::vector<GLuint>& indices = indexLists[i];
|
||||
|
||||
osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(mode);
|
||||
geometry->addPrimitiveSet(pDrawElements);
|
||||
for (size_t j = 0; j < indices.size(); ++j)
|
||||
{
|
||||
pDrawElements->push_back(indices[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (tessellateMode == TESSELLATE_POLYGONS)
|
||||
{
|
||||
osgUtil::Tessellator tessellator;
|
||||
tessellator.setTessellationType(osgUtil::Tessellator::TESS_TYPE_POLYGONS);
|
||||
tessellator.setWindingType(osgUtil::Tessellator::TESS_WINDING_POSITIVE);
|
||||
tessellator.retessellatePolygons(*geometry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -840,10 +909,10 @@ void daeReader::resolveMeshArrays(const domP_Array& domPArray,
|
||||
}
|
||||
}
|
||||
|
||||
const bool readDoubleVertices = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_VERTEX) != 0;
|
||||
const bool readDoubleColors = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_COLOR) != 0;
|
||||
const bool readDoubleNormals = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_NORMAL) != 0;
|
||||
const bool readDoubleTexcoords = (_precisionHint & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0;
|
||||
const bool readDoubleVertices = (_pluginOptions.precisionHint & osgDB::Options::DOUBLE_PRECISION_VERTEX) != 0;
|
||||
const bool readDoubleColors = (_pluginOptions.precisionHint & osgDB::Options::DOUBLE_PRECISION_COLOR) != 0;
|
||||
const bool readDoubleNormals = (_pluginOptions.precisionHint & osgDB::Options::DOUBLE_PRECISION_NORMAL) != 0;
|
||||
const bool readDoubleTexcoords = (_pluginOptions.precisionHint & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0;
|
||||
|
||||
// Vertices
|
||||
{
|
||||
@ -893,6 +962,4 @@ void daeReader::resolveMeshArrays(const domP_Array& domPArray,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef FOREACH_INDEX
|
||||
}
|
||||
|
@ -170,9 +170,10 @@ void daeReader::processBindMaterial( domBind_material *bm, domGeometry *geom, os
|
||||
// 2. For each possible texture unit find the correct texcoord array and
|
||||
// indices from the cached drawable and place in the cloned drawable
|
||||
// in the correct texture unit slot
|
||||
copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], AMBIENT_OCCLUSION_UNIT);
|
||||
copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], MAIN_TEXTURE_UNIT);
|
||||
copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], TRANSPARENCY_MAP_UNIT);
|
||||
unsigned int textureUnit(0);
|
||||
if (copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], AMBIENT_OCCLUSION_UNIT, textureUnit)) ++textureUnit;
|
||||
if (copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], MAIN_TEXTURE_UNIT , textureUnit)) ++textureUnit;
|
||||
if (copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], TRANSPARENCY_MAP_UNIT , textureUnit)) ++textureUnit;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -339,13 +340,15 @@ void daeReader::processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc )
|
||||
mat->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
||||
mat->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
||||
// Use the ambient texture map as an occlusion map.
|
||||
ss->setTextureMode( AMBIENT_OCCLUSION_UNIT, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute(AMBIENT_OCCLUSION_UNIT, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( AMBIENT_OCCLUSION_UNIT, AmbientStateAttribute );
|
||||
unsigned int textureUnit( _pluginOptions.usePredefinedTextureUnits ? AMBIENT_OCCLUSION_UNIT : 0);
|
||||
ss->setTextureMode( textureUnit, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute( textureUnit, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( textureUnit, AmbientStateAttribute );
|
||||
// Modulate in the diffuse texture
|
||||
ss->setTextureMode( MAIN_TEXTURE_UNIT, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute(MAIN_TEXTURE_UNIT, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( MAIN_TEXTURE_UNIT, DiffuseStateAttribute );
|
||||
textureUnit = _pluginOptions.usePredefinedTextureUnits ? MAIN_TEXTURE_UNIT : 1;
|
||||
ss->setTextureMode( textureUnit, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute( textureUnit, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( textureUnit, DiffuseStateAttribute );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -353,9 +356,10 @@ void daeReader::processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc )
|
||||
// plus any constant ambient contribution after the lighting calculation. This means that I am modulating the the
|
||||
// ambient with the texture as well but I cannot see a way of avoiding that.
|
||||
mat->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
||||
ss->setTextureMode( MAIN_TEXTURE_UNIT, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute(MAIN_TEXTURE_UNIT, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( MAIN_TEXTURE_UNIT, DiffuseStateAttribute );
|
||||
unsigned int textureUnit( _pluginOptions.usePredefinedTextureUnits ? MAIN_TEXTURE_UNIT : 0);
|
||||
ss->setTextureMode( textureUnit, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute( textureUnit, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( textureUnit, DiffuseStateAttribute );
|
||||
}
|
||||
|
||||
// Save the texture name for later
|
||||
@ -413,13 +417,15 @@ void daeReader::processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc )
|
||||
mat->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
||||
mat->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
||||
// Use the ambient texture map as an occlusion map.
|
||||
ss->setTextureMode( AMBIENT_OCCLUSION_UNIT, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute(AMBIENT_OCCLUSION_UNIT, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( AMBIENT_OCCLUSION_UNIT, AmbientStateAttribute );
|
||||
unsigned int textureUnit( _pluginOptions.usePredefinedTextureUnits ? AMBIENT_OCCLUSION_UNIT : 0);
|
||||
ss->setTextureMode( textureUnit, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute( textureUnit, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( textureUnit, AmbientStateAttribute );
|
||||
// Modulate in the diffuse texture
|
||||
ss->setTextureMode( MAIN_TEXTURE_UNIT, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute(MAIN_TEXTURE_UNIT, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( MAIN_TEXTURE_UNIT, DiffuseStateAttribute );
|
||||
textureUnit = _pluginOptions.usePredefinedTextureUnits ? MAIN_TEXTURE_UNIT : 1;
|
||||
ss->setTextureMode( textureUnit, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute( textureUnit, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( textureUnit, DiffuseStateAttribute );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -427,9 +433,10 @@ void daeReader::processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc )
|
||||
// plus any constant ambient contribution after the lighting calculation. This means that I am modulating the the
|
||||
// ambient with the texture as well but I cannot see a way of avoiding that.
|
||||
mat->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
||||
ss->setTextureMode( MAIN_TEXTURE_UNIT, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute(MAIN_TEXTURE_UNIT, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( MAIN_TEXTURE_UNIT, DiffuseStateAttribute );
|
||||
unsigned int textureUnit( _pluginOptions.usePredefinedTextureUnits ? MAIN_TEXTURE_UNIT : 0);
|
||||
ss->setTextureMode( textureUnit, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute( textureUnit, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( textureUnit, DiffuseStateAttribute );
|
||||
}
|
||||
|
||||
// Save the texture name for later
|
||||
@ -485,13 +492,15 @@ void daeReader::processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc )
|
||||
mat->setAmbient( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
||||
mat->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
||||
// Use the ambient texture map as an occlusion map.
|
||||
ss->setTextureMode( AMBIENT_OCCLUSION_UNIT, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute(AMBIENT_OCCLUSION_UNIT, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( AMBIENT_OCCLUSION_UNIT, AmbientStateAttribute );
|
||||
unsigned int textureUnit( _pluginOptions.usePredefinedTextureUnits ? AMBIENT_OCCLUSION_UNIT : 0);
|
||||
ss->setTextureMode( textureUnit, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute( textureUnit, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( textureUnit, AmbientStateAttribute );
|
||||
// Modulate in the diffuse texture
|
||||
ss->setTextureMode( MAIN_TEXTURE_UNIT, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute(MAIN_TEXTURE_UNIT, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( MAIN_TEXTURE_UNIT, DiffuseStateAttribute );
|
||||
textureUnit = _pluginOptions.usePredefinedTextureUnits ? MAIN_TEXTURE_UNIT : 1;
|
||||
ss->setTextureMode( textureUnit, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute( textureUnit, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( textureUnit, DiffuseStateAttribute );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -499,9 +508,10 @@ void daeReader::processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc )
|
||||
// plus any constant ambient contribution after the lighting calculation. This means that I am modulating the the
|
||||
// ambient with the texture as well but I cannot see a way of avoiding that.
|
||||
mat->setDiffuse( osg::Material::FRONT_AND_BACK, osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
|
||||
ss->setTextureMode( MAIN_TEXTURE_UNIT, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute(MAIN_TEXTURE_UNIT, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( MAIN_TEXTURE_UNIT, DiffuseStateAttribute );
|
||||
unsigned int textureUnit( _pluginOptions.usePredefinedTextureUnits ? MAIN_TEXTURE_UNIT : 0);
|
||||
ss->setTextureMode( textureUnit, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute( textureUnit, new osg::TexEnv(osg::TexEnv::MODULATE) );
|
||||
ss->setTextureAttribute( textureUnit, DiffuseStateAttribute );
|
||||
}
|
||||
|
||||
// Save the texture name for later
|
||||
@ -529,9 +539,10 @@ void daeReader::processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc )
|
||||
processColorOrTextureType(ss, c->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &sa );
|
||||
if (sa != NULL )
|
||||
{
|
||||
ss->setTextureMode( MAIN_TEXTURE_UNIT, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute(MAIN_TEXTURE_UNIT, new osg::TexEnv(osg::TexEnv::REPLACE) );
|
||||
ss->setTextureAttribute( MAIN_TEXTURE_UNIT, sa );
|
||||
unsigned int textureUnit( _pluginOptions.usePredefinedTextureUnits ? MAIN_TEXTURE_UNIT : 0);
|
||||
ss->setTextureMode( textureUnit, GL_TEXTURE_2D, GL_TRUE );
|
||||
ss->setTextureAttribute( textureUnit, new osg::TexEnv(osg::TexEnv::REPLACE) );
|
||||
ss->setTextureAttribute( textureUnit, sa );
|
||||
}
|
||||
|
||||
// Use the emission colour as the main colour in transparency calculations
|
||||
@ -1241,7 +1252,7 @@ void daeReader::processTransparencySettings( domCommon_transparent_type *ctt,
|
||||
}
|
||||
else
|
||||
{
|
||||
bool strictTransparency = _strictTransparency;
|
||||
bool strictTransparency = _pluginOptions.strictTransparency;
|
||||
if (!strictTransparency)
|
||||
{
|
||||
const osg::Texture* pMainTexture = dynamic_cast<osg::Texture*>(
|
||||
@ -1270,40 +1281,41 @@ void daeReader::processTransparencySettings( domCommon_transparent_type *ctt,
|
||||
ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
}
|
||||
|
||||
void daeReader::copyTextureCoordinateSet(const osg::StateSet* ss, const osg::Geometry* cachedGeometry, osg::Geometry* clonedGeometry, const domInstance_material* im, TextureUnitUsage tuu)
|
||||
bool daeReader::copyTextureCoordinateSet(const osg::StateSet* ss, const osg::Geometry* cachedGeometry, osg::Geometry* clonedGeometry, const domInstance_material* im, TextureUnitUsage tuu, unsigned int textureUnit)
|
||||
{
|
||||
if (!ss->getTextureAttribute(tuu, osg::StateAttribute::TEXTURE))
|
||||
return;
|
||||
unsigned int localTextureUnit( _pluginOptions.usePredefinedTextureUnits ? tuu : textureUnit);
|
||||
if (!ss->getTextureAttribute(localTextureUnit, osg::StateAttribute::TEXTURE))
|
||||
return false;
|
||||
|
||||
const std::string& texCoordSetName = _texCoordSetMap
|
||||
[TextureToCoordSetMap::key_type(ss, tuu)];
|
||||
if (!texCoordSetName.empty())
|
||||
if (texCoordSetName.empty()) return false;
|
||||
|
||||
const domInstance_material::domBind_vertex_input_Array &bvia = im->getBind_vertex_input_array();
|
||||
size_t k;
|
||||
for (k = 0; k < bvia.getCount(); k++)
|
||||
{
|
||||
const domInstance_material::domBind_vertex_input_Array &bvia = im->getBind_vertex_input_array();
|
||||
size_t k;
|
||||
for (k = 0; k < bvia.getCount(); k++)
|
||||
if (!strcmp(bvia[k]->getSemantic(), texCoordSetName.c_str()) && !strcmp(bvia[k]->getInput_semantic(), COMMON_PROFILE_INPUT_TEXCOORD))
|
||||
{
|
||||
if (!strcmp(bvia[k]->getSemantic(), texCoordSetName.c_str()) && !strcmp(bvia[k]->getInput_semantic(), COMMON_PROFILE_INPUT_TEXCOORD))
|
||||
unsigned set = bvia[k]->getInput_set();
|
||||
if (set < cachedGeometry->getNumTexCoordArrays())
|
||||
{
|
||||
unsigned set = bvia[k]->getInput_set();
|
||||
if (set < cachedGeometry->getNumTexCoordArrays())
|
||||
{
|
||||
clonedGeometry->setTexCoordData(tuu, cachedGeometry->getTexCoordData(set));
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_WARN << "Texture coordinate set " << set << " not found." << std::endl;
|
||||
}
|
||||
break;
|
||||
clonedGeometry->setTexCoordData(localTextureUnit, cachedGeometry->getTexCoordData(set));
|
||||
}
|
||||
}
|
||||
if (k == bvia.getCount())
|
||||
{
|
||||
OSG_WARN << "Failed to find matching <bind_vertex_input> for " << texCoordSetName << std::endl;
|
||||
if (cachedGeometry->getNumTexCoordArrays())
|
||||
else
|
||||
{
|
||||
clonedGeometry->setTexCoordData(tuu, cachedGeometry->getTexCoordData(0));
|
||||
OSG_WARN << "Texture coordinate set " << set << " not found." << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == bvia.getCount())
|
||||
{
|
||||
OSG_WARN << "Failed to find matching <bind_vertex_input> for " << texCoordSetName << std::endl;
|
||||
if (cachedGeometry->getNumTexCoordArrays())
|
||||
{
|
||||
clonedGeometry->setTexCoordData(localTextureUnit, cachedGeometry->getTexCoordData(0));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -22,7 +22,15 @@
|
||||
|
||||
using namespace osgDAE;
|
||||
|
||||
daeReader::daeReader(DAE *dae_, bool strictTransparency, int precisionHint) :
|
||||
daeReader::Options::Options() :
|
||||
strictTransparency(false),
|
||||
precisionHint(0),
|
||||
tessellateMode(TESSELLATE_POLYGONS_AS_TRIFAN), // Use old tessellation behaviour as default
|
||||
usePredefinedTextureUnits(true)
|
||||
{
|
||||
}
|
||||
|
||||
daeReader::daeReader(DAE *dae_, const Options * pluginOptions) :
|
||||
_dae(dae_),
|
||||
_rootNode(NULL),
|
||||
_visualScene(NULL),
|
||||
@ -30,12 +38,11 @@ daeReader::daeReader(DAE *dae_, bool strictTransparency, int precisionHint) :
|
||||
_currentInstance_effect(NULL),
|
||||
_currentEffect(NULL),
|
||||
_authoringTool(UNKNOWN),
|
||||
_strictTransparency(strictTransparency),
|
||||
_invertTransparency(false),
|
||||
_precisionHint(precisionHint),
|
||||
_assetUnitName("meter"),
|
||||
_assetUnitMeter(1.0),
|
||||
_assetUp_axis(UPAXISTYPE_Y_UP)
|
||||
_assetUp_axis(UPAXISTYPE_Y_UP),
|
||||
_pluginOptions(pluginOptions ? *pluginOptions : Options())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,23 @@ inline osg::Matrix parseMatrixString(const std::string& valueAsString)
|
||||
*/
|
||||
class daeReader {
|
||||
public:
|
||||
daeReader(DAE *dae_, bool strictTransparency, int precisionHint);
|
||||
enum TessellateMode
|
||||
{
|
||||
TESSELLATE_NONE, ///< Do not tessellate at all (Polygons are stored as GL_POLYGON - not suitable for concave polygons)
|
||||
TESSELLATE_POLYGONS_AS_TRIFAN, ///< Tessellate the old way, interpreting polygons as triangle fans (faster, but does not work for concave polygons)
|
||||
TESSELLATE_POLYGONS ///< Use full tessellation of polygons (slower, works for concave polygons)
|
||||
};
|
||||
|
||||
struct Options
|
||||
{
|
||||
Options();
|
||||
bool strictTransparency;
|
||||
int precisionHint; ///< Precision hint flags, as specified in osgDB::Options::PrecisionHint
|
||||
bool usePredefinedTextureUnits;
|
||||
TessellateMode tessellateMode;
|
||||
};
|
||||
|
||||
daeReader(DAE *dae_, const Options * pluginOptions);
|
||||
virtual ~daeReader();
|
||||
|
||||
bool convert( const std::string &fileURI );
|
||||
@ -305,11 +321,10 @@ private:
|
||||
template< typename T >
|
||||
void processMultiPPrimitive(osg::Geode* geode, const domMesh* pDomMesh, const T* group, SourceMap& sources, GLenum mode);
|
||||
|
||||
template <typename T>
|
||||
void processPolygons(osg::Geode* geode, const domMesh* pDomMesh, const T *group, SourceMap& sources);
|
||||
void processPolylist(osg::Geode* geode, const domMesh* pDomMesh, const domPolylist *group, SourceMap &sources, TessellateMode tessellateMode);
|
||||
|
||||
void processPolylist(osg::Geode* geode, const domMesh* pDomMesh, const domPolylist *group, SourceMap &sources);
|
||||
void processPolygons(osg::Geode* geode, const domMesh* pDomMesh, const domPolygons *group, SourceMap &sources);
|
||||
template< typename T >
|
||||
void processPolygons(osg::Geode* geode, const domMesh* pDomMesh, const T *group, SourceMap &sources, GLenum mode, TessellateMode tessellateMode);
|
||||
|
||||
void resolveMeshArrays(const domP_Array&,
|
||||
const domInputLocalOffset_Array& inputs, const domMesh* pDomMesh,
|
||||
@ -339,7 +354,7 @@ private:
|
||||
std::string processImagePath(const domImage*) const;
|
||||
osg::Image* processImageTransparency(const osg::Image*, domFx_opaque_enum, float transparency) const;
|
||||
osg::Texture2D* processTexture( domCommon_color_or_texture_type_complexType::domTexture *tex, const osg::StateSet*, TextureUnitUsage, domFx_opaque_enum = FX_OPAQUE_ENUM_A_ONE, float transparency = 1.0f);
|
||||
void copyTextureCoordinateSet(const osg::StateSet* ss, const osg::Geometry* cachedGeometry, osg::Geometry* clonedGeometry, const domInstance_material* im, TextureUnitUsage);
|
||||
bool copyTextureCoordinateSet(const osg::StateSet* ss, const osg::Geometry* cachedGeometry, osg::Geometry* clonedGeometry, const domInstance_material* im, TextureUnitUsage tuu, unsigned int textureUnit);
|
||||
|
||||
//scene objects
|
||||
osg::Node* processLight( domLight *dlight );
|
||||
@ -392,8 +407,8 @@ private:
|
||||
OldToNewIndexMap _oldToNewIndexMap;
|
||||
|
||||
AuthoringTool _authoringTool;
|
||||
bool _strictTransparency, _invertTransparency;
|
||||
int _precisionHint; ///< Precision hint flags, as specified in osgDB::Options::PrecisionHint
|
||||
bool _invertTransparency;
|
||||
Options _pluginOptions;
|
||||
|
||||
// Additional Information
|
||||
std::string _assetUnitName;
|
||||
|
@ -36,7 +36,7 @@ using namespace osgDAE;
|
||||
|
||||
void daeWriter::writeAnimations( osg::Node &node )
|
||||
{
|
||||
const std::string nodeNameUTF( _namesUseCodepage ? osgDB::convertStringFromCurrentCodePageToUTF8(node.getName()) : node.getName() );
|
||||
const std::string nodeNameUTF( _pluginOptions.namesUseCodepage ? osgDB::convertStringFromCurrentCodePageToUTF8(node.getName()) : node.getName() );
|
||||
osg::NodeCallback* ncb = node.getUpdateCallback();
|
||||
if (ncb)
|
||||
{
|
||||
@ -68,7 +68,7 @@ void daeWriter::writeAnimations( osg::Node &node )
|
||||
{
|
||||
osgAnimation::Channel* channel = animationChannels[j].get();
|
||||
std::string channelName( channel->getName() );
|
||||
std::string channelNameUTF( _namesUseCodepage ? osgDB::convertStringFromCurrentCodePageToUTF8(channelName) : channelName );
|
||||
std::string channelNameUTF( _pluginOptions.namesUseCodepage ? osgDB::convertStringFromCurrentCodePageToUTF8(channelName) : channelName );
|
||||
|
||||
// Wrap each animation channel into it's own child <animation> when more than 1 channel
|
||||
if (animationChannels.size() > 1)
|
||||
|
@ -749,7 +749,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
{
|
||||
if ( polys == NULL )
|
||||
{
|
||||
if (usePolygons)
|
||||
if (_pluginOptions.usePolygons)
|
||||
{
|
||||
polys = createPrimGroup<domPolygons>( COLLADA_ELEMENT_POLYGONS, mesh, norm, color, texcoord );
|
||||
polys->add( COLLADA_ELEMENT_P );
|
||||
@ -810,7 +810,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
{
|
||||
if ( polys == NULL )
|
||||
{
|
||||
if (usePolygons)
|
||||
if (_pluginOptions.usePolygons)
|
||||
{
|
||||
polys = createPrimGroup<domPolygons>( COLLADA_ELEMENT_POLYGONS, mesh, norm, color, texcoord );
|
||||
polys->add( COLLADA_ELEMENT_P );
|
||||
@ -890,7 +890,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
{
|
||||
//TODO : test this case
|
||||
unsigned int nbPolygons=drawArray->getCount()/primLength;
|
||||
if (usePolygons)
|
||||
if (_pluginOptions.usePolygons)
|
||||
{
|
||||
//for( unsigned int idx = 0; idx < nbPolygons; ++idx )
|
||||
p.push_back(polys->getP_array()[0]);
|
||||
@ -990,7 +990,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
default:
|
||||
{
|
||||
|
||||
if (usePolygons)
|
||||
if (_pluginOptions.usePolygons)
|
||||
{
|
||||
//for( unsigned int idx = 0; idx < nbPolygons; ++idx )
|
||||
p.push_back(polys->getP_array()[0]);
|
||||
@ -1084,7 +1084,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
default:
|
||||
{
|
||||
unsigned int nbPolygons=drawElements->size()/primLength;
|
||||
if (usePolygons)
|
||||
if (_pluginOptions.usePolygons)
|
||||
{
|
||||
//for( unsigned int idx = 0; idx < nbPolygons; ++idx ) /*idx*/
|
||||
//huh ? why only one ?
|
||||
@ -1183,7 +1183,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
default:
|
||||
{
|
||||
unsigned int nbPolygons=drawElements->size()/primLength;
|
||||
if (usePolygons)
|
||||
if (_pluginOptions.usePolygons)
|
||||
{
|
||||
//for( unsigned int idx = 0; idx < nbPolygons; ++idx ) /*idx*/
|
||||
//huh ? why only one ?
|
||||
@ -1284,7 +1284,7 @@ bool daeWriter::processGeometry( osg::Geometry *geom, domGeometry *geo, const st
|
||||
default:
|
||||
{
|
||||
unsigned int nbPolygons=drawElements->size()/primLength;
|
||||
if (usePolygons)
|
||||
if (_pluginOptions.usePolygons)
|
||||
{
|
||||
//for( unsigned int idx = 0; idx < nbPolygons; ++idx ) /*idx*/
|
||||
//huh ? why only one ?
|
||||
|
@ -33,12 +33,13 @@
|
||||
|
||||
using namespace osgDAE;
|
||||
|
||||
|
||||
void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMaterial, const std::string &geoName )
|
||||
{
|
||||
osg::ref_ptr<osg::StateSet> ssClean = CleanStateSet(ss); // Need to hold a ref to this or the materialMap.find() will delete it
|
||||
domBind_material::domTechnique_common *tc = daeSafeCast< domBind_material::domTechnique_common >( pDomBindMaterial->add( COLLADA_ELEMENT_TECHNIQUE_COMMON ) );
|
||||
domInstance_material *pDomInstanceMaterial = daeSafeCast< domInstance_material >( tc->add( COLLADA_ELEMENT_INSTANCE_MATERIAL ) );
|
||||
const std::string symbol( _namesUseCodepage ? osgDB::convertStringFromCurrentCodePageToUTF8(geoName + "_material") : (geoName + "_material") );
|
||||
const std::string symbol( _pluginOptions.namesUseCodepage ? osgDB::convertStringFromCurrentCodePageToUTF8(geoName + "_material") : (geoName + "_material") );
|
||||
pDomInstanceMaterial->setSymbol( symbol.c_str() );
|
||||
|
||||
// See if material already exists in cache
|
||||
@ -104,65 +105,19 @@ void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMa
|
||||
domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->add( COLLADA_ELEMENT_INIT_FROM ) );
|
||||
|
||||
std::string fileURI;
|
||||
if (m_linkOrignialTextures)
|
||||
if (_pluginOptions.linkOrignialTextures)
|
||||
{
|
||||
// We link to orignial images (not the ones in memory).
|
||||
fileURI = osgDB::findDataFile(osgimg->getFileName());
|
||||
if (fileURI=="" && m_ForceTexture)
|
||||
if (fileURI=="" && _pluginOptions.forceTexture)
|
||||
{
|
||||
fileURI = osgDB::getRealPath(osgimg->getFileName());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We do not link to orignial images but to the ones in memory. Then must ensure to write the images.
|
||||
// Following code block is borrowed from FBX's WriterNodeVisitor::Material::Material().
|
||||
ImageSet::iterator it = _imageSet.find(osgimg);
|
||||
if (it != _imageSet.end())
|
||||
{
|
||||
fileURI = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
fileURI = osgDB::getRealPath(osgDB::convertFileNameToNativeStyle(osgimg->getFileName()));
|
||||
std::string destPath;
|
||||
std::string relativePath;
|
||||
if (fileURI.empty())
|
||||
{
|
||||
static const unsigned int MAX_IMAGE_NUMBER = UINT_MAX-1; // -1 to allow doing +1 without an overflow
|
||||
unsigned int imageNumber;
|
||||
for (imageNumber=_lastGeneratedImageFileName+1; imageNumber<MAX_IMAGE_NUMBER; ++imageNumber)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "Image_" << imageNumber << ".tga";
|
||||
relativePath = oss.str();
|
||||
destPath = osgDB::concatPaths(_directory, relativePath);
|
||||
if (_imageFilenameSet.find(destPath) != _imageFilenameSet.end()) break;
|
||||
}
|
||||
_lastGeneratedImageFileName = imageNumber;
|
||||
osgDB::writeImageFile(*osgimg, destPath, _options);
|
||||
}
|
||||
else
|
||||
{
|
||||
relativePath = osgDB::getPathRelative(_srcDirectory, fileURI);
|
||||
destPath = osgDB::getRealPath(osgDB::convertFileNameToNativeStyle( osgDB::concatPaths(_directory, relativePath) ));
|
||||
if (destPath != fileURI)
|
||||
{
|
||||
if (!osgDB::makeDirectoryForFile(destPath))
|
||||
{
|
||||
OSG_NOTICE << "Can't create directory for file '" << destPath << "'. May fail creating the image file." << std::endl;
|
||||
}
|
||||
osgDB::writeImageFile(*osgimg, destPath, _options);
|
||||
}
|
||||
}
|
||||
|
||||
assert(!destPath.empty()); // Else the implementation is to be fixed
|
||||
assert(!relativePath.empty()); // ditto
|
||||
fileURI = relativePath;
|
||||
it = _imageSet.insert(ImageSet::value_type(osgimg, fileURI)).first;
|
||||
_imageFilenameSet.insert(destPath);
|
||||
}
|
||||
// (end of code borrowed from FBX)
|
||||
// We do not link to original images but to the ones in memory. Then must ensure to write the images.
|
||||
_externalWriter.write(*osgimg, _options, NULL, &fileURI);
|
||||
}
|
||||
|
||||
fileURI = ReaderWriterDAE::ConvertFilePathToColladaCompatibleURI(fileURI);
|
||||
@ -170,9 +125,9 @@ void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMa
|
||||
daeURI dd(*dae, fileURI);
|
||||
imgif->setValue( dd );
|
||||
// The document URI should contain the canonical path it was created with
|
||||
if (m_linkOrignialTextures) imgif->getValue().makeRelativeTo(doc->getDocumentURI());
|
||||
if (_pluginOptions.linkOrignialTextures) imgif->getValue().makeRelativeTo(doc->getDocumentURI());
|
||||
|
||||
if (!m_EarthTex)
|
||||
if (!_pluginOptions.earthTex)
|
||||
{
|
||||
domCommon_newparam_type *np = daeSafeCast< domCommon_newparam_type >( pc->add(COLLADA_ELEMENT_NEWPARAM) );
|
||||
std::string surfName = efName + "-surface";
|
||||
@ -347,7 +302,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMa
|
||||
{
|
||||
cot = phong->getDiffuse();
|
||||
|
||||
if (writeExtras)
|
||||
if (_pluginOptions.writeExtras)
|
||||
{
|
||||
// Adds the following to a texture element
|
||||
|
||||
@ -400,7 +355,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMa
|
||||
domCommon_color_or_texture_type_complexType::domColor *pColor = daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(pTransparent->add(COLLADA_ELEMENT_COLOR));
|
||||
domCommon_float_or_param_type *pFop = daeSafeCast<domCommon_float_or_param_type>(phong->add(COLLADA_ELEMENT_TRANSPARENCY));
|
||||
domCommon_float_or_param_type_complexType::domFloat *pTransparency = daeSafeCast<domCommon_float_or_param_type_complexType::domFloat>(pFop->add(COLLADA_ELEMENT_FLOAT));
|
||||
if (m_GoogleMode)
|
||||
if (_pluginOptions.googleMode)
|
||||
{
|
||||
pColor->getValue().append(1.0);
|
||||
pColor->getValue().append(1.0);
|
||||
@ -440,7 +395,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMa
|
||||
ctt->setOpaque( FX_OPAQUE_ENUM_A_ONE );
|
||||
domCommon_color_or_texture_type_complexType::domTexture * dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( ctt->add(COLLADA_ELEMENT_TEXTURE) );
|
||||
|
||||
if (!m_EarthTex)
|
||||
if (!_pluginOptions.earthTex)
|
||||
{
|
||||
std::string sampName = efName + "-sampler";
|
||||
dtex->setTexture( sampName.c_str() );
|
||||
@ -463,7 +418,7 @@ void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMa
|
||||
}
|
||||
}
|
||||
|
||||
if (writeExtras)
|
||||
if (_pluginOptions.writeExtras)
|
||||
{
|
||||
// Adds the following to a Profile_COMMON element
|
||||
|
||||
|
@ -35,7 +35,7 @@ void daeWriter::writeNodeExtra(osg::Node &node)
|
||||
{
|
||||
unsigned int numDesc = node.getDescriptions().size();
|
||||
// Only create extra if descriptions are filled in
|
||||
if (writeExtras && (numDesc > 0))
|
||||
if (_pluginOptions.writeExtras && (numDesc > 0))
|
||||
{
|
||||
// Adds the following to a node
|
||||
|
||||
@ -73,7 +73,7 @@ void daeWriter::apply( osg::Group &node )
|
||||
|
||||
// If a multiswitch node, store it's data as extra "MultiSwitch" data in the "OpenSceneGraph" technique
|
||||
osgSim::MultiSwitch* multiswitch = dynamic_cast<osgSim::MultiSwitch*>(&node);
|
||||
if (writeExtras && multiswitch)
|
||||
if (_pluginOptions.writeExtras && multiswitch)
|
||||
{
|
||||
// Adds the following to a node
|
||||
|
||||
@ -142,7 +142,7 @@ void daeWriter::apply( osg::Switch &node )
|
||||
currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
|
||||
currentNode->setId(getNodeName(node,"switch").c_str());
|
||||
|
||||
if (writeExtras)
|
||||
if (_pluginOptions.writeExtras)
|
||||
{
|
||||
// Adds the following to a node
|
||||
|
||||
@ -190,7 +190,7 @@ void daeWriter::apply( osg::Sequence &node )
|
||||
currentNode->setId(getNodeName(node,"sequence").c_str());
|
||||
|
||||
// If a sequence node, store it's data as extra "Sequence" data in the "OpenSceneGraph" technique
|
||||
if (writeExtras)
|
||||
if (_pluginOptions.writeExtras)
|
||||
{
|
||||
// Adds the following to a node
|
||||
|
||||
@ -267,7 +267,7 @@ void daeWriter::apply( osg::LOD &node )
|
||||
currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) );
|
||||
currentNode->setId(getNodeName(node,"LOD").c_str());
|
||||
|
||||
if (writeExtras)
|
||||
if (_pluginOptions.writeExtras)
|
||||
{
|
||||
// Store LOD data as extra "LOD" data in the "OpenSceneGraph" technique
|
||||
// Adds the following to a node
|
||||
|
@ -184,7 +184,7 @@ void daeWriter::apply( osg::Transform &node )
|
||||
|
||||
// If a DOFTransform node store it's data as extra "DOFTransform" data in the "OpenSceneGraph" technique
|
||||
osgSim::DOFTransform* dof = dynamic_cast<osgSim::DOFTransform*>(&node);
|
||||
if (writeExtras && dof)
|
||||
if (_pluginOptions.writeExtras && dof)
|
||||
{
|
||||
// Adds the following to a node
|
||||
|
||||
|
@ -96,23 +96,25 @@ std::string toString(const osg::Matrix& value)
|
||||
}
|
||||
|
||||
|
||||
daeWriter::daeWriter( DAE *dae_, const std::string & fileURI, const std::string & directory, const std::string & srcDirectory, const osgDB::ReaderWriter::Options * options, bool _usePolygons, bool googleMode, TraversalMode tm, bool _writeExtras, bool earthTex, bool zUpAxis, bool linkOrignialTextures, bool forceTexture, bool namesUseCodepage) : osg::NodeVisitor( tm ),
|
||||
dae(dae_),
|
||||
_domLibraryAnimations(NULL),
|
||||
writeExtras(_writeExtras),
|
||||
rootName(*dae_),
|
||||
usePolygons (_usePolygons),
|
||||
m_GoogleMode(googleMode),
|
||||
m_EarthTex(earthTex),
|
||||
m_ZUpAxis(zUpAxis),
|
||||
m_linkOrignialTextures(linkOrignialTextures),
|
||||
m_ForceTexture(forceTexture),
|
||||
m_CurrentRenderingHint(osg::StateSet::DEFAULT_BIN),
|
||||
_lastGeneratedImageFileName(0),
|
||||
_directory(directory),
|
||||
_srcDirectory(srcDirectory),
|
||||
_options(options),
|
||||
_namesUseCodepage(namesUseCodepage)
|
||||
daeWriter::Options::Options()
|
||||
: usePolygons(false),
|
||||
googleMode(false),
|
||||
writeExtras(true),
|
||||
earthTex(false),
|
||||
linkOrignialTextures(false),
|
||||
forceTexture(false),
|
||||
namesUseCodepage(false),
|
||||
relativiseImagesPathNbUpDirs(0)
|
||||
{}
|
||||
|
||||
daeWriter::daeWriter( DAE *dae_, const std::string & fileURI, const std::string & directory, const std::string & srcDirectory, const osgDB::ReaderWriter::Options * options, TraversalMode tm, const Options * pluginOptions) : osg::NodeVisitor( tm ),
|
||||
dae(dae_),
|
||||
_domLibraryAnimations(NULL),
|
||||
rootName(*dae_),
|
||||
m_CurrentRenderingHint(osg::StateSet::DEFAULT_BIN),
|
||||
_options(options),
|
||||
_pluginOptions(pluginOptions ? *pluginOptions : Options()),
|
||||
_externalWriter(srcDirectory, directory, true, pluginOptions ? pluginOptions->relativiseImagesPathNbUpDirs : 0)
|
||||
{
|
||||
success = true;
|
||||
|
||||
@ -209,7 +211,7 @@ void daeWriter::updateCurrentDaeNode()
|
||||
|
||||
std::string daeWriter::uniquify( const std::string &_name )
|
||||
{
|
||||
const std::string name( _namesUseCodepage ? osgDB::convertStringFromCurrentCodePageToUTF8(_name) : _name );
|
||||
const std::string name( _pluginOptions.namesUseCodepage ? osgDB::convertStringFromCurrentCodePageToUTF8(_name) : _name );
|
||||
std::map< std::string, int >::iterator iter = uniqueNames.find( name );
|
||||
if ( iter != uniqueNames.end() )
|
||||
{
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/FileUtils>
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/ExternalFileWriter>
|
||||
#include <osgSim/MultiSwitch>
|
||||
#include <osgAnimation/AnimationManagerBase>
|
||||
#include <osgAnimation/UpdateBone>
|
||||
@ -136,7 +137,25 @@ class daeWriter : public osg::NodeVisitor
|
||||
protected:
|
||||
class ArrayNIndices;
|
||||
public:
|
||||
daeWriter( DAE *dae_, const std::string &fileURI, const std::string & directory, const std::string & srcDirectory, const osgDB::ReaderWriter::Options * options, bool usePolygons=false, bool googleMode = false, TraversalMode tm=TRAVERSE_ALL_CHILDREN, bool writeExtras = true, bool earthTex = false, bool zUpAxis=false, bool linkOrignialTextures=false, bool forceTexture=false, bool namesUseCodepage=false);
|
||||
struct Options
|
||||
{
|
||||
Options();
|
||||
|
||||
bool usePolygons;
|
||||
/** work in Google compatibility mode. In daeWMaterials, change transparency color. And in daeWGeometry, replace tristrip and trifans by triangles*/
|
||||
bool googleMode;
|
||||
/** Write OSG specific data as extra data. */
|
||||
bool writeExtras;
|
||||
/** work in Google compatibility mode for textures*/
|
||||
bool earthTex;
|
||||
/** link to original images instead of exporting */
|
||||
bool linkOrignialTextures;
|
||||
/** force the use an image for a texture, even if the file is not found (when m_linkOrignialTextures). */
|
||||
bool forceTexture;
|
||||
bool namesUseCodepage;
|
||||
unsigned int relativiseImagesPathNbUpDirs;
|
||||
};
|
||||
daeWriter(DAE *dae_, const std::string &fileURI, const std::string & directory, const std::string & srcDirectory, const osgDB::ReaderWriter::Options * options, TraversalMode tm=TRAVERSE_ALL_CHILDREN, const Options * pluginOptions=NULL);
|
||||
virtual ~daeWriter();
|
||||
|
||||
void setRootNode( const osg::Node &node );
|
||||
@ -216,8 +235,6 @@ protected: //members
|
||||
domNode *currentNode;
|
||||
domVisual_scene *vs;
|
||||
|
||||
/// Write OSG specific data as extra data
|
||||
bool writeExtras;
|
||||
bool success;
|
||||
unsigned int lastDepth;
|
||||
|
||||
@ -249,8 +266,6 @@ protected: //members
|
||||
|
||||
daeURI rootName;
|
||||
|
||||
bool usePolygons;
|
||||
|
||||
osg::StateSet* CleanStateSet(osg::StateSet* pStateSet) const;
|
||||
|
||||
void updateCurrentDaeNode();
|
||||
@ -305,38 +320,15 @@ private: //members
|
||||
/** provide an unique name */
|
||||
std::string uniquify( const std::string &name );
|
||||
|
||||
/** work in Google compatibility mode. In daeWMaterials, change transparency color. And in daeWGeometry, replace tristrip and trifans by triangles*/
|
||||
bool m_GoogleMode;
|
||||
|
||||
/** work in Google compatibility mode for textures*/
|
||||
bool m_EarthTex;
|
||||
|
||||
/** indicates if the up axis is on Z axis*/
|
||||
bool m_ZUpAxis;
|
||||
|
||||
/** link to original images instead of exporting */
|
||||
bool m_linkOrignialTextures;
|
||||
|
||||
/** force the use an image for a texture, even if the file is not found (when m_linkOrignialTextures). */
|
||||
bool m_ForceTexture;
|
||||
|
||||
/** Current RenderingHint */
|
||||
/** This are needed because the stateSet merge code currently does not handle it */
|
||||
int m_CurrentRenderingHint;
|
||||
|
||||
FindAnimatedNodeVisitor _animatedNodeCollector;
|
||||
|
||||
/** Number used when writing images with no name, to generate a file name. */
|
||||
unsigned int _lastGeneratedImageFileName;
|
||||
std::string _directory;
|
||||
std::string _srcDirectory;
|
||||
const osgDB::ReaderWriter::Options * _options;
|
||||
bool _namesUseCodepage;
|
||||
|
||||
typedef std::map<const osg::Image*, std::string> ImageSet;
|
||||
typedef std::set<std::string> ImageFilenameSet; // Sub-optimal because strings are doubled (in ImageSet). Moreover, an unordered_set (= hashset) would be more efficient (Waiting for unordered_set to be included in C++ standard ;) ).
|
||||
ImageSet _imageSet;
|
||||
ImageFilenameSet _imageFilenameSet;
|
||||
Options _pluginOptions;
|
||||
osgDB::ExternalFileWriter _externalWriter;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user