From cf7059f074755566a89dd1220fbbc1928ca19068 Mon Sep 17 00:00:00 2001 From: Alberto Taiuti Date: Thu, 10 Nov 2016 23:12:36 +0000 Subject: [PATCH] Fix obj .mtl file loading Fix the obj file loader by adding a new method which allows a name to be read considering the space in the middle between two words and use that for parsing the "mtlib" line in the .obj file parsing method. Before, the method used in the obj parsing function would have returned the string "mtlib NAME_OF_MTL" instead of "mtlib" only, which resulted in the .mtl file being never parsed. --- code/ObjFileParser.cpp | 2 +- code/ObjTools.h | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/code/ObjFileParser.cpp b/code/ObjFileParser.cpp index 3cf9e5f..27e4b27 100644 --- a/code/ObjFileParser.cpp +++ b/code/ObjFileParser.cpp @@ -178,7 +178,7 @@ void ObjFileParser::parseFile( IOStreamBuffer &streamBuffer ) { { std::string name; - getName(m_DataIt, m_DataItEnd, name); + getNameNoSpace(m_DataIt, m_DataItEnd, name); size_t nextSpace = name.find(" "); if (nextSpace != std::string::npos) diff --git a/code/ObjTools.h b/code/ObjTools.h index e58bf0c..b0978a1 100644 --- a/code/ObjTools.h +++ b/code/ObjTools.h @@ -165,6 +165,47 @@ inline char_t getName( char_t it, char_t end, std::string &name ) return it; } +/** @brief Get a name from the current line. Do not preserve space + * in the middle, but trim it at the end. + * @param it set to current position + * @param end set to end of scratch buffer for readout + * @param name Separated name + * @return Current-iterator with new position + */ +template +inline char_t getNameNoSpace( char_t it, char_t end, std::string &name ) +{ + name = ""; + if( isEndOfBuffer( it, end ) ) { + return end; + } + + char *pStart = &( *it ); + while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) + && !IsSpaceOrNewLine( *it ) ) { + ++it; + } + + while( isEndOfBuffer( it, end ) || IsLineEnd( *it ) + || IsSpaceOrNewLine( *it ) ) { + --it; + } + ++it; + + // Get name + // if there is no name, and the previous char is a separator, come back to start + while (&(*it) < pStart) { + ++it; + } + std::string strName( pStart, &(*it) ); + if ( strName.empty() ) + return it; + else + name = strName; + + return it; +} + /** @brief Get next word from given line * @param it set to current position * @param end set to end of scratch buffer for readout -- 2.7.4