- allow loading Quake3 BSPs directly without needing the zip archive

pull/25/head
Tai Chi Minh Ralph Eastwood 2013-04-05 13:06:42 +01:00
parent 4277413052
commit ad5c05ae47
4 changed files with 31 additions and 102 deletions

View File

@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//#include <windows.h>
#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<std::string> fileList;
rArchive.getFileList( fileList );
if ( fileList.empty() )
return false;
for ( std::vector<std::string>::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() )
{
@ -509,7 +442,7 @@ void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScen
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<std::string> 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<std::string> &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<std::string>::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;

View File

@ -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<Q3BSP::sQ3BSPFace*> &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<Q3BSP::sQ3BSPFace*> &rArray ) const;
size_t countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const;
size_t countTriangles( const std::vector<Q3BSP::sQ3BSPFace*> &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<std::string> &rExtList,
bool expandFile( IOSystem *pIOHandler, const std::string &rFilename, const std::vector<std::string> &rExtList,
std::string &rFile, std::string &rExt );
private:

View File

@ -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 <vector>
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;
}

View File

@ -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<char> m_Data;
Q3BSP::Q3BSPModel *m_pModel;
Q3BSP::Q3BSPZipArchive *m_pZipArchive;
IOSystem *m_pIOHandler;
};
} // Namespace Assimp