From ad5c05ae471f0867c9b8efce649a65894c9a3494 Mon Sep 17 00:00:00 2001 From: Tai Chi Minh Ralph Eastwood Date: Fri, 5 Apr 2013 13:06:42 +0100 Subject: [PATCH] - allow loading Quake3 BSPs directly without needing the zip archive --- code/Q3BSPFileImporter.cpp | 105 +++++++------------------------------ code/Q3BSPFileImporter.h | 10 ++-- code/Q3BSPFileParser.cpp | 13 +++-- code/Q3BSPFileParser.h | 5 +- 4 files changed, 31 insertions(+), 102 deletions(-) diff --git a/code/Q3BSPFileImporter.cpp b/code/Q3BSPFileImporter.cpp index 6ea67305a..c6d211f5b 100644 --- a/code/Q3BSPFileImporter.cpp +++ b/code/Q3BSPFileImporter.cpp @@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //#include #include "DefaultIOSystem.h" #include "Q3BSPFileImporter.h" -#include "Q3BSPZipArchive.h" #include "Q3BSPFileParser.h" #include "Q3BSPFileData.h" @@ -170,10 +169,10 @@ Q3BSPFileImporter::~Q3BSPFileImporter() // ------------------------------------------------------------------------------------------------ // Returns true, if the loader can read this. -bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const +bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* pIOHandler, bool checkSig ) const { if(!checkSig) { - return SimpleExtensionCheck( rFile, "pk3" ); + return SimpleExtensionCheck( rFile, "bsp" ); } // TODO perhaps add keyword based detection return false; @@ -188,86 +187,20 @@ const aiImporterDesc* Q3BSPFileImporter::GetInfo () const // ------------------------------------------------------------------------------------------------ // Import method. -void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* /*pIOHandler*/) +void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* pIOHandler) { - Q3BSPZipArchive Archive( rFile ); - if ( !Archive.isOpen() ) - { - throw DeadlyImportError( "Failed to open file " + rFile + "." ); - } - - std::string archiveName( "" ), mapName( "" ); - separateMapName( rFile, archiveName, mapName ); - - if ( mapName.empty() ) - { - if ( !findFirstMapInArchive( Archive, mapName ) ) - { - return; - } - } - - Q3BSPFileParser fileParser( mapName, &Archive ); + Q3BSPFileParser fileParser( rFile, pIOHandler ); Q3BSPModel *pBSPModel = fileParser.getModel(); if ( NULL != pBSPModel ) { - CreateDataFromImport( pBSPModel, pScene, &Archive ); + CreateDataFromImport( pBSPModel, pScene, pIOHandler ); } } -// ------------------------------------------------------------------------------------------------ -// Separates the map name from the import name. -void Q3BSPFileImporter::separateMapName( const std::string &rImportName, std::string &rArchiveName, - std::string &rMapName ) -{ - rArchiveName = ""; - rMapName = ""; - if ( rImportName.empty() ) - return; - - std::string::size_type pos = rImportName.rfind( "," ); - if ( std::string::npos == pos ) - { - rArchiveName = rImportName; - return; - } - - rArchiveName = rImportName.substr( 0, pos ); - rMapName = rImportName.substr( pos, rImportName.size() - pos - 1 ); -} - -// ------------------------------------------------------------------------------------------------ -// Returns the first map in the map archive. -bool Q3BSPFileImporter::findFirstMapInArchive( Q3BSPZipArchive &rArchive, std::string &rMapName ) -{ - rMapName = ""; - std::vector fileList; - rArchive.getFileList( fileList ); - if ( fileList.empty() ) - return false; - - for ( std::vector::iterator it = fileList.begin(); it != fileList.end(); - ++it ) - { - std::string::size_type pos = (*it).find( "maps/" ); - if ( std::string::npos != pos ) - { - std::string::size_type extPos = (*it).find( ".bsp" ); - if ( std::string::npos != extPos ) - { - rMapName = *it; - return true; - } - } - } - - return false; -} - // ------------------------------------------------------------------------------------------------ // Creates the assimp specific data. void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, - Q3BSPZipArchive *pArchive ) + IOSystem* pIOHandler ) { if ( NULL == pModel || NULL == pScene ) return; @@ -285,7 +218,7 @@ void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, a CreateNodes( pModel, pScene, pScene->mRootNode ); // Create the assigned materials - createMaterials( pModel, pScene, pArchive ); + createMaterials( pModel, pScene, pIOHandler ); } // ------------------------------------------------------------------------------------------------ @@ -473,7 +406,7 @@ void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, // ------------------------------------------------------------------------------------------------ // Creates all referenced materials. void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, - Q3BSPZipArchive *pArchive ) + IOSystem *pIOHandler ) { if ( m_MaterialLookupMap.empty() ) { @@ -497,7 +430,7 @@ void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScen pMatHelper->AddProperty( &aiMatName, AI_MATKEY_NAME ); extractIds( matName, textureId, lightmapId ); - + // Adding the texture if ( -1 != textureId ) { @@ -508,8 +441,8 @@ void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScen tmp += pTexture->strName; tmp += ".jpg"; normalizePathName( tmp, texName ); - - if ( !importTextureFromArchive( pModel, pArchive, pScene, pMatHelper, textureId ) ) + + if ( !importTextureFromArchive( pModel, pIOHandler, pScene, pMatHelper, textureId ) ) { } } @@ -634,14 +567,14 @@ aiFace *Q3BSPFileImporter::getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx ) // ------------------------------------------------------------------------------------------------ // Imports a texture file. bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel, - Q3BSP::Q3BSPZipArchive *pArchive, aiScene* /*pScene*/, + IOSystem *pIOHandler, aiScene* /*pScene*/, aiMaterial *pMatHelper, int textureId ) { std::vector supportedExtensions; supportedExtensions.push_back( ".jpg" ); supportedExtensions.push_back( ".png" ); supportedExtensions.push_back( ".tga" ); - if ( NULL == pArchive || NULL == pArchive || NULL == pMatHelper ) + if ( NULL == pIOHandler || NULL == pMatHelper ) { return false; } @@ -657,9 +590,9 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode return false; std::string textureName, ext; - if ( expandFile( pArchive, pTexture->strName, supportedExtensions, textureName, ext ) ) + if ( expandFile( pIOHandler, pTexture->strName, supportedExtensions, textureName, ext ) ) { - IOStream *pTextureStream = pArchive->Open( textureName.c_str() ); + IOStream *pTextureStream = pIOHandler->Open( textureName.c_str() ); if ( NULL != pTextureStream ) { size_t texSize = pTextureStream->FileSize(); @@ -681,7 +614,7 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode name.data[ 0 ] = '*'; name.length = 1 + ASSIMP_itoa10( name.data + 1, MAXLEN-1, mTextures.size() ); - pArchive->Close( pTextureStream ); + pIOHandler->Close( pTextureStream ); pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) ); mTextures.push_back( pTexture ); @@ -750,11 +683,11 @@ bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene // ------------------------------------------------------------------------------------------------ // Will search for a supported extension. -bool Q3BSPFileImporter::expandFile( Q3BSP::Q3BSPZipArchive *pArchive, const std::string &rFilename, +bool Q3BSPFileImporter::expandFile( IOSystem *pIOHandler, const std::string &rFilename, const std::vector &rExtList, std::string &rFile, std::string &rExt ) { - ai_assert( NULL != pArchive ); + ai_assert( NULL != pIOHandler ); ai_assert( !rFilename.empty() ); if ( rExtList.empty() ) @@ -768,7 +701,7 @@ bool Q3BSPFileImporter::expandFile( Q3BSP::Q3BSPZipArchive *pArchive, const std for ( std::vector::const_iterator it = rExtList.begin(); it != rExtList.end(); ++it ) { const std::string textureName = rFilename + *it; - if ( pArchive->Exists( textureName.c_str() ) ) + if ( pIOHandler->Exists( textureName.c_str() ) ) { rExt = *it; rFile = textureName; diff --git a/code/Q3BSPFileImporter.h b/code/Q3BSPFileImporter.h index 6d0e8287a..d9f01aae8 100644 --- a/code/Q3BSPFileImporter.h +++ b/code/Q3BSPFileImporter.h @@ -49,7 +49,6 @@ namespace Assimp namespace Q3BSP { -class Q3BSPZipArchive; struct Q3BSPModel; struct sQ3BSPFace; @@ -81,24 +80,23 @@ private: const aiImporterDesc* GetInfo () const; void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); void separateMapName( const std::string &rImportName, std::string &rArchiveName, std::string &rMapName ); - bool findFirstMapInArchive( Q3BSP::Q3BSPZipArchive &rArchive, std::string &rMapName ); - void CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive ); + void CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, IOSystem *pIOHandler ); void CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiNode *pParent ); aiNode *CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int materialIdx, std::vector &rArray, aiMesh* pMesh ); void createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, Q3BSP::sQ3BSPFace *pQ3BSPFace, aiMesh* pMesh, unsigned int &rFaceIdx, unsigned int &rVertIdx ); - void createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive ); + void createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, IOSystem *pIOHandler ); 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 ); - bool importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel, Q3BSP::Q3BSPZipArchive *pArchive, aiScene* pScene, + bool importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel, IOSystem *pIOHandler, aiScene* pScene, aiMaterial *pMatHelper, int textureId ); bool importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiMaterial *pMatHelper, int lightmapId ); bool importEntities( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene ); - bool expandFile( Q3BSP::Q3BSPZipArchive *pArchive, const std::string &rFilename, const std::vector &rExtList, + bool expandFile( IOSystem *pIOHandler, const std::string &rFilename, const std::vector &rExtList, std::string &rFile, std::string &rExt ); private: diff --git a/code/Q3BSPFileParser.cpp b/code/Q3BSPFileParser.cpp index 600a20f2b..acdcdeb85 100644 --- a/code/Q3BSPFileParser.cpp +++ b/code/Q3BSPFileParser.cpp @@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Q3BSPFileParser.h" #include "DefaultIOSystem.h" #include "Q3BSPFileData.h" -#include "Q3BSPZipArchive.h" #include namespace Assimp @@ -53,13 +52,13 @@ namespace Assimp using namespace Q3BSP; // ------------------------------------------------------------------------------------------------ -Q3BSPFileParser::Q3BSPFileParser( const std::string &rMapName, Q3BSPZipArchive *pZipArchive ) : +Q3BSPFileParser::Q3BSPFileParser( const std::string &rMapName, IOSystem *pIOHandler ) : m_sOffset( 0 ), m_Data(), m_pModel( NULL ), - m_pZipArchive( pZipArchive ) + m_pIOHandler( pIOHandler ) { - ai_assert( NULL != m_pZipArchive ); + ai_assert( NULL != m_pIOHandler ); ai_assert( !rMapName.empty() ); if ( !readData( rMapName ) ) @@ -90,10 +89,10 @@ Q3BSP::Q3BSPModel *Q3BSPFileParser::getModel() const // ------------------------------------------------------------------------------------------------ bool Q3BSPFileParser::readData( const std::string &rMapName ) { - if ( !m_pZipArchive->Exists( rMapName.c_str() ) ) + if ( !m_pIOHandler->Exists( rMapName.c_str() ) ) return false; - IOStream *pMapFile = m_pZipArchive->Open( rMapName.c_str() ); + IOStream *pMapFile = m_pIOHandler->Open( rMapName.c_str() ); if ( NULL == pMapFile ) return false; @@ -106,7 +105,7 @@ bool Q3BSPFileParser::readData( const std::string &rMapName ) m_Data.clear(); return false; } - m_pZipArchive->Close( pMapFile ); + m_pIOHandler->Close( pMapFile ); return true; } diff --git a/code/Q3BSPFileParser.h b/code/Q3BSPFileParser.h index d10a9c0d4..fb1c17277 100644 --- a/code/Q3BSPFileParser.h +++ b/code/Q3BSPFileParser.h @@ -49,7 +49,6 @@ namespace Assimp namespace Q3BSP { -class Q3BSPZipArchive; struct Q3BSPModel; class ZipFile; @@ -60,7 +59,7 @@ class ZipFile; class Q3BSPFileParser { public: - Q3BSPFileParser( const std::string &rMapName, Q3BSP::Q3BSPZipArchive *pZipArchive ); + Q3BSPFileParser( const std::string &rMapName, IOSystem *pIOHandler ); ~Q3BSPFileParser(); Q3BSP::Q3BSPModel *getModel() const; @@ -81,7 +80,7 @@ private: size_t m_sOffset; std::vector m_Data; Q3BSP::Q3BSPModel *m_pModel; - Q3BSP::Q3BSPZipArchive *m_pZipArchive; + IOSystem *m_pIOHandler; }; } // Namespace Assimp