2
0
Эх сурвалжийг харах

fix invalid line endling handling.

Signed-off-by: Kim Kulling <[email protected]>
Kim Kulling 10 жил өмнө
parent
commit
bd1168af30

+ 486 - 486
code/ObjFileParser.cpp

@@ -57,177 +57,177 @@ const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	Constructor with loaded data and directories.
 //	Constructor with loaded data and directories.
 ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem *io ) :
 ObjFileParser::ObjFileParser(std::vector<char> &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
     // 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_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
 //	Destructor
 ObjFileParser::~ObjFileParser()
 ObjFileParser::~ObjFileParser()
 {
 {
-	delete m_pModel;
-	m_pModel = NULL;
+    delete m_pModel;
+    m_pModel = NULL;
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	Returns a pointer to the model instance.
 //	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.
 //	File parsing method.
 void ObjFileParser::parseFile()
 void ObjFileParser::parseFile()
 {
 {
-	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 )
+    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 )
                                         ++m_DataIt;
                                         ++m_DataIt;
                                         getVector( m_pModel->m_TextureCoord );
                                         getVector( m_pModel->m_TextureCoord );
-				} 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 '#': // Parse a comment
-			{
-				getComment();
-			}
-			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 'g': // Parse group name
-			{
-				getGroupName();
-			}
-			break;
-
-		case 's': // Parse group number
-			{
-				getGroupNumber();
-			}
-			break;
-
-		case 'o': // Parse object name
-			{
-				getObjectName();
-			}
-			break;
-		
-		default:
-			{
-				m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-			}
-			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 '#': // Parse a comment
+            {
+                getComment();
+            }
+            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 'g': // Parse group name
+            {
+                getGroupName();
+            }
+            break;
+
+        case 's': // Parse group number
+            {
+                getGroupNumber();
+            }
+            break;
+
+        case 'o': // Parse object name
+            {
+                getObjectName();
+            }
+            break;
+        
+        default:
+            {
+                m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+            }
+            break;
+        }
+    }
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	Copy the next word in a temporary buffer
 //	Copy the next word in a temporary buffer
 void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
 void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
 {
 {
-	size_t index = 0;
-	m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
+    size_t index = 0;
+    m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
     while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
     while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
-		pBuffer[index] = *m_DataIt;
-		index++;
+        pBuffer[index] = *m_DataIt;
+        index++;
         if( index == length - 1 ) {
         if( index == length - 1 ) {
             break;
             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
 // Copy the next line into a temporary buffer
 void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
 void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
 {
 {
-	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;
-		}
-
-		continuation = false;
-		pBuffer[ index++ ] = c;
-	}
-	ai_assert(index < length);
-	pBuffer[ index ] = '\0';
+    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;
+        }
+
+        continuation = false;
+        pBuffer[ index++ ] = c;
+    }
+    ai_assert(index < length);
+    pBuffer[ index ] = '\0';
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
@@ -268,391 +268,391 @@ void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	Get values for a new 3D vector instance
 //	Get values for a new 3D vector instance
 void ObjFileParser::getVector3(std::vector<aiVector3D> &point3d_array) {
 void ObjFileParser::getVector3(std::vector<aiVector3D> &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 );
     copyNextWord( m_buffer, BUFFERSIZE );
     z = ( float ) fast_atof( m_buffer );
     z = ( float ) fast_atof( m_buffer );
 
 
-	point3d_array.push_back( aiVector3D( x, y, z ) );
-	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+    point3d_array.push_back( aiVector3D( x, y, z ) );
+    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	Get values for a new 2D vector instance
 //	Get values for a new 2D vector instance
 void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
 void ObjFileParser::getVector2( std::vector<aiVector2D> &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<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	Get values for a new face instance
 //	Get values for a new face instance
 void ObjFileParser::getFace(aiPrimitiveType type)
 void ObjFileParser::getFace(aiPrimitiveType type)
 {
 {
-	copyNextLine(m_buffer, BUFFERSIZE);
-	if (m_DataIt == m_DataItEnd)
-		return;
-
-	char *pPtr = m_buffer;
-	char *pEnd = &pPtr[BUFFERSIZE];
-	pPtr = getNextToken<char*>(pPtr, pEnd);
-	if (pPtr == pEnd || *pPtr == '\0')
-		return;
-
-	std::vector<unsigned int> *pIndices = 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>;
-	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 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 (*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++;
-		}
+    copyNextLine(m_buffer, BUFFERSIZE);
+    if (m_DataIt == m_DataItEnd)
+        return;
+
+    char *pPtr = m_buffer;
+    char *pEnd = &pPtr[BUFFERSIZE];
+    pPtr = getNextToken<char*>(pPtr, pEnd);
+    if (pPtr == pEnd || *pPtr == '\0')
+        return;
+
+    std::vector<unsigned int> *pIndices = 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>;
+    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 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 (*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 ) )
         else if( IsSpaceOrNewLine( *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;
-
-			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<DataArrayIt>( 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;
-
-	// 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<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+        {
+            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;
+
+            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<DataArrayIt>( 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;
+
+    // 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<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	Get values for a new material description
 //	Get values for a new material description
 void ObjFileParser::getMaterialDesc()
 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;
-
-	// Get next data for material data
-	m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
-	if (m_DataIt == m_DataItEnd)
-		return;
-
-	char *pStart = &(*m_DataIt);
+    // 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<DataArrayIt>(m_DataIt, m_DataItEnd);
+    if (m_DataIt == m_DataItEnd)
+        return;
+
+    char *pStart = &(*m_DataIt);
     while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
     while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
         ++m_DataIt;
         ++m_DataIt;
     }
     }
 
 
-	// Get name
-	std::string strName(pStart, &(*m_DataIt));
-	if ( strName.empty())
-		return;
-
-	// Search for material
-	std::map<std::string, ObjFile::Material*>::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<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+    // Get name
+    std::string strName(pStart, &(*m_DataIt));
+    if ( strName.empty())
+        return;
+
+    // Search for material
+    std::map<std::string, ObjFile::Material*>::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<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	Get a comment, values will be skipped
 //	Get a comment, values will be skipped
 void ObjFileParser::getComment()
 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.
 //	Get material library from file.
 void ObjFileParser::getMaterialLib()
 void ObjFileParser::getMaterialLib()
 {
 {
-	// Translate tuple
-	m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
+    // Translate tuple
+    m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
     if( m_DataIt == m_DataItEnd ) {
     if( m_DataIt == m_DataItEnd ) {
         return;
         return;
     }
     }
-	
-	char *pStart = &(*m_DataIt);
+    
+    char *pStart = &(*m_DataIt);
     while( m_DataIt != m_DataItEnd && !IsLineEnd( *m_DataIt ) ) {
     while( m_DataIt != m_DataItEnd && !IsLineEnd( *m_DataIt ) ) {
         ++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<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-		return;
-	}
+    if (!pFile )
+    {
+        DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName);
+        m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+        return;
+    }
 
 
-	// Import material library data from file
-	std::vector<char> buffer;
-	BaseImporter::TextFileToBuffer(pFile,buffer);
-	m_pIO->Close( pFile );
+    // Import material library data from file
+    std::vector<char> 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.
 //	Set a new material definition as the current material.
 void ObjFileParser::getNewMaterial()
 void ObjFileParser::getNewMaterial()
 {
 {
-	m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
-	m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
+    m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
+    m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
     if( m_DataIt == m_DataItEnd ) {
     if( m_DataIt == m_DataItEnd ) {
         return;
         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 ) ) {
     while( m_DataIt != m_DataItEnd && IsSpaceOrNewLine( *m_DataIt ) ) {
         ++m_DataIt;
         ++m_DataIt;
     }
     }
-	std::map<std::string, ObjFile::Material*>::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<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+    std::map<std::string, ObjFile::Material*>::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<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 int ObjFileParser::getMaterialIndex( const std::string &strMaterialName )
 int ObjFileParser::getMaterialIndex( const std::string &strMaterialName )
 {
 {
-	int mat_index = -1;
+    int mat_index = -1;
     if( strMaterialName.empty() ) {
     if( strMaterialName.empty() ) {
         return mat_index;
         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.  
 //	Getter for a group name.  
 void ObjFileParser::getGroupName()
 void ObjFileParser::getGroupName()
 {
 {
-	std::string strGroupName;
+    std::string strGroupName;
    
    
-	m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName);
+    m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName);
     if( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) {
     if( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) {
         return;
         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<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
-			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<DataArrayIt>( 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<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
+            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<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	Not supported
 //	Not supported
 void ObjFileParser::getGroupNumber()
 void ObjFileParser::getGroupNumber()
 {
 {
-	// Not used
+    // Not used
 
 
-	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	Not supported
 //	Not supported
 void ObjFileParser::getGroupNumberAndResolution()
 void ObjFileParser::getGroupNumberAndResolution()
 {
 {
-	// Not used
+    // Not used
 
 
-	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
@@ -660,105 +660,105 @@ void ObjFileParser::getGroupNumberAndResolution()
 //	identify it.
 //	identify it.
 void ObjFileParser::getObjectName()
 void ObjFileParser::getObjectName()
 {
 {
-	m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
+    m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
     if( m_DataIt == m_DataItEnd ) {
     if( m_DataIt == m_DataItEnd ) {
         return;
         return;
     }
     }
-	char *pStart = &(*m_DataIt);
+    char *pStart = &(*m_DataIt);
     while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
     while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
         ++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<ObjFile::Object*>::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
+    std::string strObjectName(pStart, &(*m_DataIt));
+    if (!strObjectName.empty()) 
+    {
+        // Reset current object
+        m_pModel->m_pCurrent = NULL;
+        
+        // Search for actual object
+        for (std::vector<ObjFile::Object*>::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
         if( NULL == m_pModel->m_pCurrent ) {
         if( NULL == m_pModel->m_pCurrent ) {
             createObject( strObjectName );
             createObject( strObjectName );
         }
         }
-	}
-	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+    }
+    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
 }
 }
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------
 //	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( !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();
-
-	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;
-	}		
+    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();
+
+    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
 //	Creates a new mesh
 void ObjFileParser::createMesh()
 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.
 //	Returns true, if a new mesh must be created.
 bool ObjFileParser::needsNewMesh( const std::string &rMaterialName )
 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.
 //	Shows an error in parsing process.
 void ObjFileParser::reportErrorTokenInFace()
 void ObjFileParser::reportErrorTokenInFace()
 {		
 {		
-	m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-	DefaultLogger::get()->error("OBJ: Not supported token in face description detected");
+    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
+    DefaultLogger::get()->error("OBJ: Not supported token in face description detected");
 }
 }
 
 
 // -------------------------------------------------------------------
 // -------------------------------------------------------------------

+ 35 - 35
code/ParsingUtils.h

@@ -64,7 +64,7 @@ static const unsigned int BufferSize = 4096;
 template <class char_t>
 template <class char_t>
 AI_FORCE_INLINE char_t ToLower( char_t in)
 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 <class char_t>
 template <class char_t>
 AI_FORCE_INLINE bool IsUpper( char_t in)
 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 <class char_t>
 template <class char_t>
 AI_FORCE_INLINE bool IsLower( char_t in)
 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 <class char_t>
 template <class char_t>
 AI_FORCE_INLINE bool IsSpace( char_t in)
 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 <class char_t>
 template <class char_t>
 AI_FORCE_INLINE bool IsLineEnd( char_t in)
 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 <class char_t>
 template <class char_t>
 AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in)
 AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in)
 {
 {
-	return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
+    return IsSpace<char_t>(in) || IsLineEnd<char_t>(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' ) {
     while( *in == ( char_t )' ' || *in == ( char_t )'\t' ) {
         ++in;
         ++in;
     }
     }
-	*out = in;
-	return !IsLineEnd<char_t>(*in);
+    *out = in;
+    return !IsLineEnd<char_t>(*in);
 }
 }
 
 
 // ---------------------------------------------------------------------------------
 // ---------------------------------------------------------------------------------
 template <class char_t>
 template <class char_t>
 AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
 AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
 {
 {
-	return SkipSpaces<char_t>(*inout,inout);
+    return SkipSpaces<char_t>(*inout,inout);
 }
 }
 
 
 // ---------------------------------------------------------------------------------
 // ---------------------------------------------------------------------------------
@@ -134,19 +134,19 @@ AI_FORCE_INLINE bool SkipLine( const char_t* in, const char_t** out)
         ++in;
         ++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' ) {
     while( *in == ( char_t )'\r' || *in == ( char_t )'\n' ) {
         ++in;
         ++in;
     }
     }
-	*out = in;
-	return *in != (char_t)'\0';
+    *out = in;
+    return *in != (char_t)'\0';
 }
 }
 
 
 // ---------------------------------------------------------------------------------
 // ---------------------------------------------------------------------------------
 template <class char_t>
 template <class char_t>
 AI_FORCE_INLINE bool SkipLine( const char_t** inout)
 AI_FORCE_INLINE bool SkipLine( const char_t** inout)
 {
 {
-	return SkipLine<char_t>(*inout,inout);
+    return SkipLine<char_t>(*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' ) {
     while( *in == ( char_t )' ' || *in == ( char_t )'\t' || *in == ( char_t )'\r' || *in == ( char_t )'\n' ) {
         ++in;
         ++in;
     }
     }
-	*out = in;
-	return *in != '\0';
+    *out = in;
+    return *in != '\0';
 }
 }
 
 
 // ---------------------------------------------------------------------------------
 // ---------------------------------------------------------------------------------
 template <class char_t>
 template <class char_t>
 AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout)
 AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout)
 {
 {
-	return SkipSpacesAndLineEnd<char_t>(*inout,inout);
+    return SkipSpacesAndLineEnd<char_t>(*inout,inout);
 }
 }
 
 
 // ---------------------------------------------------------------------------------
 // ---------------------------------------------------------------------------------
@@ -175,12 +175,12 @@ AI_FORCE_INLINE bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize
         return false;
         return false;
     }
     }
 
 
-	char* _out = out;
+    char* _out = out;
     char* const end = _out + BufferSize;
     char* const end = _out + BufferSize;
     while( !IsLineEnd( *buffer ) && _out < end ) {
     while( !IsLineEnd( *buffer ) && _out < end ) {
         *_out++ = *buffer++;
         *_out++ = *buffer++;
     }
     }
-	*_out = (char_t)'\0';
+    *_out = (char_t)'\0';
 
 
     while( IsLineEnd( *buffer ) && '\0' != *buffer ) {
     while( IsLineEnd( *buffer ) && '\0' != *buffer ) {
         ++buffer;
         ++buffer;
@@ -193,19 +193,19 @@ AI_FORCE_INLINE bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize
 template <class char_t>
 template <class char_t>
 AI_FORCE_INLINE bool IsNumeric( char_t in)
 AI_FORCE_INLINE bool IsNumeric( char_t in)
 {
 {
-	return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
+    return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
 }
 }
 
 
 // ---------------------------------------------------------------------------------
 // ---------------------------------------------------------------------------------
 template <class char_t>
 template <class char_t>
 AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len)
 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
 /** @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)
 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)
 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)
 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));
 }
 }
 
 
 // ---------------------------------------------------------------------------------
 // ---------------------------------------------------------------------------------

+ 1 - 1
contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h

@@ -62,7 +62,7 @@ bool isSpace( const T in ) {
 template<class T>
 template<class T>
 inline
 inline
 bool isNewLine( const T in ) {
 bool isNewLine( const T in ) {
-    return ( '\n' == in );
+    return ( '\n' == in || ( '\r' == in ) );
 }
 }
 
 
 template<class T>
 template<class T>