diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index 48e7b3483..16a0bf5ad 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -351,7 +351,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, { const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex ); ai_assert( tex < pModel->m_TextureCoord.size() ); - for ( size_t i=0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++) + for ( size_t i=0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; i++ ) { if ( pMesh->mNumUVComponents[ i ] > 0 ) { diff --git a/code/Q3BSPFileData.h b/code/Q3BSPFileData.h index 05267903f..b6c9ef48e 100644 --- a/code/Q3BSPFileData.h +++ b/code/Q3BSPFileData.h @@ -54,7 +54,7 @@ enum Q3BSPGeoType { Polygon = 1, Patch, - Mesh, + TriangleMesh, Billboard }; @@ -137,17 +137,8 @@ struct sQ3BSPLightmap } }; -struct sRenderVertex -{ - vec3f vPosition; - vec2f vTC; - vec2f vTCLightmap; -}; - struct SubPatch { - std::vector controlPoints; - std::vector vertices; std::vector indices; int lightmapID; }; diff --git a/code/Q3BSPFileImporter.cpp b/code/Q3BSPFileImporter.cpp index 9afa712e4..da5077d6a 100644 --- a/code/Q3BSPFileImporter.cpp +++ b/code/Q3BSPFileImporter.cpp @@ -40,18 +40,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssimpPCH.h" #ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER +#include #include "DefaultIOSystem.h" #include "Q3BSPFileImporter.h" #include "Q3BSPZipArchive.h" #include "Q3BSPFileParser.h" #include "Q3BSPFileData.h" -# ifdef ASSIMP_BUILD_NO_OWN_ZLIB -# include -# else -# include "../contrib/zlib/zlib.h" -# endif - +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB +# include +#else +# include "../contrib/zlib/zlib.h" +#endif #include "../include/aiTypes.h" #include "../include/aiMesh.h" @@ -65,6 +65,7 @@ using namespace Q3BSP; static const std::string Q3BSPExtention = "pk3"; // ------------------------------------------------------------------------------------------------ +// Local fnction to create a material keyname. static void createKey( int id1, int id2, std::string &rKey ) { std::stringstream str; @@ -73,6 +74,7 @@ static void createKey( int id1, int id2, std::string &rKey ) } // ------------------------------------------------------------------------------------------------ +// Local function to extract the texture ids from a material keyname. static void extractIds( const std::string &rKey, int &rId1, int &rId2 ) { rId1 = -1; @@ -91,19 +93,38 @@ static void extractIds( const std::string &rKey, int &rId1, int &rId2 ) } // ------------------------------------------------------------------------------------------------ +// Constructor. Q3BSPFileImporter::Q3BSPFileImporter() : - m_pCurrentMesh( NULL ) + m_pCurrentMesh( NULL ), + m_pCurrentFace( NULL ), + m_MaterialLookupMap() { // empty } // ------------------------------------------------------------------------------------------------ +// Destructor. Q3BSPFileImporter::~Q3BSPFileImporter() { - // empty + // For lint + m_pCurrentMesh = NULL; + m_pCurrentFace = NULL; + + // Clear face-to-material map + for ( FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); + ++it ) + { + std::vector *pCurFaceArray = (*it).second; + if ( NULL != pCurFaceArray ) + { + delete pCurFaceArray; + } + } + m_MaterialLookupMap.clear(); } // ------------------------------------------------------------------------------------------------ +// Returns true, if the loader can read this. bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* pIOHandler, bool checkSig ) const { bool isBSPData = false; @@ -114,7 +135,8 @@ bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* pIOHandler, } // ------------------------------------------------------------------------------------------------ -void Q3BSPFileImporter::GetExtensionList(std::set& extensions) +// Adds extensions. +void Q3BSPFileImporter::GetExtensionList( std::set& extensions ) { extensions.insert( Q3BSPExtention ); } @@ -148,6 +170,7 @@ void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene } // ------------------------------------------------------------------------------------------------ +// Separates the map name from the import name. void Q3BSPFileImporter::separateMapName( const std::string &rImportName, std::string &rArchiveName, std::string &rMapName ) { @@ -168,6 +191,7 @@ void Q3BSPFileImporter::separateMapName( const std::string &rImportName, std::st } // ------------------------------------------------------------------------------------------------ +// Returns the first map in the map archive. bool Q3BSPFileImporter::findFirstMapInArchive( Q3BSPZipArchive &rArchive, std::string &rMapName ) { rMapName = ""; @@ -190,10 +214,12 @@ bool Q3BSPFileImporter::findFirstMapInArchive( Q3BSPZipArchive &rArchive, std::s } } } + return false; } // ------------------------------------------------------------------------------------------------ +// Creates the assimp specific data. void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene ) { if ( NULL == pModel || NULL == pScene ) @@ -205,15 +231,20 @@ void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, a pScene->mRootNode->mName.Set( pModel->m_ModelName ); } + // Create the face to material relation map createMaterialMap( pModel ); + // Create all nodes CreateNodes( pModel, pScene, pScene->mRootNode ); - + + // Create the assigned materials createMaterials( pModel, pScene ); } // ------------------------------------------------------------------------------------------------ -void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiNode *pParent ) +// Creates all assimp nodes. +void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, + aiNode *pParent ) { ai_assert( NULL != pModel ); if ( NULL == pModel ) @@ -244,20 +275,17 @@ void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* p } pScene->mNumMeshes = MeshArray.size(); - pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ]; - for ( size_t i=0; imNumMeshes > 0 ) { - aiMesh *pMesh = MeshArray[ i ]; - for ( size_t j=0; jmNumFaces; j++ ) + pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ]; + for ( size_t i = 0; i < MeshArray.size(); i++ ) { - aiFace *face = &pMesh->mFaces[j]; - if ( NULL == face->mIndices ) + aiMesh *pMesh = MeshArray[ i ]; + if ( NULL != pMesh ) { - printf("error\n"); + pScene->mMeshes[ i ] = pMesh; } - ai_assert( NULL != face->mIndices ); } - pScene->mMeshes[ i ] = pMesh; } pParent->mNumChildren = MeshArray.size(); @@ -272,7 +300,7 @@ void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* p } // ------------------------------------------------------------------------------------------------ -// +// Creates the topology. aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int materialIdx, std::vector &rArray, @@ -286,8 +314,12 @@ aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel, if ( 0 == numFaces ) return NULL; - pMesh->mFaces = new aiFace[ numFaces ]; - pMesh->mNumFaces = numFaces; + size_t numTriangles = countTriangles( rArray ); + //pMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; + + pMesh->mFaces = new aiFace[ numTriangles ]; + pMesh->mNumFaces = numTriangles; + pMesh->mNumVertices = numVerts; pMesh->mVertices = new aiVector3D[ numVerts ]; pMesh->mNormals = new aiVector3D[ numVerts ]; @@ -297,22 +329,24 @@ aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int faceIdx = 0; unsigned int vertIdx = 0; - aiVector3D *pVec3( NULL ); - aiVector3D normal; - for ( std::vector::const_iterator it = rArray.begin(); it != rArray.end(); - ++it ) + pMesh->mNumUVComponents[ 0 ] = 2; + pMesh->mNumUVComponents[ 1 ] = 2; + for ( std::vector::const_iterator it = rArray.begin(); it != rArray.end(); ++it ) { Q3BSP::sQ3BSPFace *pQ3BSPFace = *it; ai_assert( NULL != pQ3BSPFace ); if ( NULL == pQ3BSPFace ) - continue; - if ( pQ3BSPFace->iNumOfFaceVerts == 0 ) - continue; - - if ( pQ3BSPFace->iType == 1 || pQ3BSPFace->iType == 3 ) { - createTriangleTopology( pModel, pQ3BSPFace, pMesh, faceIdx, vertIdx ); - } + continue; + } + + if ( pQ3BSPFace->iNumOfFaceVerts > 0 ) + { + if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh ) + { + createTriangleTopology( pModel, pQ3BSPFace, pMesh, faceIdx, vertIdx ); + } + } } aiNode *pNode = new aiNode; @@ -323,6 +357,7 @@ aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel, } // ------------------------------------------------------------------------------------------------ +// Creates the triangle topology from a face array. void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, Q3BSP::sQ3BSPFace *pQ3BSPFace, aiMesh* pMesh, @@ -330,39 +365,58 @@ void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int &rVertIdx ) { ai_assert( rFaceIdx < pMesh->mNumFaces ); - aiFace *pFace = &pMesh->mFaces[ rFaceIdx ]; - ai_assert( NULL != pFace ); - rFaceIdx++; - - pFace->mNumIndices = pQ3BSPFace->iNumOfFaceVerts; - pFace->mIndices = new unsigned int[ pFace->mNumIndices ]; - aiVector3D normal; - normal.Set( pQ3BSPFace->vNormal.x, pQ3BSPFace->vNormal.y, pQ3BSPFace->vNormal.z ); - for ( size_t i = 0; i < pFace->mNumIndices; ++i ) + m_pCurrentFace = getNextFace( pMesh, rFaceIdx ); + ai_assert( NULL != m_pCurrentFace ); + if ( NULL == m_pCurrentFace ) + return; + + m_pCurrentFace->mNumIndices = 3; + m_pCurrentFace->mIndices = new unsigned int[ m_pCurrentFace->mNumIndices ]; + + size_t idx = 0; + for ( size_t i = 0; i < pQ3BSPFace->iNumOfFaceVerts; i++ ) { const size_t index = pQ3BSPFace->iVertexIndex + pModel->m_Indices[ pQ3BSPFace->iFaceVertexIndex + i ]; - ai_assert( index < pModel->m_Vertices.size() ); + if ( index >= pModel->m_Vertices.size() ) + { + continue; + } + sQ3BSPVertex *pVertex = pModel->m_Vertices[ index ]; ai_assert( NULL != pVertex ); if ( NULL == pVertex ) + { continue; + } pMesh->mVertices[ rVertIdx ].Set( pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z ); - pMesh->mNormals[ rVertIdx ].Set( normal.x, normal.y, normal.z ); + pMesh->mNormals[ rVertIdx ].Set( pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z ); - pMesh->mNumUVComponents[ 0 ] = 2; pMesh->mTextureCoords[ 0 ][ rVertIdx ].Set( pVertex->vTexCoord.x, pVertex->vTexCoord.y, 0.0f ); - - pMesh->mNumUVComponents[ 1 ] = 2; pMesh->mTextureCoords[ 1 ][ rVertIdx ].Set( pVertex->vLightmap.x, pVertex->vLightmap.y, 0.0f ); - pFace->mIndices[ i ] = rVertIdx; + + m_pCurrentFace->mIndices[ idx ] = rVertIdx; rVertIdx++; + + idx++; + if ( idx > 2 ) + { + idx = 0; + m_pCurrentFace = getNextFace( pMesh, rFaceIdx ); + if ( NULL != m_pCurrentFace ) + { + m_pCurrentFace->mNumIndices = 3; + m_pCurrentFace->mIndices = new unsigned int[ 3 ]; + } + } } + rFaceIdx--; } // ------------------------------------------------------------------------------------------------ +// Creates all referenced materials. void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene ) { if ( m_MaterialLookupMap.empty() ) @@ -391,12 +445,14 @@ void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScen sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ]; if ( NULL != pTexture ) { - aiString textureName( pTexture->strName ); + std::string texName( pTexture->strName ); + texName += ".jpg"; + aiString textureName( texName.c_str() ); pMatHelper->AddProperty( &textureName, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) ); } -/* if ( 0 != pCurrentMaterial->textureSpecular.length ) - mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0));*/ + /*if ( 0 != pCurrentMaterial->textureSpecular.length ) + mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0));*/ } @@ -406,6 +462,7 @@ void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScen } // ------------------------------------------------------------------------------------------------ +// Counts the number of referenced verices size_t Q3BSPFileImporter::countData( const std::vector &rArray ) const { size_t numVerts = 0; @@ -413,7 +470,7 @@ size_t Q3BSPFileImporter::countData( const std::vector &rArray ) co ++it ) { sQ3BSPFace *pQ3BSPFace = *it; - if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == Mesh ) + if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh ) { Q3BSP::sQ3BSPFace *pQ3BSPFace = *it; ai_assert( NULL != pQ3BSPFace ); @@ -425,6 +482,7 @@ size_t Q3BSPFileImporter::countData( const std::vector &rArray ) co } // ------------------------------------------------------------------------------------------------ +// Counts the faces with vertices. size_t Q3BSPFileImporter::countFaces( const std::vector &rArray ) const { size_t numFaces = 0; @@ -432,7 +490,7 @@ size_t Q3BSPFileImporter::countFaces( const std::vector &rAr ++it ) { Q3BSP::sQ3BSPFace *pQ3BSPFace = *it; - if ( pQ3BSPFace->iNumOfFaceVerts > 0) + if ( pQ3BSPFace->iNumOfFaceVerts > 0 ) { numFaces++; } @@ -442,35 +500,71 @@ size_t Q3BSPFileImporter::countFaces( const std::vector &rAr } // ------------------------------------------------------------------------------------------------ -void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel) +// Counts the number of triangles in a Q3-facearray. +size_t Q3BSPFileImporter::countTriangles( const std::vector &rArray ) const +{ + size_t numTriangles = 0; + for ( std::vector::const_iterator it = rArray.begin(); it != rArray.end(); + ++it ) + { + const Q3BSP::sQ3BSPFace *pQ3BSPFace = *it; + if ( NULL != pQ3BSPFace ) + { + numTriangles += pQ3BSPFace->iNumOfFaceVerts / 3; + } + } + + return numTriangles; +} + +// ------------------------------------------------------------------------------------------------ +// Creates the faces-to-material map. +void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel ) { std::string key( "" ); std::vector *pCurFaceArray = NULL; - for ( size_t idx=0; idx < pModel->m_Faces.size(); idx++ ) + for ( size_t idx = 0; idx < pModel->m_Faces.size(); idx++ ) { Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[ idx ]; - int texId = pQ3BSPFace->iTextureID; - int lightMapId = pQ3BSPFace->iLightmapID; + const int texId = pQ3BSPFace->iTextureID; + const int lightMapId = pQ3BSPFace->iLightmapID; createKey( texId, lightMapId, key ); FaceMapIt it = m_MaterialLookupMap.find( key ); if ( m_MaterialLookupMap.end() == it ) { - std::vector *pArray = new std::vector; - pArray->push_back( pQ3BSPFace ); - m_MaterialLookupMap[ key ] = pArray; + pCurFaceArray = new std::vector; + m_MaterialLookupMap[ key ] = pCurFaceArray; } else { - std::vector *pArray = (*it).second; - ai_assert( NULL != pArray ); - if ( NULL != pArray ) - { - pArray->push_back( pQ3BSPFace ); - } + pCurFaceArray = (*it).second; + } + ai_assert( NULL != pCurFaceArray ); + if ( NULL != pCurFaceArray ) + { + pCurFaceArray->push_back( pQ3BSPFace ); } } } +// ------------------------------------------------------------------------------------------------ +// Returns the next face. +aiFace *Q3BSPFileImporter::getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx ) +{ + aiFace *pFace = NULL; + if ( rFaceIdx < pMesh->mNumFaces ) + { + pFace = &pMesh->mFaces[ rFaceIdx ]; + rFaceIdx++; + } + else + { + pFace = NULL; + } + + return pFace; +} + // ------------------------------------------------------------------------------------------------ } // Namespace Assimp diff --git a/code/Q3BSPFileImporter.h b/code/Q3BSPFileImporter.h index a3663dd3e..a68a8366f 100644 --- a/code/Q3BSPFileImporter.h +++ b/code/Q3BSPFileImporter.h @@ -89,10 +89,13 @@ private: void createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene ); size_t countData( const std::vector &rArray ) const; size_t countFaces( const std::vector &rArray ) const; + size_t countTriangles( const std::vector &rArray ) const; void createMaterialMap( const Q3BSP::Q3BSPModel *pModel); + aiFace *getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx ); private: aiMesh *m_pCurrentMesh; + aiFace *m_pCurrentFace; FaceMap m_MaterialLookupMap; }; diff --git a/code/Q3BSPFileParser.cpp b/code/Q3BSPFileParser.cpp index 558055284..7d27abfec 100644 --- a/code/Q3BSPFileParser.cpp +++ b/code/Q3BSPFileParser.cpp @@ -250,7 +250,6 @@ void Q3BSPFileParser::getLightMaps() sQ3BSPLightmap *pLightmap = new sQ3BSPLightmap; memcpy( pLightmap, &m_Data[ Offset ], sizeof( sQ3BSPLightmap ) ); Offset += sizeof( sQ3BSPLightmap ); - //ChangeGamma( (unsigned char*) &pLightmap->bLMapData[ 0 ], sizeof( sQ3BSPLightmap ), 3.0f); m_pModel->m_Lightmaps[ idx ] = pLightmap; } } diff --git a/code/aiAssert.cpp b/code/aiAssert.cpp index 487345538..5b0eda509 100644 --- a/code/aiAssert.cpp +++ b/code/aiAssert.cpp @@ -1,12 +1,49 @@ +/* +Open Asset Import Library (ASSIMP) +---------------------------------------------------------------------- +Copyright (c) 2006-2008, ASSIMP Development 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 Development 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 "../include/aiAssert.h" #ifdef _WIN32 #ifndef __GNUC__ # include "crtdbg.h" -#endif //ndef gcc -#endif +#endif // ndef gcc +#endif // _WIN32 // Set a breakpoint using win32, else line, file and message will be returned and progam ends with // errrocode = 1 diff --git a/samples/SimpleOpenGL/Sample_SimpleOpenGL.c b/samples/SimpleOpenGL/Sample_SimpleOpenGL.c index 9bce7dc89..a9512735c 100644 --- a/samples/SimpleOpenGL/Sample_SimpleOpenGL.c +++ b/samples/SimpleOpenGL/Sample_SimpleOpenGL.c @@ -76,6 +76,7 @@ void get_bounding_box_for_node (const struct aiNode* nd, } // ---------------------------------------------------------------------------- + void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max) { struct aiMatrix4x4 trafo; @@ -96,6 +97,8 @@ 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; diff --git a/test/models/PK3/SGDTT3.pk3 b/test/models/PK3/SGDTT3.pk3 new file mode 100644 index 000000000..0d997e5d9 Binary files /dev/null and b/test/models/PK3/SGDTT3.pk3 differ