Example #1
0
// -------------------------------------------------------------------
//	Get values for a new face instance
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++;
		}
		else if ( isSeparator(*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 );
}
Example #2
0
// -------------------------------------------------------------------
//	Get values for a new face instance
void ObjFileParser::getFace()
{
	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 == '\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;
	

	bool vt = (!m_pModel->m_TextureCoord.empty());
	bool vn = (!m_pModel->m_Normals.empty());
	int iStep = 0, iPos = 0;
	while (pPtr != pEnd)
	{
		iStep = 1;
		if (*pPtr == '\0')
			break;

		if (*pPtr=='\r')
			break;

		if (*pPtr=='/' )
		{
			if (iPos == 0)
			{
				//if there are no texturecoordinates in the obj file but normals
				if (!vt && vn) {
					iPos = 1;
					iStep++;
				}
			}
			iPos++;
		}
		else if ( isSeparator(*pPtr) )
		{
			iPos = 0;
		}
		else 
		{
			//OBJ USES 1 Base ARRAYS!!!!
			const int iVal = atoi( pPtr );
			int tmp = iVal;
			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();
				}
			}
		}
		for ( int i=0; i<iStep; i++ )
			++pPtr;
	}

	ObjFile::Face *face = new ObjFile::Face(pIndices, pNormalID, pTexID);
	
	// 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 there
	if ( NULL == m_pModel->m_pCurrent )
		createObject("defaultobject");

	// Store the new instance
	m_pModel->m_pCurrent->m_Faces.push_back(face);
	
	// Assign face to mesh
	if ( NULL == m_pModel->m_pCurrentMesh )
	{
		m_pModel->m_pCurrentMesh = new ObjFile::Mesh();
		m_pModel->m_Meshes.push_back( m_pModel->m_pCurrentMesh );
	}
	
	// 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 );
}