From b3b732c12b12e995110a041f5083384983b2c0b9 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 3 Jul 2014 20:33:52 +0200 Subject: [PATCH 01/80] update: some micro improvements, replace post-increment operator with pre-increment operator. Signed-off-by: Kim Kulling --- code/CalcTangentsProcess.cpp | 4 ++-- code/ObjExporter.cpp | 15 +++++++++------ code/ObjFileParser.cpp | 36 +++++++++++++++++++++--------------- code/ObjTools.h | 2 +- code/ParsingUtils.h | 1 + 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/code/CalcTangentsProcess.cpp b/code/CalcTangentsProcess.cpp index 46ab8f868..4ceca3f7a 100644 --- a/code/CalcTangentsProcess.cpp +++ b/code/CalcTangentsProcess.cpp @@ -115,9 +115,9 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) // we assume that the mesh is still in the verbose vertex format where each face has its own set // of vertices and no vertices are shared between faces. Sadly I don't know any quick test to // assert() it here. - //assert( must be verbose, dammit); + // assert( must be verbose, dammit); - if (pMesh->mTangents) // thisimplies that mBitangents is also there + if (pMesh->mTangents) // this implies that mBitangents is also there return false; // If the mesh consists of lines and/or points but not of diff --git a/code/ObjExporter.cpp b/code/ObjExporter.cpp index 282983965..4ed2824e5 100644 --- a/code/ObjExporter.cpp +++ b/code/ObjExporter.cpp @@ -75,6 +75,7 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene } // end of namespace Assimp +static const std::string MaterialExt = ".mtl"; // ------------------------------------------------------------------------------------------------ ObjExporter :: ObjExporter(const char* _filename, const aiScene* pScene) @@ -107,7 +108,7 @@ std::string ObjExporter :: GetMaterialLibName() // ------------------------------------------------------------------------------------------------ std::string ObjExporter :: GetMaterialLibFileName() { - return filename + ".mtl"; + return filename + MaterialExt; } // ------------------------------------------------------------------------------------------------ @@ -132,7 +133,7 @@ std::string ObjExporter :: GetMaterialName(unsigned int index) } // ------------------------------------------------------------------------------------------------ -void ObjExporter :: WriteMaterialFile() +void ObjExporter::WriteMaterialFile() { WriteHeader(mOutputMat); @@ -281,7 +282,7 @@ void ObjExporter::vecIndexMap::getVectors( std::vector& vecs ) } // ------------------------------------------------------------------------------------------------ -void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) +void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) { meshes.push_back(MeshInstance()); MeshInstance& mesh = meshes.back(); @@ -332,7 +333,7 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri } // ------------------------------------------------------------------------------------------------ -void ObjExporter :: AddNode(const aiNode* nd, const aiMatrix4x4& mParent) +void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent) { const aiMatrix4x4& mAbs = mParent * nd->mTransformation; @@ -345,5 +346,7 @@ void ObjExporter :: AddNode(const aiNode* nd, const aiMatrix4x4& mParent) } } -#endif -#endif +// ------------------------------------------------------------------------------------------------ + +#endif // ASSIMP_BUILD_NO_OBJ_EXPORTER +#endif // ASSIMP_BUILD_NO_EXPORT diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index 5b8305723..f2e65db71 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -550,13 +550,15 @@ void ObjFileParser::getNewMaterial() { m_DataIt = getNextToken(m_DataIt, m_DataItEnd); m_DataIt = getNextWord(m_DataIt, m_DataItEnd); - if ( m_DataIt == m_DataItEnd ) - return; + if( m_DataIt == m_DataItEnd ) { + return; + } char *pStart = &(*m_DataIt); std::string strMat( pStart, *m_DataIt ); - while ( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) ) - m_DataIt++; + while( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) ) { + ++m_DataIt; + } std::map::iterator it = m_pModel->m_MaterialMap.find( strMat ); if ( it == m_pModel->m_MaterialMap.end() ) { @@ -581,8 +583,9 @@ void ObjFileParser::getNewMaterial() int ObjFileParser::getMaterialIndex( const std::string &strMaterialName ) { int mat_index = -1; - if ( strMaterialName.empty() ) - return mat_index; + if( strMaterialName.empty() ) { + return mat_index; + } for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index) { if ( strMaterialName == m_pModel->m_MaterialLib[ index ]) @@ -601,8 +604,9 @@ void ObjFileParser::getGroupName() std::string strGroupName; m_DataIt = getName(m_DataIt, m_DataItEnd, strGroupName); - if ( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) - return; + if( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) { + return; + } // Change active group, if necessary if ( m_pModel->m_strActiveGroup != strGroupName ) @@ -653,11 +657,13 @@ void ObjFileParser::getGroupNumberAndResolution() void ObjFileParser::getObjectName() { m_DataIt = getNextToken(m_DataIt, m_DataItEnd); - if (m_DataIt == m_DataItEnd) - return; + if( m_DataIt == m_DataItEnd ) { + return; + } char *pStart = &(*m_DataIt); - while ( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) ) - ++m_DataIt; + while( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) ) { + ++m_DataIt; + } std::string strObjectName(pStart, &(*m_DataIt)); if (!strObjectName.empty()) @@ -678,8 +684,9 @@ void ObjFileParser::getObjectName() } // Allocate a new object, if current one was not found before - if ( NULL == m_pModel->m_pCurrent ) - createObject(strObjectName); + if( NULL == m_pModel->m_pCurrent ) { + createObject( strObjectName ); + } } m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } @@ -694,7 +701,6 @@ void ObjFileParser::createObject(const std::string &strObjectName) m_pModel->m_pCurrent->m_strObjName = strObjectName; m_pModel->m_Objects.push_back( m_pModel->m_pCurrent ); - createMesh(); if( m_pModel->m_pCurrentMaterial ) diff --git a/code/ObjTools.h b/code/ObjTools.h index 530588368..047c9a4cd 100644 --- a/code/ObjTools.h +++ b/code/ObjTools.h @@ -259,4 +259,4 @@ unsigned int tokenize( const string_type& str, std::vector& tokens, } // Namespace Assimp -#endif +#endif // OBJ_TOOLS_H_INC diff --git a/code/ParsingUtils.h b/code/ParsingUtils.h index 422471fc8..d0e8ba681 100644 --- a/code/ParsingUtils.h +++ b/code/ParsingUtils.h @@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define AI_PARSING_UTILS_H_INC #include "StringComparison.h" + namespace Assimp { // NOTE: the functions below are mostly intended as replacement for From c6b516b68ba509dfab729763e427ceee9e3d14ba Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 4 Jul 2014 00:22:13 +0200 Subject: [PATCH 02/80] bugfix: handling possible nullptr access. update: replace clear be resize( 0 ) at some places to avoid double allocations ( only a micro optimization ). Signed-off-by: Kim Kulling --- code/CalcTangentsProcess.cpp | 2 +- code/ConvertToLHProcess.cpp | 28 ++++++++---- code/DeboneProcess.cpp | 2 +- code/ParsingUtils.h | 84 +++++++++++++++++++++++++----------- 4 files changed, 79 insertions(+), 37 deletions(-) diff --git a/code/CalcTangentsProcess.cpp b/code/CalcTangentsProcess.cpp index 4ceca3f7a..338c16aaa 100644 --- a/code/CalcTangentsProcess.cpp +++ b/code/CalcTangentsProcess.cpp @@ -271,7 +271,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) const aiVector3D& origNorm = pMesh->mNormals[a]; const aiVector3D& origTang = pMesh->mTangents[a]; const aiVector3D& origBitang = pMesh->mBitangents[a]; - closeVertices.clear(); + closeVertices.resize( 0 ); // find all vertices close to that position vertexFinder->FindPositions( origPos, posEpsilon, verticesFound); diff --git a/code/ConvertToLHProcess.cpp b/code/ConvertToLHProcess.cpp index 3a51daf57..4f5b40840 100644 --- a/code/ConvertToLHProcess.cpp +++ b/code/ConvertToLHProcess.cpp @@ -57,12 +57,15 @@ using namespace Assimp; // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer MakeLeftHandedProcess::MakeLeftHandedProcess() -{} +: BaseProcess() { + // empty +} // ------------------------------------------------------------------------------------------------ // Destructor, private as well -MakeLeftHandedProcess::~MakeLeftHandedProcess() -{} +MakeLeftHandedProcess::~MakeLeftHandedProcess() { + // empty +} // ------------------------------------------------------------------------------------------------ // Returns whether the processing step is present in the given flag field. @@ -121,8 +124,9 @@ void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pPare pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways... // continue for all children - for( size_t a = 0; a < pNode->mNumChildren; ++a) - ProcessNode( pNode->mChildren[a], pParentGlobalRotation * pNode->mTransformation); + for( size_t a = 0; a < pNode->mNumChildren; ++a ) { + ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation ); + } } // ------------------------------------------------------------------------------------------------ @@ -244,6 +248,10 @@ void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat) aiMaterial* mat = (aiMaterial*)_mat; for (unsigned int a = 0; a < mat->mNumProperties;++a) { aiMaterialProperty* prop = mat->mProperties[a]; + if( !prop ) { + DefaultLogger::get()->debug( "Property is null" ); + continue; + } // UV transformation key? if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) { @@ -263,11 +271,13 @@ void FlipUVsProcess::ProcessMesh( aiMesh* pMesh) { // mirror texture y coordinate for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { - if( !pMesh->HasTextureCoords( a)) - break; + if( !pMesh->HasTextureCoords( a ) ) { + break; + } - for( unsigned int b = 0; b < pMesh->mNumVertices; b++) - pMesh->mTextureCoords[a][b].y = 1.0f - pMesh->mTextureCoords[a][b].y; + for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) { + pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y; + } } } diff --git a/code/DeboneProcess.cpp b/code/DeboneProcess.cpp index 7e72b836e..8a2a9e640 100644 --- a/code/DeboneProcess.cpp +++ b/code/DeboneProcess.cpp @@ -111,7 +111,7 @@ void DeboneProcess::Execute( aiScene* pScene) if(numSplits) { // we need to do something. Let's go. - mSubMeshIndices.clear(); + //mSubMeshIndices.clear(); really needed? mSubMeshIndices.resize(pScene->mNumMeshes); // build a new array of meshes for the scene diff --git a/code/ParsingUtils.h b/code/ParsingUtils.h index d0e8ba681..1ed8ee923 100644 --- a/code/ParsingUtils.h +++ b/code/ParsingUtils.h @@ -49,14 +49,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { - // NOTE: the functions below are mostly intended as replacement for - // std::upper, std::lower, std::isupper, std::islower, std::isspace. - // we don't bother of locales. We don't want them. We want reliable - // (i.e. identical) results across all locales. +// NOTE: the functions below are mostly intended as replacement for +// std::upper, std::lower, std::isupper, std::islower, std::isspace. +// we don't bother of locales. We don't want them. We want reliable +// (i.e. identical) results across all locales. - // The functions below accept any character type, but know only - // about ASCII. However, UTF-32 is the only safe ASCII superset to - // use since it doesn't have multibyte sequences. +// The functions below accept any character type, but know only +// about ASCII. However, UTF-32 is the only safe ASCII superset to +// use since it doesn't have multi-byte sequences. + +static const unsigned int BufferSize = 4096; // --------------------------------------------------------------------------------- template @@ -64,118 +66,145 @@ AI_FORCE_INLINE char_t ToLower( char_t in) { return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in; } + // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE char_t ToUpper( char_t in) -{ - return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in; +AI_FORCE_INLINE char_t ToUpper( char_t in) { + return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in; } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsUpper( char_t in) { return (in >= (char_t)'A' && in <= (char_t)'Z'); } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsLower( char_t in) { return (in >= (char_t)'a' && in <= (char_t)'z'); } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsSpace( char_t in) { return (in == (char_t)' ' || in == (char_t)'\t'); } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsLineEnd( char_t in) { return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0'); } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in) { return IsSpace(in) || IsLineEnd(in); } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipSpaces( const char_t* in, const char_t** out) { - while (*in == (char_t)' ' || *in == (char_t)'\t')in++; + while( *in == ( char_t )' ' || *in == ( char_t )'\t' ) { + ++in; + } *out = in; return !IsLineEnd(*in); } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipSpaces( const char_t** inout) { return SkipSpaces(*inout,inout); } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipLine( const char_t* in, const char_t** out) { - while (*in != (char_t)'\r' && *in != (char_t)'\n' && *in != (char_t)'\0')in++; + while( *in != ( char_t )'\r' && *in != ( char_t )'\n' && *in != ( char_t )'\0' ) { + ++in; + } // files are opened in binary mode. Ergo there are both NL and CR - while (*in == (char_t)'\r' || *in == (char_t)'\n')in++; + while( *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { + ++in; + } *out = in; return *in != (char_t)'\0'; } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipLine( const char_t** inout) { return SkipLine(*inout,inout); } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) { - while (*in == (char_t)' ' || *in == (char_t)'\t' || - *in == (char_t)'\r' || *in == (char_t)'\n')in++; + while( *in == ( char_t )' ' || *in == ( char_t )'\t' || *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { + ++in; + } *out = in; return *in != '\0'; } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout) { return SkipSpacesAndLineEnd(*inout,inout); } + // --------------------------------------------------------------------------------- template -AI_FORCE_INLINE bool GetNextLine(const char_t*& buffer, char_t out[4096]) +AI_FORCE_INLINE bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize ] ) { - if ((char_t)'\0' == *buffer)return false; + if( ( char_t )'\0' == *buffer ) { + return false; + } char* _out = out; - char* const end = _out+4096; - while (!IsLineEnd( *buffer ) && _out < end) - *_out++ = *buffer++; + char* const end = _out + BufferSize; + while( !IsLineEnd( *buffer ) && _out < end ) { + *_out++ = *buffer++; + } *_out = (char_t)'\0'; - while (IsLineEnd( *buffer ) && '\0' != *buffer)++buffer; - return true; + while( IsLineEnd( *buffer ) && '\0' != *buffer ) { + ++buffer; + } + + return true; } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsNumeric( char_t in) { return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in; } + // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len) { - if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) - { + if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) { in += len+1; return true; } + return false; } // --------------------------------------------------------------------------------- @@ -186,8 +215,7 @@ AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len */ AI_FORCE_INLINE bool TokenMatchI(const char*& in, const char* token, unsigned int len) { - if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) - { + if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) { in += len+1; return true; } @@ -207,5 +235,9 @@ AI_FORCE_INLINE std::string GetNextToken(const char*& in) while (!IsSpaceOrNewLine(*in))++in; return std::string(cur,(size_t)(in-cur)); } + +// --------------------------------------------------------------------------------- + } // ! namespace Assimp + #endif // ! AI_PARSING_UTILS_H_INC From 231e4e0cd0b7df54ba723bf235485f01faaca81b Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Fri, 4 Jul 2014 00:23:02 +0200 Subject: [PATCH 03/80] update: commit not saved changes. Signed-off-by: Kim Kulling --- code/DeboneProcess.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/DeboneProcess.cpp b/code/DeboneProcess.cpp index 8a2a9e640..e22e2fb00 100644 --- a/code/DeboneProcess.cpp +++ b/code/DeboneProcess.cpp @@ -111,8 +111,8 @@ void DeboneProcess::Execute( aiScene* pScene) if(numSplits) { // we need to do something. Let's go. - //mSubMeshIndices.clear(); really needed? - mSubMeshIndices.resize(pScene->mNumMeshes); + //mSubMeshIndices.clear(); // really needed? + mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway // build a new array of meshes for the scene std::vector meshes; From 47e7667071a9bf49de3fac7ed843feb5408976c2 Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 9 Jul 2014 15:35:00 +0200 Subject: [PATCH 04/80] Added alpha texture map (map_d) --- code/ObjExporter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/ObjExporter.cpp b/code/ObjExporter.cpp index 4ed2824e5..058133f8e 100644 --- a/code/ObjExporter.cpp +++ b/code/ObjExporter.cpp @@ -182,6 +182,9 @@ void ObjExporter::WriteMaterialFile() if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SHININESS(0),s)) { mOutputMat << "map_ns " << s.data << endl; } + if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_OPACITY(0),s)) { + mOutputMat << "map_d " << s.data << endl; + } if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_HEIGHT(0),s) || AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_NORMALS(0),s)) { // implementations seem to vary here, so write both variants mOutputMat << "bump " << s.data << endl; From afa2d3da940f4b254d52d21c90a859db1446d1cf Mon Sep 17 00:00:00 2001 From: Robin Date: Wed, 9 Jul 2014 15:37:27 +0200 Subject: [PATCH 05/80] Improved texture map data in mtl exporter (in most cases an upper first character is used) --- code/ObjExporter.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/ObjExporter.cpp b/code/ObjExporter.cpp index 058133f8e..7ebb55b3e 100644 --- a/code/ObjExporter.cpp +++ b/code/ObjExporter.cpp @@ -145,16 +145,16 @@ void ObjExporter::WriteMaterialFile() aiColor4D c; if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_DIFFUSE,c)) { - mOutputMat << "kd " << c.r << " " << c.g << " " << c.b << endl; + mOutputMat << "Kd " << c.r << " " << c.g << " " << c.b << endl; } if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_AMBIENT,c)) { - mOutputMat << "ka " << c.r << " " << c.g << " " << c.b << endl; + mOutputMat << "Ka " << c.r << " " << c.g << " " << c.b << endl; } if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_SPECULAR,c)) { - mOutputMat << "ks " << c.r << " " << c.g << " " << c.b << endl; + mOutputMat << "Ks " << c.r << " " << c.g << " " << c.b << endl; } if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_EMISSIVE,c)) { - mOutputMat << "ke " << c.r << " " << c.g << " " << c.b << endl; + mOutputMat << "Ke " << c.r << " " << c.g << " " << c.b << endl; } float o; @@ -171,16 +171,16 @@ void ObjExporter::WriteMaterialFile() aiString s; if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_DIFFUSE(0),s)) { - mOutputMat << "map_kd " << s.data << endl; + mOutputMat << "map_Kd " << s.data << endl; } if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_AMBIENT(0),s)) { - mOutputMat << "map_ka " << s.data << endl; + mOutputMat << "map_Ka " << s.data << endl; } if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SPECULAR(0),s)) { - mOutputMat << "map_ks " << s.data << endl; + mOutputMat << "map_Ks " << s.data << endl; } if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SHININESS(0),s)) { - mOutputMat << "map_ns " << s.data << endl; + mOutputMat << "map_Ns " << s.data << endl; } if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_OPACITY(0),s)) { mOutputMat << "map_d " << s.data << endl; From ce37d3bcad7ac1079ad44854cbd7add6eaac5127 Mon Sep 17 00:00:00 2001 From: Robin Date: Fri, 11 Jul 2014 08:11:54 +0200 Subject: [PATCH 06/80] Fixed possible bug with map_emmissive keyword and removed second check for ambient texture keyword --- code/ObjFileMtlImporter.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/code/ObjFileMtlImporter.cpp b/code/ObjFileMtlImporter.cpp index 8424995c0..a25b960e7 100644 --- a/code/ObjFileMtlImporter.cpp +++ b/code/ObjFileMtlImporter.cpp @@ -54,6 +54,7 @@ static const std::string DiffuseTexture = "map_kd"; static const std::string AmbientTexture = "map_ka"; static const std::string SpecularTexture = "map_ks"; static const std::string OpacityTexture = "map_d"; +static const std::string EmmissiveTexture = "map_emissive"; static const std::string BumpTexture1 = "map_bump"; static const std::string BumpTexture2 = "map_Bump"; static const std::string BumpTexture3 = "bump"; @@ -303,11 +304,7 @@ void ObjFileMtlImporter::getTexture() { // Opacity texture out = & m_pModel->m_pCurrentMaterial->textureOpacity; clampIndex = ObjFile::Material::TextureOpacityType; - } else if (!ASSIMP_strincmp( pPtr,"map_ka",6)) { - // Ambient texture - out = & m_pModel->m_pCurrentMaterial->textureAmbient; - clampIndex = ObjFile::Material::TextureAmbientType; - } else if (!ASSIMP_strincmp(&(*m_DataIt),"map_emissive",6)) { + } else if (!ASSIMP_strincmp( pPtr, EmmissiveTexture.c_str(), EmmissiveTexture.size())) { // Emissive texture out = & m_pModel->m_pCurrentMaterial->textureEmissive; clampIndex = ObjFile::Material::TextureEmissiveType; From a30ea8e92c39e4d17c9d67da45ff363849b35cf4 Mon Sep 17 00:00:00 2001 From: Andrew Short Date: Sun, 13 Jul 2014 00:34:08 +1000 Subject: [PATCH 07/80] Fix overflow in STL header colour reading. When reading the STL header for a "COLOR=rgb" part, the bytes were treated as signed chars, when in fact they can range from 0-255. This meant that any value greater than 127 would overflow, leading to an incorrect colour. This change fixes the issue by treating the header as unsigned chars. --- code/STLLoader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/STLLoader.cpp b/code/STLLoader.cpp index ebd320c1a..068008d9e 100644 --- a/code/STLLoader.cpp +++ b/code/STLLoader.cpp @@ -348,8 +348,8 @@ bool STLImporter::LoadBinaryFile() bool bIsMaterialise = false; // search for an occurence of "COLOR=" in the header - const char* sz2 = (const char*)mBuffer; - const char* const szEnd = sz2+80; + const unsigned char* sz2 = (const unsigned char*)mBuffer; + const unsigned char* const szEnd = sz2+80; while (sz2 < szEnd) { if ('C' == *sz2++ && 'O' == *sz2++ && 'L' == *sz2++ && From 5ae010028b4ba1548d5a791a9d12cd9e7bb81ced Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Sun, 13 Jul 2014 14:07:19 +0200 Subject: [PATCH 08/80] FBX: fix memory leak. Connection objects in Document never freed. See #307 --- code/FBXDocument.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/code/FBXDocument.cpp b/code/FBXDocument.cpp index 404a8d6e2..fc27c8874 100644 --- a/code/FBXDocument.cpp +++ b/code/FBXDocument.cpp @@ -253,8 +253,8 @@ Document::Document(const Parser& parser, const ImportSettings& settings) : settings(settings) , parser(parser) { - // cannot use array default initialization syntax because vc8 fails on it - for (unsigned int i = 0; i < 7; ++i) { + // Cannot use array default initialization syntax because vc8 fails on it + for (unsigned int i = 0; i < sizeof(creationTimeStamp) / sizeof(creationTimeStamp[0]); ++i) { creationTimeStamp[i] = 0; } @@ -263,7 +263,7 @@ Document::Document(const Parser& parser, const ImportSettings& settings) ReadGlobalSettings(); - // this order is important, connections need parsed objects to check + // This order is important, connections need parsed objects to check // whether connections are ok or not. Objects may not be evaluated yet, // though, since this may require valid connections. ReadObjects(); @@ -277,13 +277,18 @@ Document::~Document() BOOST_FOREACH(ObjectMap::value_type& v, objects) { delete v.second; } + + BOOST_FOREACH(ConnectionMap::value_type& v, src_connections) { + delete v.second; + } + // |dest_connections| contain the same Connection objects as the |src_connections| } // ------------------------------------------------------------------------------------------------ void Document::ReadHeader() { - // read ID objects from "Objects" section + // Read ID objects from "Objects" section const Scope& sc = parser.GetRootScope(); const Element* const ehead = sc["FBXHeaderExtension"]; if(!ehead || !ehead->Compound()) { @@ -293,7 +298,7 @@ void Document::ReadHeader() const Scope& shead = *ehead->Compound(); fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0)); - // while we maye have some success with newer files, we don't support + // While we maye have some success with newer files, we don't support // the older 6.n fbx format if(fbxVersion < 7100) { DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013"); From 7e48c1cce99c03ce47520c8575b5993958caeaa6 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Sun, 13 Jul 2014 14:11:58 +0200 Subject: [PATCH 09/80] FBX: fix memory leak, parsed TokenList never released. See #307. --- code/FBXImporter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/FBXImporter.cpp b/code/FBXImporter.cpp index 56e99063b..dfbe5dbd0 100644 --- a/code/FBXImporter.cpp +++ b/code/FBXImporter.cpp @@ -179,6 +179,8 @@ void FBXImporter::InternReadFile( const std::string& pFile, // convert the FBX DOM to aiScene ConvertToAssimpScene(pScene,doc); + + std::for_each(tokens.begin(),tokens.end(),Util::delete_fun()); } catch(std::exception&) { std::for_each(tokens.begin(),tokens.end(),Util::delete_fun()); From 2edccb7f34a6381f00f96ad037230a5ff90fa626 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Sun, 13 Jul 2014 15:08:28 +0200 Subject: [PATCH 10/80] fast_atof: If a literal ends with a trailing dot (.), only parse further if the next character is a digit. In cases where the dot ends the literal (i.e. "1.") this would cause strtoul10_64 to throw an exception. To preserve as much of the old behaviour, we still consume trailing dots though. This "regression" was introduced (exposed) by #261, which added the extra check to strtoul10_64 that triggered here. This commit now fixes #304 (IFC file reading broken due to IFC files containing "(1.,1.,1.)" lists. --- code/fast_atof.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/code/fast_atof.h b/code/fast_atof.h index 5e6f5e4a5..ddda1f29e 100644 --- a/code/fast_atof.h +++ b/code/fast_atof.h @@ -231,13 +231,13 @@ inline const char* fast_atoreal_move( const char* c, Real& out, bool check_comma { Real f; - bool inv = (*c=='-'); - if (inv || *c=='+') { + bool inv = (*c == '-'); + if (inv || *c == '+') { ++c; } f = static_cast( strtoul10_64 ( c, &c) ); - if (*c == '.' || (check_comma && c[0] == ',' && c[1] >= '0' && c[1] <= '9')) // allow for commas, too + if ((*c == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9') { ++c; @@ -255,6 +255,10 @@ inline const char* fast_atoreal_move( const char* c, Real& out, bool check_comma pl *= fast_atof_table[diff]; f += static_cast( pl ); } + // For backwards compatibility: eat trailing dots, but not trailing commas. + else if (*c == '.') { + ++c; + } // A major 'E' must be allowed. Necessary for proper reading of some DXF files. // Thanks to Zhao Lei to point out that this if() must be outside the if (*c == '.' ..) From 46ca36cb6fc06e7efb5d8c5e0c0622ae1ca34bda Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 19 Jul 2014 14:45:21 +0200 Subject: [PATCH 11/80] update: - remove dead code. - check for a possible division by zero. Signed-off-by: Kim Kulling --- code/FindInstancesProcess.cpp | 3 +-- code/GenVertexNormalsProcess.cpp | 2 +- code/LimitBoneWeightsProcess.cpp | 10 +++++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/code/FindInstancesProcess.cpp b/code/FindInstancesProcess.cpp index faf0541af..278f01115 100644 --- a/code/FindInstancesProcess.cpp +++ b/code/FindInstancesProcess.cpp @@ -174,7 +174,6 @@ void FindInstancesProcess::Execute( aiScene* pScene) // use a constant epsilon for colors and UV coordinates static const float uvEpsilon = 10e-4f; - { unsigned int i, end = orig->GetNumUVChannels(); for(i = 0; i < end; ++i) { @@ -260,7 +259,7 @@ void FindInstancesProcess::Execute( aiScene* pScene) pScene->mMeshes[real++] = pScene->mMeshes[i]; } - // And update the nodegraph with our nice lookup table + // And update the node graph with our nice lookup table UpdateMeshIndices(pScene->mRootNode,remapping.get()); // write to log diff --git a/code/GenVertexNormalsProcess.cpp b/code/GenVertexNormalsProcess.cpp index b278afb87..77ef20ac5 100644 --- a/code/GenVertexNormalsProcess.cpp +++ b/code/GenVertexNormalsProcess.cpp @@ -93,7 +93,7 @@ void GenVertexNormalsProcess::Execute( aiScene* pScene) bool bHas = false; for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { - if(GenMeshVertexNormals( pScene->mMeshes[a],a)) + if(GenMeshVertexNormals( pScene->mMeshes[a],a)) bHas = true; } diff --git a/code/LimitBoneWeightsProcess.cpp b/code/LimitBoneWeightsProcess.cpp index 91ac122ac..32a1b47c0 100644 --- a/code/LimitBoneWeightsProcess.cpp +++ b/code/LimitBoneWeightsProcess.cpp @@ -133,8 +133,12 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh) float sum = 0.0f; for( std::vector::const_iterator it = vit->begin(); it != vit->end(); ++it) sum += it->mWeight; - for( std::vector::iterator it = vit->begin(); it != vit->end(); ++it) - it->mWeight /= sum; + const float invSum = 1.0f/sum; + if( 0.0f != sum ) { + for( std::vector::iterator it = vit->begin(); it != vit->end(); ++it ) { + it->mWeight *= invSum; + } + } } if (bChanged) { @@ -177,7 +181,7 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh) // copy the weight list. should always be less weights than before, so we don't need a new allocation ai_assert( bw.size() <= bone->mNumWeights); - bone->mNumWeights = (unsigned int) bw.size(); + bone->mNumWeights = static_cast( bw.size() ); ::memcpy( bone->mWeights, &bw[0], bw.size() * sizeof( aiVertexWeight)); } From d6551990433264e029b476455db90d1d889e461c Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 19 Jul 2014 16:22:15 +0200 Subject: [PATCH 12/80] bugfix: fix stupid test introduced by myself. Signed-off-by: Kim Kulling --- code/LimitBoneWeightsProcess.cpp | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/code/LimitBoneWeightsProcess.cpp b/code/LimitBoneWeightsProcess.cpp index 32a1b47c0..f7a83a970 100644 --- a/code/LimitBoneWeightsProcess.cpp +++ b/code/LimitBoneWeightsProcess.cpp @@ -131,10 +131,11 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh) // and renormalize the weights float sum = 0.0f; - for( std::vector::const_iterator it = vit->begin(); it != vit->end(); ++it) - sum += it->mWeight; - const float invSum = 1.0f/sum; + for( std::vector::const_iterator it = vit->begin(); it != vit->end(); ++it ) { + sum += it->mWeight; + } if( 0.0f != sum ) { + const float invSum = 1.0f / sum; for( std::vector::iterator it = vit->begin(); it != vit->end(); ++it ) { it->mWeight *= invSum; } @@ -161,18 +162,6 @@ void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh) const std::vector& bw = boneWeights[a]; aiBone* bone = pMesh->mBones[a]; - // ignore the bone if no vertex weights were removed there - - // FIX (Aramis, 07|22|08) - // NO! we can't ignore it in this case ... it is possible that - // the number of weights did not change, but the weight values did. - - // if( bw.size() == bone->mNumWeights) - // continue; - - // FIX (Aramis, 07|21|08) - // It is possible that all weights of a bone have been removed. - // This would naturally cause an exception in &bw[0]. if ( bw.empty() ) { abNoNeed[a] = bChanged = true; From 3e9fab3bfc6f869c0d7be02e50ebe27818784707 Mon Sep 17 00:00:00 2001 From: Tyson Grant Nottingham Date: Mon, 21 Jul 2014 22:43:13 -0700 Subject: [PATCH 13/80] Allow numbers starting with decimal in fast_atof. --- code/fast_atof.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/code/fast_atof.h b/code/fast_atof.h index ddda1f29e..a7f0cb23f 100644 --- a/code/fast_atof.h +++ b/code/fast_atof.h @@ -229,14 +229,25 @@ inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* template inline const char* fast_atoreal_move( const char* c, Real& out, bool check_comma = true) { - Real f; + Real f = 0; bool inv = (*c == '-'); if (inv || *c == '+') { ++c; } - f = static_cast( strtoul10_64 ( c, &c) ); + if (!isdigit(*c) && !(*c == '.' && isdigit(c[1]))) + { + throw std::invalid_argument("Cannot parse string " + "as real number: does not start with digit " + "or decimal point followed by digit."); + } + + if (*c != '.') + { + f = static_cast( strtoul10_64 ( c, &c) ); + } + if ((*c == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9') { ++c; From 36c82fe5b05bfb15bc3b999d521b9ca26367992e Mon Sep 17 00:00:00 2001 From: Tyson Grant Nottingham Date: Mon, 21 Jul 2014 23:03:08 -0700 Subject: [PATCH 14/80] Allow several spaces between numbers in OBJ files. --- code/ObjFileParser.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index f2e65db71..e9a1dd9ef 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -113,8 +113,8 @@ void ObjFileParser::parseFile() getVector3(m_pModel->m_Vertices); } else if (*m_DataIt == 't') { // read in texture coordinate ( 2D or 3D ) - ++m_DataIt; - getVector( m_pModel->m_TextureCoord ); + ++m_DataIt; + getVector( m_pModel->m_TextureCoord ); } else if (*m_DataIt == 'n') { // Read in normal vector definition ++m_DataIt; @@ -234,11 +234,17 @@ void ObjFileParser::copyNextLine(char *pBuffer, size_t length) void ObjFileParser::getVector( std::vector &point3d_array ) { size_t numComponents( 0 ); DataArrayIt tmp( m_DataIt ); - while( !IsLineEnd( *tmp ) ) { - if( *tmp == ' ' ) { - ++numComponents; + while( true ) { + while( isspace(*tmp) && !IsLineEnd(*tmp) ) { + tmp++; } - tmp++; + if( IsLineEnd(*tmp) ) { + break; + } + while( !isspace(*tmp) ) { + tmp++; + } + ++numComponents; } float x, y, z; if( 2 == numComponents ) { From fcf08174b121df76b1f7b13a2b193e9183886f64 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Tue, 22 Jul 2014 17:32:09 +0200 Subject: [PATCH 15/80] Cleanup CMakeLists for unit tests, drop unneeded Windows dependency. --- test/CMakeLists.txt | 127 ++++++-------------------------------------- 1 file changed, 17 insertions(+), 110 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 87c36a893..544b57a57 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,7 +15,8 @@ SOURCE_GROUP( unit FILES unit/BoostWorkaround/tupletest.cpp ) -SOURCE_GROUP( cppunit FILES + +SET( CPPUNIT_SRCS ../contrib/cppunit-1.12.1/src/cppunit/AdditionalMessage.cpp ../contrib/cppunit-1.12.1/src/cppunit/Asserter.cpp ../contrib/cppunit-1.12.1/src/cppunit/BeOsDynamicLibraryManager.cpp @@ -70,59 +71,10 @@ SOURCE_GROUP( cppunit FILES ../contrib/cppunit-1.12.1/src/cppunit/XmlOutputter.cpp ../contrib/cppunit-1.12.1/src/cppunit/XmlOutputterHook.cpp ) +SOURCE_GROUP(cppunit FILES ${CPPUNIT_SRCS}) -SOURCE_GROUP( tests FILES - unit/Main.cpp - unit/UnitTestPCH.cpp - unit/UnitTestPCH.h - unit/utFindDegenerates.cpp - unit/utFindDegenerates.h - unit/utFindInvalidData.cpp - unit/utFindInvalidData.h - unit/utFixInfacingNormals.cpp - unit/utGenNormals.cpp - unit/utGenNormals.h - unit/utImporter.cpp - unit/utImporter.h - unit/utImproveCacheLocality.cpp - unit/utJoinVertices.cpp - unit/utJoinVertices.h - unit/utLimitBoneWeights.cpp - unit/utLimitBoneWeights.h - unit/utMaterialSystem.cpp - unit/utMaterialSystem.h - unit/utPretransformVertices.cpp - unit/utPretransformVertices.h - unit/utRemoveComments.cpp - unit/utRemoveComments.h - unit/utRemoveComponent.cpp - unit/utRemoveComponent.h - unit/utRemoveRedundantMaterials.cpp - unit/utRemoveRedundantMaterials.h - unit/utScenePreprocessor.cpp - unit/utScenePreprocessor.h - unit/utSharedPPData.cpp - unit/utSharedPPData.h - unit/utSortByPType.cpp - unit/utSortByPType.h - unit/utSplitLargeMeshes.cpp - unit/utSplitLargeMeshes.h - unit/utTargetAnimation.cpp - unit/utTargetAnimation.h - unit/utTextureTransform.cpp - unit/utTriangulate.cpp - unit/utTriangulate.h - unit/utVertexTriangleAdjacency.cpp - unit/utVertexTriangleAdjacency.h - unit/utNoBoostTest.cpp - unit/utNoBoostTest.h -) -add_executable( unit - unit/CCompilerTest.c - unit/Main.cpp - unit/UnitTestPCH.cpp - unit/UnitTestPCH.h +SET( TEST_SRCS unit/utFindDegenerates.cpp unit/utFindDegenerates.h unit/utFindInvalidData.cpp @@ -165,65 +117,20 @@ add_executable( unit unit/utNoBoostTest.cpp unit/utNoBoostTest.h unit/BoostWorkaround/tupletest.cpp - ../contrib/cppunit-1.12.1/src/cppunit/AdditionalMessage.cpp - ../contrib/cppunit-1.12.1/src/cppunit/Asserter.cpp - ../contrib/cppunit-1.12.1/src/cppunit/BeOsDynamicLibraryManager.cpp - ../contrib/cppunit-1.12.1/src/cppunit/BriefTestProgressListener.cpp - ../contrib/cppunit-1.12.1/src/cppunit/CompilerOutputter.cpp - ../contrib/cppunit-1.12.1/src/cppunit/DefaultProtector.cpp - ../contrib/cppunit-1.12.1/src/cppunit/DefaultProtector.h - ../contrib/cppunit-1.12.1/src/cppunit/DllMain.cpp - ../contrib/cppunit-1.12.1/src/cppunit/DynamicLibraryManager.cpp - ../contrib/cppunit-1.12.1/src/cppunit/DynamicLibraryManagerException.cpp - ../contrib/cppunit-1.12.1/src/cppunit/Exception.cpp - ../contrib/cppunit-1.12.1/src/cppunit/Message.cpp - ../contrib/cppunit-1.12.1/src/cppunit/PlugInManager.cpp - ../contrib/cppunit-1.12.1/src/cppunit/PlugInParameters.cpp - ../contrib/cppunit-1.12.1/src/cppunit/Protector.cpp - ../contrib/cppunit-1.12.1/src/cppunit/ProtectorChain.cpp - ../contrib/cppunit-1.12.1/src/cppunit/ProtectorChain.h - ../contrib/cppunit-1.12.1/src/cppunit/ProtectorContext.h - ../contrib/cppunit-1.12.1/src/cppunit/RepeatedTest.cpp - ../contrib/cppunit-1.12.1/src/cppunit/ShlDynamicLibraryManager.cpp - ../contrib/cppunit-1.12.1/src/cppunit/SourceLine.cpp - ../contrib/cppunit-1.12.1/src/cppunit/StringTools.cpp - ../contrib/cppunit-1.12.1/src/cppunit/SynchronizedObject.cpp - ../contrib/cppunit-1.12.1/src/cppunit/Test.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestAssert.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestCase.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestCaseDecorator.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestComposite.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestDecorator.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestFactoryRegistry.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestFailure.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestLeaf.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestNamer.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestPath.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestPlugInDefaultImpl.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestResult.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestResultCollector.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestRunner.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestSetUp.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestSuccessListener.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestSuite.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TestSuiteBuilderContext.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TextOutputter.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TextTestProgressListener.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TextTestResult.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TextTestRunner.cpp - ../contrib/cppunit-1.12.1/src/cppunit/TypeInfoHelper.cpp - ../contrib/cppunit-1.12.1/src/cppunit/UnixDynamicLibraryManager.cpp - ../contrib/cppunit-1.12.1/src/cppunit/Win32DynamicLibraryManager.cpp - ../contrib/cppunit-1.12.1/src/cppunit/XmlDocument.cpp - ../contrib/cppunit-1.12.1/src/cppunit/XmlElement.cpp - ../contrib/cppunit-1.12.1/src/cppunit/XmlOutputter.cpp - ../contrib/cppunit-1.12.1/src/cppunit/XmlOutputterHook.cpp ) -IF( WIN32 ) - FIND_PACKAGE(DirectX REQUIRED) -ENDIF( WIN32 ) +SOURCE_GROUP(tests FILES ${TEST_SRCS}) + + +add_executable( unit + unit/CCompilerTest.c + unit/Main.cpp + unit/UnitTestPCH.cpp + unit/UnitTestPCH.h + ${TEST_SRCS} + ${CPPUNIT_SRCS} +) + SET_PROPERTY(TARGET assimp PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX}) -# TODO: Port to non-Windows platforms. -target_link_libraries ( unit assimp ${DirectX_LIBRARY} ${DirectX_D3DX9_LIBRARY} comctl32.lib Winmm.lib ) +target_link_libraries ( unit assimp ) From 3419fedb3cfb1117db816c36b35c9d4e5c0dd2e7 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Tue, 22 Jul 2014 17:55:37 +0200 Subject: [PATCH 16/80] Add StreamWriter utility (mostly symmetric to StreamReader). --- code/StreamWriter.h | 209 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 code/StreamWriter.h diff --git a/code/StreamWriter.h b/code/StreamWriter.h new file mode 100644 index 000000000..d4e5e99ac --- /dev/null +++ b/code/StreamWriter.h @@ -0,0 +1,209 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Defines the StreamWriter class which writes data to + * a binary stream with a well-defined endianess. */ + +#ifndef AI_STREAMWRITER_H_INCLUDED +#define AI_STREAMWRITER_H_INCLUDED + +#include "ByteSwap.h" + +namespace Assimp { + +// -------------------------------------------------------------------------------------------- +/** Wrapper class around IOStream to allow for consistent writing of binary data in both + * little and big endian format. Don't attempt to instance the template directly. Use + * StreamWriterLE to read from a little-endian stream and StreamWriterBE to read from a + * BE stream. Alternatively, there is StreamWriterAny if the endianess of the output + * stream is to be determined at runtime. + */ +// -------------------------------------------------------------------------------------------- +template +class StreamWriter +{ +public: + + typedef std::size_t diff; + typedef std::size_t pos; + +public: + + // --------------------------------------------------------------------- + /** Construction from a given stream with a well-defined endianess. + * + * The StreamReader holds a permanent strong reference to the + * stream, which is released upon destruction. + * @param stream Input stream. The stream is not re-seeked and writing + continues at the current position of the stream cursor. + * @param le If @c RuntimeSwitch is true: specifies whether the + * stream is in little endian byte order. Otherwise the + * endianess information is defined by the @c SwapEndianess + * template parameter and this parameter is meaningless. */ + StreamWriter(boost::shared_ptr stream, bool le = false) + : stream(stream) + , le(le) + { + ai_assert(stream); + InternBegin(); + } + + // --------------------------------------------------------------------- + StreamWriter(IOStream* stream, bool le = false) + : stream(boost::shared_ptr(stream)) + , le(le) + { + ai_assert(stream); + InternBegin(); + } + + // --------------------------------------------------------------------- + ~StreamWriter() { + delete[] buffer; + } + +public: + + // --------------------------------------------------------------------- + /** Write a float to the stream */ + void PutF4(float f) + { + Put(f); + } + + // --------------------------------------------------------------------- + /** Write a double to the stream */ + void PutF8(double d) { + Put(d); + } + + // --------------------------------------------------------------------- + /** Write a signed 16 bit integer to the stream */ + void PutI2(int16_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a signed 8 bit integer to the stream */ + void PutI1(int8_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write an signed 32 bit integer to the stream */ + void PutI4(int32_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a signed 64 bit integer to the stream */ + void PutI8(int64_t n) { + Putn(); + } + + // --------------------------------------------------------------------- + /** Write a unsigned 16 bit integer to the stream */ + void PutU2(uint16_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a unsigned 8 bit integer to the stream */ + void PutU1(uint8_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write an unsigned 32 bit integer to the stream */ + void PutU4(uint32_t n) { + Put(n); + } + + // --------------------------------------------------------------------- + /** Write a unsigned 64 bit integer to the stream */ + void PutU8(uint64_t n) { + Put(n); + } + +public: + + // --------------------------------------------------------------------- + /** overload operator<< and allow chaining of MM ops. */ + template + StreamWriter& operator << (T f) { + Put(f); + return *this; + } + +private: + + // --------------------------------------------------------------------- + /** Generic write method. ByteSwap::Swap(T*) *must* be defined */ + template + void Put(T f) { + Intern :: Getter() (&f, le); + stream->Write(&f, sizeof(T), 1); + } + +private: + + boost::shared_ptr stream; + bool le; +}; + + +// -------------------------------------------------------------------------------------------- +// `static` StreamWriter. Their byte order is fixed and they might be a little bit faster. +#ifdef AI_BUILD_BIG_ENDIAN + typedef StreamWriter StreamWriterLE; + typedef StreamWriter StreamWriterBE; +#else + typedef StreamWriter StreamWriterBE; + typedef StreamWriter StreamWriterLE; +#endif + +// `dynamic` StreamWriter. The byte order of the input data is specified in the +// c'tor. This involves runtime branching and might be a little bit slower. +typedef StreamWriter StreamWriterAny; + +} // end namespace Assimp + +#endif // !! AI_STREAMWriter_H_INCLUDED From cc32eda2264bccc3b775ea44c832a0fbce1cc6b9 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Tue, 22 Jul 2014 20:35:09 +0200 Subject: [PATCH 17/80] assimp_view: fix crash when trying to export while no model is loaded. --- tools/assimp_view/MessageProc.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/assimp_view/MessageProc.cpp b/tools/assimp_view/MessageProc.cpp index c32cbde61..0b95a8ec6 100644 --- a/tools/assimp_view/MessageProc.cpp +++ b/tools/assimp_view/MessageProc.cpp @@ -1030,18 +1030,17 @@ void PopulateExportMenu() //------------------------------------------------------------------------------- void DoExport(size_t formatId) { - if (!g_szFileName) { + if (!g_szFileName[0]) { + MessageBox(g_hDlg, "No model loaded", "Export", MB_ICONERROR); return; } - Exporter exp; const aiExportFormatDesc* const e = exp.GetExportFormatDescription(formatId); ai_assert(e); char szFileName[MAX_PATH*2]; - DWORD dwTemp; - if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"ModelExportDest",NULL,NULL,(BYTE*)szFileName,&dwTemp)) { - ai_assert(dwTemp == MAX_PATH + 1); + DWORD dwTemp = sizeof(szFileName); + if(ERROR_SUCCESS == RegQueryValueEx(g_hRegistry,"ModelExportDest",NULL,NULL,(BYTE*)szFileName, &dwTemp)) { ai_assert(strlen(szFileName) <= MAX_PATH); // invent a nice default file name From 0166518132d66b48450dbc5265bc3e155967302f Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Tue, 22 Jul 2014 20:36:16 +0200 Subject: [PATCH 18/80] Extend StreamWriter to write to a buffer and to allow re-positioning of the write cursor within the buffer. --- code/StreamWriter.h | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/code/StreamWriter.h b/code/StreamWriter.h index d4e5e99ac..e35953c72 100644 --- a/code/StreamWriter.h +++ b/code/StreamWriter.h @@ -60,10 +60,9 @@ namespace Assimp { template class StreamWriter { -public: - - typedef std::size_t diff; - typedef std::size_t pos; + enum { + INITIAL_CAPACITY = 1024 + }; public: @@ -83,7 +82,7 @@ public: , le(le) { ai_assert(stream); - InternBegin(); + buffer.reserve(INITIAL_CAPACITY); } // --------------------------------------------------------------------- @@ -92,12 +91,13 @@ public: , le(le) { ai_assert(stream); - InternBegin(); + buffer.reserve(INITIAL_CAPACITY); } // --------------------------------------------------------------------- ~StreamWriter() { - delete[] buffer; + stream->Write(&buffer[0], 1, buffer.size()); + stream->Flush(); } public: @@ -173,6 +173,16 @@ public: return *this; } + // --------------------------------------------------------------------- + std::size_t GetCurrentPos() const { + return cursor; + } + + // --------------------------------------------------------------------- + void SetCurrentPos(std::size_t new_cursor) { + cursor = new_cursor; + } + private: // --------------------------------------------------------------------- @@ -180,13 +190,27 @@ private: template void Put(T f) { Intern :: Getter() (&f, le); - stream->Write(&f, sizeof(T), 1); + + if (cursor + sizeof(T) >= buffer.size()) { + buffer.resize(cursor + sizeof(T)); + } + + void* dest = &buffer[cursor]; + + // reinterpret_cast + assignment breaks strict aliasing rules + // and generally causes trouble on platforms such as ARM that + // do not silently ignore alignment faults. + ::memcpy(dest, &f, sizeof(T)); + cursor += sizeof(T); } private: boost::shared_ptr stream; bool le; + + std::vector buffer; + std::size_t cursor; }; From 79c56adea40686bb822c75ec12a72a945d079f41 Mon Sep 17 00:00:00 2001 From: Tyson Grant Nottingham Date: Tue, 22 Jul 2014 21:58:41 -0700 Subject: [PATCH 19/80] Don't use isdigit() in fast_atof. --- code/fast_atof.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/fast_atof.h b/code/fast_atof.h index a7f0cb23f..4ff666b38 100644 --- a/code/fast_atof.h +++ b/code/fast_atof.h @@ -236,7 +236,8 @@ inline const char* fast_atoreal_move( const char* c, Real& out, bool check_comma ++c; } - if (!isdigit(*c) && !(*c == '.' && isdigit(c[1]))) + if (!(c[0] >= '0' && c[0] <= '9') && + !(c[0] == '.' && c[1] >= '0' && c[1] <= '9')) { throw std::invalid_argument("Cannot parse string " "as real number: does not start with digit " From 0c5605d07df4f3faa0be7b55cc197ff979f35d84 Mon Sep 17 00:00:00 2001 From: Tyson Grant Nottingham Date: Tue, 22 Jul 2014 21:59:23 -0700 Subject: [PATCH 20/80] Don't use isspace() in OBJ file parser. --- code/ObjFileParser.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index e9a1dd9ef..6e73f0bf4 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -233,17 +233,12 @@ void ObjFileParser::copyNextLine(char *pBuffer, size_t length) // ------------------------------------------------------------------- void ObjFileParser::getVector( std::vector &point3d_array ) { size_t numComponents( 0 ); - DataArrayIt tmp( m_DataIt ); - while( true ) { - while( isspace(*tmp) && !IsLineEnd(*tmp) ) { - tmp++; - } - if( IsLineEnd(*tmp) ) { + const char* tmp( &m_DataIt[0] ); + while( !IsLineEnd( *tmp ) ) { + if ( !SkipSpaces( &tmp ) ) { break; } - while( !isspace(*tmp) ) { - tmp++; - } + SkipToken( tmp ); ++numComponents; } float x, y, z; From 084ab9d82e8415c8c4e5bafca6343fedc85a49b2 Mon Sep 17 00:00:00 2001 From: Tyson Grant Nottingham Date: Tue, 22 Jul 2014 22:00:47 -0700 Subject: [PATCH 21/80] Add test OBJ containing various number formats. --- test/models/OBJ/number_formats.obj | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 test/models/OBJ/number_formats.obj diff --git a/test/models/OBJ/number_formats.obj b/test/models/OBJ/number_formats.obj new file mode 100644 index 000000000..12b21bf44 --- /dev/null +++ b/test/models/OBJ/number_formats.obj @@ -0,0 +1,23 @@ +v 0 0 0 + +v 1 2. 3.0 +v +1 +2. +3.0 +v -1 -2. -3.0 + +v 1e2 2.e1 3.1e2 +v +1e2 +2.e1 +3.1e2 +v -1e2 -2.e1 -3.1e2 + +v 1e+2 2.e+1 3.1+e2 +v +1e+2 +2.e+1 +3.1+e2 +v -1e+2 -2.e+1 -3.1+e2 + +v 1e-2 2.e-1 3.1-e2 +v +1e-2 +2.e-1 +3.1-e2 +v -1e-2 -2.e-1 -3.1-e2 + +v 1e10 2.e01 3.1e10 + +v 1E2 2.E1 3.1E2 + +f 1 2 4 From f96375b5f6c039caf4abe95f97dcdfc1c2f8f614 Mon Sep 17 00:00:00 2001 From: Tyson Grant Nottingham Date: Tue, 22 Jul 2014 22:01:18 -0700 Subject: [PATCH 22/80] Add test OBJ w/ multiple spaces between elements. --- test/models/OBJ/multiple_spaces.obj | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 test/models/OBJ/multiple_spaces.obj diff --git a/test/models/OBJ/multiple_spaces.obj b/test/models/OBJ/multiple_spaces.obj new file mode 100644 index 000000000..4f27a0342 --- /dev/null +++ b/test/models/OBJ/multiple_spaces.obj @@ -0,0 +1,11 @@ +v 1.0 2.0 3.0 +v 2.0 3.0 1.0 +v 3.0 1.0 2.0 +v 1.0 2.0 3.0 + +vt 1.0 2.0 3.0 +vt 2.0 3.0 1.0 +vt 3.0 1.0 2.0 +vt 1.0 2.0 3.0 + +f 1 2 3 From 6fde07f7e507871c91eb267db143a1f1e05dc6a0 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Wed, 23 Jul 2014 18:27:22 +0200 Subject: [PATCH 23/80] Initial implementation of 3DS Exporter. Hierarchy exporting and smoothing groups missing. --- code/3DSExporter.cpp | 498 +++++++++++++++++++++++++++++++++++++++++++ code/3DSExporter.h | 92 ++++++++ code/CMakeLists.txt | 3 + code/Exporter.cpp | 11 +- code/StreamWriter.h | 2 + 5 files changed, 601 insertions(+), 5 deletions(-) create mode 100644 code/3DSExporter.cpp create mode 100644 code/3DSExporter.h diff --git a/code/3DSExporter.cpp b/code/3DSExporter.cpp new file mode 100644 index 000000000..7f4a292fa --- /dev/null +++ b/code/3DSExporter.cpp @@ -0,0 +1,498 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#include "AssimpPCH.h" + +#ifndef ASSIMP_BUILD_NO_EXPORT +#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER + +#include "3DSExporter.h" +#include "3DSLoader.h" +#include "SceneCombiner.h" +#include "SplitLargeMeshes.h" + +using namespace Assimp; +namespace Assimp { + +namespace { + + ////////////////////////////////////////////////////////////////////////////////////// + // Scope utility to write a 3DS file chunk. + // + // Upon construction, the chunk header is written with the chunk type (flags) + // filled out, but the chunk size left empty. Upon destruction, the correct chunk + // size based on the then-position of the output stream cursor is filled in. + class ChunkWriter { + enum { + CHUNK_SIZE_NOT_SET = 0xdeadbeef + , SIZE_OFFSET = 2 + }; + public: + + ChunkWriter(StreamWriterLE& writer, uint16_t chunk_type) + : writer(writer) + { + chunk_start_pos = writer.GetCurrentPos(); + writer.PutU2(chunk_type); + writer.PutU4(CHUNK_SIZE_NOT_SET); + } + + ~ChunkWriter() { + std::size_t head_pos = writer.GetCurrentPos(); + + ai_assert(head_pos > chunk_start_pos); + const std::size_t chunk_size = head_pos - chunk_start_pos; + + writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET); + writer.PutU4(chunk_size); + writer.SetCurrentPos(head_pos); + } + + private: + StreamWriterLE& writer; + std::size_t chunk_start_pos; + }; + + + // Return an unique name for a given |mesh| attached to |node| that + // preserves the mesh's given name if it has one. |index| is the index + // of the mesh in |aiScene::mMeshes|. + std::string GetMeshName(const aiMesh& mesh, unsigned int index, const aiNode& node) { + static const std::string underscore = "_"; + char postfix[10] = {0}; + ASSIMP_itoa10(postfix, index); + + std::string result = node.mName.C_Str(); + if (mesh.mName.length > 0) { + result += underscore + mesh.mName.C_Str(); + } + return result + underscore + postfix; + } + + // Return an unique name for a given |mat| with original position |index| + // in |aiScene::mMaterials|. The name preserves the original material + // name if possible. + std::string GetMaterialName(const aiMaterial& mat, unsigned int index) { + static const std::string underscore = "_"; + char postfix[10] = {0}; + ASSIMP_itoa10(postfix, index); + + aiString mat_name; + if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) { + return mat_name.C_Str() + underscore + postfix; + } + + return "Material" + underscore + postfix; + } + + // Collect world transformations for each node + void CollectTrafos(const aiNode* node, std::map& trafos) { + const aiMatrix4x4& parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4(); + trafos[node] = parent * node->mTransformation; + for (unsigned int i = 0; i < node->mNumChildren; ++i) { + CollectTrafos(node->mChildren[i], trafos); + } + } + + // Generate a flat list of the meshes (by index) assigned to each node + void CollectMeshes(const aiNode* node, std::multimap& meshes) { + for (unsigned int i = 0; i < node->mNumMeshes; ++i) { + meshes.insert(std::make_pair(node, node->mMeshes[i])); + } + for (unsigned int i = 0; i < node->mNumChildren; ++i) { + CollectMeshes(node->mChildren[i], meshes); + } + } +} + +// ------------------------------------------------------------------------------------------------ +// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp +void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) +{ + boost::shared_ptr outfile (pIOSystem->Open(pFile, "wb")); + if(outfile == NULL) { + throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile)); + } + + // TODO: This extra copy should be avoided and all of this made a preprocess + // requirement of the 3DS exporter. + // + // 3DS meshes can be max 0xffff (16 Bit) vertices and faces, respectively. + // SplitLargeMeshes can do this, but it requires the correct limit to be set + // which is not possible with the current way of specifying preprocess steps + // in |Exporter::ExportFormatEntry|. + aiScene* scenecopy_tmp; + SceneCombiner::CopyScene(&scenecopy_tmp,pScene); + std::auto_ptr scenecopy(scenecopy_tmp); + + SplitLargeMeshesProcess_Triangle tri_splitter; + tri_splitter.SetLimit(0xffff); + tri_splitter.Execute(scenecopy.get()); + + SplitLargeMeshesProcess_Vertex vert_splitter; + vert_splitter.SetLimit(0xffff); + vert_splitter.Execute(scenecopy.get()); + + // Invoke the actual exporter + Discreet3DSExporter exporter(outfile, scenecopy.get()); +} + +} // end of namespace Assimp + +// ------------------------------------------------------------------------------------------------ +Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr outfile, const aiScene* scene) +: scene(scene) +, writer(outfile) +{ + + CollectTrafos(scene->mRootNode, trafos); + CollectMeshes(scene->mRootNode, meshes); + + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAIN); + + { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH); + WriteMeshes(); + WriteMaterials(); + } + + { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER); + } +} + +// ------------------------------------------------------------------------------------------------ +void Discreet3DSExporter::WriteMaterials() +{ + for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL); + + const aiMaterial& mat = *scene->mMaterials[i]; + + { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATNAME); + const std::string& name = GetMaterialName(mat, i); + WriteString(name); + } + + aiColor3D color; + if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE); + WriteColor(color); + } + + if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR); + WriteColor(color); + } + + if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT); + WriteColor(color); + } + + if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM); + WriteColor(color); + } + + aiShadingMode shading_mode; + if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING); + + Discreet3DS::shadetype3ds shading_mode_out; + switch(shading_mode) { + case aiShadingMode_Flat: + case aiShadingMode_NoShading: + shading_mode_out = Discreet3DS::Flat; + break; + + case aiShadingMode_Gouraud: + case aiShadingMode_Toon: + case aiShadingMode_OrenNayar: + case aiShadingMode_Minnaert: + shading_mode_out = Discreet3DS::Gouraud; + break; + + case aiShadingMode_Phong: + case aiShadingMode_Blinn: + case aiShadingMode_CookTorrance: + case aiShadingMode_Fresnel: + shading_mode_out = Discreet3DS::Phong; + break; + + default: + ai_assert(false); + }; + writer.PutU2(static_cast(shading_mode_out)); + } + + + float f; + if (mat.Get(AI_MATKEY_SHININESS, f) == AI_SUCCESS) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS); + WritePercentChunk(f); + } + + if (mat.Get(AI_MATKEY_SHININESS_STRENGTH, f) == AI_SUCCESS) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS_PERCENT); + WritePercentChunk(f); + } + + int twosided; + if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE); + // Intentionally no more data - if the chunk exists, the TWOSIDED + // flag is assumed to be set. + } + + WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE); + WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP); + WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP); + WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP); + WriteTexture(mat, aiTextureType_SPECULAR, Discreet3DS::CHUNK_MAT_SPECMAP); + WriteTexture(mat, aiTextureType_EMISSIVE, Discreet3DS::CHUNK_MAT_SELFIMAP); + WriteTexture(mat, aiTextureType_REFLECTION, Discreet3DS::CHUNK_MAT_REFLMAP); + } +} + +// ------------------------------------------------------------------------------------------------ +void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags) +{ + aiString path; + aiTextureMapMode map_mode = aiTextureMapMode_Wrap; + float blend = 1.0f; + if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, &map_mode) != AI_SUCCESS || !path.length) { + return; + } + + // TODO: handle embedded textures properly + if (path.data[0] == '*') { + DefaultLogger::get()->error("Ignoring embedded texture for export: " + std::string(path.C_Str())); + return; + } + + ChunkWriter(writer, chunk_flags); + { + ChunkWriter(writer, Discreet3DS::CHUNK_MAPFILE); + WriteString(path); + } + + WritePercentChunk(blend); + + { + ChunkWriter(writer, Discreet3DS::CHUNK_MAT_MAP_TILING); + uint16_t val = 0; // WRAP + if (map_mode == aiTextureMapMode_Mirror) { + val = 0x2; + } + else if (map_mode == aiTextureMapMode_Decal) { + val = 0x10; + } + writer.PutU2(val); + } + // TODO: export texture transformation (i.e. UV offset, scale, rotation) +} + +// ------------------------------------------------------------------------------------------------ +void Discreet3DSExporter::WriteMeshes() +{ + // NOTE: 3DS allows for instances. However: + // i) not all importers support reading them + // ii) instances are not as flexible as they are in assimp, in particular, + // nodes can carry (and instance) only one mesh. + // + // This exporter currently deep clones all instanced meshes, i.e. for each mesh + // attached to a node a full TRIMESH chunk is written to the file. + // + // Furthermore, the TRIMESH is transformed into world space so that it will + // appear correctly if importers don't read the scene hierarchy at all. + for (MeshesByNodeMap::const_iterator it = meshes.begin(); it != meshes.end(); ++it) { + const aiNode& node = *(*it).first; + const unsigned int mesh_idx = (*it).second; + + const aiMesh& mesh = *scene->mMeshes[mesh_idx]; + + // This should not happen if the SLM step is correctly executed + // before the scene is handed to the exporter + ai_assert(mesh.mNumVertices <= 0xffff); + ai_assert(mesh.mNumFaces <= 0xffff); + + const aiMatrix4x4& trafo = trafos[&node]; + + ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJBLOCK); + + // Mesh name is tied to the node it is attached to so it can later be referenced + const std::string& name = GetMeshName(mesh, mesh_idx, node); + WriteString(name); + + + // TRIMESH chunk + ChunkWriter chunk2(writer, Discreet3DS::CHUNK_TRIMESH); + + // Vertices in world space + { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_VERTLIST); + + const uint16_t count = static_cast(mesh.mNumVertices); + writer.PutU2(count); + for (unsigned int i = 0; i < mesh.mNumVertices; ++i) { + const aiVector3D& v = trafo * mesh.mVertices[i]; + writer.PutF4(v.x); + writer.PutF4(v.y); + writer.PutF4(v.z); + } + } + + // UV coordinates + if (mesh.HasTextureCoords(0)) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPLIST); + const uint16_t count = static_cast(mesh.mNumVertices); + writer.PutU2(count); + + for (unsigned int i = 0; i < mesh.mNumVertices; ++i) { + const aiVector3D& v = mesh.mTextureCoords[0][i]; + writer.PutF4(v.x); + writer.PutF4(v.y); + } + } + + // Faces (indices) + { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACELIST); + + ai_assert(mesh.mNumFaces <= 0xffff); + + // Count triangles, discard lines and points + uint16_t count = 0; + for (unsigned int i = 0; i < mesh.mNumFaces; ++i) { + const aiFace& f = mesh.mFaces[i]; + if (f.mNumIndices < 3) { + continue; + } + // TRIANGULATE step is a pre-requisite so we should not see polys here + ai_assert(f.mNumIndices == 3); + ++count; + } + + writer.PutU2(count); + for (unsigned int i = 0; i < mesh.mNumFaces; ++i) { + const aiFace& f = mesh.mFaces[i]; + if (f.mNumIndices < 3) { + continue; + } + + for (unsigned int j = 0; j < 3; ++j) { + ai_assert(f.mIndices[j] <= 0xffff); + writer.PutI2(static_cast(f.mIndices[j])); + } + + // Edge visibility flag + writer.PutI2(0x0); + } + + // TODO: write smoothing groups (CHUNK_SMOOLIST) + + WriteFaceMaterialChunk(mesh); + } + + // Transformation matrix by which the mesh vertices have been pre-transformed with. + { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRMATRIX); + for (unsigned int r = 0; r < 4; ++r) { + for (unsigned int c = 0; c < 3; ++c) { + writer.PutF4(trafo[r][c]); + } + } + } + } +} + +// ------------------------------------------------------------------------------------------------ +void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh) +{ + ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACEMAT); + const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex); + WriteString(name); + + // Because assimp splits meshes by material, only a single + // FACEMAT chunk needs to be written + ai_assert(mesh.mNumFaces <= 0xffff); + const uint16_t count = static_cast(mesh.mNumFaces); + writer.PutU2(count); + + for (unsigned int i = 0; i < mesh.mNumFaces; ++i) { + writer.PutU2(static_cast(i)); + } +} + +// ------------------------------------------------------------------------------------------------ +void Discreet3DSExporter::WriteString(const std::string& s) { + for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) { + writer.PutI1(*it); + } + writer.PutI1('\0'); +} + +// ------------------------------------------------------------------------------------------------ +void Discreet3DSExporter::WriteString(const aiString& s) { + for (std::size_t i = 0; i < s.length; ++i) { + writer.PutI1(s.data[i]); + } + writer.PutI1('\0'); +} + +// ------------------------------------------------------------------------------------------------ +void Discreet3DSExporter::WriteColor(const aiColor3D& color) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_RGBF); + writer.PutF4(color.r); + writer.PutF4(color.g); + writer.PutF4(color.b); +} + +// ------------------------------------------------------------------------------------------------ +void Discreet3DSExporter::WritePercentChunk(float f) { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTF); + writer.PutF4(f); +} + + +#endif // ASSIMP_BUILD_NO_3DS_EXPORTER +#endif // ASSIMP_BUILD_NO_EXPORT diff --git a/code/3DSExporter.h b/code/3DSExporter.h new file mode 100644 index 000000000..bb474f062 --- /dev/null +++ b/code/3DSExporter.h @@ -0,0 +1,92 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file 3DSExporter.h + * 3DS Exporter Main Header + */ +#ifndef AI_3DSEXPORTER_H_INC +#define AI_3DSEXPORTER_H_INC + +#include + +#include "StreamWriter.h" + +struct aiScene; +struct aiNode; + +namespace Assimp +{ + +// ------------------------------------------------------------------------------------------------ +/** Helper class to export a given scene to a 3DS file. */ +// ------------------------------------------------------------------------------------------------ +class Discreet3DSExporter +{ +public: + Discreet3DSExporter(boost::shared_ptr outfile, const aiScene* pScene); + +private: + + void WriteMeshes(); + void WriteMaterials(); + void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags); + + void WriteFaceMaterialChunk(const aiMesh& mesh); + + void WriteString(const std::string& s); + void WriteString(const aiString& s); + void WriteColor(const aiColor3D& color); + void WritePercentChunk(float f); + +private: + + const aiScene* const scene; + StreamWriterLE writer; + + std::map trafos; + + typedef std::multimap MeshesByNodeMap; + MeshesByNodeMap meshes; + +}; + +} + +#endif diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 0533a05fd..15cbe1321 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -111,6 +111,7 @@ SET( Common_SRCS MemoryIOWrapper.h ParsingUtils.h StreamReader.h + StreamWriter.h StringComparison.h SGSpatialSort.cpp SGSpatialSort.h @@ -151,6 +152,8 @@ SET( 3DS_SRCS 3DSHelper.h 3DSLoader.cpp 3DSLoader.h + 3DSExporter.h + 3DSExporter.cpp ) SOURCE_GROUP(3DS FILES ${3DS_SRCS}) diff --git a/code/Exporter.cpp b/code/Exporter.cpp index 18bf77e4a..7f51fb71f 100644 --- a/code/Exporter.cpp +++ b/code/Exporter.cpp @@ -78,7 +78,7 @@ 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*) {} +void ExportScene3DS(const char*, IOSystem*, const aiScene*); // ------------------------------------------------------------------------------------------------ // global array of all export formats which Assimp supports in its current build @@ -90,7 +90,7 @@ Exporter::ExportFormatEntry gExporters[] = #ifndef ASSIMP_BUILD_NO_FXILE_EXPORTER Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile, - aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs), + aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs), #endif #ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER @@ -113,9 +113,10 @@ Exporter::ExportFormatEntry gExporters[] = ), #endif -//#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER -// ExportFormatEntry( "3ds", "Autodesk 3DS (legacy format)", "3ds" , &ExportScene3DS), -//#endif +#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER + Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS, + aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices), +#endif }; #define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0])) diff --git a/code/StreamWriter.h b/code/StreamWriter.h index e35953c72..5ea6206d1 100644 --- a/code/StreamWriter.h +++ b/code/StreamWriter.h @@ -80,6 +80,7 @@ public: StreamWriter(boost::shared_ptr stream, bool le = false) : stream(stream) , le(le) + , cursor() { ai_assert(stream); buffer.reserve(INITIAL_CAPACITY); @@ -89,6 +90,7 @@ public: StreamWriter(IOStream* stream, bool le = false) : stream(boost::shared_ptr(stream)) , le(le) + , cursor() { ai_assert(stream); buffer.reserve(INITIAL_CAPACITY); From d5db6f39e603dc4da9e7cf85ba4666be7b538eae Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Wed, 23 Jul 2014 18:54:05 +0200 Subject: [PATCH 24/80] Fix CI build. --- code/StreamWriter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/StreamWriter.h b/code/StreamWriter.h index 5ea6206d1..afa8d2489 100644 --- a/code/StreamWriter.h +++ b/code/StreamWriter.h @@ -138,7 +138,7 @@ public: // --------------------------------------------------------------------- /** Write a signed 64 bit integer to the stream */ void PutI8(int64_t n) { - Putn(); + Put(n); } // --------------------------------------------------------------------- From 026f32733dfe7c8981a2a6cd3c24a9f6fdcc01b8 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Wed, 23 Jul 2014 20:14:32 +0200 Subject: [PATCH 25/80] 3DS Export: fix texture export. --- code/3DSExporter.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/code/3DSExporter.cpp b/code/3DSExporter.cpp index 7f4a292fa..c455167b9 100644 --- a/code/3DSExporter.cpp +++ b/code/3DSExporter.cpp @@ -181,7 +181,6 @@ Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr outfile, c : scene(scene) , writer(outfile) { - CollectTrafos(scene->mRootNode, trafos); CollectMeshes(scene->mRootNode, meshes); @@ -191,6 +190,11 @@ Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr outfile, c ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH); WriteMeshes(); WriteMaterials(); + + { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE); + writer.PutF4(1.0f); + } } { @@ -203,7 +207,6 @@ void Discreet3DSExporter::WriteMaterials() { for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL); - const aiMaterial& mat = *scene->mMaterials[i]; { @@ -279,10 +282,9 @@ void Discreet3DSExporter::WriteMaterials() int twosided; if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) { ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE); - // Intentionally no more data - if the chunk exists, the TWOSIDED - // flag is assumed to be set. + writer.PutI2(1); } - + WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE); WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP); WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP); @@ -297,9 +299,11 @@ void Discreet3DSExporter::WriteMaterials() void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags) { aiString path; - aiTextureMapMode map_mode = aiTextureMapMode_Wrap; + aiTextureMapMode map_mode[2] = { + aiTextureMapMode_Wrap, aiTextureMapMode_Wrap + }; float blend = 1.0f; - if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, &map_mode) != AI_SUCCESS || !path.length) { + if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) { return; } @@ -309,21 +313,21 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type return; } - ChunkWriter(writer, chunk_flags); + ChunkWriter chunk(writer, chunk_flags); { - ChunkWriter(writer, Discreet3DS::CHUNK_MAPFILE); + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPFILE); WriteString(path); } WritePercentChunk(blend); { - ChunkWriter(writer, Discreet3DS::CHUNK_MAT_MAP_TILING); + ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING); uint16_t val = 0; // WRAP - if (map_mode == aiTextureMapMode_Mirror) { + if (map_mode[0] == aiTextureMapMode_Mirror) { val = 0x2; } - else if (map_mode == aiTextureMapMode_Decal) { + else if (map_mode[0] == aiTextureMapMode_Decal) { val = 0x10; } writer.PutU2(val); From a07cde4a813342f9a0c72dc73ccc0f2cc8ed47e1 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Wed, 23 Jul 2014 22:08:35 +0200 Subject: [PATCH 26/80] 3DS Exporter: export scene hierarchy. --- code/3DSExporter.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++ code/3DSExporter.h | 2 ++ 2 files changed, 60 insertions(+) diff --git a/code/3DSExporter.cpp b/code/3DSExporter.cpp index c455167b9..d2a353a57 100644 --- a/code/3DSExporter.cpp +++ b/code/3DSExporter.cpp @@ -199,9 +199,67 @@ Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr outfile, c { ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER); + WriteHierarchy(*scene->mRootNode, -1, -1); } } +// ------------------------------------------------------------------------------------------------ +int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling_level) +{ + // 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec + { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO); + { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME); + + // Assimp node names are unique and distinct from all mesh-node + // names we generate; thus we can use them as-is + WriteString(node.mName); + + // Two unknown int16 values - it is even unclear if 0 is a safe value + // but luckily importers do not know better either. + writer.PutI4(0); + + int16_t hierarchy_pos = static_cast(seq); + if (sibling_level != -1) { + hierarchy_pos = sibling_level; + } + + // Write the hierarchy position + writer.PutI2(hierarchy_pos); + } + } + + // TODO: write transformation chunks + + ++seq; + sibling_level = seq; + + // Write all children + for (unsigned int i = 0; i < node.mNumChildren; ++i) { + seq = WriteHierarchy(*node.mChildren[i], seq, i == 0 ? -1 : sibling_level); + } + + // Write all meshes as separate nodes to be able to reference the meshes by name + for (unsigned int i = 0; i < node.mNumMeshes; ++i) { + const bool first_child = node.mNumChildren == 0 && i == 0; + + const unsigned int mesh_idx = node.mMeshes[i]; + const aiMesh& mesh = *scene->mMeshes[mesh_idx]; + + ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO); + { + ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME); + WriteString(GetMeshName(mesh, mesh_idx, node)); + + writer.PutI4(0); + writer.PutI2(static_cast(first_child ? seq : sibling_level)); + ++seq; + } + } + return seq; +} + // ------------------------------------------------------------------------------------------------ void Discreet3DSExporter::WriteMaterials() { diff --git a/code/3DSExporter.h b/code/3DSExporter.h index bb474f062..9742abb0c 100644 --- a/code/3DSExporter.h +++ b/code/3DSExporter.h @@ -70,6 +70,8 @@ private: void WriteFaceMaterialChunk(const aiMesh& mesh); + int WriteHierarchy(const aiNode& node, int level, int sibling_level); + void WriteString(const std::string& s); void WriteString(const aiString& s); void WriteColor(const aiColor3D& color); From 9b4e7c7efb893cdbd1ab6a82430035af0134a719 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Thu, 24 Jul 2014 03:02:43 +0200 Subject: [PATCH 27/80] Add X and 3DS exporter to readme. --- Readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Readme.md b/Readme.md index 77306459c..8e186ee44 100644 --- a/Readme.md +++ b/Readme.md @@ -57,6 +57,8 @@ Exporters include: - STL - OBJ - PLY +- X +- 3DS - JSON (for WebGl, via https://github.com/acgessler/assimp2json) See [the full list here](http://assimp.sourceforge.net/main_features_formats.html). From 5d861a825020d8292768ca6cc392d993fea54f79 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Thu, 31 Jul 2014 15:09:49 +0200 Subject: [PATCH 28/80] bugfix: - fix gcc-specific compiler warnings. --- code/OgreBinarySerializer.cpp | 1 - code/OgreBinarySerializer.h | 2 +- code/OgreStructs.cpp | 2 ++ 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/OgreBinarySerializer.cpp b/code/OgreBinarySerializer.cpp index 6674f4cee..155e889d5 100644 --- a/code/OgreBinarySerializer.cpp +++ b/code/OgreBinarySerializer.cpp @@ -534,7 +534,6 @@ void OgreBinarySerializer::ReadSubMeshTextureAlias(SubMesh *submesh) void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh) { uint16_t id = 0; - uint16_t submeshIndex = 0; if (!AtEnd()) { diff --git a/code/OgreBinarySerializer.h b/code/OgreBinarySerializer.h index 69db4b722..8b4e3ccfe 100644 --- a/code/OgreBinarySerializer.h +++ b/code/OgreBinarySerializer.h @@ -75,8 +75,8 @@ private: }; OgreBinarySerializer(MemoryStreamReader *reader, AssetMode mode) : - m_reader(reader), m_currentLen(0), + m_reader(reader), assetMode(mode) { } diff --git a/code/OgreStructs.cpp b/code/OgreStructs.cpp index 3eaf2df01..6311d0b6c 100644 --- a/code/OgreStructs.cpp +++ b/code/OgreStructs.cpp @@ -963,6 +963,8 @@ aiAnimation *Animation::ConvertToAssimpAnimation() // Skeleton Skeleton::Skeleton() : + bones(), + animations(), blendMode(ANIMBLEND_AVERAGE) { } From 11af0866dce60802274b4386af246aa62d5e490e Mon Sep 17 00:00:00 2001 From: Gargaj Date: Sat, 2 Aug 2014 14:47:59 +0200 Subject: [PATCH 29/80] Add FieldOfView token type (fixes #245) "FieldOfView" has its own token type (basically just one float), if it's missing the camera will keep reverting to default FOV in ASSIMP. --- code/FBXProperties.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/FBXProperties.cpp b/code/FBXProperties.cpp index 48bdb4f40..62cbba51d 100644 --- a/code/FBXProperties.cpp +++ b/code/FBXProperties.cpp @@ -105,7 +105,7 @@ Property* ReadTypedProperty(const Element& element) ParseTokenAsFloat(*tok[6])) ); } - else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"KTime") || !strcmp(cs,"Float")) { + else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"KTime") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView")) { return new TypedProperty(ParseTokenAsFloat(*tok[4])); } return NULL; From e5ed62581d9672b05c3875e3c89d8333385790f5 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Sat, 2 Aug 2014 14:57:43 +0200 Subject: [PATCH 30/80] Handle both types of element names MAX seems to add an "s" to "Binormal" and "Tangent" when exporting --- code/FBXMeshGeometry.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/FBXMeshGeometry.cpp b/code/FBXMeshGeometry.cpp index be3fbd621..ebc75f48e 100644 --- a/code/FBXMeshGeometry.cpp +++ b/code/FBXMeshGeometry.cpp @@ -466,8 +466,9 @@ void MeshGeometry::ReadVertexDataTangents(std::vector& tangents_out, const std::string& MappingInformationType, const std::string& ReferenceInformationType) { + const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent"; ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType, - "Tangent", + str, "TangentIndex", vertices.size(), mapping_counts, @@ -481,8 +482,9 @@ void MeshGeometry::ReadVertexDataBinormals(std::vector& binormals_ou const std::string& MappingInformationType, const std::string& ReferenceInformationType) { + const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal"; ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType, - "Binormal", + str, "BinormalIndex", vertices.size(), mapping_counts, From 203d5d6fcc9c4d5559ff2cc6ac5dda9cf17d69bc Mon Sep 17 00:00:00 2001 From: acgessler Date: Sat, 2 Aug 2014 21:18:21 -0700 Subject: [PATCH 31/80] Obj: make mtl importer accept kd, ks etc. as well (Kd, Ks being the correct form). This is for keeping up compatibility with assimp's own Obj exporter, which has been inaccurate about this since inception. --- code/ObjFileMtlImporter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/ObjFileMtlImporter.cpp b/code/ObjFileMtlImporter.cpp index a25b960e7..90898f7b2 100644 --- a/code/ObjFileMtlImporter.cpp +++ b/code/ObjFileMtlImporter.cpp @@ -129,6 +129,7 @@ void ObjFileMtlImporter::load() { switch (*m_DataIt) { + case 'k': case 'K': { ++m_DataIt; From dfe1f03e5b392aa877c1760e63dd0c0171a63131 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Mon, 4 Aug 2014 23:57:08 +0200 Subject: [PATCH 32/80] Split off postprocessing progress --- code/Importer.cpp | 3 ++- include/assimp/ProgressHandler.hpp | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index c6b9daf67..50ce016d5 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -768,6 +768,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { BaseProcess* process = pimpl->mPostProcessingSteps[a]; + pimpl->mProgressHandler->UpdatePostProcess( a, pimpl->mPostProcessingSteps.size() ); if( process->IsActive( pFlags)) { if (profiler) { @@ -775,7 +776,6 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) } process->ExecuteOnScene ( this ); - pimpl->mProgressHandler->Update(); if (profiler) { profiler->EndRegion("postprocess"); @@ -803,6 +803,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) } #endif // ! DEBUG } + pimpl->mProgressHandler->UpdatePostProcess( pimpl->mPostProcessingSteps.size(), pimpl->mPostProcessingSteps.size() ); // update private scene flags if( pimpl->mScene ) diff --git a/include/assimp/ProgressHandler.hpp b/include/assimp/ProgressHandler.hpp index 31c746c59..7a4cec84f 100644 --- a/include/assimp/ProgressHandler.hpp +++ b/include/assimp/ProgressHandler.hpp @@ -88,6 +88,19 @@ public: virtual bool Update(float percentage = -1.f) = 0; + // ------------------------------------------------------------------- + /** @brief Progress callback for post-processing steps + * @param numberOfSteps The number of total post-processing + * steps + * @param currentStep The index of the current post-processing + * step that will run, or equal to numberOfSteps if all of + * them has finished. This number is always strictly monotone + * increasing, although not necessarily linearly. + * */ + virtual void UpdatePostProcess(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { + float f = currentStep / (float)numberOfSteps; + Update( f * 0.5f + 0.5f ); + }; }; // !class ProgressHandler // ------------------------------------------------------------------------------------ From dbc553343ce52211aab14227929fe5202cf2b2e9 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 00:05:18 +0200 Subject: [PATCH 33/80] Granulate file loading too --- code/Importer.cpp | 4 ++-- include/assimp/ProgressHandler.hpp | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index 50ce016d5..49cfeffa6 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -642,14 +642,14 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // Dispatch the reading to the worker class for this format DefaultLogger::get()->info("Found a matching importer for this file format"); - pimpl->mProgressHandler->Update(); + pimpl->mProgressHandler->UpdateFileRead( 0, 1 ); if (profiler) { profiler->BeginRegion("import"); } pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler); - pimpl->mProgressHandler->Update(); + pimpl->mProgressHandler->UpdateFileRead( 1, 1 ); if (profiler) { profiler->EndRegion("import"); diff --git a/include/assimp/ProgressHandler.hpp b/include/assimp/ProgressHandler.hpp index 7a4cec84f..8aaa99276 100644 --- a/include/assimp/ProgressHandler.hpp +++ b/include/assimp/ProgressHandler.hpp @@ -81,12 +81,25 @@ public: * all needed cleanup tasks prior to returning control to the * caller). If the loading is aborted, #Importer::ReadFile() * returns always NULL. - * - * @note Currently, percentage is always -1.f because there is - * no reliable way to compute it. * */ virtual bool Update(float percentage = -1.f) = 0; + // ------------------------------------------------------------------- + /** @brief Progress callback for file loading steps + * @param numberOfSteps The number of total post-processing + * steps + * @param currentStep The index of the current post-processing + * step that will run, or equal to numberOfSteps if all of + * them has finished. This number is always strictly monotone + * increasing, although not necessarily linearly. + * + * @note This is currently only used at the start and the end + * of the file parsing. + * */ + virtual void UpdateFileRead(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { + float f = currentStep / (float)numberOfSteps; + Update( f * 0.5f ); + }; // ------------------------------------------------------------------- /** @brief Progress callback for post-processing steps From 6b8cbe5c834ef99ca2f330b97068b7af7d312b01 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 00:10:23 +0200 Subject: [PATCH 34/80] this isn't needed anymore --- code/Importer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index 49cfeffa6..0a817476a 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -678,7 +678,6 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) ScenePreprocessor pre(pimpl->mScene); pre.ProcessScene(); - pimpl->mProgressHandler->Update(); if (profiler) { profiler->EndRegion("preprocess"); } From 8f960f0ed2ea073017e8f8672f3575c8de273a29 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 19:36:18 +0200 Subject: [PATCH 35/80] avoid division by zero --- include/assimp/ProgressHandler.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/assimp/ProgressHandler.hpp b/include/assimp/ProgressHandler.hpp index 8aaa99276..3ab1e489b 100644 --- a/include/assimp/ProgressHandler.hpp +++ b/include/assimp/ProgressHandler.hpp @@ -97,7 +97,7 @@ public: * of the file parsing. * */ virtual void UpdateFileRead(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { - float f = currentStep / (float)numberOfSteps; + float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; Update( f * 0.5f ); }; @@ -111,7 +111,7 @@ public: * increasing, although not necessarily linearly. * */ virtual void UpdatePostProcess(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { - float f = currentStep / (float)numberOfSteps; + float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; Update( f * 0.5f + 0.5f ); }; From 3d5e1b5cbc2e8359389172f5ff2f13b9d7593227 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 20:54:38 +0200 Subject: [PATCH 36/80] add basic framework (files, etc) --- code/AssbinExporter.cpp | 58 +++++++++++++++++++++++++++++++++++++++++ code/AssbinExporter.h | 51 ++++++++++++++++++++++++++++++++++++ code/CMakeLists.txt | 7 +++++ code/Exporter.cpp | 5 ++++ 4 files changed, 121 insertions(+) create mode 100644 code/AssbinExporter.cpp create mode 100644 code/AssbinExporter.h diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp new file mode 100644 index 000000000..2f5e885c0 --- /dev/null +++ b/code/AssbinExporter.cpp @@ -0,0 +1,58 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#include "AssimpPCH.h" +#include "assbin_chunks.h" +#include "./../include/assimp/version.h" + +#ifndef ASSIMP_BUILD_NO_EXPORT +#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER + +using namespace Assimp; + +namespace Assimp { + +void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) +{ +} +} // end of namespace Assimp + +#endif // ASSIMP_BUILD_NO_ASSBIN_EXPORTER +#endif // ASSIMP_BUILD_NO_EXPORT diff --git a/code/AssbinExporter.h b/code/AssbinExporter.h new file mode 100644 index 000000000..f6a0cf598 --- /dev/null +++ b/code/AssbinExporter.h @@ -0,0 +1,51 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file AssbinExporter.h + * ASSBIN Exporter Main Header + */ +#ifndef AI_ASSBINEXPORTER_H_INC +#define AI_ASSBINEXPORTER_H_INC + +#include + +#include "StreamWriter.h" + +#endif diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 15cbe1321..0a57d540b 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -171,6 +171,12 @@ SET( ASE_SRCS ) SOURCE_GROUP( ASE FILES ${ASE_SRCS}) +SET( ASSBIN_SRCS + AssbinExporter.h + AssbinExporter.cpp +) +SOURCE_GROUP( Assbin FILES ${ASSBIN_SRCS}) + SET( B3D_SRCS B3DImporter.cpp B3DImporter.h @@ -646,6 +652,7 @@ SET( assimp_src ${3DS_SRCS} ${AC_SRCS} ${ASE_SRCS} + ${ASSBIN_SRCS} ${B3D_SRCS} ${BVH_SRCS} ${Collada_SRCS} diff --git a/code/Exporter.cpp b/code/Exporter.cpp index 7f51fb71f..c105e36ba 100644 --- a/code/Exporter.cpp +++ b/code/Exporter.cpp @@ -79,6 +79,7 @@ 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*); +void ExportSceneAssbin(const char*, IOSystem*, const aiScene*); // ------------------------------------------------------------------------------------------------ // global array of all export formats which Assimp supports in its current build @@ -117,6 +118,10 @@ Exporter::ExportFormatEntry gExporters[] = Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS, aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices), #endif + +#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER + Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, NULL), +#endif }; #define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0])) From 2592ff07967b72d7e3d9f13dc3d88a73806ec0e1 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 22:54:45 +0200 Subject: [PATCH 37/80] convert exporter from tools/assimp_cmd --- code/AssbinExporter.cpp | 688 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 688 insertions(+) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 2f5e885c0..b3dfd082e 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -41,6 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssimpPCH.h" #include "assbin_chunks.h" #include "./../include/assimp/version.h" +#include "ProcessHelper.h" #ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER @@ -49,8 +50,695 @@ using namespace Assimp; namespace Assimp { + class AssbinChunkWriter : public IOStream + { + private: + + uint8_t* buffer; + uint32_t magic; + IOStream * container; + uint32_t cur_size, cursor, initial; + + private: + // ------------------------------------------------------------------- + void Grow(size_t need = 0) + { + size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); + + const uint8_t* const old = buffer; + buffer = new uint8_t[new_size]; + + if (old) { + memcpy(buffer,old,cur_size); + delete[] old; + } + + cur_size = new_size; + } + + public: + + AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096) + : initial(initial), buffer(NULL), cur_size(0), cursor(0), container(container), magic(magic) + { + } + + virtual ~AssbinChunkWriter() + { + if (container) { + container->Write( &magic, sizeof(uint32_t), 1 ); + container->Write( &cursor, sizeof(uint32_t), 1 ); + container->Write( buffer, 1, cursor ); + } + if (buffer) delete[] buffer; + } + + // ------------------------------------------------------------------- + virtual size_t Read(void* pvBuffer, + size_t pSize, + size_t pCount) { return 0; }; + virtual aiReturn Seek(size_t pOffset, + aiOrigin pOrigin) { return aiReturn_FAILURE; }; + virtual size_t Tell() const { return 0; }; + virtual void Flush() { }; + + virtual size_t FileSize() const + { + return cursor; + } + + // ------------------------------------------------------------------- + virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) + { + pSize *= pCount; + if (cursor + pSize > cur_size) { + Grow(cursor + pSize); + } + + memcpy(buffer+cursor, pvBuffer, pSize); + cursor += pSize; + + return pCount; + } + + template + size_t Write(const T& v) + { + return Write( &v, sizeof(T), 1 ); + } + + // ----------------------------------------------------------------------------------- + // Serialize an aiString + template <> + inline uint32_t Write(const aiString& s) + { + const uint32_t s2 = (uint32_t)s.length; + Write(&s,4,1); + Write(s.data,s2,1); + return s2+4; + } + + // ----------------------------------------------------------------------------------- + // Serialize an unsigned int as uint32_t + template <> + inline uint32_t Write(const unsigned int& w) + { + const uint32_t t = (uint32_t)w; + if (w > t) { + // this shouldn't happen, integers in Assimp data structures never exceed 2^32 + printf("loss of data due to 64 -> 32 bit integer conversion"); + } + + Write(&t,4,1); + return 4; + } + + // ----------------------------------------------------------------------------------- + // Serialize an unsigned int as uint16_t + template <> + inline uint32_t Write(const uint16_t& w) + { + Write(&w,2,1); + return 2; + } + + // ----------------------------------------------------------------------------------- + // Serialize a float + template <> + inline uint32_t Write(const float& f) + { + BOOST_STATIC_ASSERT(sizeof(float)==4); + Write(&f,4,1); + return 4; + } + + // ----------------------------------------------------------------------------------- + // Serialize a double + template <> + inline uint32_t Write(const double& f) + { + BOOST_STATIC_ASSERT(sizeof(double)==8); + Write(&f,8,1); + return 8; + } + + // ----------------------------------------------------------------------------------- + // Serialize a vec3 + template <> + inline uint32_t Write(const aiVector3D& v) + { + uint32_t t = Write(v.x); + t += Write(v.y); + t += Write(v.z); + return t; + } + + // ----------------------------------------------------------------------------------- + // Serialize a color value + template <> + inline uint32_t Write(const aiColor4D& v) + { + uint32_t t = Write(v.r); + t += Write(v.g); + t += Write(v.b); + t += Write(v.a); + return t; + } + + // ----------------------------------------------------------------------------------- + // Serialize a quaternion + template <> + inline uint32_t Write(const aiQuaternion& v) + { + uint32_t t = Write(v.w); + t += Write(v.x); + t += Write(v.y); + t += Write(v.z); + return 16; + } + + + // ----------------------------------------------------------------------------------- + // Serialize a vertex weight + template <> + inline uint32_t Write(const aiVertexWeight& v) + { + uint32_t t = Write(v.mVertexId); + return t+Write(v.mWeight); + } + + // ----------------------------------------------------------------------------------- + // Serialize a mat4x4 + template <> + inline uint32_t Write(const aiMatrix4x4& m) + { + for (unsigned int i = 0; i < 4;++i) { + for (unsigned int i2 = 0; i2 < 4;++i2) { + Write(m[i][i2]); + } + } + return 64; + } + + // ----------------------------------------------------------------------------------- + // Serialize an aiVectorKey + template <> + inline uint32_t Write(const aiVectorKey& v) + { + const uint32_t t = Write(v.mTime); + return t + Write(v.mValue); + } + + // ----------------------------------------------------------------------------------- + // Serialize an aiQuatKey + template <> + inline uint32_t Write(const aiQuatKey& v) + { + const uint32_t t = Write(v.mTime); + return t + Write(v.mValue); + } + + template + inline uint32_t WriteBounds(const T* in, unsigned int size) + { + T minc,maxc; + ArrayBounds(in,size,minc,maxc); + + const uint32_t t = Write(minc); + return t + Write(maxc); + } + + + }; + +/* + class AssbinChunkWriter + { + AssbinStream stream; + uint32_t magic; + public: + AssbinChunkWriter( uint32_t _magic ) + { + magic = _magic; + } + void AppendToStream( AssbinStream & _stream ) + { + uint32_t s = stream.FileSize(); + _stream.Write( &magic, sizeof(uint32_t), 1 ); + _stream.Write( &s, sizeof(uint32_t), 1 ); + _stream.Write( stream.GetBuffer(), stream.FileSize(), 1 ); + } + void AppendToStream( AssbinChunkWriter & _stream ) + { + uint32_t s = stream.FileSize(); + _stream.WriteRaw( &magic, sizeof(uint32_t) ); + _stream.WriteRaw( &s, sizeof(uint32_t) ); + _stream.WriteRaw( stream.GetBuffer(), stream.FileSize() ); + } + + }; +*/ + + class AssbinExport + { + private: + bool shortened; + bool compressed; + //AssbinStream stream; + + protected: + template + size_t Write( IOStream * container, const T& v) + { + return container->Write( &v, sizeof(T), 1 ); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryNode( IOStream * container, const aiNode* node) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE ); + + chunk.Write(node->mName); + chunk.Write(node->mTransformation); + chunk.Write(node->mNumChildren); + chunk.Write(node->mNumMeshes); + + for (unsigned int i = 0; i < node->mNumMeshes;++i) { + chunk.Write(node->mMeshes[i]); + } + + for (unsigned int i = 0; i < node->mNumChildren;++i) { + WriteBinaryNode( &chunk, node->mChildren[i] ); + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryTexture(IOStream * container, const aiTexture* tex) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE ); + + chunk.Write(tex->mWidth); + chunk.Write(tex->mHeight); + chunk.Write( tex->achFormatHint, sizeof(char), 4 ); + + if(!shortened) { + if (!tex->mHeight) { + chunk.Write(tex->pcData,1,tex->mWidth); + } + else { + chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); + } + } + + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryBone(IOStream * container, const aiBone* b) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE ); + + chunk.Write(b->mName); + chunk.Write(b->mNumWeights); + chunk.Write(b->mOffsetMatrix); + + // for the moment we write dumb min/max values for the bones, too. + // maybe I'll add a better, hash-like solution later + if (shortened) { + chunk.WriteBounds(b->mWeights,b->mNumWeights); + } // else write as usual + else chunk.Write(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryMesh(IOStream * container, const aiMesh* mesh) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH ); + + chunk.Write(mesh->mPrimitiveTypes); + chunk.Write(mesh->mNumVertices); + chunk.Write(mesh->mNumFaces); + chunk.Write(mesh->mNumBones); + chunk.Write(mesh->mMaterialIndex); + + // first of all, write bits for all existent vertex components + unsigned int c = 0; + if (mesh->mVertices) { + c |= ASSBIN_MESH_HAS_POSITIONS; + } + if (mesh->mNormals) { + c |= ASSBIN_MESH_HAS_NORMALS; + } + if (mesh->mTangents && mesh->mBitangents) { + c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS; + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + if (!mesh->mTextureCoords[n]) { + break; + } + c |= ASSBIN_MESH_HAS_TEXCOORD(n); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + if (!mesh->mColors[n]) { + break; + } + c |= ASSBIN_MESH_HAS_COLOR(n); + } + chunk.Write(c); + + aiVector3D minVec, maxVec; + if (mesh->mVertices) { + if (shortened) { + chunk.WriteBounds(mesh->mVertices,mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mVertices,1,12*mesh->mNumVertices); + } + if (mesh->mNormals) { + if (shortened) { + chunk.WriteBounds(mesh->mNormals,mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mNormals,1,12*mesh->mNumVertices); + } + if (mesh->mTangents && mesh->mBitangents) { + if (shortened) { + chunk.WriteBounds(mesh->mTangents,mesh->mNumVertices); + chunk.WriteBounds(mesh->mBitangents,mesh->mNumVertices); + } // else write as usual + else { + chunk.Write(mesh->mTangents,1,12*mesh->mNumVertices); + chunk.Write(mesh->mBitangents,1,12*mesh->mNumVertices); + } + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + if (!mesh->mColors[n]) + break; + + if (shortened) { + chunk.WriteBounds(mesh->mColors[n],mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mColors[n],16*mesh->mNumVertices,1); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + if (!mesh->mTextureCoords[n]) + break; + + // write number of UV components + chunk.Write(mesh->mNumUVComponents[n]); + + if (shortened) { + chunk.WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); + } + + // write faces. There are no floating-point calculations involved + // in these, so we can write a simple hash over the face data + // to the dump file. We generate a single 32 Bit hash for 512 faces + // using Assimp's standard hashing function. + if (shortened) { + unsigned int processed = 0; + for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) { + + uint32_t hash = 0; + for (unsigned int a = 0; a < job;++a) { + + const aiFace& f = mesh->mFaces[processed+a]; + uint32_t tmp = f.mNumIndices; + hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); + for (unsigned int i = 0; i < f.mNumIndices; ++i) { + BOOST_STATIC_ASSERT(AI_MAX_VERTICES <= 0xffffffff); + tmp = static_cast( f.mIndices[i] ); + hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); + } + } + chunk.Write(hash); + } + } + else // else write as usual + { + // if there are less than 2^16 vertices, we can simply use 16 bit integers ... + for (unsigned int i = 0; i < mesh->mNumFaces;++i) { + const aiFace& f = mesh->mFaces[i]; + + BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); + chunk.Write(f.mNumIndices); + + for (unsigned int a = 0; a < f.mNumIndices;++a) { + if (mesh->mNumVertices < (1u<<16)) { + chunk.Write(f.mIndices[a]); + } + else chunk.Write(f.mIndices[a]); + } + } + } + + // write bones + if (mesh->mNumBones) { + for (unsigned int a = 0; a < mesh->mNumBones;++a) { + const aiBone* b = mesh->mBones[a]; + WriteBinaryBone(&chunk,b); + } + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY ); + + chunk.Write(prop->mKey); + chunk.Write(prop->mSemantic); + chunk.Write(prop->mIndex); + + chunk.Write(prop->mDataLength); + chunk.Write((unsigned int)prop->mType); + chunk.Write(prop->mData,1,prop->mDataLength); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL); + + chunk.Write(mat->mNumProperties); + for (unsigned int i = 0; i < mat->mNumProperties;++i) { + WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]); + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM ); + + chunk.Write(nd->mNodeName); + chunk.Write(nd->mNumPositionKeys); + chunk.Write(nd->mNumRotationKeys); + chunk.Write(nd->mNumScalingKeys); + chunk.Write(nd->mPreState); + chunk.Write(nd->mPostState); + + if (nd->mPositionKeys) { + if (shortened) { + chunk.WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys); + + } // else write as usual + else chunk.Write(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); + } + if (nd->mRotationKeys) { + if (shortened) { + chunk.WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys); + + } // else write as usual + else chunk.Write(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); + } + if (nd->mScalingKeys) { + if (shortened) { + chunk.WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys); + + } // else write as usual + else chunk.Write(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); + } + } + + + // ----------------------------------------------------------------------------------- + void WriteBinaryAnim( IOStream * container, const aiAnimation* anim ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION ); + + chunk.Write (anim->mName); + chunk.Write (anim->mDuration); + chunk.Write (anim->mTicksPerSecond); + chunk.Write(anim->mNumChannels); + + for (unsigned int a = 0; a < anim->mNumChannels;++a) { + const aiNodeAnim* nd = anim->mChannels[a]; + WriteBinaryNodeAnim(&chunk,nd); + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryLight( IOStream * container, const aiLight* l ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT ); + + chunk.Write(l->mName); + chunk.Write(l->mType); + + if (l->mType != aiLightSource_DIRECTIONAL) { + chunk.Write(l->mAttenuationConstant); + chunk.Write(l->mAttenuationLinear); + chunk.Write(l->mAttenuationQuadratic); + } + + chunk.Write((const aiVector3D&)l->mColorDiffuse); + chunk.Write((const aiVector3D&)l->mColorSpecular); + chunk.Write((const aiVector3D&)l->mColorAmbient); + + if (l->mType == aiLightSource_SPOT) { + chunk.Write(l->mAngleInnerCone); + chunk.Write(l->mAngleOuterCone); + } + + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryCamera( IOStream * container, const aiCamera* cam ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA ); + + chunk.Write(cam->mName); + chunk.Write(cam->mPosition); + chunk.Write(cam->mLookAt); + chunk.Write(cam->mUp); + chunk.Write(cam->mHorizontalFOV); + chunk.Write(cam->mClipPlaneNear); + chunk.Write(cam->mClipPlaneFar); + chunk.Write(cam->mAspect); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryScene( IOStream * container, const aiScene* scene) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE ); + + // basic scene information + chunk.Write(scene->mFlags); + chunk.Write(scene->mNumMeshes); + chunk.Write(scene->mNumMaterials); + chunk.Write(scene->mNumAnimations); + chunk.Write(scene->mNumTextures); + chunk.Write(scene->mNumLights); + chunk.Write(scene->mNumCameras); + + // write node graph + WriteBinaryNode( &chunk, scene->mRootNode ); + + // write all meshes + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + const aiMesh* mesh = scene->mMeshes[i]; + WriteBinaryMesh( &chunk,mesh); + } + + // write materials + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + const aiMaterial* mat = scene->mMaterials[i]; + WriteBinaryMaterial(&chunk,mat); + } + + // write all animations + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + const aiAnimation* anim = scene->mAnimations[i]; + WriteBinaryAnim(&chunk,anim); + } + + + // write all textures + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + const aiTexture* mesh = scene->mTextures[i]; + WriteBinaryTexture(&chunk,mesh); + } + + // write lights + for (unsigned int i = 0; i < scene->mNumLights;++i) { + const aiLight* l = scene->mLights[i]; + WriteBinaryLight(&chunk,l); + } + + // write cameras + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + const aiCamera* cam = scene->mCameras[i]; + WriteBinaryCamera(&chunk,cam); + } + + } + + public: + AssbinExport() + { + shortened = false; + compressed = false; + } + + // ----------------------------------------------------------------------------------- + // Write a binary model dump + void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) + { + IOStream * out = pIOSystem->Open( pFile, "wb" ); + if (!out) return; + + time_t tt = time(NULL); + tm* p = gmtime(&tt); + + // header + char s[64]; + memset( s, 0, 64 ); +#if _MSC_VER >= 1400 + sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p)); +#else + snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p)); +#endif + out->Write( s, 44, 1 ); + // == 44 bytes + + Write( out, ASSBIN_VERSION_MAJOR ); + Write( out, ASSBIN_VERSION_MINOR ); + Write( out, aiGetVersionRevision() ); + Write( out, aiGetCompileFlags() ); + Write( out, shortened ); + Write( out, compressed ); + // == 20 bytes + + //todo + + char buff[256]; + strncpy(buff,pFile,256); + out->Write(buff,sizeof(char),256); + + char cmd[] = "\0"; + strncpy(buff,cmd,128); + out->Write(buff,sizeof(char),128); + + // leave 64 bytes free for future extensions + memset(buff,0xcd,64); + out->Write(buff,sizeof(char),64); + // == 435 bytes + + // ==== total header size: 512 bytes + ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH ); + + // Up to here the data is uncompressed. For compressed files, the rest + // is compressed using standard DEFLATE from zlib. + WriteBinaryScene( out, pScene ); + + pIOSystem->Close( out ); + } + }; + void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) { + AssbinExport exporter; + exporter.WriteBinaryDump( pFile, pIOSystem, pScene ); } } // end of namespace Assimp From fc9b4e2adf025d17bd9695f812d010b77be8e194 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 22:55:20 +0200 Subject: [PATCH 38/80] follow assimp code style (tabs) --- code/AssbinExporter.cpp | 1166 +++++++++++++++++++-------------------- 1 file changed, 583 insertions(+), 583 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index b3dfd082e..27da1a303 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -10,18 +10,18 @@ with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. + copyright notice, this list of conditions and the + following disclaimer. * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. * Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -50,695 +50,695 @@ using namespace Assimp; namespace Assimp { - class AssbinChunkWriter : public IOStream - { - private: + class AssbinChunkWriter : public IOStream + { + private: - uint8_t* buffer; - uint32_t magic; - IOStream * container; - uint32_t cur_size, cursor, initial; + uint8_t* buffer; + uint32_t magic; + IOStream * container; + uint32_t cur_size, cursor, initial; - private: - // ------------------------------------------------------------------- - void Grow(size_t need = 0) - { - size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); + private: + // ------------------------------------------------------------------- + void Grow(size_t need = 0) + { + size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); - const uint8_t* const old = buffer; - buffer = new uint8_t[new_size]; + const uint8_t* const old = buffer; + buffer = new uint8_t[new_size]; - if (old) { - memcpy(buffer,old,cur_size); - delete[] old; - } + if (old) { + memcpy(buffer,old,cur_size); + delete[] old; + } - cur_size = new_size; - } + cur_size = new_size; + } - public: + public: - AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096) - : initial(initial), buffer(NULL), cur_size(0), cursor(0), container(container), magic(magic) - { - } + AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096) + : initial(initial), buffer(NULL), cur_size(0), cursor(0), container(container), magic(magic) + { + } - virtual ~AssbinChunkWriter() - { - if (container) { - container->Write( &magic, sizeof(uint32_t), 1 ); - container->Write( &cursor, sizeof(uint32_t), 1 ); - container->Write( buffer, 1, cursor ); - } - if (buffer) delete[] buffer; - } + virtual ~AssbinChunkWriter() + { + if (container) { + container->Write( &magic, sizeof(uint32_t), 1 ); + container->Write( &cursor, sizeof(uint32_t), 1 ); + container->Write( buffer, 1, cursor ); + } + if (buffer) delete[] buffer; + } - // ------------------------------------------------------------------- - virtual size_t Read(void* pvBuffer, - size_t pSize, - size_t pCount) { return 0; }; - virtual aiReturn Seek(size_t pOffset, - aiOrigin pOrigin) { return aiReturn_FAILURE; }; - virtual size_t Tell() const { return 0; }; - virtual void Flush() { }; + // ------------------------------------------------------------------- + virtual size_t Read(void* pvBuffer, + size_t pSize, + size_t pCount) { return 0; }; + virtual aiReturn Seek(size_t pOffset, + aiOrigin pOrigin) { return aiReturn_FAILURE; }; + virtual size_t Tell() const { return 0; }; + virtual void Flush() { }; - virtual size_t FileSize() const - { - return cursor; - } + virtual size_t FileSize() const + { + return cursor; + } - // ------------------------------------------------------------------- - virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) - { - pSize *= pCount; - if (cursor + pSize > cur_size) { - Grow(cursor + pSize); - } + // ------------------------------------------------------------------- + virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) + { + pSize *= pCount; + if (cursor + pSize > cur_size) { + Grow(cursor + pSize); + } - memcpy(buffer+cursor, pvBuffer, pSize); - cursor += pSize; + memcpy(buffer+cursor, pvBuffer, pSize); + cursor += pSize; - return pCount; - } + return pCount; + } - template - size_t Write(const T& v) - { - return Write( &v, sizeof(T), 1 ); - } + template + size_t Write(const T& v) + { + return Write( &v, sizeof(T), 1 ); + } - // ----------------------------------------------------------------------------------- - // Serialize an aiString - template <> - inline uint32_t Write(const aiString& s) - { - const uint32_t s2 = (uint32_t)s.length; - Write(&s,4,1); - Write(s.data,s2,1); - return s2+4; - } + // ----------------------------------------------------------------------------------- + // Serialize an aiString + template <> + inline uint32_t Write(const aiString& s) + { + const uint32_t s2 = (uint32_t)s.length; + Write(&s,4,1); + Write(s.data,s2,1); + return s2+4; + } - // ----------------------------------------------------------------------------------- - // Serialize an unsigned int as uint32_t - template <> - inline uint32_t Write(const unsigned int& w) - { - const uint32_t t = (uint32_t)w; - if (w > t) { - // this shouldn't happen, integers in Assimp data structures never exceed 2^32 - printf("loss of data due to 64 -> 32 bit integer conversion"); - } + // ----------------------------------------------------------------------------------- + // Serialize an unsigned int as uint32_t + template <> + inline uint32_t Write(const unsigned int& w) + { + const uint32_t t = (uint32_t)w; + if (w > t) { + // this shouldn't happen, integers in Assimp data structures never exceed 2^32 + printf("loss of data due to 64 -> 32 bit integer conversion"); + } - Write(&t,4,1); - return 4; - } + Write(&t,4,1); + return 4; + } - // ----------------------------------------------------------------------------------- - // Serialize an unsigned int as uint16_t - template <> - inline uint32_t Write(const uint16_t& w) - { - Write(&w,2,1); - return 2; - } + // ----------------------------------------------------------------------------------- + // Serialize an unsigned int as uint16_t + template <> + inline uint32_t Write(const uint16_t& w) + { + Write(&w,2,1); + return 2; + } - // ----------------------------------------------------------------------------------- - // Serialize a float - template <> - inline uint32_t Write(const float& f) - { - BOOST_STATIC_ASSERT(sizeof(float)==4); - Write(&f,4,1); - return 4; - } + // ----------------------------------------------------------------------------------- + // Serialize a float + template <> + inline uint32_t Write(const float& f) + { + BOOST_STATIC_ASSERT(sizeof(float)==4); + Write(&f,4,1); + return 4; + } - // ----------------------------------------------------------------------------------- - // Serialize a double - template <> - inline uint32_t Write(const double& f) - { - BOOST_STATIC_ASSERT(sizeof(double)==8); - Write(&f,8,1); - return 8; - } + // ----------------------------------------------------------------------------------- + // Serialize a double + template <> + inline uint32_t Write(const double& f) + { + BOOST_STATIC_ASSERT(sizeof(double)==8); + Write(&f,8,1); + return 8; + } - // ----------------------------------------------------------------------------------- - // Serialize a vec3 - template <> - inline uint32_t Write(const aiVector3D& v) - { - uint32_t t = Write(v.x); - t += Write(v.y); - t += Write(v.z); - return t; - } + // ----------------------------------------------------------------------------------- + // Serialize a vec3 + template <> + inline uint32_t Write(const aiVector3D& v) + { + uint32_t t = Write(v.x); + t += Write(v.y); + t += Write(v.z); + return t; + } - // ----------------------------------------------------------------------------------- - // Serialize a color value - template <> - inline uint32_t Write(const aiColor4D& v) - { - uint32_t t = Write(v.r); - t += Write(v.g); - t += Write(v.b); - t += Write(v.a); - return t; - } + // ----------------------------------------------------------------------------------- + // Serialize a color value + template <> + inline uint32_t Write(const aiColor4D& v) + { + uint32_t t = Write(v.r); + t += Write(v.g); + t += Write(v.b); + t += Write(v.a); + return t; + } - // ----------------------------------------------------------------------------------- - // Serialize a quaternion - template <> - inline uint32_t Write(const aiQuaternion& v) - { - uint32_t t = Write(v.w); - t += Write(v.x); - t += Write(v.y); - t += Write(v.z); - return 16; - } + // ----------------------------------------------------------------------------------- + // Serialize a quaternion + template <> + inline uint32_t Write(const aiQuaternion& v) + { + uint32_t t = Write(v.w); + t += Write(v.x); + t += Write(v.y); + t += Write(v.z); + return 16; + } - // ----------------------------------------------------------------------------------- - // Serialize a vertex weight - template <> - inline uint32_t Write(const aiVertexWeight& v) - { - uint32_t t = Write(v.mVertexId); - return t+Write(v.mWeight); - } + // ----------------------------------------------------------------------------------- + // Serialize a vertex weight + template <> + inline uint32_t Write(const aiVertexWeight& v) + { + uint32_t t = Write(v.mVertexId); + return t+Write(v.mWeight); + } - // ----------------------------------------------------------------------------------- - // Serialize a mat4x4 - template <> - inline uint32_t Write(const aiMatrix4x4& m) - { - for (unsigned int i = 0; i < 4;++i) { - for (unsigned int i2 = 0; i2 < 4;++i2) { - Write(m[i][i2]); - } - } - return 64; - } + // ----------------------------------------------------------------------------------- + // Serialize a mat4x4 + template <> + inline uint32_t Write(const aiMatrix4x4& m) + { + for (unsigned int i = 0; i < 4;++i) { + for (unsigned int i2 = 0; i2 < 4;++i2) { + Write(m[i][i2]); + } + } + return 64; + } - // ----------------------------------------------------------------------------------- - // Serialize an aiVectorKey - template <> - inline uint32_t Write(const aiVectorKey& v) - { - const uint32_t t = Write(v.mTime); - return t + Write(v.mValue); - } + // ----------------------------------------------------------------------------------- + // Serialize an aiVectorKey + template <> + inline uint32_t Write(const aiVectorKey& v) + { + const uint32_t t = Write(v.mTime); + return t + Write(v.mValue); + } - // ----------------------------------------------------------------------------------- - // Serialize an aiQuatKey - template <> - inline uint32_t Write(const aiQuatKey& v) - { - const uint32_t t = Write(v.mTime); - return t + Write(v.mValue); - } + // ----------------------------------------------------------------------------------- + // Serialize an aiQuatKey + template <> + inline uint32_t Write(const aiQuatKey& v) + { + const uint32_t t = Write(v.mTime); + return t + Write(v.mValue); + } - template - inline uint32_t WriteBounds(const T* in, unsigned int size) - { - T minc,maxc; - ArrayBounds(in,size,minc,maxc); + template + inline uint32_t WriteBounds(const T* in, unsigned int size) + { + T minc,maxc; + ArrayBounds(in,size,minc,maxc); - const uint32_t t = Write(minc); - return t + Write(maxc); - } + const uint32_t t = Write(minc); + return t + Write(maxc); + } - }; + }; /* - class AssbinChunkWriter - { - AssbinStream stream; - uint32_t magic; - public: - AssbinChunkWriter( uint32_t _magic ) - { - magic = _magic; - } - void AppendToStream( AssbinStream & _stream ) - { - uint32_t s = stream.FileSize(); - _stream.Write( &magic, sizeof(uint32_t), 1 ); - _stream.Write( &s, sizeof(uint32_t), 1 ); - _stream.Write( stream.GetBuffer(), stream.FileSize(), 1 ); - } - void AppendToStream( AssbinChunkWriter & _stream ) - { - uint32_t s = stream.FileSize(); - _stream.WriteRaw( &magic, sizeof(uint32_t) ); - _stream.WriteRaw( &s, sizeof(uint32_t) ); - _stream.WriteRaw( stream.GetBuffer(), stream.FileSize() ); - } + class AssbinChunkWriter + { + AssbinStream stream; + uint32_t magic; + public: + AssbinChunkWriter( uint32_t _magic ) + { + magic = _magic; + } + void AppendToStream( AssbinStream & _stream ) + { + uint32_t s = stream.FileSize(); + _stream.Write( &magic, sizeof(uint32_t), 1 ); + _stream.Write( &s, sizeof(uint32_t), 1 ); + _stream.Write( stream.GetBuffer(), stream.FileSize(), 1 ); + } + void AppendToStream( AssbinChunkWriter & _stream ) + { + uint32_t s = stream.FileSize(); + _stream.WriteRaw( &magic, sizeof(uint32_t) ); + _stream.WriteRaw( &s, sizeof(uint32_t) ); + _stream.WriteRaw( stream.GetBuffer(), stream.FileSize() ); + } - }; + }; */ - class AssbinExport - { - private: - bool shortened; - bool compressed; - //AssbinStream stream; + class AssbinExport + { + private: + bool shortened; + bool compressed; + //AssbinStream stream; - protected: - template - size_t Write( IOStream * container, const T& v) - { - return container->Write( &v, sizeof(T), 1 ); - } + protected: + template + size_t Write( IOStream * container, const T& v) + { + return container->Write( &v, sizeof(T), 1 ); + } - // ----------------------------------------------------------------------------------- - void WriteBinaryNode( IOStream * container, const aiNode* node) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE ); + // ----------------------------------------------------------------------------------- + void WriteBinaryNode( IOStream * container, const aiNode* node) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE ); - chunk.Write(node->mName); - chunk.Write(node->mTransformation); - chunk.Write(node->mNumChildren); - chunk.Write(node->mNumMeshes); + chunk.Write(node->mName); + chunk.Write(node->mTransformation); + chunk.Write(node->mNumChildren); + chunk.Write(node->mNumMeshes); - for (unsigned int i = 0; i < node->mNumMeshes;++i) { - chunk.Write(node->mMeshes[i]); - } + for (unsigned int i = 0; i < node->mNumMeshes;++i) { + chunk.Write(node->mMeshes[i]); + } - for (unsigned int i = 0; i < node->mNumChildren;++i) { - WriteBinaryNode( &chunk, node->mChildren[i] ); - } - } + for (unsigned int i = 0; i < node->mNumChildren;++i) { + WriteBinaryNode( &chunk, node->mChildren[i] ); + } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryTexture(IOStream * container, const aiTexture* tex) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE ); + // ----------------------------------------------------------------------------------- + void WriteBinaryTexture(IOStream * container, const aiTexture* tex) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE ); - chunk.Write(tex->mWidth); - chunk.Write(tex->mHeight); - chunk.Write( tex->achFormatHint, sizeof(char), 4 ); + chunk.Write(tex->mWidth); + chunk.Write(tex->mHeight); + chunk.Write( tex->achFormatHint, sizeof(char), 4 ); - if(!shortened) { - if (!tex->mHeight) { - chunk.Write(tex->pcData,1,tex->mWidth); - } - else { - chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); - } - } + if(!shortened) { + if (!tex->mHeight) { + chunk.Write(tex->pcData,1,tex->mWidth); + } + else { + chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); + } + } - } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryBone(IOStream * container, const aiBone* b) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE ); + // ----------------------------------------------------------------------------------- + void WriteBinaryBone(IOStream * container, const aiBone* b) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE ); - chunk.Write(b->mName); - chunk.Write(b->mNumWeights); - chunk.Write(b->mOffsetMatrix); + chunk.Write(b->mName); + chunk.Write(b->mNumWeights); + chunk.Write(b->mOffsetMatrix); - // for the moment we write dumb min/max values for the bones, too. - // maybe I'll add a better, hash-like solution later - if (shortened) { - chunk.WriteBounds(b->mWeights,b->mNumWeights); - } // else write as usual - else chunk.Write(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); - } + // for the moment we write dumb min/max values for the bones, too. + // maybe I'll add a better, hash-like solution later + if (shortened) { + chunk.WriteBounds(b->mWeights,b->mNumWeights); + } // else write as usual + else chunk.Write(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); + } - // ----------------------------------------------------------------------------------- - void WriteBinaryMesh(IOStream * container, const aiMesh* mesh) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH ); + // ----------------------------------------------------------------------------------- + void WriteBinaryMesh(IOStream * container, const aiMesh* mesh) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH ); - chunk.Write(mesh->mPrimitiveTypes); - chunk.Write(mesh->mNumVertices); - chunk.Write(mesh->mNumFaces); - chunk.Write(mesh->mNumBones); - chunk.Write(mesh->mMaterialIndex); + chunk.Write(mesh->mPrimitiveTypes); + chunk.Write(mesh->mNumVertices); + chunk.Write(mesh->mNumFaces); + chunk.Write(mesh->mNumBones); + chunk.Write(mesh->mMaterialIndex); - // first of all, write bits for all existent vertex components - unsigned int c = 0; - if (mesh->mVertices) { - c |= ASSBIN_MESH_HAS_POSITIONS; - } - if (mesh->mNormals) { - c |= ASSBIN_MESH_HAS_NORMALS; - } - if (mesh->mTangents && mesh->mBitangents) { - c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS; - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { - if (!mesh->mTextureCoords[n]) { - break; - } - c |= ASSBIN_MESH_HAS_TEXCOORD(n); - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { - if (!mesh->mColors[n]) { - break; - } - c |= ASSBIN_MESH_HAS_COLOR(n); - } - chunk.Write(c); + // first of all, write bits for all existent vertex components + unsigned int c = 0; + if (mesh->mVertices) { + c |= ASSBIN_MESH_HAS_POSITIONS; + } + if (mesh->mNormals) { + c |= ASSBIN_MESH_HAS_NORMALS; + } + if (mesh->mTangents && mesh->mBitangents) { + c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS; + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + if (!mesh->mTextureCoords[n]) { + break; + } + c |= ASSBIN_MESH_HAS_TEXCOORD(n); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + if (!mesh->mColors[n]) { + break; + } + c |= ASSBIN_MESH_HAS_COLOR(n); + } + chunk.Write(c); - aiVector3D minVec, maxVec; - if (mesh->mVertices) { - if (shortened) { - chunk.WriteBounds(mesh->mVertices,mesh->mNumVertices); - } // else write as usual - else chunk.Write(mesh->mVertices,1,12*mesh->mNumVertices); - } - if (mesh->mNormals) { - if (shortened) { - chunk.WriteBounds(mesh->mNormals,mesh->mNumVertices); - } // else write as usual - else chunk.Write(mesh->mNormals,1,12*mesh->mNumVertices); - } - if (mesh->mTangents && mesh->mBitangents) { - if (shortened) { - chunk.WriteBounds(mesh->mTangents,mesh->mNumVertices); - chunk.WriteBounds(mesh->mBitangents,mesh->mNumVertices); - } // else write as usual - else { - chunk.Write(mesh->mTangents,1,12*mesh->mNumVertices); - chunk.Write(mesh->mBitangents,1,12*mesh->mNumVertices); - } - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { - if (!mesh->mColors[n]) - break; + aiVector3D minVec, maxVec; + if (mesh->mVertices) { + if (shortened) { + chunk.WriteBounds(mesh->mVertices,mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mVertices,1,12*mesh->mNumVertices); + } + if (mesh->mNormals) { + if (shortened) { + chunk.WriteBounds(mesh->mNormals,mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mNormals,1,12*mesh->mNumVertices); + } + if (mesh->mTangents && mesh->mBitangents) { + if (shortened) { + chunk.WriteBounds(mesh->mTangents,mesh->mNumVertices); + chunk.WriteBounds(mesh->mBitangents,mesh->mNumVertices); + } // else write as usual + else { + chunk.Write(mesh->mTangents,1,12*mesh->mNumVertices); + chunk.Write(mesh->mBitangents,1,12*mesh->mNumVertices); + } + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + if (!mesh->mColors[n]) + break; - if (shortened) { - chunk.WriteBounds(mesh->mColors[n],mesh->mNumVertices); - } // else write as usual - else chunk.Write(mesh->mColors[n],16*mesh->mNumVertices,1); - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { - if (!mesh->mTextureCoords[n]) - break; + if (shortened) { + chunk.WriteBounds(mesh->mColors[n],mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mColors[n],16*mesh->mNumVertices,1); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + if (!mesh->mTextureCoords[n]) + break; - // write number of UV components - chunk.Write(mesh->mNumUVComponents[n]); + // write number of UV components + chunk.Write(mesh->mNumUVComponents[n]); - if (shortened) { - chunk.WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices); - } // else write as usual - else chunk.Write(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); - } + if (shortened) { + chunk.WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); + } - // write faces. There are no floating-point calculations involved - // in these, so we can write a simple hash over the face data - // to the dump file. We generate a single 32 Bit hash for 512 faces - // using Assimp's standard hashing function. - if (shortened) { - unsigned int processed = 0; - for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) { + // write faces. There are no floating-point calculations involved + // in these, so we can write a simple hash over the face data + // to the dump file. We generate a single 32 Bit hash for 512 faces + // using Assimp's standard hashing function. + if (shortened) { + unsigned int processed = 0; + for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) { - uint32_t hash = 0; - for (unsigned int a = 0; a < job;++a) { + uint32_t hash = 0; + for (unsigned int a = 0; a < job;++a) { - const aiFace& f = mesh->mFaces[processed+a]; - uint32_t tmp = f.mNumIndices; - hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); - for (unsigned int i = 0; i < f.mNumIndices; ++i) { - BOOST_STATIC_ASSERT(AI_MAX_VERTICES <= 0xffffffff); - tmp = static_cast( f.mIndices[i] ); - hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); - } - } - chunk.Write(hash); - } - } - else // else write as usual - { - // if there are less than 2^16 vertices, we can simply use 16 bit integers ... - for (unsigned int i = 0; i < mesh->mNumFaces;++i) { - const aiFace& f = mesh->mFaces[i]; + const aiFace& f = mesh->mFaces[processed+a]; + uint32_t tmp = f.mNumIndices; + hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); + for (unsigned int i = 0; i < f.mNumIndices; ++i) { + BOOST_STATIC_ASSERT(AI_MAX_VERTICES <= 0xffffffff); + tmp = static_cast( f.mIndices[i] ); + hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); + } + } + chunk.Write(hash); + } + } + else // else write as usual + { + // if there are less than 2^16 vertices, we can simply use 16 bit integers ... + for (unsigned int i = 0; i < mesh->mNumFaces;++i) { + const aiFace& f = mesh->mFaces[i]; - BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); - chunk.Write(f.mNumIndices); + BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); + chunk.Write(f.mNumIndices); - for (unsigned int a = 0; a < f.mNumIndices;++a) { - if (mesh->mNumVertices < (1u<<16)) { - chunk.Write(f.mIndices[a]); - } - else chunk.Write(f.mIndices[a]); - } - } - } + for (unsigned int a = 0; a < f.mNumIndices;++a) { + if (mesh->mNumVertices < (1u<<16)) { + chunk.Write(f.mIndices[a]); + } + else chunk.Write(f.mIndices[a]); + } + } + } - // write bones - if (mesh->mNumBones) { - for (unsigned int a = 0; a < mesh->mNumBones;++a) { - const aiBone* b = mesh->mBones[a]; - WriteBinaryBone(&chunk,b); - } - } - } + // write bones + if (mesh->mNumBones) { + for (unsigned int a = 0; a < mesh->mNumBones;++a) { + const aiBone* b = mesh->mBones[a]; + WriteBinaryBone(&chunk,b); + } + } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY ); + // ----------------------------------------------------------------------------------- + void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY ); - chunk.Write(prop->mKey); - chunk.Write(prop->mSemantic); - chunk.Write(prop->mIndex); + chunk.Write(prop->mKey); + chunk.Write(prop->mSemantic); + chunk.Write(prop->mIndex); - chunk.Write(prop->mDataLength); - chunk.Write((unsigned int)prop->mType); - chunk.Write(prop->mData,1,prop->mDataLength); - } + chunk.Write(prop->mDataLength); + chunk.Write((unsigned int)prop->mType); + chunk.Write(prop->mData,1,prop->mDataLength); + } - // ----------------------------------------------------------------------------------- - void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL); + // ----------------------------------------------------------------------------------- + void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL); - chunk.Write(mat->mNumProperties); - for (unsigned int i = 0; i < mat->mNumProperties;++i) { - WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]); - } - } + chunk.Write(mat->mNumProperties); + for (unsigned int i = 0; i < mat->mNumProperties;++i) { + WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]); + } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM ); + // ----------------------------------------------------------------------------------- + void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM ); - chunk.Write(nd->mNodeName); - chunk.Write(nd->mNumPositionKeys); - chunk.Write(nd->mNumRotationKeys); - chunk.Write(nd->mNumScalingKeys); - chunk.Write(nd->mPreState); - chunk.Write(nd->mPostState); + chunk.Write(nd->mNodeName); + chunk.Write(nd->mNumPositionKeys); + chunk.Write(nd->mNumRotationKeys); + chunk.Write(nd->mNumScalingKeys); + chunk.Write(nd->mPreState); + chunk.Write(nd->mPostState); - if (nd->mPositionKeys) { - if (shortened) { - chunk.WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys); + if (nd->mPositionKeys) { + if (shortened) { + chunk.WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys); - } // else write as usual - else chunk.Write(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); - } - if (nd->mRotationKeys) { - if (shortened) { - chunk.WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys); + } // else write as usual + else chunk.Write(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); + } + if (nd->mRotationKeys) { + if (shortened) { + chunk.WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys); - } // else write as usual - else chunk.Write(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); - } - if (nd->mScalingKeys) { - if (shortened) { - chunk.WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys); + } // else write as usual + else chunk.Write(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); + } + if (nd->mScalingKeys) { + if (shortened) { + chunk.WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys); - } // else write as usual - else chunk.Write(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); - } - } + } // else write as usual + else chunk.Write(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); + } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryAnim( IOStream * container, const aiAnimation* anim ) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION ); + // ----------------------------------------------------------------------------------- + void WriteBinaryAnim( IOStream * container, const aiAnimation* anim ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION ); - chunk.Write (anim->mName); - chunk.Write (anim->mDuration); - chunk.Write (anim->mTicksPerSecond); - chunk.Write(anim->mNumChannels); + chunk.Write (anim->mName); + chunk.Write (anim->mDuration); + chunk.Write (anim->mTicksPerSecond); + chunk.Write(anim->mNumChannels); - for (unsigned int a = 0; a < anim->mNumChannels;++a) { - const aiNodeAnim* nd = anim->mChannels[a]; - WriteBinaryNodeAnim(&chunk,nd); - } - } + for (unsigned int a = 0; a < anim->mNumChannels;++a) { + const aiNodeAnim* nd = anim->mChannels[a]; + WriteBinaryNodeAnim(&chunk,nd); + } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryLight( IOStream * container, const aiLight* l ) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT ); + // ----------------------------------------------------------------------------------- + void WriteBinaryLight( IOStream * container, const aiLight* l ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT ); - chunk.Write(l->mName); - chunk.Write(l->mType); + chunk.Write(l->mName); + chunk.Write(l->mType); - if (l->mType != aiLightSource_DIRECTIONAL) { - chunk.Write(l->mAttenuationConstant); - chunk.Write(l->mAttenuationLinear); - chunk.Write(l->mAttenuationQuadratic); - } + if (l->mType != aiLightSource_DIRECTIONAL) { + chunk.Write(l->mAttenuationConstant); + chunk.Write(l->mAttenuationLinear); + chunk.Write(l->mAttenuationQuadratic); + } - chunk.Write((const aiVector3D&)l->mColorDiffuse); - chunk.Write((const aiVector3D&)l->mColorSpecular); - chunk.Write((const aiVector3D&)l->mColorAmbient); + chunk.Write((const aiVector3D&)l->mColorDiffuse); + chunk.Write((const aiVector3D&)l->mColorSpecular); + chunk.Write((const aiVector3D&)l->mColorAmbient); - if (l->mType == aiLightSource_SPOT) { - chunk.Write(l->mAngleInnerCone); - chunk.Write(l->mAngleOuterCone); - } + if (l->mType == aiLightSource_SPOT) { + chunk.Write(l->mAngleInnerCone); + chunk.Write(l->mAngleOuterCone); + } - } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryCamera( IOStream * container, const aiCamera* cam ) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA ); + // ----------------------------------------------------------------------------------- + void WriteBinaryCamera( IOStream * container, const aiCamera* cam ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA ); - chunk.Write(cam->mName); - chunk.Write(cam->mPosition); - chunk.Write(cam->mLookAt); - chunk.Write(cam->mUp); - chunk.Write(cam->mHorizontalFOV); - chunk.Write(cam->mClipPlaneNear); - chunk.Write(cam->mClipPlaneFar); - chunk.Write(cam->mAspect); - } + chunk.Write(cam->mName); + chunk.Write(cam->mPosition); + chunk.Write(cam->mLookAt); + chunk.Write(cam->mUp); + chunk.Write(cam->mHorizontalFOV); + chunk.Write(cam->mClipPlaneNear); + chunk.Write(cam->mClipPlaneFar); + chunk.Write(cam->mAspect); + } - // ----------------------------------------------------------------------------------- - void WriteBinaryScene( IOStream * container, const aiScene* scene) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE ); + // ----------------------------------------------------------------------------------- + void WriteBinaryScene( IOStream * container, const aiScene* scene) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE ); - // basic scene information - chunk.Write(scene->mFlags); - chunk.Write(scene->mNumMeshes); - chunk.Write(scene->mNumMaterials); - chunk.Write(scene->mNumAnimations); - chunk.Write(scene->mNumTextures); - chunk.Write(scene->mNumLights); - chunk.Write(scene->mNumCameras); + // basic scene information + chunk.Write(scene->mFlags); + chunk.Write(scene->mNumMeshes); + chunk.Write(scene->mNumMaterials); + chunk.Write(scene->mNumAnimations); + chunk.Write(scene->mNumTextures); + chunk.Write(scene->mNumLights); + chunk.Write(scene->mNumCameras); - // write node graph - WriteBinaryNode( &chunk, scene->mRootNode ); + // write node graph + WriteBinaryNode( &chunk, scene->mRootNode ); - // write all meshes - for (unsigned int i = 0; i < scene->mNumMeshes;++i) { - const aiMesh* mesh = scene->mMeshes[i]; - WriteBinaryMesh( &chunk,mesh); - } + // write all meshes + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + const aiMesh* mesh = scene->mMeshes[i]; + WriteBinaryMesh( &chunk,mesh); + } - // write materials - for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { - const aiMaterial* mat = scene->mMaterials[i]; - WriteBinaryMaterial(&chunk,mat); - } + // write materials + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + const aiMaterial* mat = scene->mMaterials[i]; + WriteBinaryMaterial(&chunk,mat); + } - // write all animations - for (unsigned int i = 0; i < scene->mNumAnimations;++i) { - const aiAnimation* anim = scene->mAnimations[i]; - WriteBinaryAnim(&chunk,anim); - } + // write all animations + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + const aiAnimation* anim = scene->mAnimations[i]; + WriteBinaryAnim(&chunk,anim); + } - // write all textures - for (unsigned int i = 0; i < scene->mNumTextures;++i) { - const aiTexture* mesh = scene->mTextures[i]; - WriteBinaryTexture(&chunk,mesh); - } + // write all textures + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + const aiTexture* mesh = scene->mTextures[i]; + WriteBinaryTexture(&chunk,mesh); + } - // write lights - for (unsigned int i = 0; i < scene->mNumLights;++i) { - const aiLight* l = scene->mLights[i]; - WriteBinaryLight(&chunk,l); - } + // write lights + for (unsigned int i = 0; i < scene->mNumLights;++i) { + const aiLight* l = scene->mLights[i]; + WriteBinaryLight(&chunk,l); + } - // write cameras - for (unsigned int i = 0; i < scene->mNumCameras;++i) { - const aiCamera* cam = scene->mCameras[i]; - WriteBinaryCamera(&chunk,cam); - } + // write cameras + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + const aiCamera* cam = scene->mCameras[i]; + WriteBinaryCamera(&chunk,cam); + } - } + } - public: - AssbinExport() - { - shortened = false; - compressed = false; - } + public: + AssbinExport() + { + shortened = false; + compressed = false; + } - // ----------------------------------------------------------------------------------- - // Write a binary model dump - void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) - { - IOStream * out = pIOSystem->Open( pFile, "wb" ); - if (!out) return; + // ----------------------------------------------------------------------------------- + // Write a binary model dump + void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) + { + IOStream * out = pIOSystem->Open( pFile, "wb" ); + if (!out) return; - time_t tt = time(NULL); - tm* p = gmtime(&tt); + time_t tt = time(NULL); + tm* p = gmtime(&tt); - // header - char s[64]; - memset( s, 0, 64 ); + // header + char s[64]; + memset( s, 0, 64 ); #if _MSC_VER >= 1400 - sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p)); + sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p)); #else - snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p)); + snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p)); #endif - out->Write( s, 44, 1 ); - // == 44 bytes + out->Write( s, 44, 1 ); + // == 44 bytes - Write( out, ASSBIN_VERSION_MAJOR ); - Write( out, ASSBIN_VERSION_MINOR ); - Write( out, aiGetVersionRevision() ); - Write( out, aiGetCompileFlags() ); - Write( out, shortened ); - Write( out, compressed ); - // == 20 bytes + Write( out, ASSBIN_VERSION_MAJOR ); + Write( out, ASSBIN_VERSION_MINOR ); + Write( out, aiGetVersionRevision() ); + Write( out, aiGetCompileFlags() ); + Write( out, shortened ); + Write( out, compressed ); + // == 20 bytes - //todo + //todo - char buff[256]; - strncpy(buff,pFile,256); - out->Write(buff,sizeof(char),256); + char buff[256]; + strncpy(buff,pFile,256); + out->Write(buff,sizeof(char),256); - char cmd[] = "\0"; - strncpy(buff,cmd,128); - out->Write(buff,sizeof(char),128); + char cmd[] = "\0"; + strncpy(buff,cmd,128); + out->Write(buff,sizeof(char),128); - // leave 64 bytes free for future extensions - memset(buff,0xcd,64); - out->Write(buff,sizeof(char),64); - // == 435 bytes + // leave 64 bytes free for future extensions + memset(buff,0xcd,64); + out->Write(buff,sizeof(char),64); + // == 435 bytes - // ==== total header size: 512 bytes - ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH ); + // ==== total header size: 512 bytes + ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH ); - // Up to here the data is uncompressed. For compressed files, the rest - // is compressed using standard DEFLATE from zlib. - WriteBinaryScene( out, pScene ); + // Up to here the data is uncompressed. For compressed files, the rest + // is compressed using standard DEFLATE from zlib. + WriteBinaryScene( out, pScene ); - pIOSystem->Close( out ); - } - }; + pIOSystem->Close( out ); + } + }; void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) { - AssbinExport exporter; - exporter.WriteBinaryDump( pFile, pIOSystem, pScene ); + AssbinExport exporter; + exporter.WriteBinaryDump( pFile, pIOSystem, pScene ); } } // end of namespace Assimp From cd86818888703063f3a85b659793ec479c16b86c Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 23:18:45 +0200 Subject: [PATCH 39/80] - add compression support - remove unneeded code - change log warning to exception - document --- code/AssbinExporter.cpp | 109 ++++++++++++++++++++++------------------ code/AssbinExporter.h | 4 +- 2 files changed, 61 insertions(+), 52 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 27da1a303..2f1c403e9 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -10,18 +10,18 @@ with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. + copyright notice, this list of conditions and the + following disclaimer. * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. * Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -37,12 +37,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ - +/** @file AssbinExporter.cpp + * ASSBIN exporter main code + */ #include "AssimpPCH.h" #include "assbin_chunks.h" #include "./../include/assimp/version.h" #include "ProcessHelper.h" +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB +# include +#else +# include "../contrib/zlib/zlib.h" +#endif + #ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER @@ -50,6 +58,16 @@ using namespace Assimp; namespace Assimp { + // ---------------------------------------------------------------------------------- + /** @class AssbinChunkWriter + * @brief Chunk writer mechanism for the .assbin file structure + * + * This is a standard in-memory IOStream (most of the code is based on BlobIOStream), + * the difference being that this takes another IOStream as a "container" in the + * constructor, and when it is destroyed, it appends the magic number, the chunk size, + * and the chunk contents to the container stream. This allows relatively easy chunk + * chunk construction, even recursively. + */ class AssbinChunkWriter : public IOStream { private: @@ -93,13 +111,12 @@ namespace Assimp { if (buffer) delete[] buffer; } + void * GetBufferPointer() { return buffer; }; + // ------------------------------------------------------------------- - virtual size_t Read(void* pvBuffer, - size_t pSize, - size_t pCount) { return 0; }; - virtual aiReturn Seek(size_t pOffset, - aiOrigin pOrigin) { return aiReturn_FAILURE; }; - virtual size_t Tell() const { return 0; }; + virtual size_t Read(void* pvBuffer, size_t pSize, size_t pCount) { return 0; }; + virtual aiReturn Seek(size_t pOffset, aiOrigin pOrigin) { return aiReturn_FAILURE; }; + virtual size_t Tell() const { return cursor; }; virtual void Flush() { }; virtual size_t FileSize() const @@ -127,6 +144,7 @@ namespace Assimp { return Write( &v, sizeof(T), 1 ); } + // ----------------------------------------------------------------------------------- // Serialize an aiString template <> @@ -146,7 +164,7 @@ namespace Assimp { const uint32_t t = (uint32_t)w; if (w > t) { // this shouldn't happen, integers in Assimp data structures never exceed 2^32 - printf("loss of data due to 64 -> 32 bit integer conversion"); + throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion"); } Write(&t,4,1); @@ -268,43 +286,19 @@ namespace Assimp { return t + Write(maxc); } - }; -/* - class AssbinChunkWriter - { - AssbinStream stream; - uint32_t magic; - public: - AssbinChunkWriter( uint32_t _magic ) - { - magic = _magic; - } - void AppendToStream( AssbinStream & _stream ) - { - uint32_t s = stream.FileSize(); - _stream.Write( &magic, sizeof(uint32_t), 1 ); - _stream.Write( &s, sizeof(uint32_t), 1 ); - _stream.Write( stream.GetBuffer(), stream.FileSize(), 1 ); - } - void AppendToStream( AssbinChunkWriter & _stream ) - { - uint32_t s = stream.FileSize(); - _stream.WriteRaw( &magic, sizeof(uint32_t) ); - _stream.WriteRaw( &s, sizeof(uint32_t) ); - _stream.WriteRaw( stream.GetBuffer(), stream.FileSize() ); - } - - }; -*/ - + // ---------------------------------------------------------------------------------- + /** @class AssbinExport + * @brief Assbin exporter class + * + * This class performs the .assbin exporting, and is responsible for the file layout. + */ class AssbinExport { private: bool shortened; bool compressed; - //AssbinStream stream; protected: template @@ -709,8 +703,6 @@ namespace Assimp { Write( out, compressed ); // == 20 bytes - //todo - char buff[256]; strncpy(buff,pFile,256); out->Write(buff,sizeof(char),256); @@ -729,7 +721,26 @@ namespace Assimp { // Up to here the data is uncompressed. For compressed files, the rest // is compressed using standard DEFLATE from zlib. - WriteBinaryScene( out, pScene ); + if (compressed) + { + AssbinChunkWriter uncompressedStream( NULL, NULL ); + WriteBinaryScene( &uncompressedStream, pScene ); + + uLongf uncompressedSize = uncompressedStream.Tell(); + uLongf compressedSize = (uLongf)(uncompressedStream.Tell() * 1.001 + 12.); + uint8_t* compressedBuffer = new uint8_t[ compressedSize ]; + + compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 ); + + out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); + out->Write( compressedBuffer, sizeof(char), compressedSize ); + + delete[] compressedBuffer; + } + else + { + WriteBinaryScene( out, pScene ); + } pIOSystem->Close( out ); } diff --git a/code/AssbinExporter.h b/code/AssbinExporter.h index f6a0cf598..34ccda3e1 100644 --- a/code/AssbinExporter.h +++ b/code/AssbinExporter.h @@ -44,8 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_ASSBINEXPORTER_H_INC #define AI_ASSBINEXPORTER_H_INC -#include - -#include "StreamWriter.h" +// nothing really needed here - reserved for future use like properties #endif From 0f822d38cd5aa01bccfcaef50c24ef59fd66df48 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 00:39:54 +0200 Subject: [PATCH 40/80] add basic framework for importer --- code/AssbinLoader.cpp | 71 ++++++++++++++++++++++++++++++++++++ code/AssbinLoader.h | 77 +++++++++++++++++++++++++++++++++++++++ code/ImporterRegistry.cpp | 8 +++- 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 code/AssbinLoader.cpp create mode 100644 code/AssbinLoader.h diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp new file mode 100644 index 000000000..336061326 --- /dev/null +++ b/code/AssbinLoader.cpp @@ -0,0 +1,71 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file AssbinLoader.cpp + * @brief Implementation of the .assbin importer class + * + * see assbin_chunks.h + */ + +#include "AssimpPCH.h" +#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER + +// internal headers +#include "AssbinLoader.h" + +using namespace Assimp; + +bool Assimp::AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const +{ + return false; +} + +const aiImporterDesc* Assimp::AssbinImporter::GetInfo() const +{ + return NULL; +} + +void Assimp::AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) +{ + +} + +#endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h new file mode 100644 index 000000000..c3f6a5873 --- /dev/null +++ b/code/AssbinLoader.h @@ -0,0 +1,77 @@ + +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file AssbinLoader.h + * @brief .assbin File format loader + */ +#ifndef AI_ASSBINIMPORTER_H_INC +#define AI_ASSBINIMPORTER_H_INC + +#include "BaseImporter.h" +#include "../include/assimp/types.h" + +#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER + +namespace Assimp { + +// --------------------------------------------------------------------------------- +/** Importer class for 3D Studio r3 and r4 3DS files + */ +class AssbinImporter : public BaseImporter +{ + virtual bool CanRead( + const std::string& pFile, + IOSystem* pIOHandler, + bool checkSig + ) const; + virtual const aiImporterDesc* GetInfo() const; + virtual void InternReadFile( + const std::string& pFile, + aiScene* pScene, + IOSystem* pIOHandler + ); +}; + +} // end of namespace Assimp + +#endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER + +#endif // AI_ASSBINIMPORTER_H_INC diff --git a/code/ImporterRegistry.cpp b/code/ImporterRegistry.cpp index e301804e2..8499aaeaa 100644 --- a/code/ImporterRegistry.cpp +++ b/code/ImporterRegistry.cpp @@ -166,6 +166,9 @@ corresponding preprocessor flag to selectively disable formats. #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER # include "FBXImporter.h" #endif +#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER +# include "AssbinLoader.h" +#endif namespace Assimp { @@ -289,7 +292,10 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out) out.push_back( new XGLImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER ) - out.push_back( new FBXImporter() ); + out.push_back( new FBXImporter() ); +#endif +#if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER ) + out.push_back( new AssbinImporter() ); #endif } From 9cdecc780bbaf665c785f8239d912d3713bac14c Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 00:44:30 +0200 Subject: [PATCH 41/80] Fix wrong nesting Otherwise doesn't compile if ASSIMP_BUILD_NO_3DS_IMPORTER is defined because the #endif is inside the namespace block --- code/3DSLoader.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/3DSLoader.h b/code/3DSLoader.h index 5e80195f5..2b1dd26f8 100644 --- a/code/3DSLoader.h +++ b/code/3DSLoader.h @@ -273,8 +273,8 @@ protected: bool bIsPrj; }; -#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER - } // end of namespace Assimp +#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER + #endif // AI_3DSIMPORTER_H_INC From 5b512dd9ddcd163163c2af6341df3bdea33ee860 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 00:52:05 +0200 Subject: [PATCH 42/80] add info + header check --- code/AssbinLoader.cpp | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 336061326..890036b68 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -53,19 +53,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; -bool Assimp::AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const -{ - return false; -} +static const aiImporterDesc desc = { + ".assbin Importer", + "Gargaj / Conspiracy", + "", + "", + aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour, + 0, + 0, + 0, + 0, + "assbin" +}; const aiImporterDesc* Assimp::AssbinImporter::GetInfo() const { - return NULL; + return &desc; +} + +bool Assimp::AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const +{ + IOStream * in = pIOHandler->Open(pFile); + if (!in) + return false; + + char s[32]; + in->Read( s, sizeof(char), 32 ); + + pIOHandler->Close(in); + + return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; } void Assimp::AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) { - + // TODO } #endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER From 87dff6a00eb38f327b504067fc3fafa81267be3c Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 13:26:26 +0200 Subject: [PATCH 43/80] start importer, load nodes --- code/AssbinLoader.cpp | 153 ++++++++++++++++++++++++++++++++++++++++-- code/AssbinLoader.h | 8 +++ 2 files changed, 157 insertions(+), 4 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 890036b68..cfe205ea8 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // internal headers #include "AssbinLoader.h" +#include "assbin_chunks.h" using namespace Assimp; @@ -66,12 +67,12 @@ static const aiImporterDesc desc = { "assbin" }; -const aiImporterDesc* Assimp::AssbinImporter::GetInfo() const +const aiImporterDesc* AssbinImporter::GetInfo() const { return &desc; } -bool Assimp::AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const +bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const { IOStream * in = pIOHandler->Open(pFile); if (!in) @@ -85,9 +86,153 @@ bool Assimp::AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHan return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; } -void Assimp::AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) +template +T Read(IOStream * stream) { - // TODO + T t; + stream->Read( &t, sizeof(T), 1 ); + return t; +} + +template <> +aiString Read(IOStream * stream) +{ + aiString s; + stream->Read(&s.length,4,1); + stream->Read(s.data,s.length,1); + return s; +} + +template <> +aiMatrix4x4 Read(IOStream * stream) +{ + aiMatrix4x4 m; + for (unsigned int i = 0; i < 4;++i) { + for (unsigned int i2 = 0; i2 < 4;++i2) { + m[i][i2] = Read(stream); + } + } + return m; +} + +void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AINODE); + uint32_t size = Read(stream); + + *node = new aiNode(); + + (*node)->mName = Read(stream); + (*node)->mTransformation = Read(stream); + (*node)->mNumChildren = Read(stream); + (*node)->mNumMeshes = Read(stream); + + if ((*node)->mNumMeshes) + { + (*node)->mMeshes = new unsigned int[(*node)->mNumMeshes]; + for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) { + (*node)->mMeshes[i] = Read(stream); + } + } + + if ((*node)->mNumChildren) + { + (*node)->mChildren = new aiNode*[(*node)->mNumChildren]; + for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) { + ReadBinaryNode( stream, &(*node)->mChildren[i] ); + } + } + +} + +void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); + uint32_t size = Read(stream); + + scene->mFlags = Read(stream); + scene->mNumMeshes = Read(stream); + scene->mNumMaterials = Read(stream); + scene->mNumAnimations = Read(stream); + scene->mNumTextures = Read(stream); + scene->mNumLights = Read(stream); + scene->mNumCameras = Read(stream); + + // Read node graph + scene->mRootNode = new aiNode[1]; + ReadBinaryNode( stream, &scene->mRootNode ); + +/* + // Read all meshes + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + const aiMesh* mesh = scene->mMeshes[i]; + ReadBinaryMesh( stream,mesh); + } + + // Read materials + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + const aiMaterial* mat = scene->mMaterials[i]; + ReadBinaryMaterial(stream,mat); + } + + // Read all animations + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + const aiAnimation* anim = scene->mAnimations[i]; + ReadBinaryAnim(stream,anim); + } + + + // Read all textures + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + const aiTexture* mesh = scene->mTextures[i]; + ReadBinaryTexture(stream,mesh); + } + + // Read lights + for (unsigned int i = 0; i < scene->mNumLights;++i) { + const aiLight* l = scene->mLights[i]; + ReadBinaryLight(stream,l); + } + + // Read cameras + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + const aiCamera* cam = scene->mCameras[i]; + ReadBinaryCamera(stream,cam); + } +*/ + +} + +void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) +{ + IOStream * stream = pIOHandler->Open(pFile,"rb"); + if (!stream) + return; + + stream->Seek( 44, aiOrigin_CUR ); // signature + + unsigned int versionMajor = Read(stream); + unsigned int versionMinor = Read(stream); + unsigned int versionRevision = Read(stream); + unsigned int compileFlags = Read(stream); + + shortened = Read(stream) > 0; + compressed = Read(stream) > 0; + + stream->Seek( 256, aiOrigin_CUR ); // original filename + stream->Seek( 128, aiOrigin_CUR ); // options + stream->Seek( 64, aiOrigin_CUR ); // padding + + if (compressed) + { + // TODO + } + else + { + ReadBinaryScene(stream,pScene); + } + + pIOHandler->Close(stream); } #endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h index c3f6a5873..189b019ba 100644 --- a/code/AssbinLoader.h +++ b/code/AssbinLoader.h @@ -57,6 +57,12 @@ namespace Assimp { */ class AssbinImporter : public BaseImporter { +private: + bool shortened; + bool compressed; +protected: + +public: virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, @@ -68,6 +74,8 @@ class AssbinImporter : public BaseImporter aiScene* pScene, IOSystem* pIOHandler ); + void ReadBinaryScene( IOStream * stream, aiScene* pScene ); + void ReadBinaryNode( IOStream * stream, aiNode** mRootNode ); }; } // end of namespace Assimp From ac5c1f9df1b335f3a30e606b3057846fa2684def Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 13:27:09 +0200 Subject: [PATCH 44/80] add to cmake --- code/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 0a57d540b..4e05887ba 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -174,6 +174,8 @@ SOURCE_GROUP( ASE FILES ${ASE_SRCS}) SET( ASSBIN_SRCS AssbinExporter.h AssbinExporter.cpp + AssbinLoader.h + AssbinLoader.cpp ) SOURCE_GROUP( Assbin FILES ${ASSBIN_SRCS}) From ad298cd84f6525d39d32c2c91716604471041896 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 13:29:09 +0200 Subject: [PATCH 45/80] fix code style --- code/ImporterRegistry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/ImporterRegistry.cpp b/code/ImporterRegistry.cpp index 8499aaeaa..dff195854 100644 --- a/code/ImporterRegistry.cpp +++ b/code/ImporterRegistry.cpp @@ -292,10 +292,10 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out) out.push_back( new XGLImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER ) - out.push_back( new FBXImporter() ); + out.push_back( new FBXImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER ) - out.push_back( new AssbinImporter() ); + out.push_back( new AssbinImporter() ); #endif } From f38dd8e6e2468f417fa2a1d2cc133d8a2f1d9640 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 14:06:08 +0200 Subject: [PATCH 46/80] add mesh loader --- code/AssbinLoader.cpp | 167 ++++++++++++++++++++++++++++++++++++++++-- code/AssbinLoader.h | 2 + 2 files changed, 164 insertions(+), 5 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index cfe205ea8..24924ade5 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -115,6 +115,12 @@ aiMatrix4x4 Read(IOStream * stream) return m; } +template void ReadBounds( IOStream * stream, T* p, unsigned int n ) +{ + // not sure what to do here, the data isn't really useful. + stream->Seek( sizeof(T) * n, aiOrigin_CUR ); +} + void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AINODE); @@ -145,6 +151,153 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) } +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AIBONE ); + uint32_t size = Read(stream); + + b->mName = Read(stream); + b->mNumWeights = Read(stream); + b->mOffsetMatrix = Read(stream); + + // for the moment we write dumb min/max values for the bones, too. + // maybe I'll add a better, hash-like solution later + if (shortened) + { + ReadBounds(stream,b->mWeights,b->mNumWeights); + } // else write as usual + else + { + b->mWeights = new aiVertexWeight[b->mNumWeights]; + stream->Read(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); + } +} + + +void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AIMESH); + uint32_t size = Read(stream); + + mesh->mPrimitiveTypes = Read(stream); + mesh->mNumVertices = Read(stream); + mesh->mNumFaces = Read(stream); + mesh->mNumBones = Read(stream); + mesh->mMaterialIndex = Read(stream); + + // first of all, write bits for all existent vertex components + unsigned int c = Read(stream); + + if (c & ASSBIN_MESH_HAS_POSITIONS) + { + if (shortened) { + ReadBounds(stream,mesh->mVertices,mesh->mNumVertices); + } // else write as usual + else + { + mesh->mVertices = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mVertices,1,12*mesh->mNumVertices); + } + } + if (c & ASSBIN_MESH_HAS_NORMALS) + { + if (shortened) { + ReadBounds(stream,mesh->mNormals,mesh->mNumVertices); + } // else write as usual + else + { + mesh->mNormals = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mNormals,1,12*mesh->mNumVertices); + } + } + if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) + { + if (shortened) { + ReadBounds(stream,mesh->mTangents,mesh->mNumVertices); + ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices); + } // else write as usual + else { + mesh->mTangents = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mTangents,1,12*mesh->mNumVertices); + mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mBitangents,1,12*mesh->mNumVertices); + } + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) + { + if (!(c & ASSBIN_MESH_HAS_COLOR(n))) + break; + + if (shortened) + { + ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices); + } // else write as usual + else + { + mesh->mColors[n] = new aiColor4D[mesh->mNumVertices]; + stream->Read(mesh->mColors[n],16*mesh->mNumVertices,1); + } + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) + { + if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n))) + break; + + // write number of UV components + mesh->mNumUVComponents[n] = Read(stream); + + if (shortened) { + ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices); + } // else write as usual + else + { + mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); + } + } + + // write faces. There are no floating-point calculations involved + // in these, so we can write a simple hash over the face data + // to the dump file. We generate a single 32 Bit hash for 512 faces + // using Assimp's standard hashing function. + if (shortened) { + Read(stream); + } + else // else write as usual + { + // if there are less than 2^16 vertices, we can simply use 16 bit integers ... + mesh->mFaces = new aiFace[mesh->mNumFaces]; + for (unsigned int i = 0; i < mesh->mNumFaces;++i) { + aiFace& f = mesh->mFaces[i]; + + BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); + f.mNumIndices = Read(stream); + f.mIndices = new unsigned int[f.mNumIndices]; + + for (unsigned int a = 0; a < f.mNumIndices;++a) { + if (mesh->mNumVertices < (1u<<16)) + { + f.mIndices[a] = Read(stream); + } + else + { + f.mIndices[a] = Read(stream); + } + } + } + } + + // write bones + if (mesh->mNumBones) { + mesh->mBones = new C_STRUCT aiBone*[mesh->mNumBones]; + for (unsigned int a = 0; a < mesh->mNumBones;++a) { + mesh->mBones[a] = new aiBone(); + ReadBinaryBone(stream,mesh->mBones[a]); + } + } +} + void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); @@ -162,13 +315,17 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) scene->mRootNode = new aiNode[1]; ReadBinaryNode( stream, &scene->mRootNode ); -/* // Read all meshes - for (unsigned int i = 0; i < scene->mNumMeshes;++i) { - const aiMesh* mesh = scene->mMeshes[i]; - ReadBinaryMesh( stream,mesh); - } + if (scene->mNumMeshes) + { + scene->mMeshes = new aiMesh*[scene->mNumMeshes]; + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + scene->mMeshes[i] = new aiMesh(); + ReadBinaryMesh( stream,scene->mMeshes[i]); + } + } +/* // Read materials for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { const aiMaterial* mat = scene->mMaterials[i]; diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h index 189b019ba..64fb7056e 100644 --- a/code/AssbinLoader.h +++ b/code/AssbinLoader.h @@ -76,6 +76,8 @@ public: ); void ReadBinaryScene( IOStream * stream, aiScene* pScene ); void ReadBinaryNode( IOStream * stream, aiNode** mRootNode ); + void ReadBinaryMesh( IOStream * stream, aiMesh* mesh ); + void ReadBinaryBone( IOStream * stream, aiBone* bone ); }; } // end of namespace Assimp From 50487930969dda61caa5206c37401d452c0f5424 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 14:21:53 +0200 Subject: [PATCH 47/80] add material import --- code/AssbinLoader.cpp | 50 ++++++++++++++++++++++++++++++++++++++----- code/AssbinLoader.h | 2 ++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 24924ade5..ee970cd2e 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -298,6 +298,42 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) } } +void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AIMATERIALPROPERTY); + uint32_t size = Read(stream); + + prop->mKey = Read(stream); + prop->mSemantic = Read(stream); + prop->mIndex = Read(stream); + + prop->mDataLength = Read(stream); + prop->mType = (aiPropertyTypeInfo)Read(stream); + prop->mData = new char [ prop->mDataLength ]; + stream->Read(prop->mData,1,prop->mDataLength); +} + +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AIMATERIAL); + uint32_t size = Read(stream); + + mat->mNumAllocated = mat->mNumProperties = Read(stream); + if (mat->mNumProperties) + { + if (mat->mProperties) + { + delete[] mat->mProperties; + } + mat->mProperties = new aiMaterialProperty*[mat->mNumProperties]; + for (unsigned int i = 0; i < mat->mNumProperties;++i) { + mat->mProperties[i] = new aiMaterialProperty(); + ReadBinaryMaterialProperty( stream, mat->mProperties[i]); + } + } +} + void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); @@ -325,12 +361,16 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) } } -/* // Read materials - for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { - const aiMaterial* mat = scene->mMaterials[i]; - ReadBinaryMaterial(stream,mat); - } + if (scene->mNumMaterials) + { + scene->mMaterials = new aiMaterial*[scene->mNumMaterials]; + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + scene->mMaterials[i] = new aiMaterial(); + ReadBinaryMaterial(stream,scene->mMaterials[i]); + } + } +/* // Read all animations for (unsigned int i = 0; i < scene->mNumAnimations;++i) { diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h index 64fb7056e..7b99860b4 100644 --- a/code/AssbinLoader.h +++ b/code/AssbinLoader.h @@ -78,6 +78,8 @@ public: void ReadBinaryNode( IOStream * stream, aiNode** mRootNode ); void ReadBinaryMesh( IOStream * stream, aiMesh* mesh ); void ReadBinaryBone( IOStream * stream, aiBone* bone ); + void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat); + void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop); }; } // end of namespace Assimp From 886a704c17d323f0b1d71eb22ec3c3989d2df208 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 14:43:47 +0200 Subject: [PATCH 48/80] some notes to self --- code/AssbinExporter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 2f1c403e9..439f2e61f 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -337,7 +337,7 @@ namespace Assimp { if(!shortened) { if (!tex->mHeight) { - chunk.Write(tex->pcData,1,tex->mWidth); + chunk.Write(tex->pcData,1,tex->mWidth); // BUG?! should be *4? } else { chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); @@ -732,7 +732,7 @@ namespace Assimp { compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 ); - out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); + out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); // BUG?! are we writing compressed or uncompressed size here? out->Write( compressedBuffer, sizeof(char), compressedSize ); delete[] compressedBuffer; From 97c9ce1d5b1e8fd76677c38e9759c3b182ee82e0 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 14:44:06 +0200 Subject: [PATCH 49/80] add animations and textures --- code/AssbinLoader.cpp | 118 ++++++++++++++++++++++++++++++++++++++---- code/AssbinLoader.h | 3 ++ 2 files changed, 111 insertions(+), 10 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index ee970cd2e..c0777a87b 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -334,6 +334,97 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) } } +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AINODEANIM); + uint32_t size = Read(stream); + + nd->mNodeName = Read(stream); + nd->mNumPositionKeys = Read(stream); + nd->mNumRotationKeys = Read(stream); + nd->mNumScalingKeys = Read(stream); + nd->mPreState = (aiAnimBehaviour)Read(stream); + nd->mPostState = (aiAnimBehaviour)Read(stream); + + if (nd->mNumPositionKeys) { + if (shortened) { + ReadBounds(stream,nd->mPositionKeys,nd->mNumPositionKeys); + + } // else write as usual + else { + nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; + stream->Read(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); + } + } + if (nd->mNumRotationKeys) { + if (shortened) { + ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys); + + } // else write as usual + else + { + nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; + stream->Read(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); + } + } + if (nd->mNumScalingKeys) { + if (shortened) { + ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys); + + } // else write as usual + else + { + nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; + stream->Read(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); + } + } +} + + +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AIANIMATION); + uint32_t size = Read(stream); + + anim->mName = Read (stream); + anim->mDuration = Read (stream); + anim->mTicksPerSecond = Read (stream); + anim->mNumChannels = Read(stream); + + if (anim->mNumChannels) + { + anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ]; + for (unsigned int a = 0; a < anim->mNumChannels;++a) { + anim->mChannels[a] = new aiNodeAnim(); + ReadBinaryNodeAnim(stream,anim->mChannels[a]); + } + } +} + +void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AITEXTURE); + uint32_t size = Read(stream); + + tex->mWidth = Read(stream); + tex->mHeight = Read(stream); + stream->Read( tex->achFormatHint, sizeof(char), 4 ); + + if(!shortened) { + if (!tex->mHeight) { + tex->pcData = new aiTexel[ tex->mWidth ]; + stream->Read(tex->pcData,1,tex->mWidth); + } + else { + tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ]; + stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4); + } + } + +} + void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); @@ -370,21 +461,28 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) ReadBinaryMaterial(stream,scene->mMaterials[i]); } } -/* // Read all animations - for (unsigned int i = 0; i < scene->mNumAnimations;++i) { - const aiAnimation* anim = scene->mAnimations[i]; - ReadBinaryAnim(stream,anim); - } - + if (scene->mNumAnimations) + { + scene->mAnimations = new aiAnimation*[scene->mNumAnimations]; + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + scene->mAnimations[i] = new aiAnimation(); + ReadBinaryAnim(stream,scene->mAnimations[i]); + } + } // Read all textures - for (unsigned int i = 0; i < scene->mNumTextures;++i) { - const aiTexture* mesh = scene->mTextures[i]; - ReadBinaryTexture(stream,mesh); - } + if (scene->mNumTextures) + { + scene->mTextures = new aiTexture*[scene->mNumTextures]; + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + scene->mTextures[i] = new aiTexture(); + ReadBinaryTexture(stream,scene->mTextures[i]); + } + } +/* // Read lights for (unsigned int i = 0; i < scene->mNumLights;++i) { const aiLight* l = scene->mLights[i]; diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h index 7b99860b4..a1b2a71d6 100644 --- a/code/AssbinLoader.h +++ b/code/AssbinLoader.h @@ -80,6 +80,9 @@ public: void ReadBinaryBone( IOStream * stream, aiBone* bone ); void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat); void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop); + void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd); + void ReadBinaryAnim( IOStream * stream, aiAnimation* anim ); + void ReadBinaryTexture(IOStream * stream, aiTexture* tex); }; } // end of namespace Assimp From 1aeaef2037c71f1312e8cfe93dacae30f870683a Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 15:01:04 +0200 Subject: [PATCH 50/80] add lights and cameras --- code/AssbinLoader.cpp | 68 ++++++++++++++++++++++++++++++++++++------- code/AssbinLoader.h | 2 ++ 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index c0777a87b..8dbbbae22 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -425,6 +425,48 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) } +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AILIGHT); + uint32_t size = Read(stream); + + l->mName = Read(stream); + l->mType = (aiLightSourceType)Read(stream); + + if (l->mType != aiLightSource_DIRECTIONAL) { + l->mAttenuationConstant = Read(stream); + l->mAttenuationLinear = Read(stream); + l->mAttenuationQuadratic = Read(stream); + } + + l->mColorDiffuse = Read(stream); + l->mColorSpecular = Read(stream); + l->mColorAmbient = Read(stream); + + if (l->mType == aiLightSource_SPOT) { + l->mAngleInnerCone = Read(stream); + l->mAngleOuterCone = Read(stream); + } + +} + +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AICAMERA); + uint32_t size = Read(stream); + + cam->mName = Read(stream); + cam->mPosition = Read(stream); + cam->mLookAt = Read(stream); + cam->mUp = Read(stream); + cam->mHorizontalFOV = Read(stream); + cam->mClipPlaneNear = Read(stream); + cam->mClipPlaneFar = Read(stream); + cam->mAspect = Read(stream); +} + void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); @@ -482,19 +524,25 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) } } -/* // Read lights - for (unsigned int i = 0; i < scene->mNumLights;++i) { - const aiLight* l = scene->mLights[i]; - ReadBinaryLight(stream,l); - } + if (scene->mNumLights) + { + scene->mLights = new aiLight*[scene->mNumLights]; + for (unsigned int i = 0; i < scene->mNumLights;++i) { + scene->mLights[i] = new aiLight(); + ReadBinaryLight(stream,scene->mLights[i]); + } + } // Read cameras - for (unsigned int i = 0; i < scene->mNumCameras;++i) { - const aiCamera* cam = scene->mCameras[i]; - ReadBinaryCamera(stream,cam); - } -*/ + if (scene->mNumCameras) + { + scene->mCameras = new aiCamera*[scene->mNumCameras]; + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + scene->mCameras[i] = new aiCamera(); + ReadBinaryCamera(stream,scene->mCameras[i]); + } + } } diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h index a1b2a71d6..f4e6e059a 100644 --- a/code/AssbinLoader.h +++ b/code/AssbinLoader.h @@ -83,6 +83,8 @@ public: void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd); void ReadBinaryAnim( IOStream * stream, aiAnimation* anim ); void ReadBinaryTexture(IOStream * stream, aiTexture* tex); + void ReadBinaryLight( IOStream * stream, aiLight* l ); + void ReadBinaryCamera( IOStream * stream, aiCamera* cam ); }; } // end of namespace Assimp From fb546b694e1dc66d781c5df192e712290d2e3729 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 15:25:39 +0200 Subject: [PATCH 51/80] code style --- code/AssbinLoader.cpp | 375 +++++++++++++++++++++--------------------- 1 file changed, 188 insertions(+), 187 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 8dbbbae22..1739659b1 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -55,58 +55,58 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; static const aiImporterDesc desc = { - ".assbin Importer", - "Gargaj / Conspiracy", - "", - "", - aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour, - 0, - 0, - 0, - 0, - "assbin" + ".assbin Importer", + "Gargaj / Conspiracy", + "", + "", + aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour, + 0, + 0, + 0, + 0, + "assbin" }; const aiImporterDesc* AssbinImporter::GetInfo() const { - return &desc; + return &desc; } bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const { - IOStream * in = pIOHandler->Open(pFile); - if (!in) - return false; + IOStream * in = pIOHandler->Open(pFile); + if (!in) + return false; - char s[32]; - in->Read( s, sizeof(char), 32 ); + char s[32]; + in->Read( s, sizeof(char), 32 ); - pIOHandler->Close(in); + pIOHandler->Close(in); - return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; + return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; } template T Read(IOStream * stream) { - T t; - stream->Read( &t, sizeof(T), 1 ); - return t; + T t; + stream->Read( &t, sizeof(T), 1 ); + return t; } template <> aiString Read(IOStream * stream) { - aiString s; + aiString s; stream->Read(&s.length,4,1); - stream->Read(s.data,s.length,1); - return s; + stream->Read(s.data,s.length,1); + return s; } template <> aiMatrix4x4 Read(IOStream * stream) { - aiMatrix4x4 m; + aiMatrix4x4 m; for (unsigned int i = 0; i < 4;++i) { for (unsigned int i2 = 0; i2 < 4;++i2) { m[i][i2] = Read(stream); @@ -117,37 +117,37 @@ aiMatrix4x4 Read(IOStream * stream) template void ReadBounds( IOStream * stream, T* p, unsigned int n ) { - // not sure what to do here, the data isn't really useful. + // not sure what to do here, the data isn't really useful. stream->Seek( sizeof(T) * n, aiOrigin_CUR ); } void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AINODE); - uint32_t size = Read(stream); + uint32_t size = Read(stream); - *node = new aiNode(); + *node = new aiNode(); (*node)->mName = Read(stream); (*node)->mTransformation = Read(stream); (*node)->mNumChildren = Read(stream); (*node)->mNumMeshes = Read(stream); - if ((*node)->mNumMeshes) - { - (*node)->mMeshes = new unsigned int[(*node)->mNumMeshes]; - for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) { - (*node)->mMeshes[i] = Read(stream); - } - } + if ((*node)->mNumMeshes) + { + (*node)->mMeshes = new unsigned int[(*node)->mNumMeshes]; + for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) { + (*node)->mMeshes[i] = Read(stream); + } + } - if ((*node)->mNumChildren) - { - (*node)->mChildren = new aiNode*[(*node)->mNumChildren]; - for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) { - ReadBinaryNode( stream, &(*node)->mChildren[i] ); - } - } + if ((*node)->mNumChildren) + { + (*node)->mChildren = new aiNode*[(*node)->mNumChildren]; + for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) { + ReadBinaryNode( stream, &(*node)->mChildren[i] ); + } + } } @@ -155,7 +155,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIBONE ); - uint32_t size = Read(stream); + uint32_t size = Read(stream); b->mName = Read(stream); b->mNumWeights = Read(stream); @@ -164,21 +164,21 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) // for the moment we write dumb min/max values for the bones, too. // maybe I'll add a better, hash-like solution later if (shortened) - { + { ReadBounds(stream,b->mWeights,b->mNumWeights); } // else write as usual else - { - b->mWeights = new aiVertexWeight[b->mNumWeights]; - stream->Read(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); - } + { + b->mWeights = new aiVertexWeight[b->mNumWeights]; + stream->Read(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); + } } void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIMESH); - uint32_t size = Read(stream); + uint32_t size = Read(stream); mesh->mPrimitiveTypes = Read(stream); mesh->mNumVertices = Read(stream); @@ -190,57 +190,58 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) unsigned int c = Read(stream); if (c & ASSBIN_MESH_HAS_POSITIONS) - { + { if (shortened) { ReadBounds(stream,mesh->mVertices,mesh->mNumVertices); } // else write as usual else - { - mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mVertices,1,12*mesh->mNumVertices); - } + { + mesh->mVertices = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mVertices,1,12*mesh->mNumVertices); + } } if (c & ASSBIN_MESH_HAS_NORMALS) - { + { if (shortened) { ReadBounds(stream,mesh->mNormals,mesh->mNumVertices); } // else write as usual else - { - mesh->mNormals = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mNormals,1,12*mesh->mNumVertices); - } + { + mesh->mNormals = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mNormals,1,12*mesh->mNumVertices); + } } if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) - { + { if (shortened) { ReadBounds(stream,mesh->mTangents,mesh->mNumVertices); ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices); } // else write as usual - else { - mesh->mTangents = new aiVector3D[mesh->mNumVertices]; + else + { + mesh->mTangents = new aiVector3D[mesh->mNumVertices]; stream->Read(mesh->mTangents,1,12*mesh->mNumVertices); - mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; + mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; stream->Read(mesh->mBitangents,1,12*mesh->mNumVertices); } } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) - { + { if (!(c & ASSBIN_MESH_HAS_COLOR(n))) break; if (shortened) - { + { ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices); } // else write as usual else - { - mesh->mColors[n] = new aiColor4D[mesh->mNumVertices]; - stream->Read(mesh->mColors[n],16*mesh->mNumVertices,1); - } + { + mesh->mColors[n] = new aiColor4D[mesh->mNumVertices]; + stream->Read(mesh->mColors[n],16*mesh->mNumVertices,1); + } } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) - { + { if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n))) break; @@ -251,10 +252,10 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices); } // else write as usual else - { - mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); - } + { + mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); + } } // write faces. There are no floating-point calculations involved @@ -267,30 +268,30 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) else // else write as usual { // if there are less than 2^16 vertices, we can simply use 16 bit integers ... - mesh->mFaces = new aiFace[mesh->mNumFaces]; + mesh->mFaces = new aiFace[mesh->mNumFaces]; for (unsigned int i = 0; i < mesh->mNumFaces;++i) { aiFace& f = mesh->mFaces[i]; BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); f.mNumIndices = Read(stream); - f.mIndices = new unsigned int[f.mNumIndices]; + f.mIndices = new unsigned int[f.mNumIndices]; for (unsigned int a = 0; a < f.mNumIndices;++a) { if (mesh->mNumVertices < (1u<<16)) - { + { f.mIndices[a] = Read(stream); } else - { - f.mIndices[a] = Read(stream); - } + { + f.mIndices[a] = Read(stream); + } } } } // write bones if (mesh->mNumBones) { - mesh->mBones = new C_STRUCT aiBone*[mesh->mNumBones]; + mesh->mBones = new C_STRUCT aiBone*[mesh->mNumBones]; for (unsigned int a = 0; a < mesh->mNumBones;++a) { mesh->mBones[a] = new aiBone(); ReadBinaryBone(stream,mesh->mBones[a]); @@ -301,7 +302,7 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIMATERIALPROPERTY); - uint32_t size = Read(stream); + uint32_t size = Read(stream); prop->mKey = Read(stream); prop->mSemantic = Read(stream); @@ -309,7 +310,7 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro prop->mDataLength = Read(stream); prop->mType = (aiPropertyTypeInfo)Read(stream); - prop->mData = new char [ prop->mDataLength ]; + prop->mData = new char [ prop->mDataLength ]; stream->Read(prop->mData,1,prop->mDataLength); } @@ -317,28 +318,28 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIMATERIAL); - uint32_t size = Read(stream); + uint32_t size = Read(stream); mat->mNumAllocated = mat->mNumProperties = Read(stream); - if (mat->mNumProperties) - { - if (mat->mProperties) - { - delete[] mat->mProperties; - } - mat->mProperties = new aiMaterialProperty*[mat->mNumProperties]; - for (unsigned int i = 0; i < mat->mNumProperties;++i) { - mat->mProperties[i] = new aiMaterialProperty(); - ReadBinaryMaterialProperty( stream, mat->mProperties[i]); - } - } + if (mat->mNumProperties) + { + if (mat->mProperties) + { + delete[] mat->mProperties; + } + mat->mProperties = new aiMaterialProperty*[mat->mNumProperties]; + for (unsigned int i = 0; i < mat->mNumProperties;++i) { + mat->mProperties[i] = new aiMaterialProperty(); + ReadBinaryMaterialProperty( stream, mat->mProperties[i]); + } + } } // ----------------------------------------------------------------------------------- void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) { ai_assert( Read(stream) == ASSBIN_CHUNK_AINODEANIM); - uint32_t size = Read(stream); + uint32_t size = Read(stream); nd->mNodeName = Read(stream); nd->mNumPositionKeys = Read(stream); @@ -353,9 +354,9 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) } // else write as usual else { - nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; - stream->Read(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); - } + nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; + stream->Read(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); + } } if (nd->mNumRotationKeys) { if (shortened) { @@ -363,10 +364,10 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) } // else write as usual else - { - nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; - stream->Read(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); - } + { + nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; + stream->Read(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); + } } if (nd->mNumScalingKeys) { if (shortened) { @@ -374,10 +375,10 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) } // else write as usual else - { - nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; - stream->Read(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); - } + { + nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; + stream->Read(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); + } } } @@ -386,27 +387,27 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIANIMATION); - uint32_t size = Read(stream); + uint32_t size = Read(stream); anim->mName = Read (stream); anim->mDuration = Read (stream); anim->mTicksPerSecond = Read (stream); anim->mNumChannels = Read(stream); - if (anim->mNumChannels) - { - anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ]; - for (unsigned int a = 0; a < anim->mNumChannels;++a) { - anim->mChannels[a] = new aiNodeAnim(); - ReadBinaryNodeAnim(stream,anim->mChannels[a]); - } - } + if (anim->mNumChannels) + { + anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ]; + for (unsigned int a = 0; a < anim->mNumChannels;++a) { + anim->mChannels[a] = new aiNodeAnim(); + ReadBinaryNodeAnim(stream,anim->mChannels[a]); + } + } } void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) { ai_assert( Read(stream) == ASSBIN_CHUNK_AITEXTURE); - uint32_t size = Read(stream); + uint32_t size = Read(stream); tex->mWidth = Read(stream); tex->mHeight = Read(stream); @@ -414,11 +415,11 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) if(!shortened) { if (!tex->mHeight) { - tex->pcData = new aiTexel[ tex->mWidth ]; + tex->pcData = new aiTexel[ tex->mWidth ]; stream->Read(tex->pcData,1,tex->mWidth); } else { - tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ]; + tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ]; stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4); } } @@ -429,7 +430,7 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AILIGHT); - uint32_t size = Read(stream); + uint32_t size = Read(stream); l->mName = Read(stream); l->mType = (aiLightSourceType)Read(stream); @@ -455,7 +456,7 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AICAMERA); - uint32_t size = Read(stream); + uint32_t size = Read(stream); cam->mName = Read(stream); cam->mPosition = Read(stream); @@ -470,7 +471,7 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); - uint32_t size = Read(stream); + uint32_t size = Read(stream); scene->mFlags = Read(stream); scene->mNumMeshes = Read(stream); @@ -481,68 +482,68 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) scene->mNumCameras = Read(stream); // Read node graph - scene->mRootNode = new aiNode[1]; + scene->mRootNode = new aiNode[1]; ReadBinaryNode( stream, &scene->mRootNode ); // Read all meshes - if (scene->mNumMeshes) - { - scene->mMeshes = new aiMesh*[scene->mNumMeshes]; - for (unsigned int i = 0; i < scene->mNumMeshes;++i) { - scene->mMeshes[i] = new aiMesh(); - ReadBinaryMesh( stream,scene->mMeshes[i]); - } - } + if (scene->mNumMeshes) + { + scene->mMeshes = new aiMesh*[scene->mNumMeshes]; + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + scene->mMeshes[i] = new aiMesh(); + ReadBinaryMesh( stream,scene->mMeshes[i]); + } + } // Read materials - if (scene->mNumMaterials) - { - scene->mMaterials = new aiMaterial*[scene->mNumMaterials]; - for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { - scene->mMaterials[i] = new aiMaterial(); - ReadBinaryMaterial(stream,scene->mMaterials[i]); - } - } + if (scene->mNumMaterials) + { + scene->mMaterials = new aiMaterial*[scene->mNumMaterials]; + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + scene->mMaterials[i] = new aiMaterial(); + ReadBinaryMaterial(stream,scene->mMaterials[i]); + } + } // Read all animations - if (scene->mNumAnimations) - { - scene->mAnimations = new aiAnimation*[scene->mNumAnimations]; - for (unsigned int i = 0; i < scene->mNumAnimations;++i) { - scene->mAnimations[i] = new aiAnimation(); - ReadBinaryAnim(stream,scene->mAnimations[i]); - } - } + if (scene->mNumAnimations) + { + scene->mAnimations = new aiAnimation*[scene->mNumAnimations]; + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + scene->mAnimations[i] = new aiAnimation(); + ReadBinaryAnim(stream,scene->mAnimations[i]); + } + } // Read all textures - if (scene->mNumTextures) - { - scene->mTextures = new aiTexture*[scene->mNumTextures]; - for (unsigned int i = 0; i < scene->mNumTextures;++i) { - scene->mTextures[i] = new aiTexture(); - ReadBinaryTexture(stream,scene->mTextures[i]); - } - } + if (scene->mNumTextures) + { + scene->mTextures = new aiTexture*[scene->mNumTextures]; + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + scene->mTextures[i] = new aiTexture(); + ReadBinaryTexture(stream,scene->mTextures[i]); + } + } // Read lights - if (scene->mNumLights) - { - scene->mLights = new aiLight*[scene->mNumLights]; - for (unsigned int i = 0; i < scene->mNumLights;++i) { - scene->mLights[i] = new aiLight(); - ReadBinaryLight(stream,scene->mLights[i]); - } - } + if (scene->mNumLights) + { + scene->mLights = new aiLight*[scene->mNumLights]; + for (unsigned int i = 0; i < scene->mNumLights;++i) { + scene->mLights[i] = new aiLight(); + ReadBinaryLight(stream,scene->mLights[i]); + } + } // Read cameras - if (scene->mNumCameras) - { - scene->mCameras = new aiCamera*[scene->mNumCameras]; - for (unsigned int i = 0; i < scene->mNumCameras;++i) { - scene->mCameras[i] = new aiCamera(); - ReadBinaryCamera(stream,scene->mCameras[i]); - } - } + if (scene->mNumCameras) + { + scene->mCameras = new aiCamera*[scene->mNumCameras]; + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + scene->mCameras[i] = new aiCamera(); + ReadBinaryCamera(stream,scene->mCameras[i]); + } + } } @@ -550,9 +551,9 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, { IOStream * stream = pIOHandler->Open(pFile,"rb"); if (!stream) - return; + return; - stream->Seek( 44, aiOrigin_CUR ); // signature + stream->Seek( 44, aiOrigin_CUR ); // signature unsigned int versionMajor = Read(stream); unsigned int versionMinor = Read(stream); @@ -562,20 +563,20 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, shortened = Read(stream) > 0; compressed = Read(stream) > 0; - stream->Seek( 256, aiOrigin_CUR ); // original filename - stream->Seek( 128, aiOrigin_CUR ); // options - stream->Seek( 64, aiOrigin_CUR ); // padding + stream->Seek( 256, aiOrigin_CUR ); // original filename + stream->Seek( 128, aiOrigin_CUR ); // options + stream->Seek( 64, aiOrigin_CUR ); // padding - if (compressed) - { - // TODO - } - else - { - ReadBinaryScene(stream,pScene); - } - - pIOHandler->Close(stream); + if (compressed) + { + // TODO + } + else + { + ReadBinaryScene(stream,pScene); + } + + pIOHandler->Close(stream); } #endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER From 061911bdbff6ac9613d8daaf202b95ebaf37cac4 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:05:07 +0200 Subject: [PATCH 52/80] add support for compressed, drop support for shortened --- code/AssbinLoader.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 1739659b1..9bc9a0a08 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -51,6 +51,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // internal headers #include "AssbinLoader.h" #include "assbin_chunks.h" +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB +# include +#else +# include "../contrib/zlib/zlib.h" +#include "MemoryIOWrapper.h" +#endif using namespace Assimp; @@ -563,13 +569,31 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, shortened = Read(stream) > 0; compressed = Read(stream) > 0; + if (shortened) + throw DeadlyImportError( "Shortened binaries are not supported!" ); + stream->Seek( 256, aiOrigin_CUR ); // original filename stream->Seek( 128, aiOrigin_CUR ); // options stream->Seek( 64, aiOrigin_CUR ); // padding if (compressed) { - // TODO + uLongf uncompressedSize = Read(stream); + uLongf compressedSize = stream->FileSize() - stream->Tell(); + + unsigned char * compressedData = new unsigned char[ compressedSize ]; + stream->Read( compressedData, 1, compressedSize ); + + unsigned char * uncompressedData = new unsigned char[ uncompressedSize ]; + + uncompress( uncompressedData, &uncompressedSize, compressedData, compressedSize ); + + MemoryIOStream io( uncompressedData, uncompressedSize ); + + ReadBinaryScene(&io,pScene); + + delete[] uncompressedData; + delete[] compressedData; } else { From 523d87bbe7c76ffbdc74ee49b5977a66055bea0d Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:22:47 +0200 Subject: [PATCH 53/80] use 0..fileSize as progress metric (easier for loaders) --- code/Importer.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index 0a817476a..9cfb5be46 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -640,16 +640,21 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) } } + // Get file size for progress handler + IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); + uint32_t fileSize = fileIO->FileSize(); + pimpl->mIOHandler->Close( fileIO ); + // Dispatch the reading to the worker class for this format DefaultLogger::get()->info("Found a matching importer for this file format"); - pimpl->mProgressHandler->UpdateFileRead( 0, 1 ); + pimpl->mProgressHandler->UpdateFileRead( 0, fileSize ); if (profiler) { profiler->BeginRegion("import"); } pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler); - pimpl->mProgressHandler->UpdateFileRead( 1, 1 ); + pimpl->mProgressHandler->UpdateFileRead( fileSize, fileSize ); if (profiler) { profiler->EndRegion("import"); From 7925dcadba2778d8e8a4308aacf252ef19ace689 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:25:10 +0200 Subject: [PATCH 54/80] avoid NULL, just in case (loader might just probably crash anyway) --- code/Importer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index 9cfb5be46..c22b76057 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -642,8 +642,11 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // Get file size for progress handler IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); - uint32_t fileSize = fileIO->FileSize(); - pimpl->mIOHandler->Close( fileIO ); + if (fileIO) + { + uint32_t fileSize = fileIO->FileSize(); + pimpl->mIOHandler->Close( fileIO ); + } // Dispatch the reading to the worker class for this format DefaultLogger::get()->info("Found a matching importer for this file format"); From aa5c1a1a23eb69af3e721e5d59fd2c7f08d12ce1 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:26:04 +0200 Subject: [PATCH 55/80] syntax --- code/Importer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index c22b76057..01f853a05 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -642,9 +642,10 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // Get file size for progress handler IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); + uint32_t fileSize = 0; if (fileIO) { - uint32_t fileSize = fileIO->FileSize(); + fileSize = fileIO->FileSize(); pimpl->mIOHandler->Close( fileIO ); } From df4b17d145530403b507f528de28ff59b2df3bf0 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:26:34 +0200 Subject: [PATCH 56/80] code style --- code/Importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index 01f853a05..a9173cddc 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -642,7 +642,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // Get file size for progress handler IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); - uint32_t fileSize = 0; + uint32_t fileSize = 0; if (fileIO) { fileSize = fileIO->FileSize(); From 3c172988bbb0360ad01d3ba01202081e044b1475 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:43:52 +0200 Subject: [PATCH 57/80] remove BUG notices (discussed with acgessler) --- code/AssbinExporter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 439f2e61f..2f1c403e9 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -337,7 +337,7 @@ namespace Assimp { if(!shortened) { if (!tex->mHeight) { - chunk.Write(tex->pcData,1,tex->mWidth); // BUG?! should be *4? + chunk.Write(tex->pcData,1,tex->mWidth); } else { chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); @@ -732,7 +732,7 @@ namespace Assimp { compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 ); - out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); // BUG?! are we writing compressed or uncompressed size here? + out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); out->Write( compressedBuffer, sizeof(char), compressedSize ); delete[] compressedBuffer; From 2775141da3db933f5eadf3d69a7fb5ce15c30f23 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 09:07:09 +0200 Subject: [PATCH 58/80] #include should be outside --- code/AssbinLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 9bc9a0a08..617355263 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -51,11 +51,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // internal headers #include "AssbinLoader.h" #include "assbin_chunks.h" +#include "MemoryIOWrapper.h" #ifdef ASSIMP_BUILD_NO_OWN_ZLIB # include #else # include "../contrib/zlib/zlib.h" -#include "MemoryIOWrapper.h" #endif using namespace Assimp; From b53a425fe4424a45bf52fb40e0ebdbd2f753ee4e Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 09:28:50 +0200 Subject: [PATCH 59/80] make templates gcc compatible --- code/AssbinExporter.cpp | 445 ++++++++++++++++++++-------------------- 1 file changed, 220 insertions(+), 225 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 2f1c403e9..bca9a3975 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -58,6 +58,154 @@ using namespace Assimp; namespace Assimp { +template +size_t Write(IOStream * stream, const T& v) +{ + return stream->Write( &v, sizeof(T), 1 ); +} + + +// ----------------------------------------------------------------------------------- +// Serialize an aiString +template <> +inline size_t Write(IOStream * stream, const aiString& s) +{ + const size_t s2 = (uint32_t)s.length; + stream->Write(&s,4,1); + stream->Write(s.data,s2,1); + return s2+4; +} + +// ----------------------------------------------------------------------------------- +// Serialize an unsigned int as uint32_t +template <> +inline size_t Write(IOStream * stream, const unsigned int& w) +{ + const uint32_t t = (uint32_t)w; + if (w > t) { + // this shouldn't happen, integers in Assimp data structures never exceed 2^32 + throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion"); + } + + stream->Write(&t,4,1); + return 4; +} + +// ----------------------------------------------------------------------------------- +// Serialize an unsigned int as uint16_t +template <> +inline size_t Write(IOStream * stream, const uint16_t& w) +{ + stream->Write(&w,2,1); + return 2; +} + +// ----------------------------------------------------------------------------------- +// Serialize a float +template <> +inline size_t Write(IOStream * stream, const float& f) +{ + BOOST_STATIC_ASSERT(sizeof(float)==4); + stream->Write(&f,4,1); + return 4; +} + +// ----------------------------------------------------------------------------------- +// Serialize a double +template <> +inline size_t Write(IOStream * stream, const double& f) +{ + BOOST_STATIC_ASSERT(sizeof(double)==8); + stream->Write(&f,8,1); + return 8; +} + +// ----------------------------------------------------------------------------------- +// Serialize a vec3 +template <> +inline size_t Write(IOStream * stream, const aiVector3D& v) +{ + size_t t = Write(stream,v.x); + t += Write(stream,v.y); + t += Write(stream,v.z); + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a color value +template <> +inline size_t Write(IOStream * stream, const aiColor4D& v) +{ + size_t t = Write(stream,v.r); + t += Write(stream,v.g); + t += Write(stream,v.b); + t += Write(stream,v.a); + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a quaternion +template <> +inline size_t Write(IOStream * stream, const aiQuaternion& v) +{ + size_t t = Write(stream,v.w); + t += Write(stream,v.x); + t += Write(stream,v.y); + t += Write(stream,v.z); + return 16; +} + + +// ----------------------------------------------------------------------------------- +// Serialize a vertex weight +template <> +inline size_t Write(IOStream * stream, const aiVertexWeight& v) +{ + uint32_t t = Write(stream,v.mVertexId); + return t+Write(stream,v.mWeight); +} + +// ----------------------------------------------------------------------------------- +// Serialize a mat4x4 +template <> +inline size_t Write(IOStream * stream, const aiMatrix4x4& m) +{ + for (unsigned int i = 0; i < 4;++i) { + for (unsigned int i2 = 0; i2 < 4;++i2) { + Write(stream,m[i][i2]); + } + } + return 64; +} + +// ----------------------------------------------------------------------------------- +// Serialize an aiVectorKey +template <> +inline size_t Write(IOStream * stream, const aiVectorKey& v) +{ + const size_t t = Write(stream,v.mTime); + return t + Write(stream,v.mValue); +} + +// ----------------------------------------------------------------------------------- +// Serialize an aiQuatKey +template <> +inline size_t Write(IOStream * stream, const aiQuatKey& v) +{ + const size_t t = Write(stream,v.mTime); + return t + Write(stream,v.mValue); +} + +template +inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) +{ + T minc,maxc; + ArrayBounds(in,size,minc,maxc); + + const size_t t = Write(stream,minc); + return t + Write(stream,maxc); +} + // ---------------------------------------------------------------------------------- /** @class AssbinChunkWriter * @brief Chunk writer mechanism for the .assbin file structure @@ -138,154 +286,6 @@ namespace Assimp { return pCount; } - template - size_t Write(const T& v) - { - return Write( &v, sizeof(T), 1 ); - } - - - // ----------------------------------------------------------------------------------- - // Serialize an aiString - template <> - inline uint32_t Write(const aiString& s) - { - const uint32_t s2 = (uint32_t)s.length; - Write(&s,4,1); - Write(s.data,s2,1); - return s2+4; - } - - // ----------------------------------------------------------------------------------- - // Serialize an unsigned int as uint32_t - template <> - inline uint32_t Write(const unsigned int& w) - { - const uint32_t t = (uint32_t)w; - if (w > t) { - // this shouldn't happen, integers in Assimp data structures never exceed 2^32 - throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion"); - } - - Write(&t,4,1); - return 4; - } - - // ----------------------------------------------------------------------------------- - // Serialize an unsigned int as uint16_t - template <> - inline uint32_t Write(const uint16_t& w) - { - Write(&w,2,1); - return 2; - } - - // ----------------------------------------------------------------------------------- - // Serialize a float - template <> - inline uint32_t Write(const float& f) - { - BOOST_STATIC_ASSERT(sizeof(float)==4); - Write(&f,4,1); - return 4; - } - - // ----------------------------------------------------------------------------------- - // Serialize a double - template <> - inline uint32_t Write(const double& f) - { - BOOST_STATIC_ASSERT(sizeof(double)==8); - Write(&f,8,1); - return 8; - } - - // ----------------------------------------------------------------------------------- - // Serialize a vec3 - template <> - inline uint32_t Write(const aiVector3D& v) - { - uint32_t t = Write(v.x); - t += Write(v.y); - t += Write(v.z); - return t; - } - - // ----------------------------------------------------------------------------------- - // Serialize a color value - template <> - inline uint32_t Write(const aiColor4D& v) - { - uint32_t t = Write(v.r); - t += Write(v.g); - t += Write(v.b); - t += Write(v.a); - return t; - } - - // ----------------------------------------------------------------------------------- - // Serialize a quaternion - template <> - inline uint32_t Write(const aiQuaternion& v) - { - uint32_t t = Write(v.w); - t += Write(v.x); - t += Write(v.y); - t += Write(v.z); - return 16; - } - - - // ----------------------------------------------------------------------------------- - // Serialize a vertex weight - template <> - inline uint32_t Write(const aiVertexWeight& v) - { - uint32_t t = Write(v.mVertexId); - return t+Write(v.mWeight); - } - - // ----------------------------------------------------------------------------------- - // Serialize a mat4x4 - template <> - inline uint32_t Write(const aiMatrix4x4& m) - { - for (unsigned int i = 0; i < 4;++i) { - for (unsigned int i2 = 0; i2 < 4;++i2) { - Write(m[i][i2]); - } - } - return 64; - } - - // ----------------------------------------------------------------------------------- - // Serialize an aiVectorKey - template <> - inline uint32_t Write(const aiVectorKey& v) - { - const uint32_t t = Write(v.mTime); - return t + Write(v.mValue); - } - - // ----------------------------------------------------------------------------------- - // Serialize an aiQuatKey - template <> - inline uint32_t Write(const aiQuatKey& v) - { - const uint32_t t = Write(v.mTime); - return t + Write(v.mValue); - } - - template - inline uint32_t WriteBounds(const T* in, unsigned int size) - { - T minc,maxc; - ArrayBounds(in,size,minc,maxc); - - const uint32_t t = Write(minc); - return t + Write(maxc); - } - }; // ---------------------------------------------------------------------------------- @@ -301,24 +301,19 @@ namespace Assimp { bool compressed; protected: - template - size_t Write( IOStream * container, const T& v) - { - return container->Write( &v, sizeof(T), 1 ); - } // ----------------------------------------------------------------------------------- void WriteBinaryNode( IOStream * container, const aiNode* node) { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE ); - chunk.Write(node->mName); - chunk.Write(node->mTransformation); - chunk.Write(node->mNumChildren); - chunk.Write(node->mNumMeshes); + Write(&chunk,node->mName); + Write(&chunk,node->mTransformation); + Write(&chunk,node->mNumChildren); + Write(&chunk,node->mNumMeshes); for (unsigned int i = 0; i < node->mNumMeshes;++i) { - chunk.Write(node->mMeshes[i]); + Write(&chunk,node->mMeshes[i]); } for (unsigned int i = 0; i < node->mNumChildren;++i) { @@ -331,8 +326,8 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE ); - chunk.Write(tex->mWidth); - chunk.Write(tex->mHeight); + Write(&chunk,tex->mWidth); + Write(&chunk,tex->mHeight); chunk.Write( tex->achFormatHint, sizeof(char), 4 ); if(!shortened) { @@ -351,14 +346,14 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE ); - chunk.Write(b->mName); - chunk.Write(b->mNumWeights); - chunk.Write(b->mOffsetMatrix); + Write(&chunk,b->mName); + Write(&chunk,b->mNumWeights); + Write(&chunk,b->mOffsetMatrix); // for the moment we write dumb min/max values for the bones, too. // maybe I'll add a better, hash-like solution later if (shortened) { - chunk.WriteBounds(b->mWeights,b->mNumWeights); + WriteBounds(&chunk,b->mWeights,b->mNumWeights); } // else write as usual else chunk.Write(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); } @@ -368,11 +363,11 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH ); - chunk.Write(mesh->mPrimitiveTypes); - chunk.Write(mesh->mNumVertices); - chunk.Write(mesh->mNumFaces); - chunk.Write(mesh->mNumBones); - chunk.Write(mesh->mMaterialIndex); + Write(&chunk,mesh->mPrimitiveTypes); + Write(&chunk,mesh->mNumVertices); + Write(&chunk,mesh->mNumFaces); + Write(&chunk,mesh->mNumBones); + Write(&chunk,mesh->mMaterialIndex); // first of all, write bits for all existent vertex components unsigned int c = 0; @@ -397,25 +392,25 @@ namespace Assimp { } c |= ASSBIN_MESH_HAS_COLOR(n); } - chunk.Write(c); + Write(&chunk,c); aiVector3D minVec, maxVec; if (mesh->mVertices) { if (shortened) { - chunk.WriteBounds(mesh->mVertices,mesh->mNumVertices); + WriteBounds(&chunk,mesh->mVertices,mesh->mNumVertices); } // else write as usual else chunk.Write(mesh->mVertices,1,12*mesh->mNumVertices); } if (mesh->mNormals) { if (shortened) { - chunk.WriteBounds(mesh->mNormals,mesh->mNumVertices); + WriteBounds(&chunk,mesh->mNormals,mesh->mNumVertices); } // else write as usual else chunk.Write(mesh->mNormals,1,12*mesh->mNumVertices); } if (mesh->mTangents && mesh->mBitangents) { if (shortened) { - chunk.WriteBounds(mesh->mTangents,mesh->mNumVertices); - chunk.WriteBounds(mesh->mBitangents,mesh->mNumVertices); + WriteBounds(&chunk,mesh->mTangents,mesh->mNumVertices); + WriteBounds(&chunk,mesh->mBitangents,mesh->mNumVertices); } // else write as usual else { chunk.Write(mesh->mTangents,1,12*mesh->mNumVertices); @@ -427,7 +422,7 @@ namespace Assimp { break; if (shortened) { - chunk.WriteBounds(mesh->mColors[n],mesh->mNumVertices); + WriteBounds(&chunk,mesh->mColors[n],mesh->mNumVertices); } // else write as usual else chunk.Write(mesh->mColors[n],16*mesh->mNumVertices,1); } @@ -436,10 +431,10 @@ namespace Assimp { break; // write number of UV components - chunk.Write(mesh->mNumUVComponents[n]); + Write(&chunk,mesh->mNumUVComponents[n]); if (shortened) { - chunk.WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices); + WriteBounds(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices); } // else write as usual else chunk.Write(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); } @@ -464,7 +459,7 @@ namespace Assimp { hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); } } - chunk.Write(hash); + Write(&chunk,hash); } } else // else write as usual @@ -474,13 +469,13 @@ namespace Assimp { const aiFace& f = mesh->mFaces[i]; BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); - chunk.Write(f.mNumIndices); + Write(&chunk,f.mNumIndices); for (unsigned int a = 0; a < f.mNumIndices;++a) { if (mesh->mNumVertices < (1u<<16)) { - chunk.Write(f.mIndices[a]); + Write(&chunk,f.mIndices[a]); } - else chunk.Write(f.mIndices[a]); + else Write(&chunk,f.mIndices[a]); } } } @@ -499,12 +494,12 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY ); - chunk.Write(prop->mKey); - chunk.Write(prop->mSemantic); - chunk.Write(prop->mIndex); + Write(&chunk,prop->mKey); + Write(&chunk,prop->mSemantic); + Write(&chunk,prop->mIndex); - chunk.Write(prop->mDataLength); - chunk.Write((unsigned int)prop->mType); + Write(&chunk,prop->mDataLength); + Write(&chunk,(unsigned int)prop->mType); chunk.Write(prop->mData,1,prop->mDataLength); } @@ -513,7 +508,7 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL); - chunk.Write(mat->mNumProperties); + Write(&chunk,mat->mNumProperties); for (unsigned int i = 0; i < mat->mNumProperties;++i) { WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]); } @@ -524,30 +519,30 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM ); - chunk.Write(nd->mNodeName); - chunk.Write(nd->mNumPositionKeys); - chunk.Write(nd->mNumRotationKeys); - chunk.Write(nd->mNumScalingKeys); - chunk.Write(nd->mPreState); - chunk.Write(nd->mPostState); + Write(&chunk,nd->mNodeName); + Write(&chunk,nd->mNumPositionKeys); + Write(&chunk,nd->mNumRotationKeys); + Write(&chunk,nd->mNumScalingKeys); + Write(&chunk,nd->mPreState); + Write(&chunk,nd->mPostState); if (nd->mPositionKeys) { if (shortened) { - chunk.WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys); + WriteBounds(&chunk,nd->mPositionKeys,nd->mNumPositionKeys); } // else write as usual else chunk.Write(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); } if (nd->mRotationKeys) { if (shortened) { - chunk.WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys); + WriteBounds(&chunk,nd->mRotationKeys,nd->mNumRotationKeys); } // else write as usual else chunk.Write(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); } if (nd->mScalingKeys) { if (shortened) { - chunk.WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys); + WriteBounds(&chunk,nd->mScalingKeys,nd->mNumScalingKeys); } // else write as usual else chunk.Write(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); @@ -560,10 +555,10 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION ); - chunk.Write (anim->mName); - chunk.Write (anim->mDuration); - chunk.Write (anim->mTicksPerSecond); - chunk.Write(anim->mNumChannels); + Write(&chunk,anim->mName); + Write(&chunk,anim->mDuration); + Write(&chunk,anim->mTicksPerSecond); + Write(&chunk,anim->mNumChannels); for (unsigned int a = 0; a < anim->mNumChannels;++a) { const aiNodeAnim* nd = anim->mChannels[a]; @@ -576,22 +571,22 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT ); - chunk.Write(l->mName); - chunk.Write(l->mType); + Write(&chunk,l->mName); + Write(&chunk,l->mType); if (l->mType != aiLightSource_DIRECTIONAL) { - chunk.Write(l->mAttenuationConstant); - chunk.Write(l->mAttenuationLinear); - chunk.Write(l->mAttenuationQuadratic); + Write(&chunk,l->mAttenuationConstant); + Write(&chunk,l->mAttenuationLinear); + Write(&chunk,l->mAttenuationQuadratic); } - chunk.Write((const aiVector3D&)l->mColorDiffuse); - chunk.Write((const aiVector3D&)l->mColorSpecular); - chunk.Write((const aiVector3D&)l->mColorAmbient); + Write(&chunk,(const aiVector3D&)l->mColorDiffuse); + Write(&chunk,(const aiVector3D&)l->mColorSpecular); + Write(&chunk,(const aiVector3D&)l->mColorAmbient); if (l->mType == aiLightSource_SPOT) { - chunk.Write(l->mAngleInnerCone); - chunk.Write(l->mAngleOuterCone); + Write(&chunk,l->mAngleInnerCone); + Write(&chunk,l->mAngleOuterCone); } } @@ -601,14 +596,14 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA ); - chunk.Write(cam->mName); - chunk.Write(cam->mPosition); - chunk.Write(cam->mLookAt); - chunk.Write(cam->mUp); - chunk.Write(cam->mHorizontalFOV); - chunk.Write(cam->mClipPlaneNear); - chunk.Write(cam->mClipPlaneFar); - chunk.Write(cam->mAspect); + Write(&chunk,cam->mName); + Write(&chunk,cam->mPosition); + Write(&chunk,cam->mLookAt); + Write(&chunk,cam->mUp); + Write(&chunk,cam->mHorizontalFOV); + Write(&chunk,cam->mClipPlaneNear); + Write(&chunk,cam->mClipPlaneFar); + Write(&chunk,cam->mAspect); } // ----------------------------------------------------------------------------------- @@ -617,13 +612,13 @@ namespace Assimp { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE ); // basic scene information - chunk.Write(scene->mFlags); - chunk.Write(scene->mNumMeshes); - chunk.Write(scene->mNumMaterials); - chunk.Write(scene->mNumAnimations); - chunk.Write(scene->mNumTextures); - chunk.Write(scene->mNumLights); - chunk.Write(scene->mNumCameras); + Write(&chunk,scene->mFlags); + Write(&chunk,scene->mNumMeshes); + Write(&chunk,scene->mNumMaterials); + Write(&chunk,scene->mNumAnimations); + Write(&chunk,scene->mNumTextures); + Write(&chunk,scene->mNumLights); + Write(&chunk,scene->mNumCameras); // write node graph WriteBinaryNode( &chunk, scene->mRootNode ); From 61ecff3474afa5f811db6d6247b260aa0fe8df08 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 09:30:20 +0200 Subject: [PATCH 60/80] missed one 32/64 type conversion --- code/AssbinExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index bca9a3975..9322f5047 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -161,7 +161,7 @@ inline size_t Write(IOStream * stream, const aiQuaternion& v) template <> inline size_t Write(IOStream * stream, const aiVertexWeight& v) { - uint32_t t = Write(stream,v.mVertexId); + size_t t = Write(stream,v.mVertexId); return t+Write(stream,v.mWeight); } From c3977bd1320f87c5a070f6e6b4c91653afb5662e Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 09:32:00 +0200 Subject: [PATCH 61/80] unify data types --- code/AssbinExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 9322f5047..0acf5c25e 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -223,7 +223,7 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) uint8_t* buffer; uint32_t magic; IOStream * container; - uint32_t cur_size, cursor, initial; + size_t cur_size, cursor, initial; private: // ------------------------------------------------------------------- From 58861542472aa3920d2a7dbd136d6712fe2183f6 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 11:30:44 +0200 Subject: [PATCH 62/80] tweaks according to the comments of kimkulling --- code/AssbinExporter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 0acf5c25e..2a39a5be3 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -96,6 +96,7 @@ inline size_t Write(IOStream * stream, const unsigned int& w) template <> inline size_t Write(IOStream * stream, const uint16_t& w) { + BOOST_STATIC_ASSERT(sizeof(uint16_t)==2); stream->Write(&w,2,1); return 2; } @@ -245,7 +246,7 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) public: AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096) - : initial(initial), buffer(NULL), cur_size(0), cursor(0), container(container), magic(magic) + : buffer(NULL), magic(magic), container(container), cur_size(0), cursor(0), initial(initial) { } @@ -663,10 +664,9 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) } public: - AssbinExport() + AssbinExport() + : shortened(false), compressed(false) // temporary settings until properties are introduced for exporters { - shortened = false; - compressed = false; } // ----------------------------------------------------------------------------------- From b712bf1770aba8bb57f4dc072938edd8fce1fa66 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Fri, 8 Aug 2014 12:46:29 +0200 Subject: [PATCH 63/80] Change to looped writes to avoid struct packing issues --- code/AssbinExporter.cpp | 28 ++++++++++++++++---------- code/AssbinLoader.cpp | 44 +++++++++++++++++++++++++++++++---------- 2 files changed, 52 insertions(+), 20 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 2a39a5be3..1c697b7e2 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -207,6 +207,14 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) return t + Write(stream,maxc); } +template +inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size) +{ + size_t n = 0; + for (unsigned int i=0; i(stream,in[i]); + return n; +} + // ---------------------------------------------------------------------------------- /** @class AssbinChunkWriter * @brief Chunk writer mechanism for the .assbin file structure @@ -356,7 +364,7 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) if (shortened) { WriteBounds(&chunk,b->mWeights,b->mNumWeights); } // else write as usual - else chunk.Write(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); + else WriteArray(&chunk,b->mWeights,b->mNumWeights); } // ----------------------------------------------------------------------------------- @@ -400,13 +408,13 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) if (shortened) { WriteBounds(&chunk,mesh->mVertices,mesh->mNumVertices); } // else write as usual - else chunk.Write(mesh->mVertices,1,12*mesh->mNumVertices); + else WriteArray(&chunk,mesh->mVertices,mesh->mNumVertices); } if (mesh->mNormals) { if (shortened) { WriteBounds(&chunk,mesh->mNormals,mesh->mNumVertices); } // else write as usual - else chunk.Write(mesh->mNormals,1,12*mesh->mNumVertices); + else WriteArray(&chunk,mesh->mNormals,mesh->mNumVertices); } if (mesh->mTangents && mesh->mBitangents) { if (shortened) { @@ -414,8 +422,8 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) WriteBounds(&chunk,mesh->mBitangents,mesh->mNumVertices); } // else write as usual else { - chunk.Write(mesh->mTangents,1,12*mesh->mNumVertices); - chunk.Write(mesh->mBitangents,1,12*mesh->mNumVertices); + WriteArray(&chunk,mesh->mTangents,mesh->mNumVertices); + WriteArray(&chunk,mesh->mBitangents,mesh->mNumVertices); } } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { @@ -425,7 +433,7 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) if (shortened) { WriteBounds(&chunk,mesh->mColors[n],mesh->mNumVertices); } // else write as usual - else chunk.Write(mesh->mColors[n],16*mesh->mNumVertices,1); + else WriteArray(&chunk,mesh->mColors[n],mesh->mNumVertices); } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { if (!mesh->mTextureCoords[n]) @@ -437,7 +445,7 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) if (shortened) { WriteBounds(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices); } // else write as usual - else chunk.Write(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); + else WriteArray(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices); } // write faces. There are no floating-point calculations involved @@ -532,21 +540,21 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) WriteBounds(&chunk,nd->mPositionKeys,nd->mNumPositionKeys); } // else write as usual - else chunk.Write(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); + else WriteArray(&chunk,nd->mPositionKeys,nd->mNumPositionKeys); } if (nd->mRotationKeys) { if (shortened) { WriteBounds(&chunk,nd->mRotationKeys,nd->mNumRotationKeys); } // else write as usual - else chunk.Write(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); + else WriteArray(&chunk,nd->mRotationKeys,nd->mNumRotationKeys); } if (nd->mScalingKeys) { if (shortened) { WriteBounds(&chunk,nd->mScalingKeys,nd->mNumScalingKeys); } // else write as usual - else chunk.Write(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); + else WriteArray(&chunk,nd->mScalingKeys,nd->mNumScalingKeys); } } diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 617355263..9cc725092 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -121,6 +121,30 @@ aiMatrix4x4 Read(IOStream * stream) return m; } +template <> +aiVectorKey Read(IOStream * stream) +{ + aiVectorKey v; + v.mTime = Read(stream); + v.mValue = Read(stream); + return v; +} + +template <> +aiQuatKey Read(IOStream * stream) +{ + aiQuatKey v; + v.mTime = Read(stream); + v.mValue = Read(stream); + return v; +} + +template +void ReadArray(IOStream * stream, T * out, unsigned int size) +{ + for (unsigned int i=0; i(stream); +} + template void ReadBounds( IOStream * stream, T* p, unsigned int n ) { // not sure what to do here, the data isn't really useful. @@ -176,7 +200,7 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) else { b->mWeights = new aiVertexWeight[b->mNumWeights]; - stream->Read(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); + ReadArray(stream,b->mWeights,b->mNumWeights); } } @@ -203,7 +227,7 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) else { mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mVertices,1,12*mesh->mNumVertices); + ReadArray(stream,mesh->mVertices,mesh->mNumVertices); } } if (c & ASSBIN_MESH_HAS_NORMALS) @@ -214,7 +238,7 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) else { mesh->mNormals = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mNormals,1,12*mesh->mNumVertices); + ReadArray(stream,mesh->mNormals,mesh->mNumVertices); } } if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) @@ -226,9 +250,9 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) else { mesh->mTangents = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mTangents,1,12*mesh->mNumVertices); + ReadArray(stream,mesh->mTangents,mesh->mNumVertices); mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mBitangents,1,12*mesh->mNumVertices); + ReadArray(stream,mesh->mBitangents,mesh->mNumVertices); } } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) @@ -243,7 +267,7 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) else { mesh->mColors[n] = new aiColor4D[mesh->mNumVertices]; - stream->Read(mesh->mColors[n],16*mesh->mNumVertices,1); + ReadArray(stream,mesh->mColors[n],mesh->mNumVertices); } } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) @@ -260,7 +284,7 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) else { mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); + ReadArray(stream,mesh->mTextureCoords[n],mesh->mNumVertices); } } @@ -361,7 +385,7 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) } // else write as usual else { nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; - stream->Read(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); + ReadArray(stream,nd->mPositionKeys,nd->mNumPositionKeys); } } if (nd->mNumRotationKeys) { @@ -372,7 +396,7 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) else { nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; - stream->Read(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); + ReadArray(stream,nd->mRotationKeys,nd->mNumRotationKeys); } } if (nd->mNumScalingKeys) { @@ -383,7 +407,7 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) else { nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; - stream->Read(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); + ReadArray(stream,nd->mScalingKeys,nd->mNumScalingKeys); } } } From fa99aa0d3a9eebd7f9677e3ccac1204ee7971d7c Mon Sep 17 00:00:00 2001 From: Gargaj Date: Fri, 8 Aug 2014 12:56:11 +0200 Subject: [PATCH 64/80] add remaining specializations hopefully i didnt mess this up too bad --- code/AssbinLoader.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 9cc725092..a17d37f9e 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -100,6 +100,38 @@ T Read(IOStream * stream) return t; } +template <> +aiVector3D Read(IOStream * stream) +{ + aiVector3D v; + v.x = Read(stream); + v.y = Read(stream); + v.z = Read(stream); + return v; +} + +template <> +aiColor4D Read(IOStream * stream) +{ + aiColor4D c; + c.r = Read(stream); + c.g = Read(stream); + c.b = Read(stream); + c.a = Read(stream); + return c; +} + +template <> +aiQuaternion Read(IOStream * stream) +{ + aiQuaternion v; + v.w = Read(stream); + v.x = Read(stream); + v.y = Read(stream); + v.z = Read(stream); + return v; +} + template <> aiString Read(IOStream * stream) { @@ -109,6 +141,15 @@ aiString Read(IOStream * stream) return s; } +template <> +aiVertexWeight Read(IOStream * stream) +{ + aiVertexWeight w; + w.mVertexId = Read(stream); + w.mWeight = Read(stream); + return w; +} + template <> aiMatrix4x4 Read(IOStream * stream) { From 58b78fa2654959cf19a63773762697948abafafc Mon Sep 17 00:00:00 2001 From: Gargaj Date: Fri, 8 Aug 2014 13:10:05 +0200 Subject: [PATCH 65/80] comment --- code/AssbinExporter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 1c697b7e2..29ebfeee7 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -207,6 +207,8 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) return t + Write(stream,maxc); } +// We use this to write out non-byte arrays so that we write using the specializations. +// This way we avoid writing out extra bytes that potentially come from struct alignment. template inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size) { From 9b5bb6b088cfcad543225e362da0fc33210c9d11 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Fri, 8 Aug 2014 22:47:19 -0700 Subject: [PATCH 66/80] Add assbin file format to readme --- Readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Readme.md b/Readme.md index 8e186ee44..5725e4570 100644 --- a/Readme.md +++ b/Readme.md @@ -46,6 +46,7 @@ The library provides importers for a lot of file formats, including: - Ogre Binary - Ogre XML - Q3D +- ASSBIN (Assimp scene serialization) Additionally, the following formats are also supported, but not part of the core library as they depend on proprietary libraries. @@ -60,6 +61,7 @@ Exporters include: - X - 3DS - JSON (for WebGl, via https://github.com/acgessler/assimp2json) +- ASSBIN See [the full list here](http://assimp.sourceforge.net/main_features_formats.html). From 3d6b1932f9113f7bbd7124a8d9f23a382f197f88 Mon Sep 17 00:00:00 2001 From: Alexander Gessler Date: Wed, 13 Aug 2014 23:27:22 -0700 Subject: [PATCH 67/80] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 5725e4570..1945b9dbb 100644 --- a/Readme.md +++ b/Readme.md @@ -1,7 +1,7 @@ Open Asset Import Library (assimp) ======== -Open Asset Import Library is a Open Source library designed to load various __3d file formats and convert them into a shared, in-memory format__. It supports more than __30 file formats__ for import and a growing selection of file formats for export. Additionally, assimp features various __post processing tools__ to refine the imported data: _normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials_ and many more. +Open Asset Import Library is a Open Source library designed to load various __3d file formats and convert them into a shared, in-memory format__. It supports more than __40 file formats__ for import and a growing selection of file formats for export. Additionally, assimp features various __post processing tools__ to refine the imported data: _normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials_ and many more. This is the development trunk of assimp containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories. According to [Travis-CI] (https://travis-ci.org/), the current build status of the trunk is [![Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp) From 5e265610fbfa7625caf53e3799003e660ede6ba9 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 16 Aug 2014 11:39:28 +0200 Subject: [PATCH 68/80] bugfix: add obj-material handling for 0 instead of r g b. Signed-off-by: Kim Kulling --- code/ObjFileMtlImporter.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/code/ObjFileMtlImporter.cpp b/code/ObjFileMtlImporter.cpp index 90898f7b2..e494fa515 100644 --- a/code/ObjFileMtlImporter.cpp +++ b/code/ObjFileMtlImporter.cpp @@ -223,15 +223,17 @@ void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor ) { ai_assert( NULL != pColor ); - float r, g, b; + float r( 0.0f ), g( 0.0f ), b( 0.0f ); m_DataIt = getFloat( m_DataIt, m_DataItEnd, r ); pColor->r = r; - m_DataIt = getFloat( m_DataIt, m_DataItEnd, g ); - pColor->g = g; - - m_DataIt = getFloat( m_DataIt, m_DataItEnd, b ); - pColor->b = b; + // we have to check if color is default 0 with only one token + if( !isNewLine( *m_DataIt ) ) { + m_DataIt = getFloat( m_DataIt, m_DataItEnd, g ); + m_DataIt = getFloat( m_DataIt, m_DataItEnd, b ); + } + pColor->g = g; + pColor->b = b; } // ------------------------------------------------------------------- From d2e4dda3937d3d27592dcb7411a6ec82f7677883 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 16 Aug 2014 11:54:04 +0200 Subject: [PATCH 69/80] update: add testcase for empty color. Signed-off-by: Kim Kulling --- test/models/OBJ/empty_mat.mtl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/models/OBJ/empty_mat.mtl b/test/models/OBJ/empty_mat.mtl index 84db99062..8f52a73b0 100644 --- a/test/models/OBJ/empty_mat.mtl +++ b/test/models/OBJ/empty_mat.mtl @@ -4,7 +4,7 @@ newmtl Ns 0 Ka 0.000000 0.000000 0.000000 Kd 0.8 0.8 0.8 -Ks 0.8 0.8 0.8 +Ks 0 d 1 illum 2 From 0ede630b108424f7c72a57fa5f272ee06cb0a3e6 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 16 Aug 2014 13:34:35 +0200 Subject: [PATCH 70/80] bugfix: - fix unhandled exception with sample SimpleTexturedOpenGL #308 - remove commented code, which made no sense any more. Signed-off-by: Kim Kulling --- .../src/model_loading.cpp | 98 ++++++++----------- 1 file changed, 41 insertions(+), 57 deletions(-) diff --git a/samples/SimpleTexturedOpenGL/SimpleTexturedOpenGL/src/model_loading.cpp b/samples/SimpleTexturedOpenGL/SimpleTexturedOpenGL/src/model_loading.cpp index 253387509..2787fad52 100644 --- a/samples/SimpleTexturedOpenGL/SimpleTexturedOpenGL/src/model_loading.cpp +++ b/samples/SimpleTexturedOpenGL/SimpleTexturedOpenGL/src/model_loading.cpp @@ -12,9 +12,6 @@ // Thanks to NeHe on whose OpenGL tutorials this one's based on! :) // http://nehe.gamedev.net/ // ---------------------------------------------------------------------------- - - - #include #include #include @@ -36,7 +33,7 @@ #include "assimp/LogStream.hpp" -// The default hardcoded path. Can be overridden by supplying a path through the commandline. +// The default hard-coded path. Can be overridden by supplying a path through the command line. static std::string modelpath = "../../test/models/OBJ/spider.obj"; @@ -47,7 +44,7 @@ HINSTANCE hInstance; // Holds The Instance Of The Application bool keys[256]; // Array used for Keyboard Routine; bool active=TRUE; // Window Active Flag Set To TRUE by Default -bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen By Default +bool fullscreen=TRUE; // full-screen Flag Set To full-screen By Default GLfloat xrot; GLfloat yrot; @@ -80,6 +77,7 @@ Assimp::Importer importer; void createAILogger() { + // Change this line to normal if you not want to analyse the import process //Assimp::Logger::LogSeverity severity = Assimp::Logger::NORMAL; Assimp::Logger::LogSeverity severity = Assimp::Logger::VERBOSE; @@ -101,20 +99,20 @@ void destroyAILogger() void logInfo(std::string logString) { - //Will add message to File with "info" Tag + // Will add message to File with "info" Tag Assimp::DefaultLogger::get()->info(logString.c_str()); } void logDebug(const char* logString) { - //Will add message to File with "debug" Tag + // Will add message to File with "debug" Tag Assimp::DefaultLogger::get()->debug(logString); } bool Import3DFromFile( const std::string& pFile) { - //check if file exists + // Check if file exists std::ifstream fin(pFile.c_str()); if(!fin.fail()) { @@ -143,12 +141,14 @@ bool Import3DFromFile( const std::string& pFile) return true; } - -void ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window +// Resize And Initialize The GL Window +void ReSizeGLScene(GLsizei width, GLsizei height) { - if (height==0) // Prevent A Divide By Zero By + // Prevent A Divide By Zero By + if (height==0) { - height=1; // Making Height Equal One + // Making Height Equal One + height=1; } glViewport(0, 0, width, height); // Reset The Current Viewport @@ -217,9 +217,6 @@ int LoadGLTextures(const aiScene* scene) textureIds = new GLuint[numTextures]; glGenTextures(numTextures, textureIds); /* Texture name generation */ - /* define texture path */ - //std::string texturepath = "../../../test/models/Obj/"; - /* get iterator */ std::map::iterator itr = textureIdMap.begin(); @@ -239,48 +236,50 @@ int LoadGLTextures(const aiScene* scene) if (success) /* If no error occured: */ { - success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); /* Convert every colour component into - unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA */ + // Convert every colour component into unsigned byte.If your image contains + // alpha channel you can replace IL_RGB with IL_RGBA + success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); if (!success) { /* Error occured */ abortGLInit("Couldn't convert image"); return -1; } - //glGenTextures(numTextures, &textureIds[i]); /* Texture name generation */ - glBindTexture(GL_TEXTURE_2D, textureIds[i]); /* Binding of texture name */ - //redefine standard texture values - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use linear - interpolation for magnification filter */ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use linear - interpolation for minifying filter */ - glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), + // Binding of texture name + glBindTexture(GL_TEXTURE_2D, textureIds[i]); + // redefine standard texture values + // We will use linear interpolation for magnification filter + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + // We will use linear interpolation for minifying filter + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + // Texture specification + glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, - ilGetData()); /* Texture specification */ + ilGetData()); + // we also want to be able to deal with odd texture dimensions + glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); + glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 ); + glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 ); + glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 ); } else { /* Error occured */ MessageBox(NULL, ("Couldn't load Image: " + fileloc).c_str() , "ERROR", MB_OK | MB_ICONEXCLAMATION); } - - } + // Because we have already copied image data into texture data we can release memory used by image. + ilDeleteImages(numTextures, imageIds); - ilDeleteImages(numTextures, imageIds); /* Because we have already copied image data into texture data - we can release memory used by image. */ - - //Cleanup + // Cleanup delete [] imageIds; imageIds = NULL; - //return success; return TRUE; } - - -int InitGL() // All Setup For OpenGL goes here +// All Setup For OpenGL goes here +int InitGL() { if (!LoadGLTextures(scene)) { @@ -307,9 +306,6 @@ int InitGL() // All Setup For OpenGL goes here glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); glEnable(GL_LIGHT1); - //glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - - return TRUE; // Initialization Went OK } @@ -449,8 +445,6 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float glDisable(GL_COLOR_MATERIAL); } - - for (t = 0; t < mesh->mNumFaces; ++t) { const struct aiFace* face = &mesh->mFaces[t]; GLenum face_mode; @@ -480,14 +474,10 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float glNormal3fv(&mesh->mNormals[vertexIndex].x); glVertex3fv(&mesh->mVertices[vertexIndex].x); } - glEnd(); - } - } - // draw all children for (n = 0; n < nd->mNumChildren; ++n) { @@ -521,12 +511,11 @@ int DrawGLScene() //Here's where we do all the drawing drawAiScene(scene); - //xrot+=0.3f; yrot+=0.2f; //zrot+=0.4f; - return TRUE; // Ewwrissing okay + return TRUE; // okay } @@ -667,11 +656,6 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful { abortGLInit("Window Creation Error."); return FALSE; - /* - KillGLWindow(); // Reset The Display - MessageBox(NULL, "Window Creation Error.", "ERROR", MB_OK|MB_ICONEXCLAMATION); - return FALSE; // Return False - */ } static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be @@ -767,8 +751,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, // Handles for this Window { switch (wParam) { - case SC_SCREENSAVE: // Screensaver trying to start - case SC_MONITORPOWER: // Monitor tryig to enter powersafe + case SC_SCREENSAVE: // Screen-saver trying to start + case SC_MONITORPOWER: // Monitor trying to enter power-safe return 0; } break; @@ -799,12 +783,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, // Handles for this Window } } - // Pass All Unhandled Messaged To DefWindowProc + // Pass All unhandled Messaged To DefWindowProc return DefWindowProc(hWnd, uMsg, wParam, lParam); } -int WINAPI WinMain( HINSTANCE hInstance, // Instance - HINSTANCE hPrevInstance, // Previous Instance +int WINAPI WinMain( HINSTANCE hInstance, // The instance + HINSTANCE hPrevInstance, // Previous instance LPSTR lpCmdLine, // Command Line Parameters int nShowCmd ) // Window Show State { From 69810a2a07db62606596c73eea969bf7c3e1db6f Mon Sep 17 00:00:00 2001 From: Jared Duke Date: Sun, 17 Aug 2014 08:41:45 -0700 Subject: [PATCH 71/80] Avoid raw reinterpret_casts in the FBX parser As reinterpret_cast can break strict aliasing rules, causing runtime failure on Android, replace such usage in FBXParser with memcpy. Also provide a utility routine for both performing the copy and asserting the validity of the buffer length relative to the copied region. --- code/FBXParser.cpp | 52 +++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/code/FBXParser.cpp b/code/FBXParser.cpp index f6dc2e7e2..bc0458ff6 100644 --- a/code/FBXParser.cpp +++ b/code/FBXParser.cpp @@ -113,6 +113,18 @@ namespace { ParseError(message); } + // Initially, we did reinterpret_cast, breaking strict aliasing rules. + // This actually caused trouble on Android, so let's be safe this time. + // https://github.com/assimp/assimp/issues/24 + template + T SafeParse(const char* data, const char* end) { + // Actual size validation happens during Tokenization so + // this is valid as an assertion. + ai_assert(static_cast(end - data) >= sizeof(T)); + T result = static_cast(0); + ::memcpy(&result, data, sizeof(T)); + return result; + } } namespace Assimp { @@ -275,9 +287,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out) return 0L; } - ai_assert(t.end() - data == 9); - - BE_NCONST uint64_t id = *reinterpret_cast(data+1); + BE_NCONST uint64_t id = SafeParse(data+1, t.end()); AI_SWAP8(id); return id; } @@ -316,8 +326,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out) return 0; } - ai_assert(t.end() - data == 9); - BE_NCONST uint64_t id = *reinterpret_cast(data+1); + BE_NCONST uint64_t id = SafeParse(data+1, t.end()); AI_SWAP8(id); return static_cast(id); } @@ -364,24 +373,10 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out) } if (data[0] == 'F') { - // Actual size validation happens during Tokenization so - // this is valid as an assertion. - ai_assert(t.end() - data == sizeof(float) + 1); - // Initially, we did reinterpret_cast, breaking strict aliasing rules. - // This actually caused trouble on Android, so let's be safe this time. - // https://github.com/assimp/assimp/issues/24 - - float out_float; - ::memcpy(&out_float, data+1, sizeof(float)); - return out_float; + return SafeParse(data+1, t.end()); } else { - ai_assert(t.end() - data == sizeof(double) + 1); - - // Same - double out_double; - ::memcpy(&out_double, data+1, sizeof(double)); - return static_cast(out_double); + return SafeParse(data+1, t.end()); } } @@ -416,8 +411,7 @@ int ParseTokenAsInt(const Token& t, const char*& err_out) return 0; } - ai_assert(t.end() - data == 5); - BE_NCONST int32_t ival = *reinterpret_cast(data+1); + BE_NCONST int32_t ival = SafeParse(data+1, t.end()); AI_SWAP4(ival); return static_cast(ival); } @@ -453,10 +447,8 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out) return ""; } - ai_assert(t.end() - data >= 5); - // read string length - BE_NCONST int32_t len = *reinterpret_cast(data+1); + BE_NCONST int32_t len = SafeParse(data+1, t.end()); AI_SWAP4(len); ai_assert(t.end() - data == 5 + len); @@ -494,7 +486,7 @@ void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uin type = *data; // read number of elements - BE_NCONST uint32_t len = *reinterpret_cast(data+1); + BE_NCONST uint32_t len = SafeParse(data+1, end); AI_SWAP4(len); count = len; @@ -508,14 +500,12 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha std::vector& buff, const Element& el) { - ai_assert(static_cast(end-data) >= 4); // runtime check for this happens at tokenization stage - - BE_NCONST uint32_t encmode = *reinterpret_cast(data); + BE_NCONST uint32_t encmode = SafeParse(data, end); AI_SWAP4(encmode); data += 4; // next comes the compressed length - BE_NCONST uint32_t comp_len = *reinterpret_cast(data); + BE_NCONST uint32_t comp_len = SafeParse(data, end); AI_SWAP4(comp_len); data += 4; From aafc8d5f3f92b32fe101d3a018c8af3e002e1c86 Mon Sep 17 00:00:00 2001 From: abma Date: Sun, 17 Aug 2014 23:10:06 +0200 Subject: [PATCH 72/80] CMake: changed cached bools into "option" --- CMakeLists.txt | 23 ++++++++++++++--------- code/CMakeLists.txt | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31561864f..c5bbfdb1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,8 +76,7 @@ SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH "Path the header files are installed to." ) SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH "Path the tool executables are installed to." ) -SET ( ASSIMP_BUILD_STATIC_LIB OFF CACHE BOOL - "Build a static (.a) version of the library" ) +option (ASSIMP_BUILD_STATIC_LIB "Build a static (.a) version of the library" OFF) SET(ASSIMP_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools") @@ -102,8 +101,9 @@ ENDIF() # Globally enable Boost resp. the Boost workaround – it is also needed by the # tools which include the Assimp headers. -SET ( ASSIMP_ENABLE_BOOST_WORKAROUND ON CACHE BOOL +option ( ASSIMP_ENABLE_BOOST_WORKAROUND "If a simple implementation of the used Boost functions is used. Slightly reduces functionality, but enables builds without Boost available." + ON ) IF ( ASSIMP_ENABLE_BOOST_WORKAROUND ) INCLUDE_DIRECTORIES( code/BoostWorkaround ) @@ -129,8 +129,9 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${C configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT}) -SET ( ASSIMP_NO_EXPORT OFF CACHE BOOL - "Disable Assimp's export functionality." +option ( ASSIMP_NO_EXPORT + "Disable Assimp's export functionality." + OFF ) # Search for external dependencies, and build them from source if not found @@ -186,8 +187,9 @@ ENDIF ( ASSIMP_BUILD_COMPILER STREQUAL "") MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER ) ADD_SUBDIRECTORY( code/ ) -SET ( ASSIMP_BUILD_ASSIMP_TOOLS ON CACHE BOOL +option ( ASSIMP_BUILD_ASSIMP_TOOLS "If the supplementary tools for Assimp are built in addition to the library." + ON ) IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) IF ( WIN32 ) @@ -196,8 +198,9 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS ) ADD_SUBDIRECTORY( tools/assimp_cmd/ ) ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS ) -SET ( ASSIMP_BUILD_SAMPLES OFF CACHE BOOL +option ( ASSIMP_BUILD_SAMPLES "If the official samples are built as well (needs Glut)." + OFF ) IF ( ASSIMP_BUILD_SAMPLES) @@ -208,8 +211,9 @@ IF ( ASSIMP_BUILD_SAMPLES) ENDIF ( ASSIMP_BUILD_SAMPLES ) IF ( WIN32 ) - SET ( ASSIMP_BUILD_TESTS ON CACHE BOOL + option ( ASSIMP_BUILD_TESTS "If the test suite for Assimp is built in addition to the library." + ON ) IF ( ASSIMP_BUILD_TESTS ) @@ -218,8 +222,9 @@ IF ( WIN32 ) ENDIF ( WIN32 ) IF(MSVC) - SET ( ASSIMP_INSTALL_PDB ON CACHE BOOL + option ( ASSIMP_INSTALL_PDB "Install MSVC debug files." + ON ) ENDIF(MSVC) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 4e05887ba..13e297be2 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -623,7 +623,7 @@ SOURCE_GROUP( unzip FILES ${unzip_SRCS}) # VC2010 fixes if(MSVC10) - OPTION( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF ) + option( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF ) if( VC10_STDINT_FIX ) ADD_DEFINITIONS( -D_STDINT ) endif( VC10_STDINT_FIX ) From 56ddb4f4afcbf75f294282fdd0656b4107ea1f65 Mon Sep 17 00:00:00 2001 From: abma Date: Sun, 17 Aug 2014 23:28:00 +0200 Subject: [PATCH 73/80] fix some compile warnings: - passing NULL to non-pointer - unused vars - unused function - order of init - parentheses --- code/3DSExporter.cpp | 2 +- code/AssbinExporter.cpp | 2 +- code/AssbinLoader.cpp | 30 +++++++++++++++--------------- code/Exporter.cpp | 2 +- code/FBXParser.cpp | 4 ++-- code/OgreStructs.cpp | 20 ++++++++++---------- code/Q3BSPFileImporter.cpp | 2 ++ contrib/clipper/clipper.cpp | 2 ++ 8 files changed, 34 insertions(+), 30 deletions(-) diff --git a/code/3DSExporter.cpp b/code/3DSExporter.cpp index d2a353a57..8ad367058 100644 --- a/code/3DSExporter.cpp +++ b/code/3DSExporter.cpp @@ -147,7 +147,7 @@ namespace { void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) { boost::shared_ptr outfile (pIOSystem->Open(pFile, "wb")); - if(outfile == NULL) { + if(!outfile) { throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile)); } diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 29ebfeee7..c28058778 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -728,7 +728,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size) // is compressed using standard DEFLATE from zlib. if (compressed) { - AssbinChunkWriter uncompressedStream( NULL, NULL ); + AssbinChunkWriter uncompressedStream( NULL, 0 ); WriteBinaryScene( &uncompressedStream, pScene ); uLongf uncompressedSize = uncompressedStream.Tell(); diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index a17d37f9e..20f707df5 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -195,7 +195,7 @@ template void ReadBounds( IOStream * stream, T* p, unsigned int n ) void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AINODE); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); *node = new aiNode(); @@ -226,7 +226,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIBONE ); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); b->mName = Read(stream); b->mNumWeights = Read(stream); @@ -249,7 +249,7 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIMESH); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); mesh->mPrimitiveTypes = Read(stream); mesh->mNumVertices = Read(stream); @@ -373,7 +373,7 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIMATERIALPROPERTY); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); prop->mKey = Read(stream); prop->mSemantic = Read(stream); @@ -389,7 +389,7 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIMATERIAL); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); mat->mNumAllocated = mat->mNumProperties = Read(stream); if (mat->mNumProperties) @@ -410,7 +410,7 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) { ai_assert( Read(stream) == ASSBIN_CHUNK_AINODEANIM); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); nd->mNodeName = Read(stream); nd->mNumPositionKeys = Read(stream); @@ -458,7 +458,7 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIANIMATION); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); anim->mName = Read (stream); anim->mDuration = Read (stream); @@ -478,7 +478,7 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) { ai_assert( Read(stream) == ASSBIN_CHUNK_AITEXTURE); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); tex->mWidth = Read(stream); tex->mHeight = Read(stream); @@ -501,7 +501,7 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AILIGHT); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); l->mName = Read(stream); l->mType = (aiLightSourceType)Read(stream); @@ -527,7 +527,7 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AICAMERA); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); cam->mName = Read(stream); cam->mPosition = Read(stream); @@ -542,7 +542,7 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); - uint32_t size = Read(stream); + /*uint32_t size =*/ Read(stream); scene->mFlags = Read(stream); scene->mNumMeshes = Read(stream); @@ -626,10 +626,10 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, stream->Seek( 44, aiOrigin_CUR ); // signature - unsigned int versionMajor = Read(stream); - unsigned int versionMinor = Read(stream); - unsigned int versionRevision = Read(stream); - unsigned int compileFlags = Read(stream); + /*unsigned int versionMajor =*/ Read(stream); + /*unsigned int versionMinor =*/ Read(stream); + /*unsigned int versionRevision =*/ Read(stream); + /*unsigned int compileFlags =*/ Read(stream); shortened = Read(stream) > 0; compressed = Read(stream) > 0; diff --git a/code/Exporter.cpp b/code/Exporter.cpp index c105e36ba..22c60ebee 100644 --- a/code/Exporter.cpp +++ b/code/Exporter.cpp @@ -120,7 +120,7 @@ Exporter::ExportFormatEntry gExporters[] = #endif #ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER - Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, NULL), + Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0), #endif }; diff --git a/code/FBXParser.cpp b/code/FBXParser.cpp index f6dc2e7e2..2b5a85bdc 100644 --- a/code/FBXParser.cpp +++ b/code/FBXParser.cpp @@ -93,7 +93,7 @@ namespace { } // ------------------------------------------------------------------------------------------------ - void ParseWarning(const std::string& message, const Element* element = NULL) +/* void ParseWarning(const std::string& message, const Element* element = NULL) { if(element) { ParseWarning(message,element->KeyToken()); @@ -103,7 +103,7 @@ namespace { DefaultLogger::get()->warn("FBX-Parser: " + message); } } - +*/ // ------------------------------------------------------------------------------------------------ void ParseError(const std::string& message, TokenPtr token) { diff --git a/code/OgreStructs.cpp b/code/OgreStructs.cpp index 6311d0b6c..40dda5fb9 100644 --- a/code/OgreStructs.cpp +++ b/code/OgreStructs.cpp @@ -404,9 +404,9 @@ size_t IndexData::FaceSize() const // Mesh Mesh::Mesh() : - sharedVertexData(0), - skeleton(0), - hasSkeletalAnimations(false) + hasSkeletalAnimations(false), + skeleton(NULL), + sharedVertexData(NULL) { } @@ -712,8 +712,8 @@ aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent) // MeshXml MeshXml::MeshXml() : - sharedVertexData(0), - skeleton(0) + skeleton(0), + sharedVertexData(0) { } @@ -797,8 +797,8 @@ void MeshXml::ConvertToAssimpScene(aiScene* dest) // SubMeshXml SubMeshXml::SubMeshXml() : - vertexData(0), - indexData(new IndexDataXml()) + indexData(new IndexDataXml()), + vertexData(0) { } @@ -912,8 +912,8 @@ aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent) // Animation Animation::Animation(Skeleton *parent) : + parentMesh(NULL), parentSkeleton(parent), - parentMesh(0), length(0.0f), baseTime(-1.0f) { @@ -1124,8 +1124,8 @@ aiBone *Bone::ConvertToAssimpBone(Skeleton *parent, const std::vector &supportedExtensions) { supportedExtensions.push_back( ".jpg" ); supportedExtensions.push_back( ".png" ); supportedExtensions.push_back( ".tga" ); } +*/ using namespace Q3BSP; diff --git a/contrib/clipper/clipper.cpp b/contrib/clipper/clipper.cpp index b9754e4eb..1efa01df8 100644 --- a/contrib/clipper/clipper.cpp +++ b/contrib/clipper/clipper.cpp @@ -2124,11 +2124,13 @@ void Clipper::AddOutPt(TEdge *e, const IntPoint &pt) { //check for 'rounding' artefacts ... if (outRec->sides == esNeither && pt.Y == op->pt.Y) + { if (ToFront) { if (pt.X == op->pt.X +1) return; //ie wrong side of bottomPt } else if (pt.X == op->pt.X -1) return; //ie wrong side of bottomPt + } outRec->sides = (EdgeSide)(outRec->sides | e->side); if (outRec->sides == esBoth) From c7ab8383bdd2d9e298fbc73b3002c50f9b8715f7 Mon Sep 17 00:00:00 2001 From: abma Date: Sun, 17 Aug 2014 23:39:49 +0200 Subject: [PATCH 74/80] fix warning: equality comparison with extraneous parentheses --- contrib/unzip/unzip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/unzip/unzip.c b/contrib/unzip/unzip.c index f62b45ec8..e83862a43 100644 --- a/contrib/unzip/unzip.c +++ b/contrib/unzip/unzip.c @@ -1246,7 +1246,7 @@ extern int ZEXPORT unzReadCurrentFile (file, buf, len) return UNZ_PARAMERROR; - if ((pfile_in_zip_read_info->read_buffer == NULL)) + if (pfile_in_zip_read_info->read_buffer == NULL) return UNZ_END_OF_LIST_OF_FILE; if (len==0) return 0; From b2643a3835ef6e3f95f6300121d6a3b8436d4855 Mon Sep 17 00:00:00 2001 From: abma Date: Sun, 17 Aug 2014 23:49:36 +0200 Subject: [PATCH 75/80] fix SimpleOpenGL linking (missing libm) --- samples/SimpleOpenGL/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/SimpleOpenGL/CMakeLists.txt b/samples/SimpleOpenGL/CMakeLists.txt index 49e5fc212..dea335ee1 100644 --- a/samples/SimpleOpenGL/CMakeLists.txt +++ b/samples/SimpleOpenGL/CMakeLists.txt @@ -1,5 +1,6 @@ FIND_PACKAGE(OpenGL) FIND_PACKAGE(GLUT) +find_library(M_LIB m) IF ( NOT GLUT_FOUND ) IF ( MSVC ) @@ -29,7 +30,7 @@ ADD_EXECUTABLE( assimp_simpleogl SET_PROPERTY(TARGET assimp_simpleogl PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX}) -TARGET_LINK_LIBRARIES( assimp_simpleogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ) +TARGET_LINK_LIBRARIES( assimp_simpleogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${M_LIB} ) SET_TARGET_PROPERTIES( assimp_simpleogl PROPERTIES OUTPUT_NAME assimp_simpleogl ) From d795491c487cb0626641821cfa1452666dbf94be Mon Sep 17 00:00:00 2001 From: abma Date: Mon, 18 Aug 2014 00:34:45 +0200 Subject: [PATCH 76/80] fix unittests on linux / enable on travis-ci --- .travis.yml | 10 ++++++---- CMakeLists.txt | 16 +++++++--------- code/GenVertexNormalsProcess.h | 2 +- code/JoinVerticesProcess.h | 2 +- test/CMakeLists.txt | 8 +++++--- test/unit/Main.cpp | 7 +++---- test/unit/utImporter.cpp | 4 ++-- test/unit/utNoBoostTest.h | 4 ++-- 8 files changed, 27 insertions(+), 26 deletions(-) diff --git a/.travis.yml b/.travis.yml index aa07c4f75..e0c0788ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ before_install: - - sudo apt-get install cmake + - sudo apt-get install cmake libcppunit-dev env: - TRAVIS_NO_EXPORT=YES @@ -13,7 +13,9 @@ compiler: - gcc - clang -script: cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD && make - - +script: + - cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD + - make + - cd test/unit + - ../../bin/unit diff --git a/CMakeLists.txt b/CMakeLists.txt index c5bbfdb1f..e32afb166 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,16 +210,14 @@ IF ( ASSIMP_BUILD_SAMPLES) ADD_SUBDIRECTORY( samples/SimpleOpenGL/ ) ENDIF ( ASSIMP_BUILD_SAMPLES ) -IF ( WIN32 ) - option ( ASSIMP_BUILD_TESTS - "If the test suite for Assimp is built in addition to the library." - ON - ) +option ( ASSIMP_BUILD_TESTS + "If the test suite for Assimp is built in addition to the library." + ON +) - IF ( ASSIMP_BUILD_TESTS ) - ADD_SUBDIRECTORY( test/ ) - ENDIF ( ASSIMP_BUILD_TESTS ) -ENDIF ( WIN32 ) +IF ( ASSIMP_BUILD_TESTS ) + ADD_SUBDIRECTORY( test/ ) +ENDIF ( ASSIMP_BUILD_TESTS ) IF(MSVC) option ( ASSIMP_INSTALL_PDB diff --git a/code/GenVertexNormalsProcess.h b/code/GenVertexNormalsProcess.h index 9b103892c..e77e71e59 100644 --- a/code/GenVertexNormalsProcess.h +++ b/code/GenVertexNormalsProcess.h @@ -53,7 +53,7 @@ namespace Assimp { // --------------------------------------------------------------------------- /** The GenFaceNormalsProcess computes vertex normals for all vertizes */ -class ASSIMP_API_WINONLY GenVertexNormalsProcess : public BaseProcess +class ASSIMP_API GenVertexNormalsProcess : public BaseProcess { public: diff --git a/code/JoinVerticesProcess.h b/code/JoinVerticesProcess.h index a004b2528..0195c0168 100644 --- a/code/JoinVerticesProcess.h +++ b/code/JoinVerticesProcess.h @@ -59,7 +59,7 @@ class JoinVerticesTest; * erases all but one of the copies. This usually reduces the number of vertices * in a mesh by a serious amount and is the standard form to render a mesh. */ -class ASSIMP_API_WINONLY JoinVerticesProcess : public BaseProcess +class ASSIMP_API JoinVerticesProcess : public BaseProcess { public: diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 544b57a57..92b618558 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -15,7 +15,7 @@ SOURCE_GROUP( unit FILES unit/BoostWorkaround/tupletest.cpp ) - +if(WIN32) SET( CPPUNIT_SRCS ../contrib/cppunit-1.12.1/src/cppunit/AdditionalMessage.cpp ../contrib/cppunit-1.12.1/src/cppunit/Asserter.cpp @@ -72,7 +72,9 @@ SET( CPPUNIT_SRCS ../contrib/cppunit-1.12.1/src/cppunit/XmlOutputterHook.cpp ) SOURCE_GROUP(cppunit FILES ${CPPUNIT_SRCS}) - +else() + find_library(CPPUNIT_LIBRARY cppunit) +endif() SET( TEST_SRCS unit/utFindDegenerates.cpp @@ -133,4 +135,4 @@ add_executable( unit SET_PROPERTY(TARGET assimp PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX}) -target_link_libraries ( unit assimp ) +target_link_libraries ( unit assimp ${CPPUNIT_LIBRARY} ) diff --git a/test/unit/Main.cpp b/test/unit/Main.cpp index 5c7bb60fb..33840a3c0 100644 --- a/test/unit/Main.cpp +++ b/test/unit/Main.cpp @@ -26,9 +26,8 @@ int main (int argc, char* argv[]) // .. and C. They should smoothly work together aiEnableVerboseLogging(AI_TRUE); - aiAttachLogStream(&aiGetPredefinedLogStream( - aiDefaultLogStream_FILE, - "AssimpLog_C.txt")); + aiLogStream logstream= aiGetPredefinedLogStream(aiDefaultLogStream_FILE, "AssimpLog_C.txt"); + aiAttachLogStream(&logstream); // ............................................................................ @@ -66,4 +65,4 @@ int main (int argc, char* argv[]) // Rueckmeldung, ob Tests erfolgreich waren return collectedresults.wasSuccessful () ? 0 : 1; -} \ No newline at end of file +} diff --git a/test/unit/utImporter.cpp b/test/unit/utImporter.cpp index 702bb7978..51b7764dd 100644 --- a/test/unit/utImporter.cpp +++ b/test/unit/utImporter.cpp @@ -208,11 +208,11 @@ void ImporterTest :: testMultipleReads (void) CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/test.x",flags)); //CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/dwarf.x",flags)); # is in nonbsd - CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/Testwuson.x",flags)); + CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/Testwuson.X",flags)); CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/anim_test.x",flags)); //CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/dwarf.x",flags)); # is in nonbsd CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/anim_test.x",flags)); - CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/bcn_epileptic.x",flags)); + CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/BCN_Epileptic.X",flags)); //CPPUNIT_ASSERT(pImp->ReadFile("../../test/models/X/dwarf.x",flags)); # is in nonbsd } diff --git a/test/unit/utNoBoostTest.h b/test/unit/utNoBoostTest.h index 5fe3ceabd..6fbff7dff 100644 --- a/test/unit/utNoBoostTest.h +++ b/test/unit/utNoBoostTest.h @@ -4,7 +4,7 @@ namespace noboost { #define ASSIMP_FORCE_NOBOOST -#include "..\..\code\BoostWorkaround\boost\format.hpp" +#include "../../code/BoostWorkaround/boost/format.hpp" using boost::format; using boost::str; @@ -34,4 +34,4 @@ class NoBoostTest : public CPPUNIT_NS :: TestFixture }; -#endif \ No newline at end of file +#endif From 48a772b20bda1ab2b59ba79c93213ec162eb4074 Mon Sep 17 00:00:00 2001 From: abma Date: Mon, 18 Aug 2014 00:46:21 +0200 Subject: [PATCH 77/80] =?UTF-8?q?fix=20compiler=20warnings:=20-=20defined?= =?UTF-8?q?=20but=20not=20used=20-=20deprecated=20conversion=20from=20stri?= =?UTF-8?q?ng=20constant=20to=20=E2=80=98char*=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/OgreBinarySerializer.h | 4 ++++ test/unit/utRemoveComments.cpp | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/code/OgreBinarySerializer.h b/code/OgreBinarySerializer.h index 8b4e3ccfe..429c9b1c5 100644 --- a/code/OgreBinarySerializer.h +++ b/code/OgreBinarySerializer.h @@ -306,6 +306,7 @@ enum MeshChunkId // float extremes [n_extremes][3]; }; +/* static std::string MeshHeaderToString(MeshChunkId id) { switch(id) @@ -347,6 +348,7 @@ static std::string MeshHeaderToString(MeshChunkId id) } return "Unknown_MeshChunkId"; } +*/ enum SkeletonChunkId { @@ -393,6 +395,7 @@ enum SkeletonChunkId // float scale : scale to apply to trans/scale keys }; +/* static std::string SkeletonHeaderToString(SkeletonChunkId id) { switch(id) @@ -409,6 +412,7 @@ static std::string SkeletonHeaderToString(SkeletonChunkId id) } return "Unknown_SkeletonChunkId"; } +*/ } // Ogre } // Assimp diff --git a/test/unit/utRemoveComments.cpp b/test/unit/utRemoveComments.cpp index f1d11ec72..5779946eb 100644 --- a/test/unit/utRemoveComments.cpp +++ b/test/unit/utRemoveComments.cpp @@ -43,7 +43,7 @@ void RemoveCommentsTest :: testSingleLineComments (void) // ------------------------------------------------------------------------------------------------ void RemoveCommentsTest :: testMultiLineComments (void) { - char* szTest = + const char* szTest = "/* comment to be removed */\n" "valid text /* \n " " comment across multiple lines */" @@ -62,4 +62,4 @@ void RemoveCommentsTest :: testMultiLineComments (void) CPPUNIT_ASSERT(0 == ::strcmp(szTest2,szTestResult)); delete[] szTest2; -} \ No newline at end of file +} From 6c5f9ecb06a830fcc4701d74663eeb6f61f02d67 Mon Sep 17 00:00:00 2001 From: abma Date: Mon, 18 Aug 2014 02:09:06 +0200 Subject: [PATCH 78/80] fix most warnings with -pendantic --- code/AssbinExporter.cpp | 4 +- code/AssbinLoader.cpp | 4 +- code/BlenderLoader.cpp | 4 +- code/BoostWorkaround/boost/tuple/tuple.hpp | 6 +- code/FBXAnimation.cpp | 2 +- code/FBXConverter.cpp | 12 +-- code/FBXDocument.h | 4 +- code/FBXMaterial.cpp | 2 +- code/FBXParser.cpp | 2 +- code/FBXProperties.h | 6 +- code/IFCBoolean.cpp | 2 +- code/IFCOpenings.cpp | 4 +- code/IFCProfile.cpp | 2 +- code/IFCReaderGen.cpp | 6 +- code/OgreBinarySerializer.cpp | 10 +-- code/OgreBinarySerializer.h | 2 +- code/OgreStructs.cpp | 2 +- code/Q3BSPZipArchive.cpp | 10 +-- include/assimp/importerdesc.h | 2 +- samples/SimpleOpenGL/Sample_SimpleOpenGL.c | 94 +++++++++++----------- test/unit/CCompilerTest.c | 2 +- test/unit/utImporter.cpp | 6 +- tools/assimp_cmd/WriteDumb.cpp | 2 +- 23 files changed, 95 insertions(+), 95 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index c28058778..a330dfd45 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -273,8 +273,8 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size) void * GetBufferPointer() { return buffer; }; // ------------------------------------------------------------------- - virtual size_t Read(void* pvBuffer, size_t pSize, size_t pCount) { return 0; }; - virtual aiReturn Seek(size_t pOffset, aiOrigin pOrigin) { return aiReturn_FAILURE; }; + virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { return 0; }; + virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { return aiReturn_FAILURE; }; virtual size_t Tell() const { return cursor; }; virtual void Flush() { }; diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 20f707df5..65299f577 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -78,7 +78,7 @@ const aiImporterDesc* AssbinImporter::GetInfo() const return &desc; } -bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const +bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const { IOStream * in = pIOHandler->Open(pFile); if (!in) @@ -186,7 +186,7 @@ void ReadArray(IOStream * stream, T * out, unsigned int size) for (unsigned int i=0; i(stream); } -template void ReadBounds( IOStream * stream, T* p, unsigned int n ) +template void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n ) { // not sure what to do here, the data isn't really useful. stream->Seek( sizeof(T) * n, aiOrigin_CUR ); diff --git a/code/BlenderLoader.cpp b/code/BlenderLoader.cpp index 4bbf5f9f6..562d3729b 100644 --- a/code/BlenderLoader.cpp +++ b/code/BlenderLoader.cpp @@ -999,7 +999,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co } // ------------------------------------------------------------------------------------------------ -aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* camera, ConversionData& /*conv_data*/) +aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* /*camera*/, ConversionData& /*conv_data*/) { ScopeGuard out(new aiCamera()); out->mName = obj->id.name+2; @@ -1010,7 +1010,7 @@ aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, } // ------------------------------------------------------------------------------------------------ -aiLight* BlenderImporter::ConvertLight(const Scene& in, const Object* obj, const Lamp* lamp, ConversionData& conv_data) +aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, const Lamp* lamp, ConversionData& /*conv_data*/) { ScopeGuard out(new aiLight()); out->mName = obj->id.name+2; diff --git a/code/BoostWorkaround/boost/tuple/tuple.hpp b/code/BoostWorkaround/boost/tuple/tuple.hpp index a0b46b497..ed5d11861 100644 --- a/code/BoostWorkaround/boost/tuple/tuple.hpp +++ b/code/BoostWorkaround/boost/tuple/tuple.hpp @@ -100,7 +100,7 @@ namespace boost { }; // dummy - list_elem& operator = (const list_elem& other) { + list_elem& operator = (const list_elem& /*other*/) { return *this; } @@ -142,7 +142,7 @@ namespace boost { return me.me; } }; - }; + } // A very minimal implementation for up to 5 elements template t; return t; } -}; +} #endif // !! BOOST_TUPLE_INCLUDED diff --git a/code/FBXAnimation.cpp b/code/FBXAnimation.cpp index ccf1d82f4..3bf60acd4 100644 --- a/code/FBXAnimation.cpp +++ b/code/FBXAnimation.cpp @@ -59,7 +59,7 @@ namespace FBX { using namespace Util; // ------------------------------------------------------------------------------------------------ -AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc) +AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/) : Object(id, element, name) { const Scope& sc = GetRequiredScope(element); diff --git a/code/FBXConverter.cpp b/code/FBXConverter.cpp index 075a4903c..03d359875 100644 --- a/code/FBXConverter.cpp +++ b/code/FBXConverter.cpp @@ -1319,7 +1319,7 @@ private: // ------------------------------------------------------------------------------------------------ - void ConvertCluster(std::vector& bones, const Model& model, const Cluster& cl, + void ConvertCluster(std::vector& bones, const Model& /*model*/, const Cluster& cl, std::vector& out_indices, std::vector& index_out_indices, std::vector& count_out_indices, @@ -2347,7 +2347,7 @@ private: // ------------------------------------------------------------------------------------------------ aiNodeAnim* GenerateScalingNodeAnim(const std::string& name, - const Model& target, + const Model& /*target*/, const std::vector& curves, const LayerMap& layer_map, double& max_time, @@ -2378,7 +2378,7 @@ private: // ------------------------------------------------------------------------------------------------ aiNodeAnim* GenerateTranslationNodeAnim(const std::string& name, - const Model& target, + const Model& /*target*/, const std::vector& curves, const LayerMap& layer_map, double& max_time, @@ -2830,7 +2830,7 @@ private: // ------------------------------------------------------------------------------------------------ - void ConvertScaleKeys(aiNodeAnim* na, const std::vector& nodes, const LayerMap& layers, + void ConvertScaleKeys(aiNodeAnim* na, const std::vector& nodes, const LayerMap& /*layers*/, double& maxTime, double& minTime) { @@ -2851,7 +2851,7 @@ private: // ------------------------------------------------------------------------------------------------ void ConvertTranslationKeys(aiNodeAnim* na, const std::vector& nodes, - const LayerMap& layers, + const LayerMap& /*layers*/, double& maxTime, double& minTime) { @@ -2869,7 +2869,7 @@ private: // ------------------------------------------------------------------------------------------------ void ConvertRotationKeys(aiNodeAnim* na, const std::vector& nodes, - const LayerMap& layers, + const LayerMap& /*layers*/, double& maxTime, double& minTime, Model::RotOrder order) diff --git a/code/FBXDocument.h b/code/FBXDocument.h index 9dd5c79dd..8cf8202a1 100644 --- a/code/FBXDocument.h +++ b/code/FBXDocument.h @@ -696,7 +696,7 @@ public: public: /** Get the Skin attached to this geometry or NULL */ - const Skin* const DeformerSkin() const { + const Skin* DeformerSkin() const { return skin; } @@ -1096,7 +1096,7 @@ public: return transformLink; } - const Model* const TargetNode() const { + const Model* TargetNode() const { return node; } diff --git a/code/FBXMaterial.cpp b/code/FBXMaterial.cpp index a5e2a1169..fffa14fd3 100644 --- a/code/FBXMaterial.cpp +++ b/code/FBXMaterial.cpp @@ -207,7 +207,7 @@ Texture::~Texture() } -LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& doc, const std::string& name) +LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& /*doc*/, const std::string& name) : Object(id,element,name) ,texture(0) ,blendMode(BlendMode_Modulate) diff --git a/code/FBXParser.cpp b/code/FBXParser.cpp index 2b5a85bdc..dd51233e2 100644 --- a/code/FBXParser.cpp +++ b/code/FBXParser.cpp @@ -506,7 +506,7 @@ void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uin // read binary data array, assume cursor points to the 'compression mode' field (i.e. behind the header) void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const char* end, std::vector& buff, - const Element& el) + const Element& /*el*/) { ai_assert(static_cast(end-data) >= 4); // runtime check for this happens at tokenization stage diff --git a/code/FBXProperties.h b/code/FBXProperties.h index 9219c3eea..bcbdc8a30 100644 --- a/code/FBXProperties.h +++ b/code/FBXProperties.h @@ -143,8 +143,7 @@ private: // ------------------------------------------------------------------------------------------------ template inline T PropertyGet(const PropertyTable& in, const std::string& name, - const T& defaultValue, - bool ignoreTemplate = false) + const T& defaultValue) { const Property* const prop = in.Get(name); if(!prop) { @@ -164,8 +163,7 @@ inline T PropertyGet(const PropertyTable& in, const std::string& name, // ------------------------------------------------------------------------------------------------ template inline T PropertyGet(const PropertyTable& in, const std::string& name, - bool& result, - bool ignoreTemplate = false) + bool& result) { const Property* const prop = in.Get(name); if(!prop) { diff --git a/code/IFCBoolean.cpp b/code/IFCBoolean.cpp index 8573e4d62..7d3840710 100644 --- a/code/IFCBoolean.cpp +++ b/code/IFCBoolean.cpp @@ -85,7 +85,7 @@ Intersect IntersectSegmentPlane(const IfcVector3& p,const IfcVector3& n, const I // ------------------------------------------------------------------------------------------------ void ProcessBooleanHalfSpaceDifference(const IfcHalfSpaceSolid* hs, TempMesh& result, const TempMesh& first_operand, - ConversionData& conv) + ConversionData& /*conv*/) { ai_assert(hs != NULL); diff --git a/code/IFCOpenings.cpp b/code/IFCOpenings.cpp index c26574cc3..0af90eb5b 100644 --- a/code/IFCOpenings.cpp +++ b/code/IFCOpenings.cpp @@ -259,7 +259,7 @@ BoundingBox GetBoundingBox(const ClipperLib::Polygon& poly) // ------------------------------------------------------------------------------------------------ void InsertWindowContours(const ContourVector& contours, - const std::vector& openings, + const std::vector& /*openings*/, TempMesh& curmesh) { // fix windows - we need to insert the real, polygonal shapes into the quadratic holes that we have now @@ -1741,4 +1741,4 @@ bool TryAddOpenings_Poly2Tri(const std::vector& openings,const std: #undef from_int64 #undef one_vec -#endif \ No newline at end of file +#endif diff --git a/code/IFCProfile.cpp b/code/IFCProfile.cpp index 5119338c1..84f5c3194 100644 --- a/code/IFCProfile.cpp +++ b/code/IFCProfile.cpp @@ -101,7 +101,7 @@ void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout } // ------------------------------------------------------------------------------------------------ -void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv) +void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& /*conv*/) { if(const IfcRectangleProfileDef* const cprofile = def.ToPtr()) { const IfcFloat x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f; diff --git a/code/IFCReaderGen.cpp b/code/IFCReaderGen.cpp index 2e7d357ca..00ff4aa35 100644 --- a/code/IFCReaderGen.cpp +++ b/code/IFCReaderGen.cpp @@ -1045,7 +1045,7 @@ void IFC::GetSchema(EXPRESS::ConversionSchema& out) namespace STEP { // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill(const STEP::DB& db, const LIST& params, NotImplemented* in) +template <> size_t GenericFill(const STEP::DB& /*db*/, const LIST& /*params*/, NotImplemented* /*in*/) { return 0; } @@ -1253,7 +1253,7 @@ template <> size_t GenericFill(const DB& db, const LIST& return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill(const DB& db, const LIST& params, IfcRepresentationItem* in) +template <> size_t GenericFill(const DB& /*db*/, const LIST& /*params*/, IfcRepresentationItem* /*in*/) { size_t base = 0; return base; @@ -1715,7 +1715,7 @@ template <> size_t GenericFill(const DB& db, const LIST& params, I return base; } // ----------------------------------------------------------------------------------------------------------- -template <> size_t GenericFill(const DB& db, const LIST& params, IfcObjectPlacement* in) +template <> size_t GenericFill(const DB& /*db*/, const LIST& /*params*/, IfcObjectPlacement* /*in*/) { size_t base = 0; return base; diff --git a/code/OgreBinarySerializer.cpp b/code/OgreBinarySerializer.cpp index 155e889d5..2908ca056 100644 --- a/code/OgreBinarySerializer.cpp +++ b/code/OgreBinarySerializer.cpp @@ -376,14 +376,14 @@ void OgreBinarySerializer::ReadMeshSkeletonLink(Mesh *mesh) mesh->skeletonRef = ReadLine(); } -void OgreBinarySerializer::ReadMeshBounds(Mesh *mesh) +void OgreBinarySerializer::ReadMeshBounds(Mesh * /*mesh*/) { // Skip bounds, not compatible with Assimp. // 2x float vec3 + 1x float sphere radius SkipBytes(sizeof(float) * 7); } -void OgreBinarySerializer::ReadMeshExtremes(Mesh *mesh) +void OgreBinarySerializer::ReadMeshExtremes(Mesh * /*mesh*/) { // Skip extremes, not compatible with Assimp. size_t numBytes = m_currentLen - MSTREAM_OVERHEAD_SIZE; @@ -643,7 +643,7 @@ void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest) DefaultLogger::get()->debug(Formatter::format() << " - Read vertex buffer for source " << bindIndex << " of " << numBytes << " bytes"); } -void OgreBinarySerializer::ReadEdgeList(Mesh *mesh) +void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/) { // Assimp does not acknowledge LOD levels as far as I can see it. This info is just skipped. @@ -1054,7 +1054,7 @@ void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton) DefaultLogger::get()->debug(Formatter::format() << " " << anim->name << " (" << anim->length << " sec, " << anim->tracks.size() << " tracks)"); } -void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton *skeleton, Animation *dest) +void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, Animation *dest) { uint16_t boneId = Read(); Bone *bone = dest->parentSkeleton->BoneById(boneId); @@ -1096,7 +1096,7 @@ void OgreBinarySerializer::ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *d dest->transformKeyFrames.push_back(keyframe); } -void OgreBinarySerializer::ReadSkeletonAnimationLink(Skeleton *skeleton) +void OgreBinarySerializer::ReadSkeletonAnimationLink(Skeleton * /*skeleton*/) { // Skip bounds, not compatible with Assimp. ReadLine(); // skeleton name diff --git a/code/OgreBinarySerializer.h b/code/OgreBinarySerializer.h index 429c9b1c5..1080b226a 100644 --- a/code/OgreBinarySerializer.h +++ b/code/OgreBinarySerializer.h @@ -301,7 +301,7 @@ enum MeshChunkId // unsigned short poseIndex // float influence // Optional submesh extreme vertex list chink - M_TABLE_EXTREMES = 0xE000, + M_TABLE_EXTREMES = 0xE000 // unsigned short submesh_index; // float extremes [n_extremes][3]; }; diff --git a/code/OgreStructs.cpp b/code/OgreStructs.cpp index 40dda5fb9..2009214cc 100644 --- a/code/OgreStructs.cpp +++ b/code/OgreStructs.cpp @@ -1105,7 +1105,7 @@ aiNode *Bone::ConvertToAssimpNode(Skeleton *skeleton, aiNode *parentNode) return node; } -aiBone *Bone::ConvertToAssimpBone(Skeleton *parent, const std::vector &boneWeights) +aiBone *Bone::ConvertToAssimpBone(Skeleton * /*parent*/, const std::vector &boneWeights) { aiBone *bone = new aiBone(); bone->mName = name; diff --git a/code/Q3BSPZipArchive.cpp b/code/Q3BSPZipArchive.cpp index 947b7ca7b..e683e63f8 100644 --- a/code/Q3BSPZipArchive.cpp +++ b/code/Q3BSPZipArchive.cpp @@ -68,25 +68,25 @@ voidpf IOSystem2Unzip::open(voidpf opaque, const char* filename, int mode) { return (voidpf) io_system->Open(filename, mode_fopen); } -uLong IOSystem2Unzip::read(voidpf opaque, voidpf stream, void* buf, uLong size) { +uLong IOSystem2Unzip::read(voidpf /*opaque*/, voidpf stream, void* buf, uLong size) { IOStream* io_stream = (IOStream*) stream; return io_stream->Read(buf, 1, size); } -uLong IOSystem2Unzip::write(voidpf opaque, voidpf stream, const void* buf, uLong size) { +uLong IOSystem2Unzip::write(voidpf /*opaque*/, voidpf stream, const void* buf, uLong size) { IOStream* io_stream = (IOStream*) stream; return io_stream->Write(buf, 1, size); } -long IOSystem2Unzip::tell(voidpf opaque, voidpf stream) { +long IOSystem2Unzip::tell(voidpf /*opaque*/, voidpf stream) { IOStream* io_stream = (IOStream*) stream; return io_stream->Tell(); } -long IOSystem2Unzip::seek(voidpf opaque, voidpf stream, uLong offset, int origin) { +long IOSystem2Unzip::seek(voidpf /*opaque*/, voidpf stream, uLong offset, int origin) { IOStream* io_stream = (IOStream*) stream; aiOrigin assimp_origin; @@ -115,7 +115,7 @@ int IOSystem2Unzip::close(voidpf opaque, voidpf stream) { return 0; } -int IOSystem2Unzip::testerror(voidpf opaque, voidpf stream) { +int IOSystem2Unzip::testerror(voidpf /*opaque*/, voidpf /*stream*/) { return 0; } diff --git a/include/assimp/importerdesc.h b/include/assimp/importerdesc.h index a1e29b23b..32b0013ae 100644 --- a/include/assimp/importerdesc.h +++ b/include/assimp/importerdesc.h @@ -72,7 +72,7 @@ enum aiImporterFlags * should be used with care. This only happens for trunk * (i.e. SVN) versions, experimental code is not included * in releases. */ - aiImporterFlags_Experimental = 0x10, + aiImporterFlags_Experimental = 0x10 }; diff --git a/samples/SimpleOpenGL/Sample_SimpleOpenGL.c b/samples/SimpleOpenGL/Sample_SimpleOpenGL.c index 921046a44..18cb43959 100644 --- a/samples/SimpleOpenGL/Sample_SimpleOpenGL.c +++ b/samples/SimpleOpenGL/Sample_SimpleOpenGL.c @@ -1,4 +1,4 @@ -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- // Simple sample to prove that Assimp is easy to use with OpenGL. // It takes a file name as command line parameter, loads it using standard // settings and displays it. @@ -9,29 +9,30 @@ // The vc8 solution links against assimp-release-dll_win32 - be sure to // have this configuration built. // ---------------------------------------------------------------------------- +*/ #include #include #include -// assimp include files. These three are usually needed. +/* assimp include files. These three are usually needed. */ #include #include #include -// the global Assimp scene object +/* the global Assimp scene object */ const struct aiScene* scene = NULL; GLuint scene_list = 0; struct aiVector3D scene_min, scene_max, scene_center; -// current rotation angle +/* current rotation angle */ static float angle = 0.f; #define aisgl_min(x,y) (xx?y:x) -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ void reshape(int width, int height) { const double aspectRatio = (float) width / height, fieldOfView = 45.0; @@ -43,7 +44,7 @@ void reshape(int width, int height) glViewport(0, 0, width, height); } -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ void get_bounding_box_for_node (const struct aiNode* nd, struct aiVector3D* min, struct aiVector3D* max, @@ -78,7 +79,7 @@ void get_bounding_box_for_node (const struct aiNode* nd, *trafo = prev; } -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max) { struct aiMatrix4x4 trafo; @@ -89,7 +90,7 @@ void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max) get_bounding_box_for_node(scene->mRootNode,min,max,&trafo); } -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ void color4_to_float4(const struct aiColor4D *c, float f[4]) { f[0] = c->r; @@ -98,7 +99,7 @@ void color4_to_float4(const struct aiColor4D *c, float f[4]) f[3] = c->a; } -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ void set_float4(float f[4], float a, float b, float c, float d) { f[0] = a; @@ -107,7 +108,7 @@ void set_float4(float f[4], float a, float b, float c, float d) f[3] = d; } -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ void apply_material(const struct aiMaterial *mtl) { float c[4]; @@ -173,19 +174,19 @@ void apply_material(const struct aiMaterial *mtl) glEnable(GL_CULL_FACE); } -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ void recursive_render (const struct aiScene *sc, const struct aiNode* nd) { unsigned int i; unsigned int n = 0, t; struct aiMatrix4x4 m = nd->mTransformation; - // update transform + /* update transform */ aiTransposeMatrix4(&m); glPushMatrix(); glMultMatrixf((float*)&m); - // draw all meshes assigned to this node + /* draw all meshes assigned to this node */ for (; n < nd->mNumMeshes; ++n) { const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; @@ -224,7 +225,7 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd) } - // draw all children + /* draw all children */ for (n = 0; n < nd->mNumChildren; ++n) { recursive_render(sc, nd->mChildren[n]); } @@ -232,7 +233,7 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd) glPopMatrix(); } -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ void do_motion (void) { static GLint prev_time = 0; @@ -244,7 +245,7 @@ void do_motion (void) prev_time = time; frames += 1; - if ((time - prev_fps_time) > 1000) // update every seconds + if ((time - prev_fps_time) > 1000) /* update every seconds */ { int current_fps = frames * 1000 / (time - prev_fps_time); printf("%d fps\n", current_fps); @@ -256,7 +257,7 @@ void do_motion (void) glutPostRedisplay (); } -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ void display(void) { float tmp; @@ -267,27 +268,27 @@ void display(void) glLoadIdentity(); gluLookAt(0.f,0.f,3.f,0.f,0.f,-5.f,0.f,1.f,0.f); - // rotate it around the y axis + /* rotate it around the y axis */ glRotatef(angle,0.f,1.f,0.f); - // scale the whole asset to fit into our view frustum + /* scale the whole asset to fit into our view frustum */ tmp = scene_max.x-scene_min.x; tmp = aisgl_max(scene_max.y - scene_min.y,tmp); tmp = aisgl_max(scene_max.z - scene_min.z,tmp); tmp = 1.f / tmp; glScalef(tmp, tmp, tmp); - // center the model + /* center the model */ glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z ); - // if the display list has not been made yet, create a new one and - // fill it with scene contents + /* if the display list has not been made yet, create a new one and + fill it with scene contents */ if(scene_list == 0) { scene_list = glGenLists(1); glNewList(scene_list, GL_COMPILE); - // now begin at the root node of the imported data and traverse - // the scenegraph by multiplying subsequent local transforms - // together on GL's matrix stack. + /* now begin at the root node of the imported data and traverse + the scenegraph by multiplying subsequent local transforms + together on GL's matrix stack. */ recursive_render(scene, scene->mRootNode); glEndList(); } @@ -299,11 +300,11 @@ void display(void) do_motion(); } -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ int loadasset (const char* path) { - // we are taking one of the postprocessing presets to avoid - // spelling out 20+ single postprocessing flags here. + /* we are taking one of the postprocessing presets to avoid + spelling out 20+ single postprocessing flags here. */ scene = aiImportFile(path,aiProcessPreset_TargetRealtime_MaxQuality); if (scene) { @@ -316,7 +317,7 @@ int loadasset (const char* path) return 1; } -// ---------------------------------------------------------------------------- +/* ---------------------------------------------------------------------------- */ int main(int argc, char **argv) { struct aiLogStream stream; @@ -330,21 +331,21 @@ int main(int argc, char **argv) glutDisplayFunc(display); glutReshapeFunc(reshape); - // get a handle to the predefined STDOUT log stream and attach - // it to the logging system. It remains active for all further - // calls to aiImportFile(Ex) and aiApplyPostProcessing. + /* get a handle to the predefined STDOUT log stream and attach + it to the logging system. It remains active for all further + calls to aiImportFile(Ex) and aiApplyPostProcessing. */ stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL); aiAttachLogStream(&stream); - // ... same procedure, but this stream now writes the - // log messages to assimp_log.txt + /* ... same procedure, but this stream now writes the + log messages to assimp_log.txt */ stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt"); aiAttachLogStream(&stream); - // the model name can be specified on the command line. If none - // is specified, we try to locate one of the more expressive test - // models from the repository (/models-nonbsd may be missing in - // some distributions so we need a fallback from /models!). + /* the model name can be specified on the command line. If none + is specified, we try to locate one of the more expressive test + models from the repository (/models-nonbsd may be missing in + some distributions so we need a fallback from /models!). */ if( 0 != loadasset( argc >= 2 ? argv[1] : "../../test/models-nonbsd/X/dwarf.x")) { if( argc != 1 || (0 != loadasset( "../../../../test/models-nonbsd/X/dwarf.x") && 0 != loadasset( "../../test/models/X/Testwuson.X"))) { return -1; @@ -354,14 +355,14 @@ int main(int argc, char **argv) glClearColor(0.1f,0.1f,0.1f,1.f); glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); // Uses default lighting parameters + glEnable(GL_LIGHT0); /* Uses default lighting parameters */ glEnable(GL_DEPTH_TEST); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glEnable(GL_NORMALIZE); - // XXX docs say all polygons are emitted CCW, but tests show that some aren't. + /* XXX docs say all polygons are emitted CCW, but tests show that some aren't. */ if(getenv("MODEL_IS_BROKEN")) glFrontFace(GL_CW); @@ -370,14 +371,15 @@ int main(int argc, char **argv) glutGet(GLUT_ELAPSED_TIME); glutMainLoop(); - // cleanup - calling 'aiReleaseImport' is important, as the library - // keeps internal resources until the scene is freed again. Not - // doing so can cause severe resource leaking. + /* cleanup - calling 'aiReleaseImport' is important, as the library + keeps internal resources until the scene is freed again. Not + doing so can cause severe resource leaking. */ aiReleaseImport(scene); - // We added a log stream to the library, it's our job to disable it - // again. This will definitely release the last resources allocated - // by Assimp. + /* We added a log stream to the library, it's our job to disable it + again. This will definitely release the last resources allocated + by Assimp.*/ aiDetachAllLogStreams(); return 0; } + diff --git a/test/unit/CCompilerTest.c b/test/unit/CCompilerTest.c index b27376350..6020e265b 100644 --- a/test/unit/CCompilerTest.c +++ b/test/unit/CCompilerTest.c @@ -1,5 +1,5 @@ -// This is just a small test to check whether Assimp's API compiles from C +/* This is just a small test to check whether Assimp's API compiles from C */ #include #include diff --git a/test/unit/utImporter.cpp b/test/unit/utImporter.cpp index 51b7764dd..a3b9a6fe1 100644 --- a/test/unit/utImporter.cpp +++ b/test/unit/utImporter.cpp @@ -72,7 +72,7 @@ static const aiImporterDesc desc = { bool TestPlugin :: CanRead( const std::string& pFile, - IOSystem* pIOHandler, bool test) const + IOSystem* /*pIOHandler*/, bool /*test*/) const { std::string::size_type pos = pFile.find_last_of('.'); // no file extension - can't read @@ -90,8 +90,8 @@ const aiImporterDesc* TestPlugin :: GetInfo() const return & desc; } -void TestPlugin :: InternReadFile( const std::string& pFile, - aiScene* pScene, IOSystem* pIOHandler) +void TestPlugin :: InternReadFile( const std::string& /*pFile*/, + aiScene* /*pScene*/, IOSystem* /*pIOHandler*/) { throw DeadlyImportError(AIUT_DEF_ERROR_TEXT); } diff --git a/tools/assimp_cmd/WriteDumb.cpp b/tools/assimp_cmd/WriteDumb.cpp index 669e71b3a..185d4c4dc 100644 --- a/tools/assimp_cmd/WriteDumb.cpp +++ b/tools/assimp_cmd/WriteDumb.cpp @@ -656,7 +656,7 @@ uint32_t WriteBinaryScene(const aiScene* scene) // ----------------------------------------------------------------------------------- // Write a binary model dump void WriteBinaryDump(const aiScene* scene, FILE* _out, const char* src, const char* cmd, - bool _shortened, bool compressed, ImportData& imp) + bool _shortened, bool compressed, ImportData& /*imp*/) { out = _out; shortened = _shortened; From ed124ccbab7471599d7528f3b93179470dfa142b Mon Sep 17 00:00:00 2001 From: Jared Duke Date: Wed, 20 Aug 2014 18:37:00 -0700 Subject: [PATCH 79/80] Gracefully handle NaN/inf values in fast_atoreal_move There are legitimate cases where inf/nan values are embeddded in a mesh. Such values should not cause loading to fail, and indeed, previous versions of Assimp supported their existence. Update the new fast_atoreal_move method to gracefully parse such values, allowing case-insensitive checks for "NAN", "INF" and "INFINITY" as per the atof guidelines found at http://en.cppreference.com/w/cpp/string/byte/atof. Note that the inf/nan text parsing is fairly loose, but is fast for the general case and should handle most legitimate inf/nan values. --- code/fast_atof.h | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/code/fast_atof.h b/code/fast_atof.h index 4ff666b38..03e08f404 100644 --- a/code/fast_atof.h +++ b/code/fast_atof.h @@ -16,7 +16,9 @@ #define __FAST_A_TO_F_H_INCLUDED__ #include -#include +#include + +#include "StringComparison.h" namespace Assimp { @@ -236,18 +238,36 @@ inline const char* fast_atoreal_move( const char* c, Real& out, bool check_comma ++c; } - if (!(c[0] >= '0' && c[0] <= '9') && - !(c[0] == '.' && c[1] >= '0' && c[1] <= '9')) - { - throw std::invalid_argument("Cannot parse string " - "as real number: does not start with digit " - "or decimal point followed by digit."); - } + if ((c[0] == 'N' || c[0] == 'n') && ASSIMP_strincmp(c, "nan", 3) == 0) + { + out = std::numeric_limits::quiet_NaN(); + c += 3; + return c; + } - if (*c != '.') - { - f = static_cast( strtoul10_64 ( c, &c) ); - } + if ((c[0] == 'I' || c[0] == 'i') && ASSIMP_strincmp(c, "inf", 3) == 0) + { + out = std::numeric_limits::infinity(); + c += 3; + if ((c[0] == 'I' || c[0] == 'i') && ASSIMP_strincmp(c, "inity", 5) == 0) + { + c += 5; + } + return c; + } + + if (!(c[0] >= '0' && c[0] <= '9') && + !(c[0] == '.' && c[1] >= '0' && c[1] <= '9')) + { + throw std::invalid_argument("Cannot parse string " + "as real number: does not start with digit " + "or decimal point followed by digit."); + } + + if (*c != '.') + { + f = static_cast( strtoul10_64 ( c, &c) ); + } if ((*c == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9') { From 33ffb0003e0c8ad141f2302c7d325b15d55bbbf7 Mon Sep 17 00:00:00 2001 From: acgessler Date: Sat, 23 Aug 2014 15:42:47 -0700 Subject: [PATCH 80/80] Collada Export: escape user-defined strings in XML output. --- code/CMakeLists.txt | 1 + code/ColladaExporter.cpp | 70 ++++--- code/XMLTools.h | 81 +++++++ test/models/Collada/cube_xmlspecialchars.dae | 210 +++++++++++++++++++ 4 files changed, 331 insertions(+), 31 deletions(-) create mode 100644 code/XMLTools.h create mode 100644 test/models/Collada/cube_xmlspecialchars.dae diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 13e297be2..224ae7f57 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -144,6 +144,7 @@ SET( Common_SRCS LogAux.h Bitmap.cpp Bitmap.h + XMLTools.h ) SOURCE_GROUP(Common FILES ${Common_SRCS}) diff --git a/code/ColladaExporter.cpp b/code/ColladaExporter.cpp index 963827966..d2e85a015 100644 --- a/code/ColladaExporter.cpp +++ b/code/ColladaExporter.cpp @@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Bitmap.h" #include "fast_atof.h" #include "SceneCombiner.h" +#include "XMLTools.h" #include #include @@ -93,6 +94,7 @@ void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* p } // end of namespace Assimp + // ------------------------------------------------------------------------------------------------ // Constructor for a specific scene to export ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file) @@ -140,7 +142,7 @@ void ColladaExporter::WriteFile() // useless Collada fu at the end, just in case we haven't had enough indirections, yet. mOutput << startstr << "" << endstr; PushTag(); - mOutput << startstr << "mRootNode->mName.C_Str()) + "\" />" << endstr; + mOutput << startstr << "mRootNode->mName.C_Str()) + "\" />" << endstr; PopTag(); mOutput << startstr << "" << endstr; PopTag(); @@ -236,12 +238,12 @@ void ColladaExporter::WriteHeader() if (!meta || !meta->Get("Author", value)) mOutput << startstr << "" << "Assimp" << "" << endstr; else - mOutput << startstr << "" << value.C_Str() << "" << endstr; + mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; if (!meta || !meta->Get("AuthoringTool", value)) mOutput << startstr << "" << "Assimp Exporter" << "" << endstr; else - mOutput << startstr << "" << value.C_Str() << "" << endstr; + mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; //mOutput << startstr << "" << mScene->author.C_Str() << "" << endstr; //mOutput << startstr << "" << mScene->authoringTool.C_Str() << "" << endstr; @@ -342,16 +344,20 @@ void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::strin { if( !pSurface.texture.empty() ) { - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; PushTag(); mOutput << startstr << ""; + + // URL encode image file name first, then XML encode on top + std::stringstream imageUrlEncoded; for( std::string::const_iterator it = pSurface.texture.begin(); it != pSurface.texture.end(); ++it ) { if( isalnum( *it) || *it == '_' || *it == '.' || *it == '/' || *it == '\\' ) - mOutput << *it; + imageUrlEncoded << *it; else - mOutput << '%' << std::hex << size_t( (unsigned char) *it) << std::dec; + imageUrlEncoded << '%' << std::hex << size_t( (unsigned char) *it) << std::dec; } + mOutput << XMLEscape(imageUrlEncoded.str()); mOutput << "" << endstr; PopTag(); mOutput << startstr << "" << endstr; @@ -371,7 +377,7 @@ void ColladaExporter::WriteTextureColorEntry( const Surface& pSurface, const std } else { - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; } PopTag(); mOutput << startstr << "" << endstr; @@ -385,21 +391,21 @@ void ColladaExporter::WriteTextureParamEntry( const Surface& pSurface, const std // if surface is a texture, write out the sampler and the surface parameters necessary to reference the texture if( !pSurface.texture.empty() ) { - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; PushTag(); mOutput << startstr << "" << endstr; PushTag(); - mOutput << startstr << "" << pMatName << "-" << pTypeName << "-image" << endstr; + mOutput << startstr << "" << XMLEscape(pMatName) << "-" << pTypeName << "-image" << endstr; PopTag(); mOutput << startstr << "" << endstr; PopTag(); mOutput << startstr << "" << endstr; - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; PushTag(); mOutput << startstr << "" << endstr; PushTag(); - mOutput << startstr << "" << pMatName << "-" << pTypeName << "-surface" << endstr; + mOutput << startstr << "" << XMLEscape(pMatName) << "-" << pTypeName << "-surface" << endstr; PopTag(); mOutput << startstr << "" << endstr; PopTag(); @@ -439,7 +445,7 @@ void ColladaExporter::WriteMaterials() name = "mat"; materials[a].name = std::string( "m") + boost::lexical_cast (a) + name.C_Str(); for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) { - // isalnum on MSVC asserts for code points in [0,255]. Thus prevent unwanted promotion + // isalnum on MSVC asserts for code points outside [0,255]. Thus prevent unwanted promotion // of char to signed int and take the unsigned char value. if( !isalnum( static_cast(*it) ) ) { *it = '_'; @@ -510,7 +516,7 @@ void ColladaExporter::WriteMaterials() { const Material& mat = *it; // this is so ridiculous it must be right - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; PushTag(); mOutput << startstr << "" << endstr; PushTag(); @@ -561,9 +567,9 @@ void ColladaExporter::WriteMaterials() for( std::vector::const_iterator it = materials.begin(); it != materials.end(); ++it ) { const Material& mat = *it; - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; PushTag(); - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; PopTag(); mOutput << startstr << "" << endstr; } @@ -591,13 +597,14 @@ void ColladaExporter::WriteGeometryLibrary() void ColladaExporter::WriteGeometry( size_t pIndex) { const aiMesh* mesh = mScene->mMeshes[pIndex]; - std::string idstr = GetMeshId( pIndex); + const std::string idstr = GetMeshId( pIndex); + const std::string idstrEscaped = XMLEscape(idstr); if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 ) return; // opening tag - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; PushTag(); mOutput << startstr << "" << endstr; @@ -627,20 +634,20 @@ void ColladaExporter::WriteGeometry( size_t pIndex) } // assemble vertex structure - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; PushTag(); - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; if( mesh->HasNormals() ) - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a ) { if( mesh->HasTextureCoords( a) ) - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; } for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a ) { if( mesh->HasVertexColors( a) ) - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; } PopTag(); @@ -660,7 +667,7 @@ void ColladaExporter::WriteGeometry( size_t pIndex) { mOutput << startstr << "" << endstr; PushTag(); - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; mOutput << startstr << "

