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

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