diff --git a/code/ObjFileData.h b/code/ObjFileData.h index 370d0e4fb..f4abd643f 100644 --- a/code/ObjFileData.h +++ b/code/ObjFileData.h @@ -240,6 +240,8 @@ struct Mesh { unsigned int m_uiMaterialIndex; /// True, if normals are stored. bool m_hasNormals; + /// True, if vertex colors are stored. + bool m_hasVertexColors; /// Constructor explicit Mesh( const std::string &name ) @@ -289,6 +291,8 @@ struct Model std::vector m_Vertices; //! vector with all generated normals std::vector m_Normals; + //! vector with all vertex colors + std::vector m_VertexColors; //! Group map GroupMap m_Groups; //! Group to face id assignment diff --git a/code/ObjFileImporter.cpp b/code/ObjFileImporter.cpp index a0e016ba5..082709dc7 100644 --- a/code/ObjFileImporter.cpp +++ b/code/ObjFileImporter.cpp @@ -416,6 +416,10 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, if ( !pModel->m_Normals.empty() && pObjMesh->m_hasNormals ) pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ]; + // Allocate buffer for vertex-color vectors + if ( !pModel->m_VertexColors.empty() ) + pMesh->mColors[0] = new aiColor4D[ pMesh->mNumVertices ]; + // Allocate buffer for texture coordinates if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] ) { @@ -449,6 +453,13 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ]; } + // Copy all vertex colors + if ( !pModel->m_VertexColors.empty()) + { + const aiVector3D color = pModel->m_VertexColors[ vertex ]; + pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0); + } + // Copy all texture coordinates if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_pTexturCoords->size()) { diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index a6f515aba..79bc299bc 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -136,8 +136,14 @@ void ObjFileParser::parseFile() { ++m_DataIt; if (*m_DataIt == ' ' || *m_DataIt == '\t') { - // read in vertex definition - getVector3(m_pModel->m_Vertices); + size_t numComponents = getNumComponentsInLine(); + if (numComponents == 3) { + // read in vertex definition + getVector3(m_pModel->m_Vertices); + } else if (numComponents == 6) { + // read vertex and vertex-color + getTwoVectors3(m_pModel->m_Vertices, m_pModel->m_VertexColors); + } } else if (*m_DataIt == 't') { // read in texture coordinate ( 2D or 3D ) ++m_DataIt; @@ -257,8 +263,7 @@ void ObjFileParser::copyNextLine(char *pBuffer, size_t length) pBuffer[ index ] = '\0'; } -// ------------------------------------------------------------------- -void ObjFileParser::getVector( std::vector &point3d_array ) { +size_t ObjFileParser::getNumComponentsInLine() { size_t numComponents( 0 ); const char* tmp( &m_DataIt[0] ); while( !IsLineEnd( *tmp ) ) { @@ -268,6 +273,12 @@ void ObjFileParser::getVector( std::vector &point3d_array ) { SkipToken( tmp ); ++numComponents; } + return numComponents; +} + +// ------------------------------------------------------------------- +void ObjFileParser::getVector( std::vector &point3d_array ) { + size_t numComponents = getNumComponentsInLine(); float x, y, z; if( 2 == numComponents ) { copyNextWord( m_buffer, Buffersize ); @@ -309,6 +320,35 @@ void ObjFileParser::getVector3( std::vector &point3d_array ) { m_DataIt = skipLine( m_DataIt, m_DataItEnd, m_uiLine ); } +// ------------------------------------------------------------------- +// Get values for two 3D vectors on the same line +void ObjFileParser::getTwoVectors3( std::vector &point3d_array_a, std::vector &point3d_array_b ) { + 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_a.push_back( aiVector3D( 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_b.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 ) { diff --git a/code/ObjFileParser.h b/code/ObjFileParser.h index 7170f0d50..f1be764f0 100644 --- a/code/ObjFileParser.h +++ b/code/ObjFileParser.h @@ -89,6 +89,8 @@ private: void getVector( std::vector &point3d_array ); /// Stores the following 3d vector. void getVector3( std::vector &point3d_array ); + /// Stores the following two 3d vectors on the line. + void getTwoVectors3( std::vector &point3d_array_a, std::vector &point3d_array_b ); /// Stores the following 3d vector. void getVector2(std::vector &point2d_array); /// Stores the following face. @@ -119,6 +121,8 @@ private: bool needsNewMesh( const std::string &rMaterialName ); /// Error report in token void reportErrorTokenInFace(); + /// Get the number of components in a line. + size_t getNumComponentsInLine(); private: // Copy and assignment constructor should be private