- UPDATE : Q3BSPLoader now imports topology of a quake-level. Known issues: It seems, that faces a still missing.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@771 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
kimmi
2010-07-08 21:25:48 +00:00
parent edb2fca8d6
commit 7f2f5e7555
5 changed files with 278 additions and 21 deletions

View File

@@ -1,6 +1,6 @@
/*
Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved.
@@ -35,7 +35,7 @@ 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_Q3BSP_IMPORTER
@@ -44,7 +44,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Q3BSPFileImporter.h"
#include "Q3BSPZipArchive.h"
#include "Q3BSPFileParser.h"
#include "Q3BSPFileData.h"
#include "../contrib/zlib/zlib.h"
#include "../include/aiTypes.h"
#include "../include/aiMesh.h"
#include <vector>
namespace Assimp
@@ -53,7 +56,16 @@ namespace Assimp
using namespace Q3BSP;
// ------------------------------------------------------------------------------------------------
Q3BSPFileImporter::Q3BSPFileImporter()
static void createKey( int id1, int id2, std::string &rKey )
{
std::stringstream str;
str << id1 << "." << id2;
rKey = str.str();
}
// ------------------------------------------------------------------------------------------------
Q3BSPFileImporter::Q3BSPFileImporter() :
m_pCurrentMesh( NULL )
{
}
@@ -75,7 +87,7 @@ bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* pIOHandler,
// ------------------------------------------------------------------------------------------------
void Q3BSPFileImporter::GetExtensionList(std::set<std::string>& extensions)
{
extensions.insert("pk3");
extensions.insert( "pk3" );
}
// ------------------------------------------------------------------------------------------------
@@ -102,6 +114,7 @@ void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene
Q3BSPModel *pBSPModel = fileParser.getModel();
if ( NULL != pBSPModel )
{
CreateDataFromImport( pBSPModel, pScene );
}
}
@@ -151,6 +164,228 @@ bool Q3BSPFileImporter::findFirstMapInArchive( Q3BSPZipArchive &rArchive, std::s
return false;
}
// ------------------------------------------------------------------------------------------------
void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene )
{
if ( NULL == pModel || NULL == pScene )
return;
pScene->mRootNode = new aiNode;
if ( !pModel->m_ModelName.empty() )
{
pScene->mRootNode->mName.Set( pModel->m_ModelName );
}
CreateNodes( pModel, pScene, pScene->mRootNode );
}
// ------------------------------------------------------------------------------------------------
void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiNode *pParent )
{
ai_assert( NULL != pModel );
if ( NULL == pModel )
return;
FaceMap matLookupTable;
std::string key( "" );
std::vector<sQ3BSPFace*> *pCurFaceArray = NULL;
FaceMap lookupMap;
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;
createKey( texId, lightMapId, key );
FaceMapIt it = lookupMap.find( key );
if ( lookupMap.end() == it)
{
std::vector<Q3BSP::sQ3BSPFace*> *pArray = new std::vector<Q3BSP::sQ3BSPFace*>;
pArray->push_back( pQ3BSPFace );
lookupMap[ key ] = pArray;
}
else
{
std::vector<Q3BSP::sQ3BSPFace*> *pArray = (*it).second;
ai_assert( NULL != pArray );
if ( NULL != pArray )
{
pArray->push_back( pQ3BSPFace );
}
}
}
std::vector<aiMesh*> MeshArray;
std::vector<aiNode*> NodeArray;
for ( FaceMapIt it = lookupMap.begin(); it != lookupMap.end(); ++it )
{
std::vector<Q3BSP::sQ3BSPFace*> *pArray = (*it).second;
size_t numVerts = countData( *pArray );
if ( 0 != numVerts )
{
aiMesh* pMesh = new aiMesh;
aiNode *pNode = CreateTopology( pModel, *pArray, pMesh );
if ( NULL != pNode )
{
NodeArray.push_back( pNode );
MeshArray.push_back( pMesh );
}
else
{
delete pMesh;
}
}
}
pScene->mNumMeshes = MeshArray.size();
pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
for ( size_t i=0; i<MeshArray.size(); ++i )
{
aiMesh *pMesh = MeshArray[ i ];
for ( size_t j=0; j<pMesh->mNumFaces; j++ )
{
aiFace *face = &pMesh->mFaces[j];
if ( NULL == face->mIndices )
{
printf("error\n");
}
ai_assert( NULL != face->mIndices );
}
pScene->mMeshes[ i ] = pMesh;
}
pParent->mNumChildren = MeshArray.size();
pParent->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren ];
for ( size_t i=0; i<NodeArray.size(); i++ )
{
aiNode *pNode = NodeArray[ i ];
pNode->mParent = pParent;
pParent->mChildren[ i ] = pNode;
pParent->mChildren[ i ]->mMeshes[ 0 ] = i;
}
}
// ------------------------------------------------------------------------------------------------
aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel,
std::vector<sQ3BSPFace*> &rArray, aiMesh* pMesh )
{
size_t numVerts = countData( rArray );
if ( 0 == numVerts )
return NULL;
size_t numFaces = countFaces( rArray );
if ( 0 == numFaces )
return NULL;
pMesh->mFaces = new aiFace[ numFaces ];
pMesh->mNumFaces = numFaces;
pMesh->mNumVertices = numVerts;
pMesh->mVertices = new aiVector3D[ numVerts ];
pMesh->mNormals = new aiVector3D[ numVerts ];
pMesh->mTextureCoords[ 0 ] = new aiVector3D[ numVerts ];
pMesh->mTextureCoords[ 1 ] = new aiVector3D[ numVerts ];
unsigned int faceIdx = 0;
unsigned int vertIdx = 0;
aiVector3D *pVec3( NULL );
aiVector3D normal;
for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end();
++it )
{
Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
ai_assert( NULL != pQ3BSPFace );
if ( pQ3BSPFace->iNumOfMeshVerts == 0 )
{
continue;
}
if ( pQ3BSPFace->iType == 1 || pQ3BSPFace->iType == 3 )
{
createTriangleTopology( pModel, pQ3BSPFace, pMesh, faceIdx, vertIdx );
}
}
aiNode *pNode = new aiNode;
pNode->mNumMeshes = 1;
pNode->mMeshes = new unsigned int[ 1 ];
return pNode;
}
// ------------------------------------------------------------------------------------------------
void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel,
Q3BSP::sQ3BSPFace *pQ3BSPFace,
aiMesh* pMesh, unsigned int &rFaceIdx,
unsigned int &rVertIdx )
{
ai_assert( faceIdx < pMesh->mNumFaces );
aiFace *pFace = &pMesh->mFaces[ rFaceIdx ];
ai_assert( NULL != pFace );
rFaceIdx++;
pFace->mNumIndices = pQ3BSPFace->iNumOfMeshVerts;
pFace->mIndices = new unsigned int[ pFace->mNumIndices ];
aiVector3D normal;
normal.Set( pQ3BSPFace->vNormal.x, pQ3BSPFace->vNormal.y, pQ3BSPFace->vNormal.z );
for ( int i = 0; i < pQ3BSPFace->iNumOfMeshVerts; ++i )
{
size_t idx = pModel->m_Indices[ pQ3BSPFace->iMeshVertexIndex + i ];;
const unsigned int index = pQ3BSPFace->iVertexIndex + pModel->m_Indices[idx];
ai_assert( index < pModel->m_Vertices.size() );
sQ3BSPVertex *pVertex = pModel->m_Vertices[ index ];
ai_assert( NULL != pVertex );
pMesh->mVertices[ rVertIdx ].Set( pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z );
pMesh->mNormals[ rVertIdx ].Set( normal.x, normal.y, normal.z );
pMesh->mTextureCoords[ 0 ][ rVertIdx ].Set( pVertex->vTexCoord.x, pVertex->vTexCoord.y, 0.0f );
pMesh->mTextureCoords[ 1 ][ rVertIdx ].Set( pVertex->vLightmap.x, pVertex->vLightmap.y, 0.0f );
pFace->mIndices[ i ] = rVertIdx;
rVertIdx++;
}
}
// ------------------------------------------------------------------------------------------------
void Q3BSPFileImporter::createMaterials()
{
// TODO
}
// ------------------------------------------------------------------------------------------------
size_t Q3BSPFileImporter::countData( const std::vector<sQ3BSPFace*> &rArray ) const
{
size_t numVerts = 0;
for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end();
++it )
{
sQ3BSPFace *pQ3BSPFace = *it;
if ( pQ3BSPFace->iType == 1 || pQ3BSPFace->iType == 3 )
{
Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
ai_assert( NULL != pQ3BSPFace );
numVerts += pQ3BSPFace->iNumOfMeshVerts;
}
}
return numVerts;
}
// ------------------------------------------------------------------------------------------------
size_t Q3BSPFileImporter::countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const
{
size_t numFaces = 0;
for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end();
++it )
{
Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
if ( pQ3BSPFace->iNumOfMeshVerts > 0)
{
numFaces++;
}
}
return numFaces;
}
// ------------------------------------------------------------------------------------------------
} // Namespace Assimp