Procházet zdrojové kódy

Improving ColladaExporter to allow non-destructive cycles of import/export

Léo Terziman před 12 roky
rodič
revize
b4b39e026d
1 změnil soubory, kde provedl 50 přidání a 34 odebrání
  1. 50 34
      code/ColladaExporter.cpp

+ 50 - 34
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 <set>
+
 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<std::string> 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<std::string> (a) + name.C_Str();
+	if(material_names.find(name.C_Str()) != material_names.end()) {
+		materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (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 << "<node id=\"" << pNode->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 << "<matrix>";
-	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 << "</matrix>" << 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;
+	if(name.compare("myscene") != 0) {
+		mOutput << startstr << "<node id=\"" << pNode->mName.data << "\" name=\"" << pNode->mName.data << "\">" << endstr;
+		PushTag();
 
-		mOutput << startstr << "<instance_geometry url=\"#" << GetMeshId( pNode->mMeshes[a]) << "\">" << 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 << "<matrix>";
+		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 << "</matrix>" << 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 << "<instance_geometry url=\"#" << GetMeshId( pNode->mMeshes[a]) << "\">" << endstr;
+			PushTag();
+		mOutput << startstr << "<bind_material>" << endstr;
 		PushTag();
-    mOutput << startstr << "<bind_material>" << endstr;
-    PushTag();
-    mOutput << startstr << "<technique_common>" << endstr;
-    PushTag();
-    mOutput << startstr << "<instance_material symbol=\"theresonlyone\" target=\"#" << materials[mesh->mMaterialIndex].name << "\" />" << endstr;
+		mOutput << startstr << "<technique_common>" << endstr;
+		PushTag();
+		mOutput << startstr << "<instance_material symbol=\"theresonlyone\" target=\"#" << materials[mesh->mMaterialIndex].name << "\" />" << endstr;
+			PopTag();
+		mOutput << startstr << "</technique_common>" << endstr;
 		PopTag();
-    mOutput << startstr << "</technique_common>" << endstr;
-    PopTag();
-    mOutput << startstr << "</bind_material>" << endstr;
-    PopTag();
-		mOutput << startstr << "</instance_geometry>" << endstr;
+		mOutput << startstr << "</bind_material>" << endstr;
+		PopTag();
+			mOutput << startstr << "</instance_geometry>" << endstr;
+		}
 	}
 
 	// recurse into subnodes
 	for( size_t a = 0; a < pNode->mNumChildren; ++a )
 		WriteNode( pNode->mChildren[a]);
 
-	PopTag();
-	mOutput << startstr << "</node>" << endstr;
+	if(name.compare("myscene") != 0) {
+		PopTag();
+		mOutput << startstr << "</node>" << endstr;
+	}
 }
 
 #endif