"; for( size_t a = 0; a < mesh->mNumFaces; ++a ) { @@ -681,7 +688,7 @@ void ColladaExporter::WriteGeometry( size_t pIndex) { mOutput << startstr << "" << endstr; PushTag(); - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; mOutput << startstr << ""; for( size_t a = 0; a < mesh->mNumFaces; ++a ) @@ -728,11 +735,11 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy std::string arrayId = pIdString + "-array"; - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; PushTag(); // source array - mOutput << startstr << " "; + mOutput << startstr << " "; PushTag(); if( pType == FloatType_TexCoord2 ) @@ -804,11 +811,11 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy // Writes the scene library void ColladaExporter::WriteSceneLibrary() { - std::string scene_name = mScene->mRootNode->mName.C_Str(); + const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str()); mOutput << startstr << "" << endstr; PushTag(); - mOutput << startstr << "" << endstr; + mOutput << startstr << "" << endstr; PushTag(); // start recursive write at the root node @@ -833,7 +840,8 @@ void ColladaExporter::WriteNode(aiNode* pNode) pNode->mName.Set(ss.str()); } - mOutput << startstr << "mName.data << "\" name=\"" << pNode->mName.data << "\">" << endstr; + const std::string node_name_escaped = XMLEscape(pNode->mName.data); + mOutput << startstr << "" << endstr; PushTag(); // write transformation - we can directly put the matrix there @@ -854,13 +862,13 @@ void ColladaExporter::WriteNode(aiNode* pNode) if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 ) continue; - mOutput << startstr << "mMeshes[a]) << "\">" << endstr; + mOutput << startstr << "mMeshes[a])) << "\">" << endstr; PushTag(); mOutput << startstr << "" << endstr; PushTag(); mOutput << startstr << "" << endstr; PushTag(); - mOutput << startstr << "mMaterialIndex].name << "\" />" << endstr; + mOutput << startstr << "mMaterialIndex].name) << "\" />" << endstr; PopTag(); mOutput << startstr << "" << endstr; PopTag(); diff --git a/code/XMLTools.h b/code/XMLTools.h new file mode 100644 index 000000000..103f1d815 --- /dev/null +++ b/code/XMLTools.h @@ -0,0 +1,81 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#ifndef INCLUDED_ASSIMP_XML_TOOLS_H +#define INCLUDED_ASSIMP_XML_TOOLS_H + +#include + +namespace Assimp { + // XML escape the 5 XML special characters (",',<,> and &) in |data| + // Based on http://stackoverflow.com/questions/5665231 + std::string XMLEscape(const std::string& data) { + std::string buffer; + + const size_t size = data.size(); + buffer.reserve(size + size / 8); + for(size_t i = 0; i < size; ++i) { + const char c = data[i]; + switch(c) { + case '&' : + buffer.append("&"); + break; + case '\"': + buffer.append("""); + break; + case '\'': + buffer.append("'"); + break; + case '<' : + buffer.append("<"); + break; + case '>' : + buffer.append(">"); + break; + default: + buffer.append(&c, 1); + break; + } + } + return buffer; + } +} + +#endif // INCLUDED_ASSIMP_XML_TOOLS_H diff --git a/test/models/Collada/cube_xmlspecialchars.dae b/test/models/Collada/cube_xmlspecialchars.dae new file mode 100644 index 000000000..94e1bed2d --- /dev/null +++ b/test/models/Collada/cube_xmlspecialchars.dae @@ -0,0 +1,210 @@ + + + + + alorino + Maya 7.0 | ColladaMaya v2.01 Jun 9 2006 at 16:08:19 | FCollada v1.11 + Collada Maya Export Options: bakeTransforms=0;exportPolygonMeshes=1;bakeLighting=0;isSampling=0; +curveConstrainSampling=0;exportCameraAsLookat=0; +exportLights=1;exportCameras=1;exportJointsAndSkin=1; +exportAnimations=1;exportTriangles=0;exportInvisibleNodes=0; +exportNormals=1;exportTexCoords=1;exportVertexColors=1;exportTangents=0; +exportTexTangents=0;exportConstraints=0;exportPhysics=0;exportXRefs=1; +dereferenceXRefs=0;cameraXFov=0;cameraYFov=1 + +Copyright 2006 Sony Computer Entertainment Inc. +Licensed under the SCEA Shared Source License, Version 1.0 (the +"License"); you may not use this file except in compliance with the +License. You may obtain a copy of the License at: +http://research.scea.com/scea_shared_source_license.html +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + + 2006-06-21T21:23:22Z + 2006-06-21T21:23:22Z + + Y_UP + + + + + + + 37.8493 + 1 + 10 + 1000 + + + + + + + + + 37.8501 + 1 + 0.01 + 1000 + + + + + + + + + + 1 1 1 + 1 + 0 + 0 + + + + 1.000000 + + + + + + 1 1 1 + 1 + 0 + 0 + + + + + + + + + + + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.137255 0.403922 0.870588 1 + + + 0.5 0.5 0.5 1 + + + 16 + + + 0 0 0 1 + + + 0.5 + + + 0 0 0 1 + + + 1 + + + 0 + + + + + + + + + + + -50 50 50 50 50 50 -50 -50 50 50 -50 50 -50 50 -50 50 50 -50 -50 -50 -50 50 -50 -50 + + + + + + + + + + 0 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 -1 + + + + + + + + + + + + + + + 4 4 4 4 4 4 +

0 0 2 1 3 2 1 3 0 4 1 5 5 6 4 7 6 8 7 9 3 10 2 11 0 12 4 13 6 14 2 15 3 16 7 17 5 18 1 19 5 20 7 21 6 22 4 23

+ +
+
+ + + + + -427.749 333.855 655.017 + 0 1 0 -33 + 1 0 0 -22.1954 + 0 0 1 0 + + + + -500 1000 400 + 0 0 1 0 + 0 1 0 0 + 1 0 0 0 + + + + 0 0 1 0 + 0 1 0 0 + 1 0 0 0 + + + + + + + + + + -427.749 333.855 655.017 + 0 1 0 -33 + 1 0 0 -22.1954 + 0 0 1 0 + + + + 3 4 10 + 0 0 1 0 + 0 1 0 0 + 1 0 0 0 + + + + + + + +