~thomas-voss/glmark2/build-for-mir

« back to all changes in this revision

Viewing changes to src/model.cpp

  • Committer: Package Import Robot
  • Author(s): Alexandros Frantzis
  • Date: 2011-09-22 11:32:17 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: package-import@ubuntu.com-20110922113217-wvok1qgruexari8d
Tags: 2011.09-0ubuntu1
* New upstream release 2011.09.
* debian/control:
  - Start the description of the glmark2-data package with
    a lowercase letter.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include "vec.h"
26
26
#include "log.h"
27
27
#include "options.h"
 
28
#include "util.h"
 
29
#include "float.h"
28
30
 
29
31
#include <fstream>
30
32
#include <sstream>
 
33
#include <memory>
 
34
 
 
35
using std::string;
 
36
using std::vector;
 
37
using LibMatrix::vec3;
 
38
using LibMatrix::vec2;
 
39
using LibMatrix::uvec3;
31
40
 
32
41
#define read_or_fail(file, dst, size) do { \
33
42
    file.read(reinterpret_cast<char *>((dst)), (size)); \
40
49
} while(0);
41
50
 
42
51
void
 
52
Model::compute_bounding_box(const Object& object)
 
53
{
 
54
    float minX(FLT_MAX);
 
55
    float maxX(FLT_MIN);
 
56
    float minY(FLT_MAX);
 
57
    float maxY(FLT_MIN);
 
58
    float minZ(FLT_MAX);
 
59
    float maxZ(FLT_MIN);
 
60
    for (vector<Vertex>::const_iterator vIt = object.vertices.begin(); vIt != object.vertices.end(); vIt++)
 
61
    {
 
62
        const vec3& curVtx = vIt->v;
 
63
        if (curVtx.x() < minX)
 
64
        {
 
65
            minX = curVtx.x();
 
66
        }
 
67
        if (curVtx.x() > maxX)
 
68
        {
 
69
            maxX = curVtx.x();
 
70
        }
 
71
        if (curVtx.y() < minY)
 
72
        {
 
73
            minY = curVtx.y();
 
74
        }
 
75
        if (curVtx.y() > maxY)
 
76
        {
 
77
            maxY = curVtx.y();
 
78
        }
 
79
        if (curVtx.z() < minZ)
 
80
        {
 
81
            minZ = curVtx.z();
 
82
        }
 
83
        if (curVtx.z() > maxZ)
 
84
        {
 
85
            maxZ = curVtx.z();
 
86
        }
 
87
    }
 
88
    maxVec_ = vec3(maxX, maxY, maxZ);
 
89
    minVec_ = vec3(minX, minY, minZ);
 
90
}
 
91
 
 
92
void
43
93
Model::append_object_to_mesh(const Object &object, Mesh &mesh,
44
94
                             int p_pos, int n_pos, int t_pos)
45
95
{
164
214
 
165
215
    Log::debug("Loading model from 3ds file '%s'\n", filename.c_str());
166
216
 
167
 
    std::ifstream input_file(filename.c_str());
 
217
    const std::auto_ptr<std::istream> input_file_ptr(Util::get_resource(filename));
 
218
    std::istream& input_file(*input_file_ptr);
 
219
 
168
220
    if (!input_file) {
169
221
        Log::error("Could not open 3ds file '%s'\n", filename.c_str());
170
222
        return false;
309
361
        }
310
362
    }
311
363
 
 
364
    // Compute bounding box for perspective projection
 
365
    compute_bounding_box(*object);
 
366
 
312
367
    if (Options::show_debug) {
313
368
        for (std::vector<Object>::const_iterator iter = objects_.begin();
314
369
             iter != objects_.end();
321
376
 
322
377
    return true;
323
378
}
 
379
 
 
380
template<typename T> T
 
381
fromString(const string& asString)
 
382
{
 
383
    std::stringstream ss(asString);
 
384
    T retVal;
 
385
    ss >> retVal;
 
386
    return retVal;
 
387
}
 
388
 
 
389
void
 
390
get_values(const string& source, vec3& v)
 
391
{
 
392
    // Skip the definition type...
 
393
    string::size_type endPos = source.find(" ");
 
394
    string::size_type startPos(0);
 
395
    if (endPos == string::npos)
 
396
    {
 
397
        Log::error("Bad element '%s'\n", source.c_str());
 
398
        return;
 
399
    }
 
400
    // Find the first value...
 
401
    startPos = endPos + 1;
 
402
    endPos = source.find(" ", startPos);
 
403
    if (endPos == string::npos)
 
404
    {
 
405
        Log::error("Bad element '%s'\n", source.c_str());
 
406
        return;
 
407
    }
 
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)
 
415
    {
 
416
        Log::error("Bad element '%s'\n", source.c_str());
 
417
        return;
 
418
    }
 
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)
 
