131 std::vector<ObjModelPart>* obj_model_parts)
134 if (filename.empty())
135 throw std::invalid_argument(
"No filename given");
138 std::ifstream input(filename.c_str(), std::ios::binary);
142 std::vector<math::Vec3f> global_vertices;
143 std::vector<math::Vec3f> global_normals;
144 std::vector<math::Vec2f> global_texcoords;
145 std::map<std::string, std::string> materials;
153 typedef std::map<ObjVertex, unsigned int> VertexIndexMap;
154 VertexIndexMap vertex_map;
155 std::string material_name;
156 std::string new_material_name;
160 std::getline(input, buffer);
164 if (input.eof() || !new_material_name.empty())
166 if (!texcoords.empty() && texcoords.size() != vertices.size())
168 if (!normals.empty() && normals.size() != vertices.size())
171 if (!vertices.empty())
176 std::swap(texcoords, obj_model_part.
mesh->get_vertex_texcoords());
177 std::swap(normals, obj_model_part.
mesh->get_vertex_normals());
180 obj_model_parts->push_back(obj_model_part);
186 material_name.swap(new_material_name);
187 new_material_name.clear();
195 if (buffer[0] ==
'#')
198 std::cout <<
"OBJ Loader: " << buffer << std::endl;
207 if (line.size() != 4 && line.size() != 5)
211 for (
int i = 0; i < 3; ++i)
212 vertex[i] = util::string::convert<float>(line[1 + i]);
215 if (line.size() == 5)
216 vertex /= util::string::convert<float>(line[4]);
218 global_vertices.push_back(vertex);
220 else if (line[0] ==
"vt")
222 if (line.size() != 3 && line.size() != 4)
226 for (
int i = 0; i < 2; ++i)
227 texcoord[i] = util::string::convert<float>(line[1 + i]);
230 if (line.size() == 4)
231 texcoord /= util::string::convert<float>(line[3]);
234 texcoord[1] = 1.0f - texcoord[1];
236 global_texcoords.push_back(texcoord);
238 else if (line[0] ==
"vn")
240 if (line.size() != 4 && line.size() != 5)
244 for (
int i = 0; i < 3; ++i)
245 normal[i] = util::string::convert<float>(line[1 + i]);
248 if (line.size() == 5)
249 normal /= util::string::convert<float>(line[4]);
251 global_normals.push_back(normal);
253 else if (line[0] ==
"f")
255 if (line.size() != 4)
258 for (
int i = 0; i < 3; ++i)
261 tok.
split(line[1 + i],
'/');
267 v.vertex_id = util::string::convert<unsigned int>(tok[0]);
268 if (tok.size() >= 2 && !tok[1].empty())
269 v.texcoord_id = util::string::convert<unsigned int>(tok[1]);
270 if (tok.size() == 3 && !tok[2].empty())
271 v.normal_id = util::string::convert<unsigned int>(tok[2]);
273 if (v.vertex_id > global_vertices.size()
274 || v.texcoord_id > global_texcoords.size()
275 || v.normal_id > global_normals.size())
278 VertexIndexMap::const_iterator iter = vertex_map.find(v);
279 if (iter != vertex_map.end())
281 faces.push_back(iter->second);
285 vertices.push_back(global_vertices[v.vertex_id - 1]);
286 if (v.texcoord_id != 0)
287 texcoords.push_back(global_texcoords[v.texcoord_id - 1]);
288 if (v.normal_id != 0)
289 normals.push_back(global_normals[v.normal_id - 1]);
290 faces.push_back(vertices.size() - 1);
291 vertex_map[v] = vertices.size() - 1;
295 else if (line[0] ==
"usemtl")
297 if (line.size() != 2)
299 new_material_name = line[1];
301 else if (line[0] ==
"mtllib")
303 if (line.size() != 2)
311 std::cout <<
"OBJ Loader: Skipping unsupported element: "
312 << line[0] << std::endl;