| 182 | } |
| 183 | |
| 184 | void ObjLoader::parse( bool includeNormals, bool includeTexCoords ) |
| 185 | { |
| 186 | Group *currentGroup; |
| 187 | mGroups.push_back( Group() ); |
| 188 | currentGroup = &mGroups[mGroups.size()-1]; |
| 189 | currentGroup->mBaseVertexOffset = currentGroup->mBaseTexCoordOffset = currentGroup->mBaseNormalOffset = 0; |
| 190 | |
| 191 | const Material *currentMaterial = 0; |
| 192 | |
| 193 | size_t lineNumber = 0; |
| 194 | while( ! mStream->isEof() ) { |
| 195 | lineNumber++; |
| 196 | string line = mStream->readLine(), tag; |
| 197 | if( line.empty() || line[0] == '#' ) |
| 198 | continue; |
| 199 | |
| 200 | while( line.back() == '\\' && ! mStream->isEof() ) { |
| 201 | auto next = mStream->readLine(); |
| 202 | line = line.substr( 0, line.size() - 1 ) + next; |
| 203 | } |
| 204 | |
| 205 | stringstream ss( line ); |
| 206 | ss >> tag; |
| 207 | if( tag == "v" ) { // vertex |
| 208 | vec3 v; |
| 209 | ss >> v.x >> v.y >> v.z; |
| 210 | mInternalVertices.push_back( v ); |
| 211 | } |
| 212 | else if( tag == "vt" ) { // vertex texture coordinates |
| 213 | if( includeTexCoords ) { |
| 214 | vec2 tex; |
| 215 | ss >> tex.x >> tex.y; |
| 216 | mInternalTexCoords.push_back( tex ); |
| 217 | } |
| 218 | } |
| 219 | else if( tag == "vn" ) { // vertex normals |
| 220 | if ( includeNormals ) { |
| 221 | vec3 v; |
| 222 | ss >> v.x >> v.y >> v.z; |
| 223 | mInternalNormals.push_back( normalize( v ) ); |
| 224 | } |
| 225 | } |
| 226 | else if( tag == "f" ) { // face |
| 227 | parseFace( currentGroup, currentMaterial, line, includeNormals, includeTexCoords ); |
| 228 | } |
| 229 | else if( tag == "g" ) { // group |
| 230 | if( ! currentGroup->mFaces.empty() ) |
| 231 | mGroups.push_back( Group() ); |
| 232 | currentGroup = &mGroups[mGroups.size()-1]; |
| 233 | currentGroup->mBaseVertexOffset = (int32_t)mInternalVertices.size(); |
| 234 | currentGroup->mBaseTexCoordOffset = (int32_t)mInternalTexCoords.size(); |
| 235 | currentGroup->mBaseNormalOffset = (int32_t)mInternalNormals.size(); |
| 236 | currentGroup->mName = line.substr( line.find( ' ' ) + 1 ); |
| 237 | } |
| 238 | else if( tag == "usemtl") { // material |
| 239 | string tag; |
| 240 | ss >> tag; |
| 241 | std::map<std::string, Material>::const_iterator m = mMaterials.find(tag); |