- Update : IMport uv- coordinates.

- Bugfix : Fix invvalid M3-faces.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1158 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/5/head
kimmi 2012-02-04 21:08:20 +00:00
parent c84a14a7a8
commit bed6c84cb6
2 changed files with 82 additions and 74 deletions

View File

@ -53,7 +53,8 @@ static const std::string M3Extension = "m3";
// Constructor. // Constructor.
M3Importer::M3Importer() : M3Importer::M3Importer() :
m_pHead( NULL ), m_pHead( NULL ),
m_pRefs( NULL ) m_pRefs( NULL ),
m_Buffer()
{ {
// empty // empty
} }
@ -70,8 +71,9 @@ M3Importer::~M3Importer()
// Check for readable file format. // Check for readable file format.
bool M3Importer::CanRead( const std::string &rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const bool M3Importer::CanRead( const std::string &rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const
{ {
if ( !checkSig ) if ( !checkSig ) {
return SimpleExtensionCheck( rFile, M3Extension.c_str() ); return SimpleExtensionCheck( rFile, M3Extension.c_str() );
}
return true; return true;
} }
@ -79,28 +81,32 @@ bool M3Importer::CanRead( const std::string &rFile, IOSystem* /*pIOHandler*/, bo
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void M3Importer::GetExtensionList(std::set<std::string>& extensions) void M3Importer::GetExtensionList(std::set<std::string>& extensions)
{ {
extensions.insert("m3"); extensions.insert( "m3" );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void M3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) void M3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler )
{ {
ai_assert( !pFile.empty() );
const std::string mode = "rb"; const std::string mode = "rb";
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode ) ); boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode ) );
if ( NULL == file.get() ) if ( NULL == file.get() ) {
throw DeadlyImportError( "Failed to open file " + pFile + "."); throw DeadlyImportError( "Failed to open file " + pFile + ".");
}
// Get the file-size and validate it, throwing an exception when it fails // Get the file-size and validate it, throwing an exception when it fails
size_t filesize = file->FileSize(); const size_t filesize = file->FileSize();
if( filesize < 1 ) if( filesize < 1 ) {
throw DeadlyImportError( "M3-file is too small."); throw DeadlyImportError( "M3-file is too small.");
}
m_Buffer.resize( filesize ); m_Buffer.resize( filesize );
size_t readsize = file->Read( &m_Buffer[ 0 ], sizeof( unsigned char ), filesize ); size_t readsize = file->Read( &m_Buffer[ 0 ], sizeof( unsigned char ), filesize );
ai_assert( readsize == filesize ); ai_assert( readsize == filesize );
m_pHead = (MD33*)( &m_Buffer[ 0 ] ); m_pHead = reinterpret_cast<MD33*>( &m_Buffer[ 0 ] );
m_pRefs = (ReferenceEntry*)( &m_Buffer[ 0 ] + m_pHead->ofsRefs ); m_pRefs = reinterpret_cast<ReferenceEntry*>( &m_Buffer[ 0 ] + m_pHead->ofsRefs );
MODL20* pMODL20( NULL ); MODL20* pMODL20( NULL );
MODL23* pMODL23( NULL ); MODL23* pMODL23( NULL );
@ -116,21 +122,17 @@ void M3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSy
uint32 nFaces = 0; uint32 nFaces = 0;
bool ok = true; bool ok = true;
switch( m_pRefs[ m_pHead->MODL.ref ].type ) switch( m_pRefs[ m_pHead->MODL.ref ].type ) {
{
case 20: case 20:
pMODL20 = GetEntries<MODL20>( m_pHead->MODL ); pMODL20 = GetEntries<MODL20>( m_pHead->MODL );
if ( ( pMODL20->flags & 0x20000) != 0 ) // Has vertices if ( ( pMODL20->flags & 0x20000) != 0 ) { // Has vertices
{ if( (pMODL20->flags & 0x40000) != 0 ) { // Has extra 4 byte
if( (pMODL20->flags & 0x40000) != 0 ) // Has extra 4 byte
{
pVerts1 = GetEntries<VertexExt>( pMODL20->vertexData ); pVerts1 = GetEntries<VertexExt>( pMODL20->vertexData );
nVertices = pMODL20->vertexData.nEntries/sizeof(VertexExt); nVertices = pMODL20->vertexData.nEntries/sizeof(VertexExt);
} }
else else {
{ pVerts2 = GetEntries<Vertex>( pMODL20->vertexData );
pVerts2 = GetEntries<Vertex>(pMODL20->vertexData); nVertices = pMODL20->vertexData.nEntries / sizeof( Vertex );
nVertices = pMODL20->vertexData.nEntries/sizeof(Vertex);
} }
} }
pViews = GetEntries<DIV>( pMODL20->views ); pViews = GetEntries<DIV>( pMODL20->views );
@ -138,17 +140,14 @@ void M3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSy
case 23: case 23:
pMODL23 = GetEntries<MODL23>(m_pHead->MODL ); pMODL23 = GetEntries<MODL23>(m_pHead->MODL );
if( (pMODL23->flags & 0x20000) != 0 ) // Has vertices if( (pMODL23->flags & 0x20000) != 0 ) { // Has vertices
{ if( (pMODL23->flags & 0x40000) != 0 ) { // Has extra 4 byte
if( (pMODL23->flags & 0x40000) != 0 ) // Has extra 4 byte pVerts1 = GetEntries<VertexExt>( pMODL23->vertexData );
{ nVertices = pMODL23->vertexData.nEntries/sizeof( VertexExt );
pVerts1 = GetEntries<VertexExt>(pMODL23->vertexData);
nVertices = pMODL23->vertexData.nEntries/sizeof(VertexExt);
} }
else else {
{ pVerts2 = GetEntries<Vertex>( pMODL23->vertexData );
pVerts2 = GetEntries<Vertex>(pMODL23->vertexData); nVertices = pMODL23->vertexData.nEntries/sizeof( Vertex );
nVertices = pMODL23->vertexData.nEntries/sizeof(Vertex);
} }
} }
pViews = GetEntries<DIV>( pMODL23->views ); pViews = GetEntries<DIV>( pMODL23->views );
@ -156,7 +155,7 @@ void M3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSy
default: default:
ok = false; ok = false;
return; break;
} }
// Get all region data // Get all region data
@ -167,25 +166,43 @@ void M3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSy
nFaces = pViews->faces.nEntries; nFaces = pViews->faces.nEntries;
// Everything ok, if not throw an exception // Everything ok, if not throw an exception
if ( !ok ) if ( !ok ) {
throw DeadlyImportError( "Failed to open file " + pFile + "."); throw DeadlyImportError( "Failed to open file " + pFile + ".");
}
// Convert the vertices // Convert the vertices
std::vector<aiVector3D> vertices; std::vector<aiVector3D> vertices;
vertices.resize( nVertices ); vertices.resize( nVertices );
unsigned int offset = 0; unsigned int offset = 0;
for ( unsigned int i = 0; i < nVertices; i++ ) for ( unsigned int i = 0; i < nVertices; i++ ) {
{ if ( pVerts1 ) {
if ( pVerts1 ) vertices[ offset ].Set( pVerts1[ i ].pos.x, pVerts1[ i ].pos.y, pVerts1[ i ].pos.z );
{ ++offset;
vertices[ offset ].Set( pVerts1[i].pos.x, pVerts1[i].pos.y, pVerts1[i].pos.z );
offset++;
} }
if ( pVerts2 ) if ( pVerts2 ) {
{
vertices[ offset ].Set( pVerts2[ i ].pos.x, pVerts2[ i ].pos.y, pVerts2[ i ].pos.z ); vertices[ offset ].Set( pVerts2[ i ].pos.x, pVerts2[ i ].pos.y, pVerts2[ i ].pos.z );
offset++; ++offset;
}
}
// Write UV coords
offset = 0;
std::vector<aiVector3D> uvCoords;
uvCoords.resize( nVertices );
for( unsigned int i = 0; i < nVertices; ++i ) {
if( pVerts1 ) {
float u = (float) pVerts1[i].uv[0] / 2048;
float v = (float) pVerts1[i].uv[1] / 2048;
uvCoords[ offset ].Set( u, v, 0.0f );
++offset;
}
if( pVerts2 ) {
float u = (float) pVerts2[i].uv[0] / 2048;
float v = (float) pVerts2[i].uv[1] / 2048;
uvCoords[ offset ].Set( u, v, 0.0f );
++offset;
} }
} }
@ -194,39 +211,35 @@ void M3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSy
normals.resize( nVertices ); normals.resize( nVertices );
float w = 0.0f; float w = 0.0f;
Vec3D norm; Vec3D norm;
for( unsigned int i = 0; i < nVertices; i++ ) offset = 0;
{ for( unsigned int i = 0; i < nVertices; i++ ) {
w = 0.0f; w = 0.0f;
if( pVerts1 ) if( pVerts1 ) {
{
norm.x = (float) 2*pVerts1[ i ].normal[ 0 ]/255.0f - 1; norm.x = (float) 2*pVerts1[ i ].normal[ 0 ]/255.0f - 1;
norm.y = (float) 2*pVerts1[ i ].normal[ 1 ]/255.0f - 1; norm.y = (float) 2*pVerts1[ i ].normal[ 1 ]/255.0f - 1;
norm.z = (float) 2*pVerts1[ i ].normal[ 2 ]/255.0f - 1; norm.z = (float) 2*pVerts1[ i ].normal[ 2 ]/255.0f - 1;
w = (float) pVerts1[ i ].normal[ 3 ]/255.0f; w = (float) pVerts1[ i ].normal[ 3 ]/255.0f;
} }
if( pVerts2 ) if( pVerts2 ) {
{
norm.x = (float) 2*pVerts2[ i ].normal[ 0 ]/255.0f - 1; norm.x = (float) 2*pVerts2[ i ].normal[ 0 ]/255.0f - 1;
norm.y = (float) 2*pVerts2[ i ].normal[ 1 ]/255.0f - 1; norm.y = (float) 2*pVerts2[ i ].normal[ 1 ]/255.0f - 1;
norm.z = (float) 2*pVerts2[ i ].normal[ 2 ]/255.0f - 1; norm.z = (float) 2*pVerts2[ i ].normal[ 2 ]/255.0f - 1;
w = (float) pVerts2[ i ].normal[ 3 ] / 255.0f; w = (float) pVerts2[ i ].normal[ 3 ] / 255.0f;
} }
if ( w ) if ( w ) {
{
const float invW = 1.0f / w; const float invW = 1.0f / w;
norm.x = norm.x * invW; norm.x = norm.x * invW;
norm.y = norm.y * invW; norm.y = norm.y * invW;
norm.z = norm.z * invW; norm.z = norm.z * invW;
normals[ offset ].Set( norm.x, norm.y, norm.z );
++offset;
} }
normals[ i ].Set( norm.x, norm.y, norm.z );
} }
// Convert the data into the assimp specific data structures // Convert the data into the assimp specific data structures
convertToAssimp( pFile, pScene, pViews, regions, faces, vertices, normals ); convertToAssimp( pFile, pScene, pViews, regions, faces, vertices, uvCoords, normals );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -234,6 +247,7 @@ void M3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSy
void M3Importer::convertToAssimp( const std::string& pFile, aiScene* pScene, DIV *pViews, void M3Importer::convertToAssimp( const std::string& pFile, aiScene* pScene, DIV *pViews,
Region *pRegions, uint16 *pFaces, Region *pRegions, uint16 *pFaces,
const std::vector<aiVector3D> &vertices, const std::vector<aiVector3D> &vertices,
const std::vector<aiVector3D> &uvCoords,
const std::vector<aiVector3D> &normals ) const std::vector<aiVector3D> &normals )
{ {
std::vector<aiMesh*> MeshArray; std::vector<aiMesh*> MeshArray;
@ -242,7 +256,6 @@ void M3Importer::convertToAssimp( const std::string& pFile, aiScene* pScene, DIV
pScene->mRootNode = createNode( NULL ); pScene->mRootNode = createNode( NULL );
// Set the name of the scene // Set the name of the scene
ai_assert( !pFile.empty() );
pScene->mRootNode->mName.Set( pFile ); pScene->mRootNode->mName.Set( pFile );
aiNode *pRootNode = pScene->mRootNode; aiNode *pRootNode = pScene->mRootNode;
@ -250,11 +263,11 @@ void M3Importer::convertToAssimp( const std::string& pFile, aiScene* pScene, DIV
// Lets create the nodes // Lets create the nodes
pRootNode->mNumChildren = pViews->regions.nEntries; pRootNode->mNumChildren = pViews->regions.nEntries;
if ( pRootNode->mNumChildren > 0 ) if ( pRootNode->mNumChildren > 0 ) {
pRootNode->mChildren = new aiNode*[ pRootNode->mNumChildren ]; pRootNode->mChildren = new aiNode*[ pRootNode->mNumChildren ];
}
for ( unsigned int i=0; i<pViews->regions.nEntries; ++i ) for ( unsigned int i=0; i<pViews->regions.nEntries; ++i ) {
{
// Create a new node // Create a new node
pCurrentNode = createNode( pRootNode ); pCurrentNode = createNode( pRootNode );
std::stringstream stream; std::stringstream stream;
@ -263,8 +276,6 @@ void M3Importer::convertToAssimp( const std::string& pFile, aiScene* pScene, DIV
pRootNode->mChildren[ i ] = pCurrentNode; pRootNode->mChildren[ i ] = pCurrentNode;
// Loop over the faces of the nodes // Loop over the faces of the nodes
// = regions[i].ofsIndices; j < (regions[i].ofsIndices + regions[i].nIndices); j +=3)
unsigned int numFaces = ( pRegions[ i ].ofsIndices + pRegions[ i ].nIndices ) - pRegions[ i ].ofsIndices; unsigned int numFaces = ( pRegions[ i ].ofsIndices + pRegions[ i ].nIndices ) - pRegions[ i ].ofsIndices;
aiMesh *pMesh = new aiMesh; aiMesh *pMesh = new aiMesh;
pMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; pMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
@ -274,21 +285,24 @@ void M3Importer::convertToAssimp( const std::string& pFile, aiScene* pScene, DIV
pMesh->mFaces = new aiFace[ pMesh->mNumFaces ]; pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
aiFace *pCurrentFace = NULL; aiFace *pCurrentFace = NULL;
unsigned int faceIdx = 0; unsigned int faceIdx = 0;
for ( unsigned int j = pRegions[ i ].ofsIndices; j < ( pRegions[ i ].ofsIndices + pRegions[ i ].nIndices ); j += 3 ) for ( unsigned int j = pRegions[ i ].ofsIndices; j < ( pRegions[ i ].ofsIndices + pRegions[ i ].nIndices ); j += 3 ) {
{
pCurrentFace = &( pMesh->mFaces[ faceIdx ] ); pCurrentFace = &( pMesh->mFaces[ faceIdx ] );
faceIdx++; faceIdx++;
pCurrentFace->mNumIndices = 3; pCurrentFace->mNumIndices = 3;
pCurrentFace->mIndices = new unsigned int[ 3 ]; pCurrentFace->mIndices = new unsigned int[ 3 ];
pCurrentFace->mIndices[ 0 ] = pFaces[ j ]+1; pCurrentFace->mIndices[ 0 ] = pFaces[ j ];
pCurrentFace->mIndices[ 1 ] = pFaces[ j+1 ] + 1; pCurrentFace->mIndices[ 1 ] = pFaces[ j+1 ];
pCurrentFace->mIndices[ 2 ] = pFaces[ j+2 ] + 1; pCurrentFace->mIndices[ 2 ] = pFaces[ j+2 ];
} }
/* fprintf_s(f, "f %d/%d/%d %d/%d/%d %d/%d/%d\n", faces[j]+1, faces[j]+1, faces[j]+1,
faces[j+1]+1, faces[j+1]+1, faces[j+1]+1,
faces[j+2]+1, faces[j+2]+1, faces[j+2]+1);*/
// Now we can create the vertex data itself // Now we can create the vertex data itself
pCurrentNode->mNumMeshes = 1; pCurrentNode->mNumMeshes = 1;
pCurrentNode->mMeshes = new unsigned int[ 1 ]; pCurrentNode->mMeshes = new unsigned int[ 1 ];
pCurrentNode->mMeshes[ 0 ] = MeshArray.size() - 1; const unsigned int meshIdx = MeshArray.size() - 1;
pCurrentNode->mMeshes[ 0 ] = meshIdx;
createVertexData( pMesh, vertices, normals ); createVertexData( pMesh, vertices, normals );
} }
@ -296,8 +310,7 @@ void M3Importer::convertToAssimp( const std::string& pFile, aiScene* pScene, DIV
pScene->mNumMeshes = MeshArray.size(); pScene->mNumMeshes = MeshArray.size();
pScene->mMeshes = new aiMesh*[ MeshArray.size() ]; pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
unsigned int pos = 0; unsigned int pos = 0;
for ( std::vector<aiMesh*>::iterator it = MeshArray.begin(); it != MeshArray.end(); ++it ) for ( std::vector<aiMesh*>::iterator it = MeshArray.begin(); it != MeshArray.end(); ++it ) {
{
pScene->mMeshes[ pos ] = *it; pScene->mMeshes[ pos ] = *it;
pos++; pos++;
} }
@ -314,19 +327,14 @@ void M3Importer::createVertexData( aiMesh *pMesh, const std::vector<aiVector3D>
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ]; pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ];
unsigned int pos = 0; unsigned int pos = 0;
for ( unsigned int currentFace = 0; currentFace < pMesh->mNumFaces; currentFace++ ) for ( unsigned int currentFace = 0; currentFace < pMesh->mNumFaces; currentFace++ ) {
{
aiFace *pFace = &( pMesh->mFaces[ currentFace ] ); aiFace *pFace = &( pMesh->mFaces[ currentFace ] );
for ( unsigned int currentIdx=0; currentIdx<pFace->mNumIndices; currentIdx++ ) for ( unsigned int currentIdx=0; currentIdx<pFace->mNumIndices; currentIdx++ ) {
{
const unsigned int idx = pFace->mIndices[ currentIdx ]; const unsigned int idx = pFace->mIndices[ currentIdx ];
if ( vertices.size() > idx ) if ( vertices.size() > idx ) {
{
pMesh->mVertices[ pos ] = vertices[ idx ]; pMesh->mVertices[ pos ] = vertices[ idx ];
pMesh->mNormals[ pos ] = normals[ idx ]; pMesh->mNormals[ pos ] = normals[ idx ];
pFace->mIndices[ currentIdx ] = pos; pFace->mIndices[ currentIdx ] = pos;
pFace->mIndices[ pos ];
pos++; pos++;
} }
} }

View File

@ -697,7 +697,7 @@ private:
void GetExtensionList( std::set<std::string>& extensions ); void GetExtensionList( std::set<std::string>& extensions );
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ); void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler );
void convertToAssimp( const std::string& pFile, aiScene* pScene, DIV *pViews, Region *pRegions, uint16 *pFaces, void convertToAssimp( const std::string& pFile, aiScene* pScene, DIV *pViews, Region *pRegions, uint16 *pFaces,
const std::vector<aiVector3D> &vertices, const std::vector<aiVector3D> &normals ); const std::vector<aiVector3D> &vertices, const std::vector<aiVector3D> &uvCoords, const std::vector<aiVector3D> &normals );
void createVertexData( aiMesh *pMesh, const std::vector<aiVector3D> &vertices, const std::vector<aiVector3D> &normals ); void createVertexData( aiMesh *pMesh, const std::vector<aiVector3D> &vertices, const std::vector<aiVector3D> &normals );
aiNode *createNode( aiNode *pParent ); aiNode *createNode( aiNode *pParent );
template<typename T> template<typename T>