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

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