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

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