diff --git a/code/ColladaExporter.cpp b/code/ColladaExporter.cpp index da208c27b..3a1c096bf 100644 --- a/code/ColladaExporter.cpp +++ b/code/ColladaExporter.cpp @@ -58,7 +58,7 @@ namespace Assimp // ------------------------------------------------------------------------------------------------ // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp -void ExportSceneCollada(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene) +void ExportSceneCollada(const char* pFile,IOSystem* pIOSystem, aiScene* pScene) { std::string path = ""; std::string file = pFile; diff --git a/code/ConvertToLHProcess.cpp b/code/ConvertToLHProcess.cpp index cc9141306..17e157c45 100644 --- a/code/ConvertToLHProcess.cpp +++ b/code/ConvertToLHProcess.cpp @@ -134,12 +134,22 @@ void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) { pMesh->mVertices[a].z *= -1.0f; if( pMesh->HasNormals()) - pMesh->mNormals[a].z *= -1.0f; + pMesh->mNormals[a].z *= -1.0f; if( pMesh->HasTangentsAndBitangents()) { pMesh->mTangents[a].z *= -1.0f; pMesh->mBitangents[a].z *= -1.0f; } + + // texture coords for all channels + for (unsigned int c = 0; c < pMesh->GetNumUVChannels(); c++) + { + if (pMesh->HasTextureCoords(c)) + { + pMesh->mTextureCoords[c][a].y = 1.0f - pMesh->mTextureCoords[c][a].y; + } + } + } // mirror offset matrices of all bones diff --git a/code/Exporter.cpp b/code/Exporter.cpp index 22db17659..37c36fb8c 100644 --- a/code/Exporter.cpp +++ b/code/Exporter.cpp @@ -71,13 +71,14 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out); // ------------------------------------------------------------------------------------------------ // Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype -void ExportSceneCollada(const char*,IOSystem*, const aiScene*); -void ExportSceneXFile(const char*,IOSystem*, const aiScene*); -void ExportSceneObj(const char*,IOSystem*, const aiScene*); -void ExportSceneSTL(const char*,IOSystem*, const aiScene*); -void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*); -void ExportScenePly(const char*,IOSystem*, const aiScene*); -void ExportScene3DS(const char*, IOSystem*, const aiScene*) {} +// do not use const, because some exporter need to convert the scene temporary +void ExportSceneCollada(const char*,IOSystem*, aiScene*); +void ExportSceneXFile(const char*,IOSystem*, aiScene*); +void ExportSceneObj(const char*,IOSystem*, aiScene*); +void ExportSceneSTL(const char*,IOSystem*, aiScene*); +void ExportSceneSTLBinary(const char*,IOSystem*, aiScene*); +void ExportScenePly(const char*,IOSystem*, aiScene*); +void ExportScene3DS(const char*, IOSystem*, aiScene*) {} // ------------------------------------------------------------------------------------------------ // global array of all export formats which Assimp supports in its current build diff --git a/code/ObjExporter.cpp b/code/ObjExporter.cpp index ff9fa4b25..25bcfc9c5 100644 --- a/code/ObjExporter.cpp +++ b/code/ObjExporter.cpp @@ -51,7 +51,7 @@ namespace Assimp { // ------------------------------------------------------------------------------------------------ // Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp -void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene) +void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, aiScene* pScene) { // invoke the exporter ObjExporter exporter(pFile, pScene); diff --git a/code/PlyExporter.cpp b/code/PlyExporter.cpp index e78cfd964..bd04dfcb3 100644 --- a/code/PlyExporter.cpp +++ b/code/PlyExporter.cpp @@ -50,7 +50,7 @@ namespace Assimp { // ------------------------------------------------------------------------------------------------ // Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp -void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene) +void ExportScenePly(const char* pFile,IOSystem* pIOSystem, aiScene* pScene) { // invoke the exporter PlyExporter exporter(pFile, pScene); diff --git a/code/STLExporter.cpp b/code/STLExporter.cpp index e3df2fbff..d1765f446 100644 --- a/code/STLExporter.cpp +++ b/code/STLExporter.cpp @@ -50,7 +50,7 @@ namespace Assimp { // ------------------------------------------------------------------------------------------------ // Worker function for exporting a scene to Stereolithograpy. Prototyped and registered in Exporter.cpp -void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene) +void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, aiScene* pScene) { // invoke the exporter STLExporter exporter(pFile, pScene); @@ -63,7 +63,7 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene outfile->Write( exporter.mOutput.str().c_str(), static_cast(exporter.mOutput.tellp()),1); } -void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene) +void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, aiScene* pScene) { // invoke the exporter STLExporter exporter(pFile, pScene, true); diff --git a/code/XFileExporter.cpp b/code/XFileExporter.cpp index 2f14dbbe4..e56dc3ce4 100644 --- a/code/XFileExporter.cpp +++ b/code/XFileExporter.cpp @@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_XFILE_EXPORTER #include "XFileExporter.h" - +#include "ConvertToLHProcess.h" #include "Bitmap.h" #include "fast_atof.h" #include "SceneCombiner.h" @@ -59,7 +59,7 @@ namespace Assimp // ------------------------------------------------------------------------------------------------ // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp -void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene) +void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, aiScene* pScene) { std::string path = ""; std::string file = pFile; @@ -96,7 +96,7 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce // ------------------------------------------------------------------------------------------------ // Constructor for a specific scene to export -XFileExporter::XFileExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file) +XFileExporter::XFileExporter(aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file) { // make sure that all formatting happens using the standard, C locale and not the user's current locale mOutput.imbue( std::locale("C") ); @@ -128,6 +128,13 @@ void XFileExporter::WriteFile() mOutput.setf(_IOSfixed); mOutput.precision(6); // precission for float + // the scene is already in OpenGL, applying MakeLeftHandedProcess, makes it xFile left handed + MakeLeftHandedProcess convertProcess; + FlipWindingOrderProcess flipper; + + convertProcess.Execute(mScene); + flipper.Execute(mScene); + // entry of writing the file WriteHeader(); @@ -141,6 +148,10 @@ void XFileExporter::WriteFile() PopTag(); mOutput << startstr << "}" << endstr; + + // and back to OpenGL right handed + convertProcess.Execute(mScene); + flipper.Execute(mScene); } // ------------------------------------------------------------------------------------------------ @@ -277,11 +288,11 @@ void XFileExporter::WriteHeader() void XFileExporter::WriteFrameTransform(aiMatrix4x4& m) { mOutput << startstr << "FrameTransformMatrix {" << endstr << " "; - PushTag(); - mOutput << startstr << m.a1 << "," << m.a2 << "," << m.a3 << "," << m.a4 << "," - << m.b1 << "," << m.b2 << "," << m.b3 << "," << m.b4 << "," - << m.c1 << "," << m.c2 << "," << m.c3 << "," << m.c4 << "," - << m.d1 << "," << m.d2 << "," << m.d3 << "," << m.d4 << ";;" << endstr; + PushTag(); + mOutput << startstr << m.a1 << "," << m.b1 << "," << m.c1 << "," << m.d1 << "," << endstr; + mOutput << startstr << m.a2 << "," << m.b2 << "," << m.c2 << "," << m.d2 << "," << endstr; + mOutput << startstr << m.a3 << "," << m.b3 << "," << m.c3 << "," << m.d3 << "," << endstr; + mOutput << startstr << m.a4 << "," << m.b4 << "," << m.c4 << "," << m.d4 << ";;" << endstr; PopTag(); mOutput << startstr << "}" << endstr << endstr; } @@ -291,11 +302,12 @@ void XFileExporter::WriteFrameTransform(aiMatrix4x4& m) // Recursively writes the given node void XFileExporter::WriteNode( const aiNode* pNode) { - mOutput << startstr << "Frame " << pNode->mName.C_Str() << " {" << endstr; + + mOutput << startstr << "Frame " << pNode->mName.C_Str() << " {" << " // " << pNode->mName.C_Str() << endstr; PushTag(); - aiMatrix4x4 m;// = pNode->mTransformation; + aiMatrix4x4 m = pNode->mTransformation; WriteFrameTransform(m); @@ -353,6 +365,43 @@ void XFileExporter::WriteMesh(const aiMesh* mesh) mOutput << ";" << endstr; } + mOutput << endstr; + + if (mesh->HasTextureCoords(0)) + { + const aiMaterial* mat = mScene->mMaterials[mesh->mMaterialIndex]; + aiString relpath; + mat->Get(_AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0, relpath); + + mOutput << startstr << "MeshMaterialList {" << endstr; + PushTag(); + mOutput << startstr << "1;" << endstr; // number of materials + mOutput << startstr << mesh->mNumFaces << ";" << endstr; // number of faces + for( size_t a = 0; a < mesh->mNumFaces; ++a ) + { + mOutput << startstr << a; + if (a < mesh->mNumFaces - 1) + mOutput << "," << endstr; + else + mOutput << ";" << endstr; + } + mOutput << startstr << "Material {" << endstr; + PushTag(); + mOutput << startstr << "1.0; 1.0; 1.0; 1.000000;;" << endstr; + mOutput << startstr << "1.000000;" << endstr; // power + mOutput << startstr << "0.000000; 0.000000; 0.000000;;" << endstr; // specularity + mOutput << startstr << "0.000000; 0.000000; 0.000000;;" << endstr; // emission + mOutput << startstr << "TextureFilename { \""; + + writePath(relpath); + + mOutput << "\"; }" << endstr; + PopTag(); + mOutput << startstr << "}" << endstr; + PopTag(); + mOutput << startstr << "}" << endstr; + } + // write normals (every vertex has one) mOutput << endstr; if (mesh->HasNormals()) @@ -400,10 +449,12 @@ void XFileExporter::WriteMesh(const aiMesh* mesh) mOutput << startstr << "MeshTextureCoords {" << endstr; mOutput << startstr << mesh->mNumVertices << ";" << endstr; for (size_t a = 0; a < mesh->mNumVertices; a++) + //for (int a = (int)mesh->mNumVertices-1; a >=0 ; a--) { aiVector3D& uv = mesh->mTextureCoords[0][a]; // uv of first uv layer for the vertex - mOutput << uv.x << ";" << uv.y; + mOutput << startstr << uv.x << ";" << uv.y; if (a < mesh->mNumVertices-1) + //if (a >0 ) mOutput << ";," << endstr; else mOutput << ";;" << endstr; @@ -449,6 +500,22 @@ void XFileExporter::WriteMesh(const aiMesh* mesh) } + +void XFileExporter::writePath(aiString path) +{ + std::string str = std::string(path.C_Str()); + BaseImporter::ConvertUTF8toISO8859_1(str); + + while( str.find( "\\\\") != std::string::npos) + str.replace( str.find( "\\\\"), 2, "\\"); + + while( str.find( "\\") != std::string::npos) + str.replace( str.find( "\\"), 1, "/"); + + mOutput << str; + +} + #endif #endif diff --git a/code/XFileExporter.h b/code/XFileExporter.h index 39660530e..5e4877c48 100644 --- a/code/XFileExporter.h +++ b/code/XFileExporter.h @@ -55,13 +55,13 @@ struct aiNode; namespace Assimp { -/// Helper class to export a given scene to a Collada file. Just for my personal -/// comfort when implementing it. +/// Helper class to export a given scene to a X-file. +/// Note: an xFile uses a left hand system. Assimp used a right hand system (OpenGL), therefore we have to transform everything class XFileExporter { public: /// Constructor for a specific scene to export - XFileExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file); + XFileExporter(aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file); /// Destructor virtual ~XFileExporter(); @@ -93,6 +93,10 @@ public: std::stringstream mOutput; protected: + + /// write a path + void writePath(aiString path); + /// The IOSystem for output IOSystem* mIOSystem; @@ -103,11 +107,12 @@ protected: const std::string mFile; /// The scene to be written - const aiScene* mScene; + aiScene* mScene; bool mSceneOwned; /// current line start string, contains the current indentation for simple stream insertion std::string startstr; + /// current line end string for simple stream insertion std::string endstr; diff --git a/include/assimp/Exporter.hpp b/include/assimp/Exporter.hpp index b9318ae29..2c9a2e2af 100644 --- a/include/assimp/Exporter.hpp +++ b/include/assimp/Exporter.hpp @@ -81,7 +81,7 @@ class ASSIMP_API Exporter public: /** Function pointer type of a Export worker function */ - typedef void (*fpExportFunc)(const char*,IOSystem*,const aiScene*); + typedef void (*fpExportFunc)(const char*,IOSystem*, aiScene*); /** Internal description of an Assimp export format option */ struct ExportFormatEntry