BUGFIX : Fix handling of multiple materials per object definition in Obj-Loader.
git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@745 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
31ff5d27eb
commit
f3310b0f36
|
@ -107,14 +107,20 @@ struct Face
|
||||||
//! \brief Stores all objects of an objfile object definition
|
//! \brief Stores all objects of an objfile object definition
|
||||||
struct Object
|
struct Object
|
||||||
{
|
{
|
||||||
|
enum ObjectType
|
||||||
|
{
|
||||||
|
ObjType,
|
||||||
|
GroupType
|
||||||
|
};
|
||||||
|
|
||||||
//! Object name
|
//! Object name
|
||||||
std::string m_strObjName;
|
std::string m_strObjName;
|
||||||
//! Assigend face instances
|
|
||||||
std::vector<Face*> m_Faces;
|
|
||||||
//! Transformation matrix, stored in OpenGL format
|
//! Transformation matrix, stored in OpenGL format
|
||||||
aiMatrix4x4 m_Transformation;
|
aiMatrix4x4 m_Transformation;
|
||||||
//! All sub-objects referenced by this object
|
//! All sub-objects referenced by this object
|
||||||
std::vector<Object*> m_SubObjects;
|
std::vector<Object*> m_SubObjects;
|
||||||
|
/// Assigned meshes
|
||||||
|
std::vector<unsigned int> m_Meshes;
|
||||||
|
|
||||||
//! \brief Default constructor
|
//! \brief Default constructor
|
||||||
Object() :
|
Object() :
|
||||||
|
@ -189,6 +195,8 @@ struct Material
|
||||||
//! \brief Data structure to store a mesh
|
//! \brief Data structure to store a mesh
|
||||||
struct Mesh
|
struct Mesh
|
||||||
{
|
{
|
||||||
|
static const unsigned int NoMaterial = 999999999;
|
||||||
|
|
||||||
/// Array with pointer to all stored faces
|
/// Array with pointer to all stored faces
|
||||||
std::vector<Face*> m_Faces;
|
std::vector<Face*> m_Faces;
|
||||||
/// Assigned material
|
/// Assigned material
|
||||||
|
@ -205,7 +213,7 @@ struct Mesh
|
||||||
Mesh() :
|
Mesh() :
|
||||||
m_pMaterial(NULL),
|
m_pMaterial(NULL),
|
||||||
m_uiNumIndices(0),
|
m_uiNumIndices(0),
|
||||||
m_uiMaterialIndex(0),
|
m_uiMaterialIndex( NoMaterial ),
|
||||||
m_hasNormals(false)
|
m_hasNormals(false)
|
||||||
{
|
{
|
||||||
memset(m_uiUVCoordinates, 0, sizeof( unsigned int ) * AI_MAX_NUMBER_OF_TEXTURECOORDS);
|
memset(m_uiUVCoordinates, 0, sizeof( unsigned int ) * AI_MAX_NUMBER_OF_TEXTURECOORDS);
|
||||||
|
@ -305,7 +313,6 @@ struct Model
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Groups.clear();
|
m_Groups.clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
|
||||||
|
|
||||||
#include "DefaultIOSystem.h"
|
#include "DefaultIOSystem.h"
|
||||||
|
|
||||||
#include "ObjFileImporter.h"
|
#include "ObjFileImporter.h"
|
||||||
#include "ObjFileParser.h"
|
#include "ObjFileParser.h"
|
||||||
#include "ObjFileData.h"
|
#include "ObjFileData.h"
|
||||||
|
@ -140,8 +139,8 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create the root node of the scene
|
// Create the root node of the scene
|
||||||
pScene->mRootNode = new aiNode();
|
pScene->mRootNode = new aiNode;
|
||||||
if (!pModel->m_ModelName.empty())
|
if ( !pModel->m_ModelName.empty() )
|
||||||
{
|
{
|
||||||
// Set the name of the scene
|
// Set the name of the scene
|
||||||
pScene->mRootNode->mName.Set(pModel->m_ModelName);
|
pScene->mRootNode->mName.Set(pModel->m_ModelName);
|
||||||
|
@ -175,40 +174,46 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Creates all nodes of the model
|
// Creates all nodes of the model
|
||||||
aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pObject,
|
||||||
unsigned int uiMeshIndex,
|
unsigned int uiMeshIndex,
|
||||||
aiNode *pParent, aiScene* pScene,
|
aiNode *pParent, aiScene* pScene,
|
||||||
std::vector<aiMesh*> &MeshArray)
|
std::vector<aiMesh*> &MeshArray )
|
||||||
{
|
{
|
||||||
ai_assert( NULL != pModel );
|
ai_assert( NULL != pModel );
|
||||||
if (NULL == pData)
|
if ( NULL == pObject )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Store older mesh size to be able to computate mesh offsets for new mesh instances
|
// Store older mesh size to be able to computate mesh offsets for new mesh instances
|
||||||
const size_t oldMeshSize = MeshArray.size();
|
const size_t oldMeshSize = MeshArray.size();
|
||||||
aiNode *pNode = new aiNode();
|
aiNode *pNode = new aiNode;
|
||||||
|
|
||||||
if (pParent != NULL)
|
if (pParent != NULL)
|
||||||
this->appendChildToParentNode(pParent, pNode);
|
appendChildToParentNode(pParent, pNode);
|
||||||
|
|
||||||
aiMesh *pMesh = new aiMesh;
|
|
||||||
createTopology( pModel, pData, uiMeshIndex, pMesh );
|
for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ )
|
||||||
if ( pMesh->mNumVertices > 0 )
|
|
||||||
{
|
{
|
||||||
MeshArray.push_back( pMesh );
|
unsigned int meshId = pObject->m_Meshes[ i ];
|
||||||
}
|
aiMesh *pMesh = new aiMesh;
|
||||||
else
|
createTopology( pModel, pObject, meshId, pMesh );
|
||||||
{
|
if ( pMesh->mNumVertices > 0 )
|
||||||
delete pMesh;
|
{
|
||||||
|
MeshArray.push_back( pMesh );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete pMesh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create all nodes from the subobjects stored in the current object
|
// Create all nodes from the sub-objects stored in the current object
|
||||||
if ( !pData->m_SubObjects.empty() )
|
if ( !pObject->m_SubObjects.empty() )
|
||||||
{
|
{
|
||||||
pNode->mNumChildren = (unsigned int)pData->m_SubObjects.size();
|
size_t numChilds = pObject->m_SubObjects.size();
|
||||||
pNode->mChildren = new aiNode*[pData->m_SubObjects.size()];
|
pNode->mNumChildren = static_cast<unsigned int>( numChilds );
|
||||||
|
pNode->mChildren = new aiNode*[ numChilds ];
|
||||||
pNode->mNumMeshes = 1;
|
pNode->mNumMeshes = 1;
|
||||||
pNode->mMeshes = new unsigned int[1];
|
pNode->mMeshes = new unsigned int[ 1 ];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set mesh instances into scene- and node-instances
|
// Set mesh instances into scene- and node-instances
|
||||||
|
@ -216,7 +221,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
|
||||||
if ( meshSizeDiff > 0 )
|
if ( meshSizeDiff > 0 )
|
||||||
{
|
{
|
||||||
pNode->mMeshes = new unsigned int[ meshSizeDiff ];
|
pNode->mMeshes = new unsigned int[ meshSizeDiff ];
|
||||||
pNode->mNumMeshes = (unsigned int)meshSizeDiff;
|
pNode->mNumMeshes = static_cast<unsigned int>( meshSizeDiff );
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
for (size_t i = oldMeshSize; i < MeshArray.size(); i++)
|
for (size_t i = oldMeshSize; i < MeshArray.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -248,7 +253,10 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
|
||||||
if ( pMesh->mNumFaces > 0 )
|
if ( pMesh->mNumFaces > 0 )
|
||||||
{
|
{
|
||||||
pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
|
pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
|
||||||
pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex;
|
if ( pObjMesh->m_uiMaterialIndex != ObjFile::Mesh::NoMaterial )
|
||||||
|
{
|
||||||
|
pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy all data from all stored meshes
|
// Copy all data from all stored meshes
|
||||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
|
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
|
||||||
|
@ -278,7 +286,7 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Creates a vretex array
|
// Creates a vertex array
|
||||||
void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
const ObjFile::Object* pCurrentObject,
|
const ObjFile::Object* pCurrentObject,
|
||||||
unsigned int uiMeshIndex,
|
unsigned int uiMeshIndex,
|
||||||
|
@ -288,7 +296,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
ai_assert( NULL != pCurrentObject );
|
ai_assert( NULL != pCurrentObject );
|
||||||
|
|
||||||
// Break, if no faces are stored in object
|
// Break, if no faces are stored in object
|
||||||
if (pCurrentObject->m_Faces.empty())
|
if ( pCurrentObject->m_Meshes.empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get current mesh
|
// Get current mesh
|
||||||
|
@ -366,10 +374,10 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes)
|
void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes)
|
||||||
{
|
{
|
||||||
iNumMeshes = 0;
|
iNumMeshes = 0;
|
||||||
if (rObjects.empty())
|
if ( rObjects.empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
iNumMeshes += (unsigned int)rObjects.size();
|
iNumMeshes += static_cast<unsigned int>( rObjects.size() );
|
||||||
for (std::vector<ObjFile::Object*>::const_iterator it = rObjects.begin();
|
for (std::vector<ObjFile::Object*>::const_iterator it = rObjects.begin();
|
||||||
it != rObjects.end();
|
it != rObjects.end();
|
||||||
++it)
|
++it)
|
||||||
|
@ -400,17 +408,18 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
|
||||||
Assimp::MaterialHelper* mat = new Assimp::MaterialHelper();
|
Assimp::MaterialHelper* mat = new Assimp::MaterialHelper();
|
||||||
|
|
||||||
// Store material name
|
// Store material name
|
||||||
std::map<std::string, ObjFile::Material*>::const_iterator it = pModel->m_MaterialMap.find( pModel->m_MaterialLib[ matIndex ] );
|
std::map<std::string, ObjFile::Material*>::const_iterator it;
|
||||||
|
it = pModel->m_MaterialMap.find( pModel->m_MaterialLib[ matIndex ] );
|
||||||
|
|
||||||
// No material found, use the default material
|
// No material found, use the default material
|
||||||
if ( pModel->m_MaterialMap.end() == it)
|
if ( pModel->m_MaterialMap.end() == it )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ObjFile::Material *pCurrentMaterial = (*it).second;
|
ObjFile::Material *pCurrentMaterial = (*it).second;
|
||||||
mat->AddProperty( &pCurrentMaterial->MaterialName, AI_MATKEY_NAME );
|
mat->AddProperty( &pCurrentMaterial->MaterialName, AI_MATKEY_NAME );
|
||||||
|
|
||||||
// convert illumination model
|
// convert illumination model
|
||||||
int sm;
|
int sm = 0;
|
||||||
switch (pCurrentMaterial->illumination_model)
|
switch (pCurrentMaterial->illumination_model)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -474,8 +483,8 @@ void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pSc
|
||||||
void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
|
void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
|
||||||
{
|
{
|
||||||
// Checking preconditions
|
// Checking preconditions
|
||||||
ai_assert (NULL != pParent);
|
ai_assert( NULL != pParent );
|
||||||
ai_assert (NULL != pChild);
|
ai_assert( NULL != pChild );
|
||||||
|
|
||||||
// Assign parent to child
|
// Assign parent to child
|
||||||
pChild->mParent = pParent;
|
pChild->mParent = pParent;
|
||||||
|
@ -486,7 +495,7 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
|
||||||
if (pParent->mChildren != NULL)
|
if (pParent->mChildren != NULL)
|
||||||
{
|
{
|
||||||
sNumChildren = pParent->mNumChildren;
|
sNumChildren = pParent->mNumChildren;
|
||||||
ai_assert (0 != sNumChildren);
|
ai_assert( 0 != sNumChildren );
|
||||||
for (size_t index = 0; index < pParent->mNumChildren; index++)
|
for (size_t index = 0; index < pParent->mNumChildren; index++)
|
||||||
{
|
{
|
||||||
temp.push_back(pParent->mChildren [ index ] );
|
temp.push_back(pParent->mChildren [ index ] );
|
||||||
|
|
|
@ -50,7 +50,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "../include/aiTypes.h"
|
#include "../include/aiTypes.h"
|
||||||
#include "DefaultIOSystem.h"
|
#include "DefaultIOSystem.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp
|
||||||
|
{
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
|
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
|
||||||
// fix: changed that to our standard default name
|
// fix: changed that to our standard default name
|
||||||
|
@ -78,6 +80,7 @@ ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModel
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
// Destrcutor.
|
||||||
ObjFileParser::~ObjFileParser()
|
ObjFileParser::~ObjFileParser()
|
||||||
{
|
{
|
||||||
delete m_pModel->m_pDefaultMaterial;
|
delete m_pModel->m_pDefaultMaterial;
|
||||||
|
@ -88,12 +91,14 @@ ObjFileParser::~ObjFileParser()
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
// Returns a pointer to the model instance.
|
||||||
ObjFile::Model *ObjFileParser::GetModel() const
|
ObjFile::Model *ObjFileParser::GetModel() const
|
||||||
{
|
{
|
||||||
return m_pModel;
|
return m_pModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
// File parsing method.
|
||||||
void ObjFileParser::parseFile()
|
void ObjFileParser::parseFile()
|
||||||
{
|
{
|
||||||
if (m_DataIt == m_DataItEnd)
|
if (m_DataIt == m_DataItEnd)
|
||||||
|
@ -201,7 +206,6 @@ void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
while (m_DataIt != m_DataItEnd)
|
while (m_DataIt != m_DataItEnd)
|
||||||
{
|
{
|
||||||
// (Aramis) removed assertion (index<length-1) in favour of an explicit check
|
|
||||||
if (*m_DataIt == '\n' || *m_DataIt == '\r' || index == length-1)
|
if (*m_DataIt == '\n' || *m_DataIt == '\r' || index == length-1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -265,7 +269,6 @@ void ObjFileParser::getFace()
|
||||||
std::vector<unsigned int> *pTexID = new std::vector<unsigned int>;
|
std::vector<unsigned int> *pTexID = new std::vector<unsigned int>;
|
||||||
std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
|
std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
|
||||||
bool hasNormal = false;
|
bool hasNormal = false;
|
||||||
|
|
||||||
|
|
||||||
bool vt = (!m_pModel->m_TextureCoord.empty());
|
bool vt = (!m_pModel->m_TextureCoord.empty());
|
||||||
bool vn = (!m_pModel->m_Normals.empty());
|
bool vn = (!m_pModel->m_Normals.empty());
|
||||||
|
@ -329,7 +332,7 @@ void ObjFileParser::getFace()
|
||||||
++pPtr;
|
++pPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjFile::Face *face = new ObjFile::Face(pIndices, pNormalID, pTexID);
|
ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID );
|
||||||
|
|
||||||
// Set active material, if one set
|
// Set active material, if one set
|
||||||
if (NULL != m_pModel->m_pCurrentMaterial)
|
if (NULL != m_pModel->m_pCurrentMaterial)
|
||||||
|
@ -339,23 +342,20 @@ void ObjFileParser::getFace()
|
||||||
|
|
||||||
// Create a default object, if nothing there
|
// Create a default object, if nothing there
|
||||||
if ( NULL == m_pModel->m_pCurrent )
|
if ( NULL == m_pModel->m_pCurrent )
|
||||||
createObject("defaultobject");
|
createObject( "defaultobject" );
|
||||||
|
|
||||||
// Store the new instance
|
|
||||||
m_pModel->m_pCurrent->m_Faces.push_back(face);
|
|
||||||
|
|
||||||
// Assign face to mesh
|
// Assign face to mesh
|
||||||
if ( NULL == m_pModel->m_pCurrentMesh )
|
if ( NULL == m_pModel->m_pCurrentMesh )
|
||||||
{
|
{
|
||||||
m_pModel->m_pCurrentMesh = new ObjFile::Mesh();
|
createMesh();
|
||||||
m_pModel->m_Meshes.push_back( m_pModel->m_pCurrentMesh );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the face
|
// Store the face
|
||||||
m_pModel->m_pCurrentMesh->m_Faces.push_back( face );
|
m_pModel->m_pCurrentMesh->m_Faces.push_back( face );
|
||||||
m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_pVertices->size();
|
m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_pVertices->size();
|
||||||
m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].size();
|
m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].size();
|
||||||
if(!m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal) {
|
if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal )
|
||||||
|
{
|
||||||
m_pModel->m_pCurrentMesh->m_hasNormals = true;
|
m_pModel->m_pCurrentMesh->m_hasNormals = true;
|
||||||
}
|
}
|
||||||
// Skip the rest of the line
|
// Skip the rest of the line
|
||||||
|
@ -391,6 +391,10 @@ void ObjFileParser::getMaterialDesc()
|
||||||
{
|
{
|
||||||
// Found, using detected material
|
// Found, using detected material
|
||||||
m_pModel->m_pCurrentMaterial = (*it).second;
|
m_pModel->m_pCurrentMaterial = (*it).second;
|
||||||
|
if ( needsNewMesh( strName ))
|
||||||
|
{
|
||||||
|
createMesh();
|
||||||
|
}
|
||||||
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName );
|
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,11 +464,11 @@ void ObjFileParser::getNewMaterial()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char *pStart = &(*m_DataIt);
|
char *pStart = &(*m_DataIt);
|
||||||
std::string strMat(pStart, *m_DataIt);
|
std::string strMat( pStart, *m_DataIt );
|
||||||
while ( isSeparator( *m_DataIt ) )
|
while ( isSeparator( *m_DataIt ) )
|
||||||
m_DataIt++;
|
m_DataIt++;
|
||||||
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
|
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
|
||||||
if (it == m_pModel->m_MaterialMap.end())
|
if ( it == m_pModel->m_MaterialMap.end() )
|
||||||
{
|
{
|
||||||
// Show a warning, if material was not found
|
// Show a warning, if material was not found
|
||||||
DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat);
|
DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat);
|
||||||
|
@ -473,7 +477,10 @@ void ObjFileParser::getNewMaterial()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Set new material
|
// Set new material
|
||||||
m_pModel->m_pCurrentMaterial = (*it).second;
|
if ( needsNewMesh( strMat ) )
|
||||||
|
{
|
||||||
|
createMesh();
|
||||||
|
}
|
||||||
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat );
|
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,13 +521,12 @@ void ObjFileParser::getGroupName()
|
||||||
std::string strGroupName(pStart, &(*m_DataIt));
|
std::string strGroupName(pStart, &(*m_DataIt));
|
||||||
|
|
||||||
// Change active group, if necessary
|
// Change active group, if necessary
|
||||||
if (m_pModel->m_strActiveGroup != strGroupName)
|
if ( m_pModel->m_strActiveGroup != strGroupName )
|
||||||
{
|
{
|
||||||
// Search for already existing entry
|
// Search for already existing entry
|
||||||
ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(&strGroupName);
|
ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(&strGroupName);
|
||||||
|
|
||||||
// We are mapping groups into the object structure
|
// We are mapping groups into the object structure
|
||||||
/// TODO: Is this the right way to do it????
|
|
||||||
createObject( strGroupName );
|
createObject( strGroupName );
|
||||||
|
|
||||||
// New group name, creating a new entry
|
// New group name, creating a new entry
|
||||||
|
@ -557,8 +563,8 @@ void ObjFileParser::getObjectName()
|
||||||
if (m_DataIt == m_DataItEnd)
|
if (m_DataIt == m_DataItEnd)
|
||||||
return;
|
return;
|
||||||
char *pStart = &(*m_DataIt);
|
char *pStart = &(*m_DataIt);
|
||||||
while (!isSeparator(*m_DataIt))
|
while ( !isSeparator( *m_DataIt ) )
|
||||||
m_DataIt++;
|
++m_DataIt;
|
||||||
|
|
||||||
std::string strObjectName(pStart, &(*m_DataIt));
|
std::string strObjectName(pStart, &(*m_DataIt));
|
||||||
if (!strObjectName.empty())
|
if (!strObjectName.empty())
|
||||||
|
@ -588,15 +594,15 @@ void ObjFileParser::getObjectName()
|
||||||
// Creates a new object instance
|
// Creates a new object instance
|
||||||
void ObjFileParser::createObject(const std::string &strObjectName)
|
void ObjFileParser::createObject(const std::string &strObjectName)
|
||||||
{
|
{
|
||||||
ai_assert (NULL != m_pModel);
|
ai_assert( NULL != m_pModel );
|
||||||
ai_assert (!strObjectName.empty());
|
ai_assert( !strObjectName.empty() );
|
||||||
|
|
||||||
m_pModel->m_pCurrent = new ObjFile::Object();
|
m_pModel->m_pCurrent = new ObjFile::Object;
|
||||||
m_pModel->m_pCurrent->m_strObjName = strObjectName;
|
m_pModel->m_pCurrent->m_strObjName = strObjectName;
|
||||||
m_pModel->m_Objects.push_back( m_pModel->m_pCurrent );
|
m_pModel->m_Objects.push_back( m_pModel->m_pCurrent );
|
||||||
|
|
||||||
m_pModel->m_pCurrentMesh = new ObjFile::Mesh();
|
|
||||||
m_pModel->m_Meshes.push_back( m_pModel->m_pCurrentMesh );
|
createMesh();
|
||||||
|
|
||||||
if( m_pModel->m_pCurrentMaterial )
|
if( m_pModel->m_pCurrentMaterial )
|
||||||
{
|
{
|
||||||
|
@ -605,6 +611,39 @@ void ObjFileParser::createObject(const std::string &strObjectName)
|
||||||
m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial;
|
m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Creates a new mesh
|
||||||
|
void ObjFileParser::createMesh()
|
||||||
|
{
|
||||||
|
ai_assert( NULL != m_pModel );
|
||||||
|
m_pModel->m_pCurrentMesh = new ObjFile::Mesh;
|
||||||
|
m_pModel->m_Meshes.push_back( m_pModel->m_pCurrentMesh );
|
||||||
|
unsigned int meshId = m_pModel->m_Meshes.size()-1;
|
||||||
|
if ( NULL != m_pModel->m_pCurrent )
|
||||||
|
{
|
||||||
|
m_pModel->m_pCurrent->m_Meshes.push_back( meshId );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->error("OBJ: No object detected to attach a new mesh instance.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Returns true, if a new mesh must be created.
|
||||||
|
bool ObjFileParser::needsNewMesh( const std::string &rMaterialName )
|
||||||
|
{
|
||||||
|
bool newMat = false;
|
||||||
|
int matIdx = getMaterialIndex( rMaterialName );
|
||||||
|
int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
|
||||||
|
if ( curMatIdx != ObjFile::Mesh::NoMaterial || curMatIdx != matIdx )
|
||||||
|
{
|
||||||
|
// New material -> only one material per mesh, so we need to create a new
|
||||||
|
// material
|
||||||
|
newMat = true;
|
||||||
|
}
|
||||||
|
return newMat;
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Shows an error in parsing process.
|
// Shows an error in parsing process.
|
||||||
|
@ -613,6 +652,7 @@ void ObjFileParser::reportErrorTokenInFace()
|
||||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||||
DefaultLogger::get()->error("OBJ: Not supported token in face description detected");
|
DefaultLogger::get()->error("OBJ: Not supported token in face description detected");
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
|
@ -108,6 +108,10 @@ private:
|
||||||
void getObjectName();
|
void getObjectName();
|
||||||
/// Creates a new object.
|
/// Creates a new object.
|
||||||
void createObject(const std::string &strObjectName);
|
void createObject(const std::string &strObjectName);
|
||||||
|
/// Creates a new mesh.
|
||||||
|
void createMesh();
|
||||||
|
/// Returns true, if a new mesh instance must be created.
|
||||||
|
bool needsNewMesh( const std::string &rMaterialName );
|
||||||
/// Error report in token
|
/// Error report in token
|
||||||
void reportErrorTokenInFace();
|
void reportErrorTokenInFace();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue