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

Revision 3277, 24.1 KB checked in by mattausch, 15 years ago (diff)
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 (!LoadSolution(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        //cout<<"here4"<<endl;
651        ++ mNumNodes;
652       
653        int buffer[4];
654        fread(buffer, sizeof(int), 4, fr);
655
656        if (buffer[2] != -1)
657        {
658                BvhInterior *interior = new BvhInterior();
659               
660                interior->first = buffer[0];
661                interior->last  = buffer[1];
662                interior->axis  = buffer[2];
663                interior->id    = buffer[3];
664                interior->depth = depth;
665
666                BvhNode *front, *back;
667
668                front = LoadNode(fr, depth + 1);
669                back  = LoadNode(fr, depth + 1);
670
671                front->parent = interior;
672                back->parent = interior;
673
674                interior->front = front;
675                interior->back = back;
676       
677                return (BvhNode *)interior;
678        }
679        else
680        {
681                // leaf
682                BvhLeaf *leaf = new BvhLeaf();
683
684                leaf->first = buffer[0];
685                leaf->last  = buffer[1];
686                leaf->axis  = buffer[2];
687                leaf->id    = buffer[3];
688
689                leaf->depth = depth;
690
691                mBvhLeaves.push_back(leaf);
692       
693                return (BvhNode *)leaf;
694        }
695}
696
697
698bool VisibilitySolutionConverter::ReadDummyTree(FILE *fr)
699{
700        int buffer[256];
701        fread(buffer, sizeof(int), 3, fr);
702
703        // read dummy bounding box
704        float dummy[6];
705        fread(dummy, sizeof(float) * 6, 1, fr);
706
707        int stack = 1;
708
709        // read dummy tree
710        while (stack)
711        {
712                int axis;
713                fread(&axis, sizeof(int), 1, fr);
714                -- stack;
715
716                if (axis != - 1)
717                {
718                        float dummy;
719                        fread(&dummy, sizeof(float), 1, fr);
720                       
721                        stack += 2;
722                }
723        }
724 
725        return true;
726}
727
728
729
730bool VisibilitySolutionConverter::LoadSolution(const string &filename)
731{
732        FILE *fr = fopen(filename.c_str(), "rb");
733
734        cerr << "Info: Loading visibility solution from file '" + filename + "'" << endl;
735 
736        if (fr == NULL)
737        {
738                cerr << "Error: Cannot open file for reading" << endl;
739                return false;
740        }
741
742        float totalSamples, totalTime;
743
744        fread(&totalSamples, sizeof(float), 1, fr);
745        fread(&totalTime, sizeof(float), 1, fr);
746
747        // just need to convert objects => read dummy visibility tree
748        bool ok = ReadDummyTree(fr);
749
750        // read bvh to determine objects (= the leaves of the bvh)
751        if (ok) ok = ReadBvh(fr);
752
753        fclose(fr);
754       
755        if (ok)
756                cout << "Info: visibility solution loaded" << endl;
757        else
758                cout << "Info: loading visibility solution failed" << endl;
759 
760        return true;
761}
762
763
764bool VisibilitySolutionConverter::LoadSolutionTest(const string &filename)
765{
766        FILE *fr = fopen(filename.c_str(), "rb");
767
768        cout << "Loading bvh from file '" + filename + "'" << endl;
769 
770        if (fr == NULL)
771        {
772                cerr << "Error: Cannot open file for reading" << endl;
773                return false;
774        }
775
776        // read bvh to determine objects (= the leaves of the bvh)
777        bool ok = ReadBvh(fr);
778
779        fclose(fr);
780       
781        if (ok)
782                cout << "Info: visibility solution loaded" << endl;
783        else
784                cout << "Info: loading visibility solution failed" << endl;
785 
786        return true;
787}
788
789
790bool VisibilitySolutionConverter::ReadBinObj(const string &filename,
791                                                                                         VertexArray &vertices
792                                                                                         )
793{
794        igzstream inStream(filename.c_str());
795       
796        if (!inStream.is_open()) return false;
797
798        cout << "binary obj dump available, loading " << filename.c_str() << endl;
799       
800        // read in triangle size
801        int numTriangles;
802
803        const int t = 500000;
804        inStream.read(reinterpret_cast<char *>(&numTriangles), sizeof(int));
805        vertices.reserve(numTriangles * 3);
806        cout << "loading " << numTriangles * 3 << " vertices ("
807                << numTriangles * 3 * sizeof(CHCDemoEngine::Vector3) / (1024 * 1024) << " MB)" << endl;
808
809        int i = 0;
810
811        while (1)
812        {
813                CHCDemoEngine::Vector3 v;
814                inStream.read(reinterpret_cast<char *>(&v), sizeof(CHCDemoEngine::Vector3));
815
816                // end of file reached
817                if (inStream.eof())     break;
818               
819                //v *= scale;
820                vertices.push_back(v);
821
822                if (((i ++) % t) == 0)
823                         cout << "\r" << i << "/" << numTriangles * 3 << "\r";
824        }
825       
826        cout << "finished loading vertices" << endl;
827
828        if (i != numTriangles * 3)
829                cerr << "warning: " << numTriangles * 3 << " != " << i << endl;
830
831        inStream.close();
832
833        return true;
834}
835
836
837bool VisibilitySolutionConverter::ExportBinObj(const string &filename,
838                                                                                           const VertexArray &vertices)
839{       
840        ogzstream ofile(filename.c_str());
841        if (!ofile.is_open()) return false;
842
843        int numTriangles = (int)vertices.size() / 3;
844
845        ofile.write(reinterpret_cast<char *>(&numTriangles), sizeof(int));
846
847        VertexArray::const_iterator it, it_end = vertices.end();
848
849        for (it = vertices.begin(); it != it_end; ++ it)
850        {
851                CHCDemoEngine::Vector3 v = *it;
852                ofile.write(reinterpret_cast<char *>(&v), sizeof(CHCDemoEngine::Vector3));
853        }
854
855        cout << "exported " << numTriangles * 3 << " vertices" << endl;
856
857        ofile.close();
858
859        return true;
860}
861
862
863void VisibilitySolutionConverter::WriteNextNode(ogzstream &stream,
864                                                                                                BvhNode *node)
865{
866        int nodeType;
867
868        if (node->IsLeaf())
869                nodeType = TYPE_LEAF;
870        else
871                nodeType = TYPE_INTERIOR;
872               
873        stream.write(reinterpret_cast<char *>(&nodeType), sizeof(int));
874
875        CHCDemoEngine::AxisAlignedBox3 box = node->box;
876        //box.Scale(sScale);
877
878        CHCDemoEngine::Vector3 bMin = box.Min();
879        CHCDemoEngine::Vector3 bMax = box.Max();
880
881        stream.write(reinterpret_cast<char *>(&(node->first)), sizeof(int));
882        stream.write(reinterpret_cast<char *>(&(node->last)), sizeof(int));
883
884        stream.write(reinterpret_cast<char *>(&bMin), sizeof(CHCDemoEngine::Vector3));
885        stream.write(reinterpret_cast<char *>(&bMax), sizeof(CHCDemoEngine::Vector3));
886}
887
888
889void VisibilitySolutionConverter::UpdateBvh(BvhNode *node)
890{
891        if (!node->IsLeaf())
892        {
893                BvhInterior *interior = (BvhInterior *)node;
894
895                UpdateBvh(interior->front);
896                UpdateBvh(interior->back);
897
898                interior->first = min(interior->front->first, interior->back->first);
899                interior->last = max(interior->front->last, interior->back->last);
900               
901                node->box = Union(interior->front->box, interior->back->box);
902        }
903        else
904        {
905                UpdateLeafBox((BvhLeaf *)node);
906                //cout << "bb: " << node->box << endl;
907        }
908}
909
910
911bool VisibilitySolutionConverter::WriteBvh(const string &filename)
912{
913        std::queue<BvhNode *> tQueue;
914        ogzstream stream(filename.c_str());
915
916        if (!stream.is_open()) return NULL;
917
918        WriteNextNode(stream, mRoot);
919
920        tQueue.push(mRoot);
921       
922        while (!tQueue.empty())
923        {
924                BvhNode *node = tQueue.front();
925                tQueue.pop();
926
927                if (!node->IsLeaf())
928                {
929                        BvhInterior *interior = static_cast<BvhInterior *>(node);
930
931                        BvhNode *front = interior->front;
932                        BvhNode *back = interior->back;
933
934                        WriteNextNode(stream, front);
935                        WriteNextNode(stream, back);
936
937                        tQueue.push(front);                     
938                        tQueue.push(back);
939                }
940        }
941
942        return true;
943}
944
945
946bool VisibilitySolutionConverter::ReadObjSimple(const string &filename,
947                                                                                                vector<CHCDemoEngine::Triangle3 *> &triangles
948                                                                                                )
949{
950        FILE *file;
951
952        if ((file = fopen(filename.c_str(), "r")) == NULL) return false;
953       
954        VertexArray vertices;
955
956        int line = 0;
957        const int len = 10000;
958        char str[len];
959
960        const string binFilename = ReplaceSuffix(filename, ".obj", ".bn");
961
962        cout << "binary dump " << binFilename << " not available, loading ascii obj" << endl;
963
964        while (fgets(str, len, file) != NULL)
965        {
966                if (line % 500000 == 0)
967                        cout << line << " " << str;
968
969                ++ line;
970
971                switch (str[0])
972                {
973                case 'v': // vertex or normal
974                        {
975                                float x, y, z;
976
977                                sscanf(str + 1, "%f %f %f", &x, &y, &z);
978                                CHCDemoEngine::Vector3 v = CHCDemoEngine::Vector3(x, -z, y) * sScale;
979                                vertices.push_back(v);
980
981                                if (vertices.size() == 3)
982                                {
983                                        CHCDemoEngine::Triangle3 *tri =
984                                                new CHCDemoEngine::Triangle3(vertices[0], vertices[1], vertices[2]);
985
986                                        triangles.push_back(tri);
987                                        vertices.clear();
988                                }
989                                break;
990                        }
991                default:
992                        // throw away line
993                        break;
994                }
995        }
996
997        fclose(file);
998
999        return !triangles.empty();
1000}
1001
1002
1003void VisibilitySolutionConverter::ConstructBvhObjects2(const vector<CHCDemoEngine::Triangle3 *> &triangles)
1004{
1005        CHCDemoEngine::AxisAlignedBox3 testBox;
1006        testBox.Initialize();
1007
1008        for (size_t i = 0; i < triangles.size(); ++ i)
1009        {
1010                testBox.Include(triangles[i]->mVertices[0]);
1011                testBox.Include(triangles[i]->mVertices[1]);
1012                testBox.Include(triangles[i]->mVertices[2]);
1013        }
1014
1015        cout << "geometry bounds: " << testBox << endl;
1016
1017        mGeometry.reserve(mBvhLeaves.size());
1018        mNumShapes = (int)mBvhLeaves.size();
1019
1020        VertexArray _vertices; 
1021        VertexArray _normals;
1022        vector<TexCoord> _texCoords;
1023
1024        int total = 0;
1025        for (size_t i = 0; i < mBvhLeaves.size(); ++ i)
1026        {
1027                BvhLeaf *node = mBvhLeaves[i];
1028                const int size = node->last - node->first + 1;
1029
1030                total += size;
1031
1032                if (i % 1000 == 0)
1033                        cout << "o " << i << " " << size << " " << total << endl;
1034
1035                _vertices.clear();
1036                _normals.clear();
1037                _texCoords.clear();
1038
1039                //cout << "vtx: " << size << endl;
1040                for (int j = node->first; j <= node->last; ++ j)
1041                {
1042                        const int idx = mGlobalTriangleIds[j];
1043
1044                        //cout << "idx: " << 3 * mGlobalTriangleIds[j] << " j " << j << " " << vertices.size()<< endl;
1045                        for (int k = 0; k < 3; ++ k)
1046                        {
1047                                _vertices.push_back(triangles[idx]->mVertices[k]);
1048                        }
1049
1050                        const CHCDemoEngine::Vector3 n = triangles[idx]->GetNormal();
1051
1052                        _normals.push_back(n);
1053                        _normals.push_back(n);
1054                        _normals.push_back(n);
1055
1056                        delete triangles[idx];
1057                }
1058
1059                LoadShape(_vertices, _normals, _texCoords);
1060               
1061                // we store geometry in our bvh => change first and last pointer
1062                // from triangles to geometry
1063                node->first = (int)mGeometry.size() - 1;
1064                node->last = (int)mGeometry.size() - 1;
1065
1066                //_vertices.clear();
1067                //_normals.clear();
1068                //_texCoords.clear();
1069        }
1070}
Note: See TracBrowser for help on using the repository browser.