426
    {
 
427
        numChars = endPos;
 
428
    }
 
429
    else
 
430
    {
 
431
        numChars = endPos - startPos;
 
432
    }
 
433
    string zs(source, startPos, endPos - startPos);
 
434
    float z = fromString<float>(zs);
 
435
    v.x(x);
 
436
    v.y(y);
 
437
    v.z(z);    
 
438
}
 
439
 
 
440
void
 
441
get_values(const string& source, vec2& v)
 
442
{
 
443
    // Skip the definition type...
 
444
    string::size_type endPos = source.find(" ");
 
445
    string::size_type startPos(0);
 
446
    if (endPos == string::npos)
 
447
    {
 
448
        Log::error("Bad element '%s'\n", source.c_str());
 
449
        return;
 
450
    }
 
451
    // Find the first value...
 
452
    startPos = endPos + 1;
 
453
    endPos = source.find(" ", startPos);
 
454
    if (endPos == string::npos)
 
455
    {
 
456
        Log::error("Bad element '%s'\n", source.c_str());
 
457
        return;
 
458
    }
 
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)
 
466
    {
 
467
        numChars = endPos;
 
468
    }
 
469
    else
 
470
    {
 
471
        numChars = endPos - startPos;
 
472
    }
 
473
    string ys(source, startPos, numChars);
 
474
    float y = fromString<float>(ys);
 
475
    v.x(x);
 
476
    v.y(y);
 
477
}
 
478
 
 
479
void
 
480
get_values(const string& source, uvec3& v)
 
481
{
 
482
    // Skip the definition type...
 
483
    string::size_type endPos = source.find(" ");
 
484
    string::size_type startPos(0);
 
485
    if (endPos == string::npos)
 
486
    {
 
487
        Log::error("Bad element '%s'\n", source.c_str());
 
488
        return;
 
489
    }
 
490
    // Find the first value...
 
491
    startPos = endPos + 1;
 
492
    endPos = source.find(" ", startPos);
 
493
    if (endPos == string::npos)
 
494
    {
 
495
        Log::error("Bad element '%s'\n", source.c_str());
 
496
        return;
 
497
    }
 
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...
 
502
    startPos = endPos+1;
 
503
    endPos = source.find(" ", startPos);
 
504
    if (endPos == string::npos)
 
505
    {
 
506
        Log::error("Bad element '%s'\n", source.c_str());
 
507
        return;
 
508
    }
 
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)
 
516
    {
 
517
        numChars = endPos;
 
518
    }
 
519
    else
 
520
    {
 
521
        numChars = endPos - startPos;
 
522
    }
 
523
    string zs(source, startPos, numChars);
 
524
    unsigned int z = fromString<unsigned int>(zs);
 
525
    v.x(x);
 
526
    v.y(y);
 
527
    v.z(z);    
 
528
}
 
529
 
 
530
bool
 
531
Model::load_obj(const std::string &filename)
 
532
{
 
533
    std::ifstream inputFile(filename.c_str());
 
534
    if (!inputFile)
 
535
    {
 
536
        Log::error("Failed to open '%s'\n", filename.c_str());
 
537
        return false;
 
538
    }
 
539
 
 
540
    vector<string> sourceVec;
 
541
    string curLine;
 
542
    while (getline(inputFile, curLine))
 
543
    {
 
544
        sourceVec.push_back(curLine);
 
545
    }
 
546
 
 
547
    // Give ourselves an object to populate.
 
548
    objects_.push_back(Object(filename));
 
549
    Object& object(objects_.back());
 
550
 
 
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();
 
557
         lineIt++)
 
558
    {
 
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)
 
567
        {
 
568
            Vertex v;
 
569
            get_values(curSrc, v.v);
 
570
            object.vertices.push_back(v);
 
571
        }
 
572
        else if (definitionType == normal_definition)
 
573
        {
 
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");
 
577
        }
 
578
        else if (definitionType == texcoord_definition)
 
579
        {
 
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");
 
583
        }
 
584
        else if (definitionType == face_definition)
 
585
        {
 
586
            uvec3 v;
 
587
            get_values(curSrc, v);
 
588
            Face f;
 
589
            // OBJ models index from '1'.
 
590
            f.a = v.x() - 1;
 
591
            f.b = v.y() - 1;
 
592
            f.c = v.z() - 1;
 
593
            object.faces.push_back(f);
 
594
        }
 
595
    }
 
596
    // Compute bounding box for perspective projection
 
597
    compute_bounding_box(object);
 
598
 
 
599
    Log::debug("Object populated with %u vertices and %u faces.\n",
 
600
        object.vertices.size(), object.faces.size());
 
601
    return true;
 
602
}