380
template<typename T> T
381
fromString(const string& asString)
383
std::stringstream ss(asString);
390
get_values(const string& source, vec3& v)
392
// Skip the definition type...
393
string::size_type endPos = source.find(" ");
394
string::size_type startPos(0);
395
if (endPos == string::npos)
397
Log::error("Bad element '%s'\n", source.c_str());
400
// Find the first value...
401
startPos = endPos + 1;
402
endPos = source.find(" ", startPos);
403
if (endPos == string::npos)
405
Log::error("Bad element '%s'\n", source.c_str());
408
string::size_type numChars(endPos - startPos);
409
string xs(source, startPos, numChars);
410
float x = fromString<float>(xs);
411
// Then the second value...
412
startPos = endPos + 1;
413
endPos = source.find(" ", startPos);
414
if (endPos == string::npos)
416
Log::error("Bad element '%s'\n", source.c_str());
419
numChars = endPos - startPos;
420
string ys(source, startPos, numChars);
421
float y = fromString<float>(ys);
422
// And the third value (there might be a fourth, but we don't care)...
423
startPos = endPos + 1;
424
endPos = source.find(" ", startPos);
425
if (endPos == string::npos)
431
numChars = endPos - startPos;
433
string zs(source, startPos, endPos - startPos);
434
float z = fromString<float>(zs);
441
get_values(const string& source, vec2& v)
443
// Skip the definition type...
444
string::size_type endPos = source.find(" ");
445
string::size_type startPos(0);
446
if (endPos == string::npos)
448
Log::error("Bad element '%s'\n", source.c_str());
451
// Find the first value...
452
startPos = endPos + 1;
453
endPos = source.find(" ", startPos);
454
if (endPos == string::npos)
456
Log::error("Bad element '%s'\n", source.c_str());
459
string::size_type numChars(endPos - startPos);
460
string xs(source, startPos, numChars);
461
float x = fromString<float>(xs);
462
// Then the second value (there might be a third, but we don't care)...
463
startPos = endPos + 1;
464
endPos = source.find(" ", startPos);
465
if (endPos == string::npos)
471
numChars = endPos - startPos;
473
string ys(source, startPos, numChars);
474
float y = fromString<float>(ys);
480
get_values(const string& source, uvec3& v)
482
// Skip the definition type...
483
string::size_type endPos = source.find(" ");
484
string::size_type startPos(0);
485
if (endPos == string::npos)
487
Log::error("Bad element '%s'\n", source.c_str());
490
// Find the first value...
491
startPos = endPos + 1;
492
endPos = source.find(" ", startPos);
493
if (endPos == string::npos)
495
Log::error("Bad element '%s'\n", source.c_str());
498
string::size_type numChars(endPos - startPos);
499
string xs(source, startPos, numChars);
500
unsigned int x = fromString<unsigned int>(xs);
501
// Then the second value...
503
endPos = source.find(" ", startPos);
504
if (endPos == string::npos)
506
Log::error("Bad element '%s'\n", source.c_str());
509
numChars = endPos - startPos;
510
string ys(source, startPos, numChars);
511
unsigned int y = fromString<unsigned int>(ys);
512
// And the third value (there might be a fourth, but we don't care)...
513
startPos = endPos + 1;
514
endPos = source.find(" ", startPos);
515
if (endPos == string::npos)
521
numChars = endPos - startPos;
523
string zs(source, startPos, numChars);
524
unsigned int z = fromString<unsigned int>(zs);
531
Model::load_obj(const std::string &filename)
533
std::ifstream inputFile(filename.c_str());
536
Log::error("Failed to open '%s'\n", filename.c_str());
540
vector<string> sourceVec;
542
while (getline(inputFile, curLine))
544
sourceVec.push_back(curLine);
547
// Give ourselves an object to populate.
548
objects_.push_back(Object(filename));
549
Object& object(objects_.back());
551
static const string vertex_definition("v");
552
static const string normal_definition("vn");
553
static const string texcoord_definition("vt");
554
static const string face_definition("f");
555
for (vector<string>::const_iterator lineIt = sourceVec.begin();
556
lineIt != sourceVec.end();
559
const string& curSrc = *lineIt;
560
// Is it a vertex attribute, a face description, comment or other?
561
// We only care about the first two, we ignore comments, object names,
562
// group names, smoothing groups, etc.
563
string::size_type startPos(0);
564
string::size_type spacePos = curSrc.find(" ", startPos);
565
string definitionType(curSrc, startPos, spacePos - startPos);
566
if (definitionType == vertex_definition)
569
get_values(curSrc, v.v);
570
object.vertices.push_back(v);
572
else if (definitionType == normal_definition)
574
// If we encounter an OBJ model with normals, we can update this
575
// to update object.vertices.n directly
576
Log::debug("We got a normal...\n");
578
else if (definitionType == texcoord_definition)
580
// If we encounter an OBJ model with normals, we can update this
581
// to update object.vertices.t directly
582
Log::debug("We got a texcoord...\n");
584
else if (definitionType == face_definition)
587
get_values(curSrc, v);
589
// OBJ models index from '1'.
593
object.faces.push_back(f);
596
// Compute bounding box for perspective projection
597
compute_bounding_box(object);
599
Log::debug("Object populated with %u vertices and %u faces.\n",
600
object.vertices.size(), object.faces.size());