// ------------------------------------------------------------------- // 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 ); }
// ------------------------------------------------------------------- // 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 ); }