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

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