source: GTP/trunk/App/Demos/Vis/FriendlyCulling/VisibilitySolutionConverter/VisibilitySolutionConverter.cpp @ 3282

Revision 3282, 24.0 KB checked in by mattausch, 15 years ago (diff)

probably found export error

Line 
1#include "VisibilitySolutionConverter.h"
2#include "Triangle3.h"
3#include "Vector3.h"
4#include "gzstream.h"
5#include <iostream>
6#include <queue>
7#include <stack>
8
9
10using namespace std;
11
12// MAGIC of all bin exports
13#ifndef MAGIC
14#define MAGIC 0x827923
15#endif
16
17#define BVH_VERSION 2.1
18
19#define TYPE_INTERIOR -2
20#define TYPE_LEAF -3
21
22
23//static const float sScale = 0.05f;
24static const float sScale = 1.0f;
25
26
27static string ReplaceSuffix(const string &str,
28                                                        const string &a,
29                                                        const string &b)
30{
31        string result = str;
32
33        int pos = (int)str.rfind(a, (int)str.size() - 1);
34        if (pos == str.size() - a.size())
35        {
36                result.replace(pos, a.size(), b);
37        }
38
39        return result;
40}
41
42
43static void LoadIndices(char *str,
44                                                const VertexArray &vertices,
45                                                const VertexArray &normals,
46                                                const vector<pair<float, float> > &texCoords,
47                                                VertexArray &faceVertices,
48                                                VertexArray &faceNormals,
49                                                vector<TexCoord> &faceTexCoords,
50                                                int line
51                                                )
52{
53        vector<string> triples;
54
55        char *next_token;
56
57        // extract the triples of the form v/t/n v/t/n ...
58        char *pch = strtok_s(str + 1, " ", &next_token);
59
60        while (pch)
61        {
62                string s(pch);
63                triples.push_back(s);
64               
65                pch = strtok_s(NULL, " ", &next_token);   
66        }
67
68        // throw away last symbol (\n)
69        triples.back().resize(triples.back().size() - 1);
70
71        vector<int> indices;
72        vector<int> nIndices;
73        vector<int> tIndices;
74
75        char seps[] = " ";
76        char seps2[] = "/";
77
78        for (size_t i = 0; i < triples.size(); ++ i)
79        {
80                size_t found;
81                found = triples[i].find_first_of(seps2);
82                size_t prevfound = 0;
83
84                // extract vertex, normal, texture indices
85                string str = triples[i].substr(prevfound, found);
86
87                int index = (int)strtol(str.c_str(), NULL, 10) - 1;
88                int tIndex = index;
89                int nIndex = index;     
90               
91                // try to extract texture and normal indices
92                prevfound = found + 1;
93                found = triples[i].find_first_of(seps2, prevfound); 
94
95                if (found != string::npos)
96                {
97                        str = triples[i].substr(prevfound, found);
98
99                        int idx = (int)strtol(str.c_str(), NULL, 10) - 1;
100                        if (idx > 0) tIndex = idx;
101                }
102               
103                if (found != string::npos)
104                {
105                        str = triples[i].substr(found + 1);
106
107                        int idx = (int)strtol(str.c_str(), NULL, 10) - 1;
108                        if (idx > 0) nIndex = idx;
109                }
110
111                // store indices
112                if (index >= 0)
113                {
114                        indices.push_back(index);
115                        nIndices.push_back(nIndex);
116                        tIndices.push_back(tIndex);
117                }
118
119                // new triangle found
120                if (indices.size() > 2)
121                {
122                        int idx1 = 0;
123                        int idx2 = (int)indices.size() - 2;
124                        int idx3 = (int)indices.size() - 1;
125
126                        faceVertices.push_back(vertices[indices[idx1]]);
127                        faceVertices.push_back(vertices[indices[idx2]]);
128                        faceVertices.push_back(vertices[indices[idx3]]);
129
130                        /*if (!normals.empty())
131                        {
132                                faceNormals.push_back(normals[nIndices[idx1]]);
133                                faceNormals.push_back(normals[nIndices[idx2]]);
134                                faceNormals.push_back(normals[nIndices[idx3]]);
135                        }
136                        else
137                        {
138                                // no face normals? => create normals
139                                const CHCDemoEngine::Triangle3
140                                        tri(vertices[indices[idx1]],
141                                            vertices[indices[idx2]],
142                                                vertices[indices[idx3]]);
143
144                                const CHCDemoEngine::Vector3 n = tri.GetNormal();
145
146                                faceNormals.push_back(n);
147                                faceNormals.push_back(n);
148                                faceNormals.push_back(n);
149                        }*/
150
151                        if (!texCoords.empty())
152                        {
153                                faceTexCoords.push_back(texCoords[tIndices[idx1]]);
154                                faceTexCoords.push_back(texCoords[tIndices[idx2]]);
155                                faceTexCoords.push_back(texCoords[tIndices[idx3]]);
156                        }
157                }
158        }
159}
160
161
162VisibilitySolutionConverter::VisibilitySolutionConverter()
163{}
164
165
166VisibilitySolutionConverter::~VisibilitySolutionConverter()
167{
168        for (size_t i = 0; i < mGeometry.size(); ++ i)
169        {
170                delete [] mGeometry[i]->mVertices;
171                delete [] mGeometry[i]->mNormals;
172                delete [] mGeometry[i]->mTexCoords;
173
174                delete mGeometry[i];
175        }
176       
177        mGeometry.clear();
178}
179
180
181void VisibilitySolutionConverter::LoadShape(const VertexArray &vertices,
182                                                                                        const VertexArray &normals,
183                                                                                        const vector<TexCoord> &texCoords)
184{
185        int numElements = (int)vertices.size();
186        Geometry *geom = new Geometry();
187
188        // convert the triangles to geometry
189        geom->mVertices = new CHCDemoEngine::Vector3[numElements];
190        geom->mNormals = new CHCDemoEngine::Vector3[numElements];
191        geom->mTexCoords = new TexCoord[numElements];
192
193        geom->mVertexCount = numElements;
194        geom->mTexcoordCount = (int)texCoords.size();
195
196        for (int i = 0; i < numElements; ++ i)
197        {
198                // convert to our camera system: change y and z
199                geom->mVertices[i] =  vertices[i];
200                geom->mNormals[i] =  normals[i];
201               
202                if (i < geom->mTexcoordCount)
203                {
204                        geom->mTexCoords[i].first = texCoords[i].first;
205                        geom->mTexCoords[i].second = texCoords[i].second;
206                }
207        }
208
209        mGeometry.push_back(geom);
210}
211
212
213bool VisibilitySolutionConverter::Convert(const std::string &sceneInputFilename,
214                                                                                  const std::string &sceneOutputFilename,
215                                                                                  const std::string &bvhInputFilename,
216                                                                                  const std::string &bvhOutputFilename)
217{
218        mNumShapes = 0;
219       
220        // delete previous geometry
221        for (size_t i = 0; i < mGeometry.size(); ++ i)
222        {
223                delete [] mGeometry[i]->mVertices;
224                delete [] mGeometry[i]->mNormals;
225                delete [] mGeometry[i]->mTexCoords;
226
227                delete mGeometry[i];
228        }
229       
230        mGeometry.clear();
231
232        if (!LoadSolutionTest(bvhInputFilename))
233        //if (!LoadSolution(bvhInputFilename))
234        {
235                cerr << "could not read solution file" << endl;
236                return false;
237        }
238
239        if (!ReadScene(sceneInputFilename))
240        {
241                cerr << "could not read file" << endl;
242                return false;
243        }
244
245        // update bvh bounding boxes with loaded geometry
246        UpdateBvh(mRoot);
247
248        cout << "loading bvh, bb: " << mRoot->box << endl;
249
250        cout << "writing scene" << endl;
251
252        if (!WriteScene(sceneOutputFilename))
253        {
254                cerr << "could not write file" << endl;
255                return false;
256        }
257
258        cout << "writing bvh" << endl;
259
260        if (!WriteBvh(bvhOutputFilename))
261        {
262                cerr << "could not write bvh!" << endl;
263                return false;
264        }
265
266        return true;
267}
268
269
270bool VisibilitySolutionConverter::ReadScene(const string &filename)
271{
272        /*
273        VertexArray vertices;
274        VertexArray normals;
275        vector<TexCoord> texCoords;
276
277        if (ReadObj(filename, vertices, normals, texCoords))
278        {
279                ConstructBvhObjects(vertices, normals, texCoords);
280                return true;
281        }*/
282
283        vector<CHCDemoEngine::Triangle3 *> triangles;
284
285        if (ReadObjSimple(filename, triangles))
286        {
287                ConstructBvhObjects2(triangles);
288                return true;
289        }
290
291        /*for (size_t i = 0; i < triangles.size(); ++ i)
292        delete triangles[i];
293        */
294
295        return false;
296}
297
298
299bool VisibilitySolutionConverter::ReadObj(const string &filename,
300                                                                                  VertexArray &vertices,
301                                                                                  VertexArray &normals,
302                                                                                  vector<TexCoord> &texcoords)
303{
304        FILE *file;
305
306        if ((file = fopen(filename.c_str(), "r")) == NULL) return false;
307       
308        VertexArray tempVertices;
309
310        VertexArray tempNormals;
311        vector<TexCoord> tempTexcoords;
312
313        vector<int> indices;
314
315        int line = 0;
316        const int len = 10000;
317        char str[len];
318
319        const string binFilename = ReplaceSuffix(filename, ".obj", ".bn");
320
321        if (!ReadBinObj(binFilename, vertices))
322        {
323                cout << "binary dump " << binFilename << " not available, loading ascii obj" << endl;
324
325                while (fgets(str, len, file) != NULL)
326                {
327                        if (line % 500000 == 0)
328                                cout << line << " " << str;
329
330                        ++ line;
331
332                        switch (str[0])
333                        {
334                        case 'v': // vertex or normal
335                                {
336                                        float x, y, z;
337
338                                        switch (str[1])
339                                        {
340                                        case 'n' :
341                                                sscanf(str + 2, "%f %f %f", &x, &y, &z);
342                                                tempNormals.push_back(CHCDemoEngine::Vector3(x, -z, y));
343                                                break;
344                                        case 't':
345                                                sscanf(str + 2, "%f %f", &x, &y);
346                                                tempTexcoords.push_back(pair<float, float>(x, y));
347                                                break;
348                                        default:
349                                                sscanf(str + 1, "%f %f %f", &x, &y, &z);
350                                                CHCDemoEngine::Vector3 v = CHCDemoEngine::Vector3(x, -z, y) * sScale;
351                                                tempVertices.push_back(v);
352                                                //cout <<"v " << x << " " << y << " "<< z << " ";
353                                        }
354                                        break;
355                                }
356                        case 'f':
357                                {
358                                        //////////
359                                        //-- indices in the current line
360
361                                        LoadIndices(str,
362                                                tempVertices, tempNormals, tempTexcoords,
363                                                vertices, normals, texcoords, line);
364
365                                        break;
366                                } 
367                                break;
368                        default:
369                                // throw away line
370                                break;
371                        }
372                }
373
374                ExportBinObj(binFilename, vertices);
375        }
376        else if (0)
377        {
378                cout << "creating normals" << endl;
379                normals.reserve(vertices.size());
380
381                for (size_t i = 0; i < vertices.size(); i += 3)
382                {
383                        // no face normals? => create normals
384                        const CHCDemoEngine::Triangle3
385                                tri(vertices[i], vertices[i + 1], vertices[i + 2]);
386
387                        const CHCDemoEngine::Vector3 n = tri.GetNormal();
388
389                        normals.push_back(n);
390                        normals.push_back(n);
391                        normals.push_back(n);
392                }
393
394                cout << "finished creating normals" << endl;
395        }
396
397        fclose(file);
398
399        return !vertices.empty();
400}
401
402
403static inline float RandomColor(float x)
404{
405        return x + (1.0f - x) * (float)rand() / RAND_MAX;
406}
407
408
409void VisibilitySolutionConverter::WriteGeometry(ogzstream &str, Geometry *geom)
410{
411        int vertexCount = geom->mVertexCount;
412        str.write(reinterpret_cast<char *>(&vertexCount), sizeof(int));
413 
414        str.write(reinterpret_cast<char *>(geom->mVertices), sizeof(CHCDemoEngine::Vector3) * vertexCount);
415        str.write(reinterpret_cast<char *>(geom->mNormals), sizeof(CHCDemoEngine::Vector3) * vertexCount);
416
417        int texCoordCount = 0;//geom->mTexcoordCount;
418        str.write(reinterpret_cast<char *>(&texCoordCount), sizeof(int));
419
420        if (texCoordCount)
421        {
422                str.write(reinterpret_cast<char *>(geom->mTexCoords), sizeof(float) * texCoordCount * 2);
423        }
424
425        ///////
426        //-- texture
427
428        int texId = -1;
429        str.write(reinterpret_cast<char *>(&texId), sizeof(int));
430
431        bool alphaTestEnabled = false;
432        bool cullFaceEnabled = true;
433        //bool cullFaceEnabled = false;
434
435        str.write(reinterpret_cast<char *>(&alphaTestEnabled), sizeof(bool));
436        str.write(reinterpret_cast<char *>(&cullFaceEnabled), sizeof(bool));
437
438        // material
439        bool hasMaterial = true;
440       
441        str.write(reinterpret_cast<char *>(&hasMaterial), sizeof(bool));
442       
443        if (hasMaterial)
444        {
445                CHCDemoEngine::Vector3 ambient, diffuse, spec, emm;
446
447                ambient.x = ambient.y = ambient.z = 0.2f;
448                //diffuse.x = diffuse.y = diffuse.z = 1.0f;
449
450                diffuse.x = RandomColor(0.5f);
451                diffuse.y = RandomColor(0.5f);
452                diffuse.z = RandomColor(0.5f);
453
454                spec.x = spec.y = spec.z = .0f;
455                emm = spec;
456
457                // only write rgb part of the material
458                str.write(reinterpret_cast<char *>(&ambient), sizeof(CHCDemoEngine::Vector3));
459                str.write(reinterpret_cast<char *>(&diffuse), sizeof(CHCDemoEngine::Vector3));
460                str.write(reinterpret_cast<char *>(&spec), sizeof(CHCDemoEngine::Vector3));
461                str.write(reinterpret_cast<char *>(&emm), sizeof(CHCDemoEngine::Vector3));
462        }
463}
464
465
466bool VisibilitySolutionConverter::WriteScene(const string &filename)
467{
468        ogzstream ofile(filename.c_str());
469
470        if (!ofile.is_open()) return false;
471       
472        int textureCount = 0;
473        ofile.write(reinterpret_cast<char *>(&textureCount), sizeof(int));
474
475
476        ///////////
477        //-- write shapes
478
479        int numShapes = (int)mGeometry.size();
480        ofile.write(reinterpret_cast<char *>(&numShapes), sizeof(int));
481
482        vector<Geometry *>::const_iterator it, it_end = mGeometry.end();
483
484        for (it = mGeometry.begin(); it != it_end; ++ it)
485        {
486                WriteGeometry(ofile, *it);
487        }
488
489
490        int entityCount = numShapes;
491        ofile.write(reinterpret_cast<char *>(&entityCount), sizeof(int));
492
493
494        //////////
495        //-- write single scene entity for each shape
496
497        for (int i = 0; i < numShapes; ++ i)
498        {
499                // no transformation
500                bool hasTrafo = false;
501                ofile.write(reinterpret_cast<char *>(&hasTrafo), sizeof(bool));
502
503                // a dummy lod
504                int numLODs = 1;
505                ofile.write(reinterpret_cast<char *>(&numLODs), sizeof(int));
506
507                float dist = 0;
508                ofile.write(reinterpret_cast<char *>(&dist), sizeof(float));
509
510                int shapesPerEntity = 1;
511                ofile.write(reinterpret_cast<char *>(&shapesPerEntity), sizeof(int));
512
513                int shapeId = i;
514                ofile.write(reinterpret_cast<char *>(&shapeId), sizeof(int));
515        }
516
517        return true;
518}
519
520
521void VisibilitySolutionConverter::ConstructBvhObjects(const VertexArray &vertices,
522                                                                                                          const VertexArray &normals,
523                                                                                                          const vector<TexCoord> &texCoords)
524{
525        CHCDemoEngine::AxisAlignedBox3 testBox;
526        testBox.Initialize();
527
528        for (int i = 0; i < vertices.size(); ++ i)
529                testBox.Include(vertices[i]);
530        cout << "geometry bounds: " << testBox << endl;
531
532        mGeometry.reserve(mBvhLeaves.size());
533        mNumShapes = (int)mBvhLeaves.size();
534
535        for (size_t i = 0; i < mBvhLeaves.size(); ++ i)
536        {
537                BvhLeaf *node = mBvhLeaves[i];
538
539                VertexArray _vertices; 
540                VertexArray _normals;
541                vector<TexCoord> _texCoords;
542
543                const int size = node->last - node->first + 1;
544
545                _vertices.reserve(size);
546                _normals.reserve(size);
547
548                //cout << "vtx: " << size << endl;
549                for (int j = node->first; j <= node->last; ++ j)
550                {
551                        const int idx = 3 * mGlobalTriangleIds[j];
552
553                        //cout << "idx: " << 3 * mGlobalTriangleIds[j] << " j " << j << " " << vertices.size()<< endl;
554                        for (int k = 0; k < 3; ++ k)
555                        {
556                                _vertices.push_back(vertices[idx + k]);
557                                //_normals.push_back(normals[idx + k]);
558                                //_texCoords.push_back(texCoords[idx + k]);
559                        }
560
561                        // no face normals? => create normals
562                        const CHCDemoEngine::Triangle3
563                                tri(vertices[idx], vertices[idx + 1], vertices[idx + 2]);
564
565                        const CHCDemoEngine::Vector3 n = tri.GetNormal();
566
567                        _normals.push_back(n);
568                        _normals.push_back(n);
569                        _normals.push_back(n);
570                }
571
572                LoadShape(_vertices, _normals, _texCoords);
573               
574                // we store geometry in our bvh => change first and last pointer
575                // from triangles to geometry
576                node->first = (int)mGeometry.size() - 1;
577                node->last = (int)mGeometry.size() - 1;
578
579                //_vertices.clear();
580                //_normals.clear();
581                //_texCoords.clear();
582        }
583}
584
585
586bool VisibilitySolutionConverter::ReadBvh(FILE *fr)
587{
588        int buffer[6];
589        fread(buffer, sizeof(int), 6, fr);
590
591        if (buffer[0] != MAGIC)
592        {
593                cerr << "Error: Wrong file type" << endl;
594                return false;
595        }
596
597        if (buffer[1] != (int)(1000 * BVH_VERSION))
598        {
599                cerr << "Error: Wrong BVH version" << endl;
600                return false;
601        }
602
603        cout << "loading " << buffer[2] << " triangles" << endl;
604        // load triangle ids
605        size_t numTriangles = buffer[2];
606        mGlobalTriangleIds.reserve(numTriangles);
607
608        for (size_t i = 0; i < numTriangles; ++i)
609        {
610                int id;
611                fread(&id, sizeof(int), 1, fr);
612                mGlobalTriangleIds.push_back(id);
613                //triangles[i] = scene->triangles[id];
614        }
615
616        const size_t numNodes = buffer[5];
617
618        mNumNodes = 0; // this was set to 1 in constructor!
619
620        mRoot = LoadNode(fr, 0);
621
622        if (mNumNodes != numNodes)
623        {
624                cerr << "Warning: Loaded " << mNumNodes <<
625                            " bvh nodes instead of " << buffer[5] << endl;
626        }
627
628        fclose(fr);
629       
630        return true;
631}
632
633
634void VisibilitySolutionConverter::UpdateLeafBox(BvhLeaf *leaf)
635{
636        leaf->box.Initialize();
637
638        Geometry *geom = mGeometry[leaf->first];
639
640        for (size_t i = 0; i < geom->mVertexCount; ++ i)
641        {
642                CHCDemoEngine::Vector3 v = geom->mVertices[i];
643                leaf->box.Include(v);
644        }
645}
646
647
648BvhNode *VisibilitySolutionConverter::LoadNode(FILE *fr, int depth)
649{
650        ++ mNumNodes;
651       
652        int buffer[4];
653        fread(buffer, sizeof(int), 4, fr);
654
655        if (buffer[2] != -1)
656        {
657                BvhInterior *interior = new BvhInterior();
658               
659                interior->first = buffer[0];
660                interior->last  = buffer[1];
661                interior->axis  = buffer[2];
662                interior->id    = buffer[3];
663                interior->depth = depth;
664
665                BvhNode *front, *back;
666
667                front = LoadNode(fr, depth + 1);
668                back  = LoadNode(fr, depth + 1);
669
670                front->parent = interior;
671                back->parent = interior;
672
673                interior->front = front;
674                interior->back = back;
675       
676                return (BvhNode *)interior;
677        }
678        else
679        {
680                // leaf
681                BvhLeaf *leaf = new BvhLeaf();
682
683                leaf->first = buffer[0];
684                leaf->last  = buffer[1];
685                leaf->axis  = buffer[2];
686                leaf->id    = buffer[3];
687
688                leaf->depth = depth;
689
690                mBvhLeaves.push_back(leaf);
691       
692                return (BvhNode *)leaf;
693        }
694}
695
696
697bool VisibilitySolutionConverter::ReadDummyTree(FILE *fr)
698{
699        int buffer[256];
700        fread(buffer, sizeof(int), 3, fr);
701
702        // read dummy bounding box
703        float dummy[6];
704        fread(dummy, sizeof(float) * 6, 1, fr);
705
706        int stack = 1;
707
708        // read dummy tree
709        while (stack)
710        {
711                int axis;
712                fread(&axis, sizeof(int), 1, fr);
713                -- stack;
714
715                if (axis != - 1)
716                {
717                        float dummy;
718                        fread(&dummy, sizeof(float), 1, fr);
719                       
720                        stack += 2;
721                }
722        }
723 
724        return true;
725}
726
727
728
729bool VisibilitySolutionConverter::LoadSolution(const string &filename)
730{
731        FILE *fr = fopen(filename.c_str(), "rb");
732
733        cerr << "Info: Loading visibility solution from file '" + filename + "'" << endl;
734 
735        if (fr == NULL)
736        {
737                cerr << "Error: Cannot open file for reading" << endl;
738                return false;
739        }
740
741        float totalSamples, totalTime;
742
743        fread(&totalSamples, sizeof(float), 1, fr);
744        fread(&totalTime, sizeof(float), 1, fr);
745
746        // just need to convert objects => read dummy visibility tree
747        bool ok = ReadDummyTree(fr);
748
749        // read bvh to determine objects (= the leaves of the bvh)
750        if (ok) ok = ReadBvh(fr);
751
752        fclose(fr);
753       
754        if (ok)
755                cout << "Info: visibility solution loaded" << endl;
756        else
757                cout << "Info: loading visibility solution failed" << endl;
758 
759        return true;
760}
761
762
763bool VisibilitySolutionConverter::LoadSolutionTest(const string &filename)
764{
765        FILE *fr = fopen(filename.c_str(), "rb");
766
767        cout << "Loading bvh from file '" + filename + "'" << endl;
768 
769        if (fr == NULL)
770        {
771                cerr << "Error: Cannot open file for reading" << endl;
772                return false;
773        }
774
775        // read bvh to determine objects (= the leaves of the bvh)
776        bool ok = ReadBvh(fr);
777
778        fclose(fr);
779       
780        if (ok)
781                cout << "Info: visibility solution loaded" << endl;
782        else
783                cout << "Info: loading visibility solution failed" << endl;
784 
785        return true;
786}
787
788
789bool VisibilitySolutionConverter::ReadBinObj(const string &filename,
790                                                                                         VertexArray &vertices
791                                                                                         )
792{
793        igzstream inStream(filename.c_str());
794       
795        if (!inStream.is_open()) return false;
796
797        cout << "binary obj dump available, loading " << filename.c_str() << endl;
798       
799        // read in triangle size
800        int numTriangles;
801
802        const int t = 500000;
803        inStream.read(reinterpret_cast<char *>(&numTriangles), sizeof(int));
804        vertices.reserve(numTriangles * 3);
805        cout << "loading " << numTriangles * 3 << " vertices ("
806                << numTriangles * 3 * sizeof(CHCDemoEngine::Vector3) / (1024 * 1024) << " MB)" << endl;
807
808        int i = 0;
809
810        while (1)
811        {
812                CHCDemoEngine::Vector3 v;
813                inStream.read(reinterpret_cast<char *>(&v), sizeof(CHCDemoEngine::Vector3));
814
815                // end of file reached
816                if (inStream.eof())     break;
817               
818                //v *= scale;
819                vertices.push_back(v);
820
821                if (((i ++) % t) == 0)
822                         cout << "\r" << i << "/" << numTriangles * 3 << "\r";
823        }
824       
825        cout << "finished loading vertices" << endl;
826
827        if (i != numTriangles * 3)
828                cerr << "warning: " << numTriangles * 3 << " != " << i << endl;
829
830        inStream.close();
831
832        return true;
833}
834
835
836bool VisibilitySolutionConverter::ExportBinObj(const string &filename,
837                                                                                           const VertexArray &vertices)
838{       
839        ogzstream ofile(filename.c_str());
840        if (!ofile.is_open()) return false;
841
842        int numTriangles = (int)vertices.size() / 3;
843
844        ofile.write(reinterpret_cast<char *>(&numTriangles), sizeof(int));
845
846        VertexArray::const_iterator it, it_end = vertices.end();
847
848        for (it = vertices.begin(); it != it_end; ++ it)
849        {
850                CHCDemoEngine::Vector3 v = *it;
851                ofile.write(reinterpret_cast<char *>(&v), sizeof(CHCDemoEngine::Vector3));
852        }
853
854        cout << "exported " << numTriangles * 3 << " vertices" << endl;
855
856        ofile.close();
857
858        return true;
859}
860
861
862void VisibilitySolutionConverter::WriteNextNode(ogzstream &stream,
863                                                                                                BvhNode *node)
864{
865        int nodeType;
866
867        if (node->IsLeaf())
868                nodeType = TYPE_LEAF;
869        else
870                nodeType = TYPE_INTERIOR;
871               
872        stream.write(reinterpret_cast<char *>(&nodeType), sizeof(int));
873
874        CHCDemoEngine::AxisAlignedBox3 box = node->box;
875        //box.Scale(sScale);
876
877        CHCDemoEngine::Vector3 bMin = box.Min();
878        CHCDemoEngine::Vector3 bMax = box.Max();
879
880        stream.write(reinterpret_cast<char *>(&(node->first)), sizeof(int));
881        stream.write(reinterpret_cast<char *>(&(node->last)), sizeof(int));
882
883        stream.write(reinterpret_cast<char *>(&bMin), sizeof(CHCDemoEngine::Vector3));
884        stream.write(reinterpret_cast<char *>(&bMax), sizeof(CHCDemoEngine::Vector3));
885}
886
887
888void VisibilitySolutionConverter::UpdateBvh(BvhNode *node)
889{
890        if (!node->IsLeaf())
891        {
892                BvhInterior *interior = (BvhInterior *)node;
893
894                UpdateBvh(interior->front);
895                UpdateBvh(interior->back);
896
897                interior->first = min(interior->front->first, interior->back->first);
898                interior->last = max(interior->front->last, interior->back->last);
899               
900                node->box = Union(interior->front->box, interior->back->box);
901        }
902        else
903        {
904                UpdateLeafBox((BvhLeaf *)node);
905                //cout << "bb: " << node->box << endl;
906        }
907}
908
909
910bool VisibilitySolutionConverter::WriteBvh(const string &filename)
911{
912        std::queue<BvhNode *> tQueue;
913        ogzstream stream(filename.c_str());
914
915        if (!stream.is_open()) return NULL;
916
917        WriteNextNode(stream, mRoot);
918
919        tQueue.push(mRoot);
920       
921        while (!tQueue.empty())
922        {
923                BvhNode *node = tQueue.front();
924                tQueue.pop();
925
926                if (!node->IsLeaf())
927                {
928                        BvhInterior *interior = static_cast<BvhInterior *>(node);
929
930                        BvhNode *front = interior->front;
931                        BvhNode *back = interior->back;
932
933                        WriteNextNode(stream, front);
934                        WriteNextNode(stream, back);
935
936                        tQueue.push(front);                     
937                        tQueue.push(back);
938                }
939        }
940
941        return true;
942}
943
944
945bool VisibilitySolutionConverter::ReadObjSimple(const string &filename,
946                                                                                                vector<CHCDemoEngine::Triangle3 *> &triangles
947                                                                                                )
948{
949        FILE *file;
950
951        if ((file = fopen(filename.c_str(), "r")) == NULL) return false;
952       
953        VertexArray vertices;
954
955        int line = 0;
956        const int len = 10000;
957        char str[len];
958
959        const string binFilename = ReplaceSuffix(filename, ".obj", ".bn");
960
961        cout << "binary dump " << binFilename << " not available, loading ascii obj" << endl;
962
963        while (fgets(str, len, file) != NULL)
964        {
965                if (line % 500000 == 0)
966                        cout << line << " " << str;
967
968                ++ line;
969
970                switch (str[0])
971                {
972                case 'v': // vertex or normal
973                        {
974                                float x, y, z;
975
976                                sscanf(str + 1, "%f %f %f", &x, &y, &z);
977                                CHCDemoEngine::Vector3 v = CHCDemoEngine::Vector3(x, -z, y) * sScale;
978                                vertices.push_back(v);
979
980                                if (vertices.size() == 3)
981                                {
982                                        CHCDemoEngine::Triangle3 *tri =
983                                                new CHCDemoEngine::Triangle3(vertices[0], vertices[1], vertices[2]);
984
985                                        triangles.push_back(tri);
986                                        vertices.clear();
987                                }
988                                break;
989                        }
990                default:
991                        // throw away line
992                        break;
993                }
994        }
995
996        fclose(file);
997
998        return !triangles.empty();
999}
1000
1001
1002void VisibilitySolutionConverter::ConstructBvhObjects2(const vector<CHCDemoEngine::Triangle3 *> &triangles)
1003{
1004        CHCDemoEngine::AxisAlignedBox3 testBox;
1005        testBox.Initialize();
1006
1007        for (size_t i = 0; i < triangles.size(); ++ i)
1008        {
1009                testBox.Include(triangles[i]->mVertices[0]);
1010                testBox.Include(triangles[i]->mVertices[1]);
1011                testBox.Include(triangles[i]->mVertices[2]);
1012        }
1013
1014        cout << "geometry bounds: " << testBox << endl;
1015
1016        mGeometry.reserve(mBvhLeaves.size());
1017        mNumShapes = (int)mBvhLeaves.size();
1018
1019        VertexArray _vertices; 
1020        VertexArray _normals;
1021        vector<TexCoord> _texCoords;
1022
1023        int total = 0;
1024        for (size_t i = 0; i < mBvhLeaves.size(); ++ i)
1025        {
1026                BvhLeaf *node = mBvhLeaves[i];
1027                const int size = node->last - node->first + 1;
1028
1029                total += size;
1030
1031                if (i % 1000 == 0)
1032                        cout << "o " << i << " " << size << " " << total << endl;
1033
1034                _vertices.clear();
1035                _normals.clear();
1036                _texCoords.clear();
1037
1038                //cout << "vtx: " << size << endl;
1039                for (int j = node->first; j <= node->last; ++ j)
1040                {
1041                        const int idx = mGlobalTriangleIds[j];
1042
1043                        //cout << "idx: " << 3 * mGlobalTriangleIds[j] << " j " << j << " " << vertices.size()<< endl;
1044                        for (int k = 0; k < 3; ++ k)
1045                        {
1046                                _vertices.push_back(triangles[idx]->mVertices[k]);
1047                        }
1048
1049                        const CHCDemoEngine::Vector3 n = triangles[idx]->GetNormal();
1050
1051                        _normals.push_back(n);
1052                        _normals.push_back(n);
1053                        _normals.push_back(n);
1054
1055                        delete triangles[idx];
1056                }
1057
1058                LoadShape(_vertices, _normals, _texCoords);
1059               
1060                // we store geometry in our bvh => change first and last pointer
1061                // from triangles to geometry
1062                node->first = (int)mGeometry.size() - 1;
1063                node->last = (int)mGeometry.size() - 1;
1064
1065                //_vertices.clear();
1066                //_normals.clear();
1067                //_texCoords.clear();
1068        }
1069}
Note: See TracBrowser for help on using the repository browser.