diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index 34bb01e0a..c4dff0ba0 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -57,177 +57,177 @@ const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME; // ------------------------------------------------------------------- // Constructor with loaded data and directories. ObjFileParser::ObjFileParser(std::vector &Data,const std::string &strModelName, IOSystem *io ) : - m_DataIt(Data.begin()), - m_DataItEnd(Data.end()), - m_pModel(NULL), - m_uiLine(0), - m_pIO( io ) + m_DataIt(Data.begin()), + m_DataItEnd(Data.end()), + m_pModel(NULL), + m_uiLine(0), + m_pIO( io ) { - std::fill_n(m_buffer,BUFFERSIZE,0); + std::fill_n(m_buffer,BUFFERSIZE,0); - // Create the model instance to store all the data - m_pModel = new ObjFile::Model(); - m_pModel->m_ModelName = strModelName; - + // Create the model instance to store all the data + m_pModel = new ObjFile::Model(); + m_pModel->m_ModelName = strModelName; + // create default material and store it - m_pModel->m_pDefaultMaterial = new ObjFile::Material(); - m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL ); + m_pModel->m_pDefaultMaterial = new ObjFile::Material(); + m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL ); m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL ); - m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial; - - // Start parsing the file - parseFile(); + m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial; + + // Start parsing the file + parseFile(); } // ------------------------------------------------------------------- // Destructor ObjFileParser::~ObjFileParser() { - delete m_pModel; - m_pModel = NULL; + delete m_pModel; + m_pModel = NULL; } // ------------------------------------------------------------------- // Returns a pointer to the model instance. ObjFile::Model *ObjFileParser::GetModel() const { - return m_pModel; + return m_pModel; } // ------------------------------------------------------------------- // File parsing method. void ObjFileParser::parseFile() { - if (m_DataIt == m_DataItEnd) - return; + if (m_DataIt == m_DataItEnd) + return; - while (m_DataIt != m_DataItEnd) - { - switch (*m_DataIt) - { - case 'v': // Parse a vertex texture coordinate - { - ++m_DataIt; - if (*m_DataIt == ' ' || *m_DataIt == '\t') { - // read in vertex definition - getVector3(m_pModel->m_Vertices); - } else if (*m_DataIt == 't') { - // read in texture coordinate ( 2D or 3D ) + while (m_DataIt != m_DataItEnd) + { + switch (*m_DataIt) + { + case 'v': // Parse a vertex texture coordinate + { + ++m_DataIt; + if (*m_DataIt == ' ' || *m_DataIt == '\t') { + // read in vertex definition + getVector3(m_pModel->m_Vertices); + } else if (*m_DataIt == 't') { + // read in texture coordinate ( 2D or 3D ) ++m_DataIt; getVector( m_pModel->m_TextureCoord ); - } else if (*m_DataIt == 'n') { - // Read in normal vector definition - ++m_DataIt; - getVector3( m_pModel->m_Normals ); - } - } - break; + } else if (*m_DataIt == 'n') { + // Read in normal vector definition + ++m_DataIt; + getVector3( m_pModel->m_Normals ); + } + } + break; - case 'p': // Parse a face, line or point statement - case 'l': - case 'f': - { - getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l' - ? aiPrimitiveType_LINE : aiPrimitiveType_POINT)); - } - break; + case 'p': // Parse a face, line or point statement + case 'l': + case 'f': + { + getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l' + ? aiPrimitiveType_LINE : aiPrimitiveType_POINT)); + } + break; - case '#': // Parse a comment - { - getComment(); - } - break; + case '#': // Parse a comment + { + getComment(); + } + break; - case 'u': // Parse a material desc. setter - { - getMaterialDesc(); - } - break; + case 'u': // Parse a material desc. setter + { + getMaterialDesc(); + } + break; - case 'm': // Parse a material library or merging group ('mg') - { - if (*(m_DataIt + 1) == 'g') - getGroupNumberAndResolution(); - else - getMaterialLib(); - } - break; + case 'm': // Parse a material library or merging group ('mg') + { + if (*(m_DataIt + 1) == 'g') + getGroupNumberAndResolution(); + else + getMaterialLib(); + } + break; - case 'g': // Parse group name - { - getGroupName(); - } - break; + case 'g': // Parse group name + { + getGroupName(); + } + break; - case 's': // Parse group number - { - getGroupNumber(); - } - break; + case 's': // Parse group number + { + getGroupNumber(); + } + break; - case 'o': // Parse object name - { - getObjectName(); - } - break; - - default: - { - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); - } - break; - } - } + case 'o': // Parse object name + { + getObjectName(); + } + break; + + default: + { + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + break; + } + } } // ------------------------------------------------------------------- // Copy the next word in a temporary buffer void ObjFileParser::copyNextWord(char *pBuffer, size_t length) { - size_t index = 0; - m_DataIt = getNextWord(m_DataIt, m_DataItEnd); + size_t index = 0; + m_DataIt = getNextWord(m_DataIt, m_DataItEnd); while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) { - pBuffer[index] = *m_DataIt; - index++; + pBuffer[index] = *m_DataIt; + index++; if( index == length - 1 ) { break; } - ++m_DataIt; - } + ++m_DataIt; + } - ai_assert(index < length); - pBuffer[index] = '\0'; + ai_assert(index < length); + pBuffer[index] = '\0'; } // ------------------------------------------------------------------- // Copy the next line into a temporary buffer void ObjFileParser::copyNextLine(char *pBuffer, size_t length) { - size_t index = 0u; + size_t index = 0u; - // some OBJ files have line continuations using \ (such as in C++ et al) - bool continuation = false; - for (;m_DataIt != m_DataItEnd && index < length-1; ++m_DataIt) - { - const char c = *m_DataIt; - if (c == '\\') { - continuation = true; - continue; - } - - if (c == '\n' || c == '\r') { - if(continuation) { - pBuffer[ index++ ] = ' '; - continue; - } - break; - } + // some OBJ files have line continuations using \ (such as in C++ et al) + bool continuation = false; + for (;m_DataIt != m_DataItEnd && index < length-1; ++m_DataIt) + { + const char c = *m_DataIt; + if (c == '\\') { + continuation = true; + continue; + } + + if (c == '\n' || c == '\r') { + if(continuation) { + pBuffer[ index++ ] = ' '; + continue; + } + break; + } - continuation = false; - pBuffer[ index++ ] = c; - } - ai_assert(index < length); - pBuffer[ index ] = '\0'; + continuation = false; + pBuffer[ index++ ] = c; + } + ai_assert(index < length); + pBuffer[ index ] = '\0'; } // ------------------------------------------------------------------- @@ -268,391 +268,391 @@ void ObjFileParser::getVector( std::vector &point3d_array ) { // ------------------------------------------------------------------- // Get values for a new 3D vector instance void ObjFileParser::getVector3(std::vector &point3d_array) { - float x, y, z; - copyNextWord(m_buffer, BUFFERSIZE); - x = (float) fast_atof(m_buffer); - - copyNextWord(m_buffer, BUFFERSIZE); - y = (float) fast_atof(m_buffer); + float x, y, z; + copyNextWord(m_buffer, BUFFERSIZE); + x = (float) fast_atof(m_buffer); + + copyNextWord(m_buffer, BUFFERSIZE); + y = (float) fast_atof(m_buffer); copyNextWord( m_buffer, BUFFERSIZE ); z = ( float ) fast_atof( m_buffer ); - point3d_array.push_back( aiVector3D( x, y, z ) ); - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + point3d_array.push_back( aiVector3D( x, y, z ) ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Get values for a new 2D vector instance void ObjFileParser::getVector2( std::vector &point2d_array ) { - float x, y; - copyNextWord(m_buffer, BUFFERSIZE); - x = (float) fast_atof(m_buffer); - - copyNextWord(m_buffer, BUFFERSIZE); - y = (float) fast_atof(m_buffer); + float x, y; + copyNextWord(m_buffer, BUFFERSIZE); + x = (float) fast_atof(m_buffer); + + copyNextWord(m_buffer, BUFFERSIZE); + y = (float) fast_atof(m_buffer); - point2d_array.push_back(aiVector2D(x, y)); + point2d_array.push_back(aiVector2D(x, y)); - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Get values for a new face instance void ObjFileParser::getFace(aiPrimitiveType type) { - copyNextLine(m_buffer, BUFFERSIZE); - if (m_DataIt == m_DataItEnd) - return; + copyNextLine(m_buffer, BUFFERSIZE); + if (m_DataIt == m_DataItEnd) + return; - char *pPtr = m_buffer; - char *pEnd = &pPtr[BUFFERSIZE]; - pPtr = getNextToken(pPtr, pEnd); - if (pPtr == pEnd || *pPtr == '\0') - return; + char *pPtr = m_buffer; + char *pEnd = &pPtr[BUFFERSIZE]; + pPtr = getNextToken(pPtr, pEnd); + if (pPtr == pEnd || *pPtr == '\0') + return; - std::vector *pIndices = new std::vector; - std::vector *pTexID = new std::vector; - std::vector *pNormalID = new std::vector; - bool hasNormal = false; + std::vector *pIndices = new std::vector; + std::vector *pTexID = new std::vector; + std::vector *pNormalID = new std::vector; + bool hasNormal = false; - const int vSize = m_pModel->m_Vertices.size(); - const int vtSize = m_pModel->m_TextureCoord.size(); - const int vnSize = m_pModel->m_Normals.size(); + const int vSize = m_pModel->m_Vertices.size(); + const int vtSize = m_pModel->m_TextureCoord.size(); + const int vnSize = m_pModel->m_Normals.size(); - const bool vt = (!m_pModel->m_TextureCoord.empty()); - const bool vn = (!m_pModel->m_Normals.empty()); - int iStep = 0, iPos = 0; - while (pPtr != pEnd) - { - iStep = 1; + const bool vt = (!m_pModel->m_TextureCoord.empty()); + const bool vn = (!m_pModel->m_Normals.empty()); + int iStep = 0, iPos = 0; + while (pPtr != pEnd) + { + iStep = 1; - if (IsLineEnd(*pPtr)) - break; + if (IsLineEnd(*pPtr)) + break; - if (*pPtr=='/' ) - { - if (type == aiPrimitiveType_POINT) { - DefaultLogger::get()->error("Obj: Separator unexpected in point statement"); - } - if (iPos == 0) - { - //if there are no texture coordinates in the file, but normals - if (!vt && vn) { - iPos = 1; - iStep++; - } - } - iPos++; - } + if (*pPtr=='/' ) + { + if (type == aiPrimitiveType_POINT) { + DefaultLogger::get()->error("Obj: Separator unexpected in point statement"); + } + if (iPos == 0) + { + //if there are no texture coordinates in the file, but normals + if (!vt && vn) { + iPos = 1; + iStep++; + } + } + iPos++; + } else if( IsSpaceOrNewLine( *pPtr ) ) - { - iPos = 0; - } - else - { - //OBJ USES 1 Base ARRAYS!!!! - const int iVal = atoi( pPtr ); + { + iPos = 0; + } + else + { + //OBJ USES 1 Base ARRAYS!!!! + const int iVal = atoi( pPtr ); - // increment iStep position based off of the sign and # of digits - int tmp = iVal; - if (iVal < 0) - ++iStep; - while ( ( tmp = tmp / 10 )!=0 ) - ++iStep; + // increment iStep position based off of the sign and # of digits + int tmp = iVal; + if (iVal < 0) + ++iStep; + while ( ( tmp = tmp / 10 )!=0 ) + ++iStep; - if ( iVal > 0 ) - { - // Store parsed index - if ( 0 == iPos ) - { - pIndices->push_back( iVal-1 ); - } - else if ( 1 == iPos ) - { - pTexID->push_back( iVal-1 ); - } - else if ( 2 == iPos ) - { - pNormalID->push_back( iVal-1 ); - hasNormal = true; - } - else - { - reportErrorTokenInFace(); - } - } - else if ( iVal < 0 ) - { - // Store relatively index - if ( 0 == iPos ) - { - pIndices->push_back( vSize + iVal ); - } - else if ( 1 == iPos ) - { - pTexID->push_back( vtSize + iVal ); - } - else if ( 2 == iPos ) - { - pNormalID->push_back( vnSize + iVal ); - hasNormal = true; - } - else - { - reportErrorTokenInFace(); - } - } - } - pPtr += iStep; - } + if ( iVal > 0 ) + { + // Store parsed index + if ( 0 == iPos ) + { + pIndices->push_back( iVal-1 ); + } + else if ( 1 == iPos ) + { + pTexID->push_back( iVal-1 ); + } + else if ( 2 == iPos ) + { + pNormalID->push_back( iVal-1 ); + hasNormal = true; + } + else + { + reportErrorTokenInFace(); + } + } + else if ( iVal < 0 ) + { + // Store relatively index + if ( 0 == iPos ) + { + pIndices->push_back( vSize + iVal ); + } + else if ( 1 == iPos ) + { + pTexID->push_back( vtSize + iVal ); + } + else if ( 2 == iPos ) + { + pNormalID->push_back( vnSize + iVal ); + hasNormal = true; + } + else + { + reportErrorTokenInFace(); + } + } + } + pPtr += iStep; + } - if ( pIndices->empty() ) - { - DefaultLogger::get()->error("Obj: Ignoring empty face"); - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); - return; - } + if ( pIndices->empty() ) + { + DefaultLogger::get()->error("Obj: Ignoring empty face"); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + return; + } - ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID, type ); - - // Set active material, if one set - if (NULL != m_pModel->m_pCurrentMaterial) - face->m_pMaterial = m_pModel->m_pCurrentMaterial; - else - face->m_pMaterial = m_pModel->m_pDefaultMaterial; + ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID, type ); + + // Set active material, if one set + if (NULL != m_pModel->m_pCurrentMaterial) + face->m_pMaterial = m_pModel->m_pCurrentMaterial; + else + face->m_pMaterial = m_pModel->m_pDefaultMaterial; - // Create a default object, if nothing is there - if ( NULL == m_pModel->m_pCurrent ) - createObject( "defaultobject" ); - - // Assign face to mesh - if ( NULL == m_pModel->m_pCurrentMesh ) - { - createMesh(); - } - - // Store the 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_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].size(); - if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal ) - { - m_pModel->m_pCurrentMesh->m_hasNormals = true; - } - // Skip the rest of the line - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + // Create a default object, if nothing is there + if ( NULL == m_pModel->m_pCurrent ) + createObject( "defaultobject" ); + + // Assign face to mesh + if ( NULL == m_pModel->m_pCurrentMesh ) + { + createMesh(); + } + + // Store the 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_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].size(); + if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal ) + { + m_pModel->m_pCurrentMesh->m_hasNormals = true; + } + // Skip the rest of the line + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Get values for a new material description void ObjFileParser::getMaterialDesc() { - // Each material request a new object. - // Sometimes the object is already created (see 'o' tag by example), but it is not initialized ! - // So, we create a new object only if the current on is already initialized ! - if (m_pModel->m_pCurrent != NULL && - ( m_pModel->m_pCurrent->m_Meshes.size() > 1 || - (m_pModel->m_pCurrent->m_Meshes.size() == 1 && m_pModel->m_Meshes[m_pModel->m_pCurrent->m_Meshes[0]]->m_Faces.size() != 0) ) - ) - m_pModel->m_pCurrent = NULL; + // Each material request a new object. + // Sometimes the object is already created (see 'o' tag by example), but it is not initialized ! + // So, we create a new object only if the current on is already initialized ! + if (m_pModel->m_pCurrent != NULL && + ( m_pModel->m_pCurrent->m_Meshes.size() > 1 || + (m_pModel->m_pCurrent->m_Meshes.size() == 1 && m_pModel->m_Meshes[m_pModel->m_pCurrent->m_Meshes[0]]->m_Faces.size() != 0) ) + ) + m_pModel->m_pCurrent = NULL; - // Get next data for material data - m_DataIt = getNextToken(m_DataIt, m_DataItEnd); - if (m_DataIt == m_DataItEnd) - return; + // Get next data for material data + m_DataIt = getNextToken(m_DataIt, m_DataItEnd); + if (m_DataIt == m_DataItEnd) + return; - char *pStart = &(*m_DataIt); + char *pStart = &(*m_DataIt); while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) { ++m_DataIt; } - // Get name - std::string strName(pStart, &(*m_DataIt)); - if ( strName.empty()) - return; + // Get name + std::string strName(pStart, &(*m_DataIt)); + if ( strName.empty()) + return; - // Search for material - std::map::iterator it = m_pModel->m_MaterialMap.find( strName ); - if ( it == m_pModel->m_MaterialMap.end() ) - { - // Not found, use default material - m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; - DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping"); - } - else - { - // Found, using detected material - m_pModel->m_pCurrentMaterial = (*it).second; - if ( needsNewMesh( strName )) - { - createMesh(); - } - m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName ); - } + // Search for material + std::map::iterator it = m_pModel->m_MaterialMap.find( strName ); + if ( it == m_pModel->m_MaterialMap.end() ) + { + // Not found, use default material + m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; + DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping"); + } + else + { + // Found, using detected material + m_pModel->m_pCurrentMaterial = (*it).second; + if ( needsNewMesh( strName )) + { + createMesh(); + } + m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strName ); + } - // Skip rest of line - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + // Skip rest of line + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Get a comment, values will be skipped void ObjFileParser::getComment() { - while (m_DataIt != m_DataItEnd) - { - if ( '\n' == (*m_DataIt)) - { - ++m_DataIt; - break; - } - else - { - ++m_DataIt; - } - } + while (m_DataIt != m_DataItEnd) + { + if ( '\n' == (*m_DataIt)) + { + ++m_DataIt; + break; + } + else + { + ++m_DataIt; + } + } } // ------------------------------------------------------------------- // Get material library from file. void ObjFileParser::getMaterialLib() { - // Translate tuple - m_DataIt = getNextToken(m_DataIt, m_DataItEnd); + // Translate tuple + m_DataIt = getNextToken(m_DataIt, m_DataItEnd); if( m_DataIt == m_DataItEnd ) { return; } - - char *pStart = &(*m_DataIt); + + char *pStart = &(*m_DataIt); while( m_DataIt != m_DataItEnd && !IsLineEnd( *m_DataIt ) ) { ++m_DataIt; } - // Check for existence - const std::string strMatName(pStart, &(*m_DataIt)); - IOStream *pFile = m_pIO->Open(strMatName); + // Check for existence + const std::string strMatName(pStart, &(*m_DataIt)); + IOStream *pFile = m_pIO->Open(strMatName); - if (!pFile ) - { - DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName); - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); - return; - } + if (!pFile ) + { + DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + return; + } - // Import material library data from file - std::vector buffer; - BaseImporter::TextFileToBuffer(pFile,buffer); - m_pIO->Close( pFile ); + // Import material library data from file + std::vector buffer; + BaseImporter::TextFileToBuffer(pFile,buffer); + m_pIO->Close( pFile ); - // Importing the material library - ObjFileMtlImporter mtlImporter( buffer, strMatName, m_pModel ); + // Importing the material library + ObjFileMtlImporter mtlImporter( buffer, strMatName, m_pModel ); } // ------------------------------------------------------------------- // Set a new material definition as the current material. void ObjFileParser::getNewMaterial() { - m_DataIt = getNextToken(m_DataIt, m_DataItEnd); - m_DataIt = getNextWord(m_DataIt, m_DataItEnd); + m_DataIt = getNextToken(m_DataIt, m_DataItEnd); + m_DataIt = getNextWord(m_DataIt, m_DataItEnd); if( m_DataIt == m_DataItEnd ) { return; } - char *pStart = &(*m_DataIt); - std::string strMat( pStart, *m_DataIt ); + char *pStart = &(*m_DataIt); + std::string strMat( pStart, *m_DataIt ); while( m_DataIt != m_DataItEnd && IsSpaceOrNewLine( *m_DataIt ) ) { ++m_DataIt; } - std::map::iterator it = m_pModel->m_MaterialMap.find( strMat ); - if ( it == m_pModel->m_MaterialMap.end() ) - { - // Show a warning, if material was not found - DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat); - m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; - } - else - { - // Set new material - if ( needsNewMesh( strMat ) ) - { - createMesh(); - } - m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat ); - } + std::map::iterator it = m_pModel->m_MaterialMap.find( strMat ); + if ( it == m_pModel->m_MaterialMap.end() ) + { + // Show a warning, if material was not found + DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat); + m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial; + } + else + { + // Set new material + if ( needsNewMesh( strMat ) ) + { + createMesh(); + } + m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat ); + } - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- int ObjFileParser::getMaterialIndex( const std::string &strMaterialName ) { - int mat_index = -1; + int mat_index = -1; if( strMaterialName.empty() ) { return mat_index; } - for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index) - { - if ( strMaterialName == m_pModel->m_MaterialLib[ index ]) - { - mat_index = (int)index; - break; - } - } - return mat_index; + for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index) + { + if ( strMaterialName == m_pModel->m_MaterialLib[ index ]) + { + mat_index = (int)index; + break; + } + } + return mat_index; } // ------------------------------------------------------------------- // Getter for a group name. void ObjFileParser::getGroupName() { - std::string strGroupName; + std::string strGroupName; - m_DataIt = getName(m_DataIt, m_DataItEnd, strGroupName); + m_DataIt = getName(m_DataIt, m_DataItEnd, strGroupName); if( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) { return; } - // Change active group, if necessary - if ( m_pModel->m_strActiveGroup != strGroupName ) - { - // Search for already existing entry - ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(strGroupName); - - // We are mapping groups into the object structure - createObject( strGroupName ); - - // New group name, creating a new entry - if (it == m_pModel->m_Groups.end()) - { - std::vector *pFaceIDArray = new std::vector; - m_pModel->m_Groups[ strGroupName ] = pFaceIDArray; - m_pModel->m_pGroupFaceIDs = (pFaceIDArray); - } - else - { - m_pModel->m_pGroupFaceIDs = (*it).second; - } - m_pModel->m_strActiveGroup = strGroupName; - } - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + // Change active group, if necessary + if ( m_pModel->m_strActiveGroup != strGroupName ) + { + // Search for already existing entry + ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(strGroupName); + + // We are mapping groups into the object structure + createObject( strGroupName ); + + // New group name, creating a new entry + if (it == m_pModel->m_Groups.end()) + { + std::vector *pFaceIDArray = new std::vector; + m_pModel->m_Groups[ strGroupName ] = pFaceIDArray; + m_pModel->m_pGroupFaceIDs = (pFaceIDArray); + } + else + { + m_pModel->m_pGroupFaceIDs = (*it).second; + } + m_pModel->m_strActiveGroup = strGroupName; + } + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Not supported void ObjFileParser::getGroupNumber() { - // Not used + // Not used - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Not supported void ObjFileParser::getGroupNumberAndResolution() { - // Not used + // Not used - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- @@ -660,105 +660,105 @@ void ObjFileParser::getGroupNumberAndResolution() // identify it. void ObjFileParser::getObjectName() { - m_DataIt = getNextToken(m_DataIt, m_DataItEnd); + m_DataIt = getNextToken(m_DataIt, m_DataItEnd); if( m_DataIt == m_DataItEnd ) { return; } - char *pStart = &(*m_DataIt); + char *pStart = &(*m_DataIt); while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) { ++m_DataIt; } - std::string strObjectName(pStart, &(*m_DataIt)); - if (!strObjectName.empty()) - { - // Reset current object - m_pModel->m_pCurrent = NULL; - - // Search for actual object - for (std::vector::const_iterator it = m_pModel->m_Objects.begin(); - it != m_pModel->m_Objects.end(); - ++it) - { - if ((*it)->m_strObjName == strObjectName) - { - m_pModel->m_pCurrent = *it; - break; - } - } + std::string strObjectName(pStart, &(*m_DataIt)); + if (!strObjectName.empty()) + { + // Reset current object + m_pModel->m_pCurrent = NULL; + + // Search for actual object + for (std::vector::const_iterator it = m_pModel->m_Objects.begin(); + it != m_pModel->m_Objects.end(); + ++it) + { + if ((*it)->m_strObjName == strObjectName) + { + m_pModel->m_pCurrent = *it; + break; + } + } - // Allocate a new object, if current one was not found before + // Allocate a new object, if current one was not found before if( NULL == m_pModel->m_pCurrent ) { createObject( strObjectName ); } - } - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + } + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } // ------------------------------------------------------------------- // Creates a new object instance void ObjFileParser::createObject(const std::string &strObjectName) { - ai_assert( NULL != m_pModel ); - //ai_assert( !strObjectName.empty() ); + ai_assert( NULL != m_pModel ); + //ai_assert( !strObjectName.empty() ); - m_pModel->m_pCurrent = new ObjFile::Object; - m_pModel->m_pCurrent->m_strObjName = strObjectName; - m_pModel->m_Objects.push_back( m_pModel->m_pCurrent ); - - createMesh(); + m_pModel->m_pCurrent = new ObjFile::Object; + m_pModel->m_pCurrent->m_strObjName = strObjectName; + m_pModel->m_Objects.push_back( m_pModel->m_pCurrent ); + + createMesh(); - if( m_pModel->m_pCurrentMaterial ) - { - m_pModel->m_pCurrentMesh->m_uiMaterialIndex = - getMaterialIndex( m_pModel->m_pCurrentMaterial->MaterialName.data ); - m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial; - } + if( m_pModel->m_pCurrentMaterial ) + { + m_pModel->m_pCurrentMesh->m_uiMaterialIndex = + getMaterialIndex( m_pModel->m_pCurrentMaterial->MaterialName.data ); + 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."); - } + 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 ) { - if(m_pModel->m_pCurrentMesh == 0) - { - // No mesh data yet - return true; - } - bool newMat = false; - int matIdx = getMaterialIndex( rMaterialName ); - int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex; - if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) || curMatIdx != matIdx ) - { - // New material -> only one material per mesh, so we need to create a new - // material - newMat = true; - } - return newMat; + if(m_pModel->m_pCurrentMesh == 0) + { + // No mesh data yet + return true; + } + bool newMat = false; + int matIdx = getMaterialIndex( rMaterialName ); + int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex; + if ( curMatIdx != int(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. void ObjFileParser::reportErrorTokenInFace() { - m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); - DefaultLogger::get()->error("OBJ: Not supported token in face description detected"); + m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); + DefaultLogger::get()->error("OBJ: Not supported token in face description detected"); } // ------------------------------------------------------------------- diff --git a/code/ParsingUtils.h b/code/ParsingUtils.h index 25495fd51..ce15f790f 100644 --- a/code/ParsingUtils.h +++ b/code/ParsingUtils.h @@ -64,7 +64,7 @@ static const unsigned int BufferSize = 4096; template AI_FORCE_INLINE char_t ToLower( char_t in) { - return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in; + return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in; } // --------------------------------------------------------------------------------- @@ -77,35 +77,35 @@ AI_FORCE_INLINE char_t ToUpper( char_t in) { template AI_FORCE_INLINE bool IsUpper( char_t in) { - return (in >= (char_t)'A' && in <= (char_t)'Z'); + return (in >= (char_t)'A' && in <= (char_t)'Z'); } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsLower( char_t in) { - return (in >= (char_t)'a' && in <= (char_t)'z'); + return (in >= (char_t)'a' && in <= (char_t)'z'); } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsSpace( char_t in) { - return (in == (char_t)' ' || in == (char_t)'\t'); + return (in == (char_t)' ' || in == (char_t)'\t'); } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsLineEnd( char_t in) { - return (in==(char_t)'\r'||in==(char_t)'\n'||in==(char_t)'\0'||in==(char_t)'\f'); + return (in==(char_t)'\r'||in==(char_t)'\n'||in==(char_t)'\0'||in==(char_t)'\f'); } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in) { - return IsSpace(in) || IsLineEnd(in); + return IsSpace(in) || IsLineEnd(in); } // --------------------------------------------------------------------------------- @@ -115,15 +115,15 @@ AI_FORCE_INLINE bool SkipSpaces( const char_t* in, const char_t** out) while( *in == ( char_t )' ' || *in == ( char_t )'\t' ) { ++in; } - *out = in; - return !IsLineEnd(*in); + *out = in; + return !IsLineEnd(*in); } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipSpaces( const char_t** inout) { - return SkipSpaces(*inout,inout); + return SkipSpaces(*inout,inout); } // --------------------------------------------------------------------------------- @@ -134,19 +134,19 @@ AI_FORCE_INLINE bool SkipLine( const char_t* in, const char_t** out) ++in; } - // files are opened in binary mode. Ergo there are both NL and CR + // files are opened in binary mode. Ergo there are both NL and CR while( *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { ++in; } - *out = in; - return *in != (char_t)'\0'; + *out = in; + return *in != (char_t)'\0'; } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipLine( const char_t** inout) { - return SkipLine(*inout,inout); + return SkipLine(*inout,inout); } // --------------------------------------------------------------------------------- @@ -156,15 +156,15 @@ AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t* in, const char_t** out) while( *in == ( char_t )' ' || *in == ( char_t )'\t' || *in == ( char_t )'\r' || *in == ( char_t )'\n' ) { ++in; } - *out = in; - return *in != '\0'; + *out = in; + return *in != '\0'; } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout) { - return SkipSpacesAndLineEnd(*inout,inout); + return SkipSpacesAndLineEnd(*inout,inout); } // --------------------------------------------------------------------------------- @@ -175,12 +175,12 @@ AI_FORCE_INLINE bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize return false; } - char* _out = out; + char* _out = out; char* const end = _out + BufferSize; while( !IsLineEnd( *buffer ) && _out < end ) { *_out++ = *buffer++; } - *_out = (char_t)'\0'; + *_out = (char_t)'\0'; while( IsLineEnd( *buffer ) && '\0' != *buffer ) { ++buffer; @@ -193,19 +193,19 @@ AI_FORCE_INLINE bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize template AI_FORCE_INLINE bool IsNumeric( char_t in) { - return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in; + return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in; } // --------------------------------------------------------------------------------- template AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len) { - if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) { - in += len+1; - return true; - } + if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) { + in += len+1; + return true; + } - return false; + return false; } // --------------------------------------------------------------------------------- /** @brief Case-ignoring version of TokenMatch @@ -215,25 +215,25 @@ AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len */ AI_FORCE_INLINE bool TokenMatchI(const char*& in, const char* token, unsigned int len) { - if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) { - in += len+1; - return true; - } - return false; + if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) { + in += len+1; + return true; + } + return false; } // --------------------------------------------------------------------------------- AI_FORCE_INLINE void SkipToken(const char*& in) { - SkipSpaces(&in); - while (!IsSpaceOrNewLine(*in))++in; + SkipSpaces(&in); + while (!IsSpaceOrNewLine(*in))++in; } // --------------------------------------------------------------------------------- AI_FORCE_INLINE std::string GetNextToken(const char*& in) { - SkipSpacesAndLineEnd(&in); - const char* cur = in; - while (!IsSpaceOrNewLine(*in))++in; - return std::string(cur,(size_t)(in-cur)); + SkipSpacesAndLineEnd(&in); + const char* cur = in; + while (!IsSpaceOrNewLine(*in))++in; + return std::string(cur,(size_t)(in-cur)); } // --------------------------------------------------------------------------------- diff --git a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h index 9e978ade2..179a51326 100644 --- a/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h +++ b/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h @@ -62,7 +62,7 @@ bool isSpace( const T in ) { template inline bool isNewLine( const T in ) { - return ( '\n' == in ); + return ( '\n' == in || ( '\r' == in ) ); } template