From b4b39e026d495951467f793bbd0fdb89bab2f8bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Terziman?= Date: Wed, 2 Oct 2013 11:25:04 +0200 Subject: [PATCH] Improving ColladaExporter to allow non-destructive cycles of import/export --- code/ColladaExporter.cpp | 86 ++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 35 deletions(-) diff --git a/code/ColladaExporter.cpp b/code/ColladaExporter.cpp index 19f86fcf8..cbc69fceb 100644 --- a/code/ColladaExporter.cpp +++ b/code/ColladaExporter.cpp @@ -44,6 +44,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER #include "ColladaExporter.h" +#include + using namespace Assimp; namespace Assimp @@ -97,7 +99,7 @@ void ColladaExporter::WriteFile() WriteHeader(); - WriteMaterials(); + WriteMaterials(); WriteGeometryLibrary(); WriteSceneLibrary(); @@ -225,6 +227,8 @@ void ColladaExporter::WriteMaterials() { materials.resize( mScene->mNumMaterials); + std::set material_names; + /// collect all materials from the scene size_t numTextures = 0; for( size_t a = 0; a < mScene->mNumMaterials; ++a ) @@ -234,7 +238,12 @@ void ColladaExporter::WriteMaterials() aiString name; if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS ) name = "mat"; - materials[a].name = std::string( "m") + boost::lexical_cast (a) + name.C_Str(); + if(material_names.find(name.C_Str()) != material_names.end()) { + materials[a].name = std::string( "m") + boost::lexical_cast (a) + "_" + name.C_Str(); + material_names.insert(materials[a].name); + } else { + materials[a].name = name.C_Str(); + } for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) if( !isalnum( *it) ) *it = '_'; @@ -560,48 +569,55 @@ void ColladaExporter::WriteSceneLibrary() // Recursively writes the given node void ColladaExporter::WriteNode( const aiNode* pNode) { - mOutput << startstr << "mName.data << "\" name=\"" << pNode->mName.data << "\">" << endstr; - PushTag(); + std::string name(pNode->mName.C_Str()); + std::transform(name.begin(), name.end(), name.begin(), ::tolower); - // write transformation - we can directly put the matrix there - // TODO: (thom) decompose into scale - rot - quad to allow adressing it by animations afterwards - const aiMatrix4x4& mat = pNode->mTransformation; - mOutput << startstr << ""; - mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " "; - mOutput << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << " "; - mOutput << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << " "; - mOutput << mat.d1 << " " << mat.d2 << " " << mat.d3 << " " << mat.d4; - mOutput << "" << endstr; - - // instance every geometry - for( size_t a = 0; a < pNode->mNumMeshes; ++a ) - { - const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]]; - // do not instanciate mesh if empty. I wonder how this could happen - if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 ) - continue; - - mOutput << startstr << "mMeshes[a]) << "\">" << endstr; + if(name.compare("myscene") != 0) { + mOutput << startstr << "mName.data << "\" name=\"" << pNode->mName.data << "\">" << endstr; PushTag(); - mOutput << startstr << "" << endstr; - PushTag(); - mOutput << startstr << "" << endstr; - PushTag(); - mOutput << startstr << "mMaterialIndex].name << "\" />" << endstr; + + // write transformation - we can directly put the matrix there + // TODO: (thom) decompose into scale - rot - quad to allow adressing it by animations afterwards + const aiMatrix4x4& mat = pNode->mTransformation; + mOutput << startstr << ""; + mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " "; + mOutput << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << " "; + mOutput << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << " "; + mOutput << mat.d1 << " " << mat.d2 << " " << mat.d3 << " " << mat.d4; + mOutput << "" << endstr; + + // instance every geometry + for( size_t a = 0; a < pNode->mNumMeshes; ++a ) + { + const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]]; + // do not instanciate mesh if empty. I wonder how this could happen + if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 ) + continue; + + mOutput << startstr << "mMeshes[a]) << "\">" << endstr; + PushTag(); + mOutput << startstr << "" << endstr; + PushTag(); + mOutput << startstr << "" << endstr; + PushTag(); + mOutput << startstr << "mMaterialIndex].name << "\" />" << endstr; + PopTag(); + mOutput << startstr << "" << endstr; PopTag(); - mOutput << startstr << "" << endstr; - PopTag(); - mOutput << startstr << "" << endstr; - PopTag(); - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; + PopTag(); + mOutput << startstr << "" << endstr; + } } // recurse into subnodes for( size_t a = 0; a < pNode->mNumChildren; ++a ) WriteNode( pNode->mChildren[a]); - PopTag(); - mOutput << startstr << "" << endstr; + if(name.compare("myscene") != 0) { + PopTag(); + mOutput << startstr << "" << endstr; + } } #endif