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

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