source: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp @ 469

Revision 469, 33.1 KB checked in by mattausch, 19 years ago (diff)

updated view cells, view cell manager. changed rendersimulator

Line 
1#include <stack>
2#include "common.h"
3#include "SceneGraph.h"
4#include "X3dExporter.h"
5#include "Mesh.h"
6#include "KdTree.h"
7#include "ViewCellBsp.h"
8#include "ViewCell.h"
9#include "Polygon3.h"
10#include "VssRay.h"
11#include "VspKdTree.h"
12#include "VssTree.h"
13#include "VspBspTree.h"
14#include "RssTree.h"
15
16
17X3dExporter::X3dExporter(const string filename):Exporter(filename)
18{
19  stream.open(mFilename.c_str());
20  stream<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
21  stream<<"<X3D>"<<endl;
22  stream<<"<Scene>"<<endl;
23 
24}
25
26X3dExporter::~X3dExporter()
27{
28  stream<<"</Scene>"<<endl;
29  stream<<"</X3D>"<<endl;
30  stream.close();
31}
32
33
34//  bool
35//  X3dExporter::ExportRays(const vector<Ray> &rays,
36//                                                                                              const float length,
37//                                                                                              const RgbColor &color)
38//  {
39//    vector<Ray>::const_iterator ri = rays.begin();
40//    stream<<"<Shape>"<<endl;
41//    stream<<"<Appearance>"<<endl;
42//    stream<<"<Material ambientColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
43//      "\" />"<<endl;
44//    stream<<"</Appearance>"<<endl;
45 
46//    stream<<"<IndexedLineSet coordIndex=\""<<endl;
47
48//    int index = 0;
49//    for (; ri != rays.end(); ri++) {
50//      stream<<index<<" "<<index+1<<" -1\n";
51//      index+=2;
52//    }
53 
54//    stream<<"\" >"<<endl;
55 
56//    stream<<"<Coordinate  point=\""<<endl;
57 
58//    ri = rays.begin();
59//    for (; ri != rays.end(); ri++) {
60//      Vector3 a = (*ri).GetLoc();
61   
62//      Vector3 b;
63//      if (length < 0)
64//        b = (*ri).GetLoc() - length*(*ri).GetDir();
65//      else
66//        if ((*ri).intersections.size()==0)
67//      b = (*ri).GetLoc() + length*(*ri).GetDir();
68//        else
69//      b = (*ri).Extrap((*ri).intersections[0].mT);
70   
71//      stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
72//      stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
73//    }
74 
75//    stream<<"\" >"<<endl;
76//    stream<<"</Coordinate>"<<endl;
77//    stream<<"</IndexedLineSet>"<<endl;
78//    stream<<"</Shape>"<<endl;
79//    return true;
80//  }
81
82
83bool
84X3dExporter::ExportRays(const RayContainer &rays,
85                                                const float length,
86                                                const RgbColor &color)
87{
88  RayContainer::const_iterator ri = rays.begin();
89
90  stream<<"<Shape>"<<endl;
91  stream<<"<Appearance>"<<endl;
92  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
93    "\" />"<<endl;
94  stream<<"</Appearance>"<<endl;
95 
96  stream<<"<IndexedLineSet coordIndex=\""<<endl;
97
98  int index = 0;
99  for (; ri != rays.end(); ri++) {
100    stream<<index<<" "<<index+1<<" -1\n";
101    index+=2;
102  }
103 
104  stream<<"\" >"<<endl;
105 
106  stream<<"<Coordinate  point=\""<<endl;
107 
108  ri = rays.begin();
109  for (; ri != rays.end(); ri++) {
110    Vector3 a = (*ri)->GetLoc();
111   
112    Vector3 b;
113    if (length < 0)
114      b = (*ri)->GetLoc() - length*(*ri)->GetDir();
115    else
116      if ((*ri)->intersections.size()==0)
117        b = (*ri)->GetLoc() + length*(*ri)->GetDir();
118      else
119        b = (*ri)->Extrap((*ri)->intersections[0].mT);
120   
121    stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
122    stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
123  }
124 
125  stream<<"\" >"<<endl;
126  stream<<"</Coordinate>"<<endl;
127  stream<<"</IndexedLineSet>"<<endl;
128  stream<<"</Shape>"<<endl;
129
130  return true;
131}
132
133bool
134X3dExporter::ExportRays(const VssRayContainer &rays,
135                                                const RgbColor &color)
136{
137  VssRayContainer::const_iterator ri = rays.begin();
138
139  stream<<"<Shape>"<<endl;
140  stream<<"<Appearance>"<<endl;
141  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
142    "\" />"<<endl;
143  stream<<"</Appearance>"<<endl;
144 
145  stream<<"<IndexedLineSet coordIndex=\""<<endl;
146
147  int index = 0;
148  for (; ri != rays.end(); ri++) {
149    stream<<index<<" "<<index+1<<" -1\n";
150    index+=2;
151  }
152 
153  stream<<"\" >"<<endl;
154 
155  stream<<"<Coordinate  point=\""<<endl;
156 
157  ri = rays.begin();
158  for (; ri != rays.end(); ri++) {
159    const Vector3 a = (*ri)->GetOrigin();
160        const Vector3 b = (*ri)->mTerminationObject ? (*ri)->GetTermination() : a + 1000 * Normalize((*ri)->GetDir());
161       
162    stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
163        stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
164  }
165 
166  stream<<"\" >"<<endl;
167  stream<<"</Coordinate>"<<endl;
168  stream<<"</IndexedLineSet>"<<endl;
169  stream<<"</Shape>"<<endl;
170       
171  return true;
172}
173
174void
175X3dExporter::ExportSceneNode(SceneGraphNode *node)
176{
177  stream<<"<Group>"<<endl;
178
179  SceneGraphNodeContainer::iterator ni = node->mChildren.begin();
180  for (; ni != node->mChildren.end(); ni++)
181    ExportSceneNode(*ni);
182 
183 
184  ObjectContainer::const_iterator mi = node->mGeometry.begin();
185  for (; mi != node->mGeometry.end(); mi++) {
186    // export the transform...
187    ExportIntersectable(*mi);
188  }
189 
190  stream<<"</Group>"<<endl;
191
192}
193void
194X3dExporter::ExportIntersectable(Intersectable *object)
195{
196  switch (object->Type()) {
197  case Intersectable::MESH_INSTANCE:
198  case Intersectable::TRANSFORMED_MESH_INSTANCE:
199    ExportMeshInstance((MeshInstance *)object);
200        break;
201  case Intersectable::VIEW_CELL:
202        ExportViewCell((ViewCell *)object);
203    break;
204  default:
205    cerr<<"Sorry the export for object not yet defined"<<endl;
206    break;
207  }
208}
209
210void
211X3dExporter::ExportMeshInstance(MeshInstance *object)
212{
213  // $$JB$$
214  // in the future check whether the mesh was not already exported
215  // and use a reference to the that mesh instead
216  ExportMesh(object->GetMesh());
217}
218
219void
220X3dExporter::ExportViewCells(const ViewCellContainer &viewCells)
221{
222        ViewCellContainer::const_iterator it, it_end = viewCells.end();
223
224        for (it = viewCells.begin(); it != it_end; ++ it)
225                ExportViewCell(*it);
226}
227
228void
229X3dExporter::ExportBspViewCellPartition(const BspTree &tree, const int maxPvs)
230{
231        ViewCellContainer viewCells;
232        tree.CollectViewCells(viewCells);
233
234        ViewCellContainer::const_iterator it, it_end = viewCells.end();
235
236        if (maxPvs > 0)
237                mUseForcedMaterial = true;
238
239        for (it = viewCells.begin(); it != it_end; ++ it)
240        {
241                if (maxPvs > 0)
242                {
243                        mForcedMaterial.mDiffuseColor.b = 1.0f;
244                        float importance = (float)(*it)->GetPvs().GetSize() / (float)maxPvs;
245
246                        mForcedMaterial.mDiffuseColor.r = importance;
247                        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
248                }
249
250                if ((*it)->GetMesh())
251                        ExportViewCell(*it);
252                else
253                {
254                        PolygonContainer cell;
255                        tree.ConstructGeometry(dynamic_cast<BspViewCell *>(*it), cell);
256
257                        ExportPolygons(cell);
258                }
259        }
260}
261
262void
263X3dExporter::ExportBspLeaves(const BspTree &tree, const int maxPvs)
264{
265        stack<pair<BspNode *, BspNodeGeometry *> > tStack;
266        ViewCell::NewMail();
267
268        BspNodeGeometry *geom = new BspNodeGeometry();
269        tree.ConstructGeometry(tree.GetRoot(), *geom);
270
271        tStack.push(pair<BspNode *, BspNodeGeometry *>(tree.GetRoot(), geom));
272
273        if (maxPvs > 0)
274                mUseForcedMaterial = true;
275
276        while (!tStack.empty())
277        {
278                BspNode *node = tStack.top().first;
279                BspNodeGeometry *cell = tStack.top().second;
280                tStack.pop();
281
282                if (!node->IsLeaf())
283                {
284                        BspInterior *interior = dynamic_cast<BspInterior *>(node);
285                                                               
286                        BspNodeGeometry *front = new BspNodeGeometry();
287                        BspNodeGeometry *back = new BspNodeGeometry();
288
289                        cell->SplitGeometry(*front,
290                                                                *back,
291                                                                interior->GetPlane(),
292                                                                tree.GetBoundingBox(),
293                                                                tree.GetEpsilon());
294
295                        tStack.push(pair<BspNode *, BspNodeGeometry *>(interior->GetFront(), front));
296                        tStack.push(pair<BspNode *, BspNodeGeometry *>(interior->GetBack(), back));
297                }
298                else
299                {
300                        if (maxPvs > 0)
301                        {
302                                BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
303
304                                mForcedMaterial.mDiffuseColor.b = 1.0f;
305                                float importance = (float)leaf->GetViewCell()->GetPvs().GetSize() / (float)maxPvs;
306
307                                mForcedMaterial.mDiffuseColor.r = importance;
308                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
309                        }
310
311                        ExportPolygons(cell->mPolys);
312                }
313               
314                DEL_PTR(cell);
315        }
316}
317
318void
319X3dExporter::ExportViewCell(ViewCell *viewCell)
320{
321        if (viewCell->GetMesh())
322                ExportMesh(viewCell->GetMesh());
323}
324
325void
326X3dExporter::ExportMesh(Mesh *mesh)
327{
328
329  stream<<"<Shape>"<<endl;
330  stream<<"<Appearance>"<<endl;
331 
332  // $$ tmp -> random material
333 
334  float r, g, b;
335
336  if (mUseForcedMaterial) {
337    r = mForcedMaterial.mDiffuseColor.r;
338    g = mForcedMaterial.mDiffuseColor.g;
339    b = mForcedMaterial.mDiffuseColor.b;
340   
341  } else
342    if (mesh->mMaterial) {
343      r = mesh->mMaterial->mDiffuseColor.r;
344      g = mesh->mMaterial->mDiffuseColor.g;
345      b = mesh->mMaterial->mDiffuseColor.b;
346    } else {
347      r = RandomValue(0.5, 1.0);
348      g = RandomValue(0.5, 1.0);
349      b = RandomValue(0.5, 1.0);
350    }
351  stream<<"<Material diffuseColor=\""<<r<<" "<<g<<" "<<b<<
352    "\" specularColor=\"0.0 0.0 0.0\"/>"<<endl;
353  stream<<"</Appearance>"<<endl;
354
355
356  if (mWireframe)
357    stream<<"<IndexedLineSet coordIndex=\""<<endl;
358  else
359    //stream<<"<IndexedFaceSet ccw=\"TRUE\" coordIndex=\""<<endl;
360        stream << "<IndexedFaceSet coordIndex=\"" << endl;
361
362  FaceContainer::const_iterator fi = mesh->mFaces.begin();
363
364  int index = 0;
365 
366  for (; fi != mesh->mFaces.end(); fi++) {
367    Face *face = *fi;
368    VertexIndexContainer::const_iterator vi = face->mVertexIndices.begin();
369    for (; vi != face->mVertexIndices.end(); vi++)
370      stream<<*vi<<" ";
371        if (mWireframe) // final line to finish polygon
372                stream << (*face->mVertexIndices.begin()) << " ";
373
374    stream<<"-1"<<endl;
375  }
376  stream<<"\" >"<<endl;
377
378  stream<<"<Coordinate  point=\""<<endl;
379 
380  VertexContainer::const_iterator vi = mesh->mVertices.begin();
381  for (; vi != mesh->mVertices.end(); vi++) {
382    stream<<(*vi).x<<" "<<(*vi).y<<" "<<(*vi).z;
383    stream<<","<<endl;
384  }
385 
386  stream<<"\" >"<<endl;
387  stream<<"</Coordinate>"<<endl;
388
389  if (mWireframe)
390    stream<<"</IndexedLineSet>"<<endl;
391  else
392    stream<<"</IndexedFaceSet>"<<endl;
393 
394  stream<<"</Shape>"<<endl;
395
396}
397
398
399void X3dExporter::ExportPolygon(Polygon3 *poly)
400{
401        stream << "<Shape>" << endl;
402        stream << "<Appearance>" << endl;
403 
404        // $$ tmp -> random material
405 
406        float r, g, b;
407
408        if (mUseForcedMaterial)
409        {
410                r = mForcedMaterial.mDiffuseColor.r;
411                g = mForcedMaterial.mDiffuseColor.g;
412                b = mForcedMaterial.mDiffuseColor.b;
413        }
414        else if (poly->mMaterial)
415        {
416                r = poly->mMaterial->mDiffuseColor.r;
417                g = poly->mMaterial->mDiffuseColor.g;
418                b = poly->mMaterial->mDiffuseColor.b;
419        } else
420        {
421                r = RandomValue(0.5, 1.0);
422                g = RandomValue(0.5, 1.0);
423                b = RandomValue(0.5, 1.0);
424        }
425
426        stream << "<Material diffuseColor=\"" << r << " " << g << " " << b
427                   << "\" specularColor=\"0.0 0.0 0.0\"/>" << endl;
428
429    stream << "</Appearance>" << endl;
430
431
432        //-- create and write indices
433        if (mWireframe)
434                stream<<"<IndexedLineSet coordIndex=\""<<endl;
435        else
436                //stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
437                stream << "<IndexedFaceSet coordIndex=\"" << endl;
438        int index = 0;
439       
440        VertexContainer::const_iterator vi; 
441       
442        for (index = 0; index < (int)poly->mVertices.size(); ++ index)
443                stream << index << " ";
444       
445        if (mWireframe) // final line to finish polygon
446                stream << "0 ";
447
448        stream << "-1" << endl;
449        stream << "\" >" << endl;
450       
451        stream << "<Coordinate  point=\"" << endl;
452 
453        for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
454        {
455                stream << (*vi).x << " " << (*vi).y << " " << (*vi).z;
456                stream << "," << endl;
457        }
458 
459        stream << "\" >" << endl;
460        stream << "</Coordinate>" << endl;
461
462        if (mWireframe)
463                stream << "</IndexedLineSet>" << endl;
464        else
465                stream << "</IndexedFaceSet>" << endl;
466 
467        stream << "</Shape>" << endl;
468}
469
470void X3dExporter::ExportPolygons(const PolygonContainer &polys)
471{
472        stream << "<Shape>" << endl;
473        stream << "<Appearance>" << endl;
474 
475        // $$ tmp -> random material
476 
477        float r, g, b;
478
479        if (mUseForcedMaterial)
480        {
481                r = mForcedMaterial.mDiffuseColor.r;
482                g = mForcedMaterial.mDiffuseColor.g;
483                b = mForcedMaterial.mDiffuseColor.b;
484        }
485        else
486        {
487                r = RandomValue(0.5, 1.0);
488                g = RandomValue(0.5, 1.0);
489                b = RandomValue(0.5, 1.0);
490        }
491
492        stream << "<Material diffuseColor=\"" << r << " " << g << " " << b
493                   << "\" specularColor=\"0.0 0.0 0.0\"/>" << endl;
494
495    stream << "</Appearance>" << endl;
496
497
498        //-- create and write indices
499        if (mWireframe)
500                stream<<"<IndexedLineSet coordIndex=\""<<endl;
501        else
502                //stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
503                stream << "<IndexedFaceSet coordIndex=\"" << endl;
504
505        int index = 0;
506       
507        PolygonContainer::const_iterator pit;
508
509    VertexContainer::const_iterator vi; 
510       
511        for (pit = polys.begin(); pit != polys.end(); ++pit)
512        {
513                Polygon3 *poly = *pit;
514                int startIdx = index;
515                for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
516                {
517                        stream << index ++ << " ";
518                }
519
520                stream << startIdx << " ";// finish line
521                stream << "-1" << endl;
522        }
523
524        stream << "\" >" << endl;
525       
526        stream << "<Coordinate  point=\"" << endl;
527        for (pit = polys.begin(); pit != polys.end(); ++ pit)
528        {
529                Polygon3 *poly = *pit;
530        for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
531                {
532                        stream << (*vi).x << " " << (*vi).y << " " << (*vi).z;
533                        stream << "," << endl;
534                }
535        }
536        stream << "\" >" << endl;
537        stream << "</Coordinate>" << endl;
538
539        if (mWireframe)
540                stream << "</IndexedLineSet>" << endl;
541        else
542                stream << "</IndexedFaceSet>" << endl;
543 
544        stream << "</Shape>" << endl;
545}
546
547bool
548X3dExporter::ExportBox(const AxisAlignedBox3 &box)
549{
550  Mesh *mesh = new Mesh;
551  // add 6 vertices of the box
552  int index = (int)mesh->mVertices.size();
553  for (int i=0; i < 8; i++) {
554    Vector3 v;
555    box.GetVertex(i, v);
556    mesh->mVertices.push_back(v);
557  }
558 
559  mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
560  mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
561  mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
562 
563  mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
564  mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
565  mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
566 
567  ExportMesh(mesh);
568  delete mesh;
569  return true;
570}
571
572bool
573X3dExporter::ExportBspTree(const BspTree &tree)
574{
575        if (mExportRayDensity)
576        {
577                return ExportBspTreeRayDensity(tree);
578        }
579 
580        bool savedWireframe = mWireframe;
581
582        SetWireframe();
583       
584        ExportBox(tree.GetBoundingBox());
585       
586        if (!savedWireframe)
587                SetFilled();
588
589        // export view cells
590        ExportBspViewCellPartition(tree);       
591
592        return true;
593}
594
595bool X3dExporter::ExportVspKdTree(const VspKdTree &tree, const int maxPvs)
596{
597        stack<VspKdNode *> tStack;
598
599        tStack.push(tree.GetRoot());
600
601        //Mesh *mesh = new Mesh;
602 
603        if (maxPvs > 0)
604                mUseForcedMaterial = true;
605
606        while (!tStack.empty())
607        {
608                VspKdNode *node = tStack.top();
609   
610                tStack.pop();
611
612                if (node->IsLeaf())
613                {
614                        AxisAlignedBox3 box = tree.GetBBox(node);
615
616                        Mesh *mesh = new Mesh;
617
618                        // add 6 vertices of the box
619                        int index = (int)mesh->mVertices.size();
620
621                        for (int i=0; i < 8; ++ i)
622                        {
623                                Vector3 v;
624                                box.GetVertex(i, v);
625                                mesh->mVertices.push_back(v);
626                        }
627
628                        mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
629                        mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
630                        mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
631
632                        mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
633                        mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
634                        mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
635
636                        if (maxPvs > 0)
637                        {
638                                VspKdLeaf *leaf = dynamic_cast<VspKdLeaf *>(node);
639
640                                mForcedMaterial.mDiffuseColor.b = 1.0f;
641                               
642                                leaf->UpdatePvsSize();
643                       
644                                const float importance = (float)leaf->GetPvsSize() / (float)maxPvs;
645                                mForcedMaterial.mDiffuseColor.r = importance;
646                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
647                        }
648
649                        ExportMesh(mesh);
650                        DEL_PTR(mesh);
651                }
652                else 
653                {
654                        VspKdInterior *interior = dynamic_cast<VspKdInterior *>(node);
655                        tStack.push(interior->GetFront());
656                        tStack.push(interior->GetBack());
657                }
658        }
659 
660        //ExportMesh(mesh);
661        //DEL_PTR(mesh);
662
663        return true;
664}
665
666bool X3dExporter::ExportVspKdTreeViewCells(const VspKdTree &tree, const int maxPvs)
667{
668        ViewCellContainer vc;
669
670        //if (maxPvs > 0)
671        mUseForcedMaterial = true;
672
673        tree.CollectViewCells(vc);
674
675        ViewCellContainer::const_iterator it, it_end = vc.end();
676
677        for (it = vc.begin(); it != it_end; ++ it)
678        {
679                VspKdViewCell *viewCell = dynamic_cast<VspKdViewCell *>(*it);
680
681                if (maxPvs > 0)
682                {                       
683                        mForcedMaterial.mDiffuseColor.b = 1.0f;
684                       
685                        const float importance = (float)viewCell->GetPvs().GetSize() / (float)maxPvs;
686                        mForcedMaterial.mDiffuseColor.r = importance;
687                        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
688                }
689                else
690                        mForcedMaterial = RandomMaterial();
691
692                ExportVspKdTreeViewCell(tree, *viewCell);
693        }
694
695        return true;
696}
697
698bool X3dExporter::ExportVspKdTreeViewCell(const VspKdTree &tree, const VspKdViewCell &vc)
699{
700        vector<VspKdLeaf *>::const_iterator it, it_end = vc.mLeaves.end();
701
702        for (it = vc.mLeaves.begin(); it != it_end; ++ it)
703                ExportBox(tree.GetBBox(*it));
704
705        return true;
706}
707
708bool X3dExporter::ExportKdTree(const KdTree &tree)
709{
710         if (mExportRayDensity) {
711    return ExportKdTreeRayDensity(tree);
712  }
713 
714  stack<KdNode *> tStack;
715
716  tStack.push(tree.GetRoot());
717
718  Mesh *mesh = new Mesh;
719 
720  while (!tStack.empty()) {
721    KdNode *node = tStack.top();
722    tStack.pop();
723    AxisAlignedBox3 box = tree.GetBox(node);
724    // add 6 vertices of the box
725    int index = (int)mesh->mVertices.size();
726    for (int i=0; i < 8; i++) {
727      Vector3 v;
728      box.GetVertex(i, v);
729      mesh->mVertices.push_back(v);
730    }
731    mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
732    mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
733    mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
734
735    mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
736    mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
737    mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
738
739    if (!node->IsLeaf()) {
740      KdInterior *interior = (KdInterior *)node;
741      tStack.push(interior->mFront);
742      tStack.push(interior->mBack);
743    }
744  }
745 
746  ExportMesh(mesh);
747  delete mesh;
748  return true;
749        // TODO
750        return true;
751}
752
753
754void
755X3dExporter::AddBoxToMesh(const AxisAlignedBox3 &box,
756                                                                                                        Mesh *mesh)
757{
758        // add 6 vertices of the box
759        int index = (int)mesh->mVertices.size();
760       
761        for (int i=0; i < 8; i++) {
762                Vector3 v;
763                box.GetVertex(i, v);
764                mesh->mVertices.push_back(v);
765        }
766       
767        mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
768        mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
769        mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
770       
771        mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
772        mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
773        mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
774
775}
776
777bool
778X3dExporter::ExportVssTree(const VssTree &tree
779                                                   )
780{
781  stack<VssTreeNode *> tStack;
782       
783  tStack.push(tree.GetRoot());
784       
785  Mesh *mesh = new Mesh;
786  VssRayContainer rays;
787       
788  while (!tStack.empty()) {
789
790                VssTreeNode *node = tStack.top();
791    tStack.pop();
792
793                       
794    if (!node->IsLeaf()) {
795      VssTreeInterior *interior = (VssTreeInterior *)node;
796      tStack.push(interior->front);
797      tStack.push(interior->back);
798    } else {
799                        VssTreeLeaf *leaf = (VssTreeLeaf *)node;
800                        AxisAlignedBox3 box;
801                        box = tree.GetBBox(leaf);
802                        AddBoxToMesh(box, mesh);
803
804                        if (tree.ValidLeaf(leaf)) {
805                               
806                                Vector3 origin = box.Center();
807                                box = tree.GetDirBBox(leaf);
808                                VssRay *ray;
809                               
810                                const indices[][2] = {{0,0}, {0,1}, {1,1}, {1,0}};
811                                MeshInstance dummy(mesh);
812                                for (int i=0; i < 4; i++) {
813                                        //                              Vector3 v = box.GetVertex(indices[i][0], indices[i][1], 0);
814                                        Vector3 v = box.Center();
815                                       
816                                        Vector3 direction = VssRay::GetDirection(v.x, v.y);
817                                        if (Magnitude(direction) > Limits::Small)
818                                          direction.Normalize();
819                                        else
820                                          direction = Vector3(0, 1, 0);
821                                        float k = 100.0f*leaf->GetImportance();
822                                        // get 4 corners of the ray directions
823                                       
824                                        ray = new VssRay(origin, origin + (direction*k), NULL, &dummy);
825                                        rays.push_back(ray);
826                                }
827                        }
828                }
829  }
830
831  ExportMesh(mesh);
832  ExportRays(rays);
833  CLEAR_CONTAINER(rays);
834  delete mesh;
835  return true;
836}
837
838bool
839X3dExporter::ExportVssTree2(const VssTree &tree,
840                                                        const Vector3 direction
841                                                        )
842{
843  stack<VssTreeNode *> tStack;
844       
845
846  mUseForcedMaterial = true;
847
848  Vector3 dirParam;
849
850  dirParam.x = VssRay::GetDirParam(0, Normalize(direction));
851  dirParam.y = VssRay::GetDirParam(1, Normalize(direction));
852
853  float maxImportance = 0.0f;
854  tStack.push(tree.GetRoot());
855  while (!tStack.empty()) {
856       
857        VssTreeNode *node = tStack.top();
858    tStack.pop();
859       
860    if (!node->IsLeaf()) {
861      VssTreeInterior *interior = (VssTreeInterior *)node;
862          if (interior->axis < 3) {
863                tStack.push(interior->front);
864                tStack.push(interior->back);
865          } else {
866                if (dirParam[interior->axis-3] < interior->position)
867                  tStack.push(interior->back);
868                else
869                  tStack.push(interior->front);
870          }
871    } else {
872          VssTreeLeaf *leaf = (VssTreeLeaf *)node;
873          if (tree.ValidLeaf(leaf)) {
874                float i = leaf->GetImportance();
875                if (i > maxImportance)
876                  maxImportance = i;
877          }
878        }
879  }
880
881  tStack.push(tree.GetRoot());
882  while (!tStack.empty()) {
883
884        VssTreeNode *node = tStack.top();
885    tStack.pop();
886       
887                       
888    if (!node->IsLeaf()) {
889      VssTreeInterior *interior = (VssTreeInterior *)node;
890          if (interior->axis < 3) {
891                tStack.push(interior->front);
892                tStack.push(interior->back);
893          } else {
894                if (dirParam[interior->axis-3] < interior->position)
895                  tStack.push(interior->back);
896                else
897                  tStack.push(interior->front);
898          }
899    } else {
900          VssTreeLeaf *leaf = (VssTreeLeaf *)node;
901          if (tree.ValidLeaf(leaf)) {
902                AxisAlignedBox3 box;
903                box = tree.GetBBox(leaf);
904                Mesh *mesh = new Mesh;
905                AddBoxToMesh(box, mesh);
906               
907                // get 4 corners of the ray directions
908               
909                mForcedMaterial.mDiffuseColor.b = 1.0f;
910                mForcedMaterial.mDiffuseColor.r = leaf->GetImportance()/maxImportance;
911                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
912               
913                ExportMesh(mesh);
914                delete mesh;
915          }
916        }
917  }
918
919  mUseForcedMaterial = false;
920
921  return true;
922}
923
924bool
925X3dExporter::ExportBspTreeRayDensity(const BspTree &tree)
926{
927        stack<BspNode *> tStack;
928
929        tStack.push(tree.GetRoot());
930
931        bool fm = mUseForcedMaterial;
932       
933        mUseForcedMaterial = true;
934       
935        mForcedMaterial.mDiffuseColor.g = 1.0f;
936        mForcedMaterial.mDiffuseColor.b = 1.0f;
937 
938        while (!tStack.empty())
939        {
940                BspNode *node = tStack.top();
941                tStack.pop();
942
943                if (node->IsLeaf())
944                {
945                        ViewCell *vc = dynamic_cast<BspLeaf *>(node)->GetViewCell();
946     
947                        // set the mesh material according to the ray density
948                        if (vc->mPassingRays.mRays)
949                        {
950                                float importance =
951                                  vc->mPassingRays.mContributions / (float)vc->mPassingRays.mRays;
952                               
953                                mForcedMaterial.mDiffuseColor.r = importance;
954                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
955                                ExportViewCell(vc);
956                        }
957                } else
958                {
959                        BspInterior *interior = (BspInterior *)node;
960                        tStack.push(interior->GetFront());
961                        tStack.push(interior->GetBack());
962                }
963        }
964 
965        // restore the state of forced material
966        mUseForcedMaterial = fm;
967
968        return true;
969}
970
971bool
972X3dExporter::ExportKdTreeRayDensity(const KdTree &tree)
973{
974  stack<KdNode *> tStack;
975
976  tStack.push(tree.GetRoot());
977
978  bool fm = mUseForcedMaterial;
979  mUseForcedMaterial = true;
980  mForcedMaterial.mDiffuseColor.g = 1.0f;
981  mForcedMaterial.mDiffuseColor.b = 1.0f;
982  while (!tStack.empty()) {
983    KdNode *node = tStack.top();
984    tStack.pop();
985    if (node->IsLeaf()) {
986      AxisAlignedBox3 box = tree.GetBox(node);
987      Mesh *mesh = new Mesh;
988     
989      // add 6 vertices of the box
990      int index = (int)mesh->mVertices.size();
991      for (int i=0; i < 8; i++) {
992        Vector3 v;
993        box.GetVertex(i, v);
994        mesh->mVertices.push_back(v);
995      }
996      mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
997      mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
998      mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
999     
1000      mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
1001      mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
1002      mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
1003
1004
1005      // set the mesh material according to the ray density
1006      KdLeaf *leaf = (KdLeaf *) node;
1007      if (leaf->mPassingRays.mRays) {
1008        float importance = leaf->mPassingRays.mContributions/(float)leaf->mPassingRays.mRays;
1009        //      float importance = leaf->mPassingRays.mContributions/1000.0f;
1010        //      float importance = leaf->mPassingRays.mRays/1000.0f;
1011        ///(float)leaf->mPassingRays.mRays;
1012        // mForcedMaterial.mDiffuseColor.r = log10(leaf->mPassingRays.mRays)/3.0f;
1013        mForcedMaterial.mDiffuseColor.r = importance;
1014        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
1015        ExportMesh(mesh);
1016      }
1017      delete mesh;
1018    } else {
1019      KdInterior *interior = (KdInterior *)node;
1020      tStack.push(interior->mFront);
1021      tStack.push(interior->mBack);
1022    }
1023  }
1024  // restore the state of forced material
1025  mUseForcedMaterial = fm;
1026  return true;
1027}
1028
1029
1030struct BspSplitData
1031{
1032        /// the current node
1033        BspNode *mNode;
1034
1035        vector<Plane3> mPlanes;
1036        vector<bool> mSides;
1037        bool mIsFront;
1038        int mDepth;
1039
1040        BspSplitData(BspNode *node):
1041        mNode(node), mIsFront(false), mDepth(0)
1042        {};     
1043
1044        BspSplitData(BspNode *node,
1045                                vector<Plane3> planes,
1046                                vector<bool> sides,
1047                                const bool isFront,
1048                                const int depth):
1049        mNode(node), mPlanes(planes), mSides(sides),
1050        mIsFront(isFront), mDepth(depth)
1051        {};
1052};
1053
1054void X3dExporter::ExportLeavesGeometry(const BspTree &tree,
1055                                                                           const vector<BspLeaf *> &leaves)
1056{
1057        vector<BspLeaf *>::const_iterator it, it_end = leaves.end();
1058
1059        for (it = leaves.begin(); it != it_end; ++ it)
1060        {
1061                PolygonContainer cell;
1062                tree.ConstructGeometry(*it, cell);
1063               
1064                ExportPolygons(cell);
1065
1066                CLEAR_CONTAINER(cell);
1067        }
1068}
1069
1070void X3dExporter::ExportBspNodeSplits(BspNode *root,
1071                                                                          const AxisAlignedBox3 &box,
1072                                                                          const bool exportDepth,
1073                                                                          const bool epsilon)
1074{
1075        std::stack<BspSplitData> tStack;
1076
1077        BspSplitData tData(root);
1078        tStack.push(tData);
1079 
1080        PolygonContainer polys;
1081        vector <int> depths;
1082
1083        int maxDepth = 0;
1084
1085        while (!tStack.empty())
1086        {
1087                // filter polygons donw the tree
1088                BspSplitData tData = tStack.top();
1089            tStack.pop();       
1090               
1091                if (tData.mNode->IsLeaf())
1092                {
1093                        if (tData.mDepth > maxDepth)
1094                                maxDepth = tData.mDepth;
1095                }
1096                else
1097                {
1098                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
1099
1100                        // add current side of split plane
1101                        if (tData.mNode != root)
1102                                tData.mSides.push_back(tData.mIsFront);
1103
1104                        // bounded plane is added to the polygons
1105                        Polygon3 *planePoly =
1106                                box.CrossSection(interior->GetPlane());
1107               
1108                        // do all the splits with the previous planes
1109                        for (int i = 0; i < (int)tData.mPlanes.size(); ++ i)
1110                        {                               
1111                                if (planePoly->ClassifyPlane(tData.mPlanes[i], epsilon)
1112                                        == Polygon3::SPLIT)
1113                                {
1114                                        Polygon3 *frontPoly = new Polygon3();
1115                                        Polygon3 *backPoly = new Polygon3();
1116
1117                                        planePoly->Split(tData.mPlanes[i],
1118                                                                         *frontPoly,
1119                                                                         *backPoly,
1120                                                                         epsilon);
1121
1122                                        DEL_PTR(planePoly);
1123
1124                                        if(tData.mSides[i] == true)
1125                                        {
1126                                                planePoly = frontPoly;
1127                                                DEL_PTR(backPoly);
1128                                        }
1129                                        else
1130                                        {
1131                                                planePoly = backPoly;
1132                                                DEL_PTR(frontPoly);
1133                                        }
1134                                }
1135                        }
1136
1137                        tData.mPlanes.push_back(interior->GetPlane()); // add plane to split planes
1138
1139                        if (planePoly->Valid(epsilon))
1140                        {
1141                                polys.push_back(planePoly);
1142                                depths.push_back(tData.mDepth);
1143                        }
1144                        else
1145                                DEL_PTR(planePoly);
1146                       
1147                        // push the children on the stack
1148                        tStack.push(BspSplitData(interior->GetFront(), tData.mPlanes,
1149                                                     tData.mSides, true, tData.mDepth + 1));
1150                        tStack.push(BspSplitData(interior->GetBack(), tData.mPlanes,
1151                                                     tData.mSides, false, tData.mDepth + 1));
1152                }
1153        }
1154
1155        if (maxDepth > 0)
1156        {       
1157                mUseForcedMaterial = true;
1158                       
1159                for (int i = 0; i < (int)polys.size(); ++ i)
1160                {
1161                        mForcedMaterial.mDiffuseColor.b = 1.0f;
1162                        float importance =  (float)depths[i]/ (float)maxDepth;
1163           
1164                        mForcedMaterial.mDiffuseColor.r = importance;
1165                        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
1166
1167                        ExportPolygon(polys[i]);
1168                }
1169        }
1170        else
1171        {
1172                ExportPolygons(polys);
1173        }
1174
1175        CLEAR_CONTAINER(polys);
1176}
1177
1178void X3dExporter::ExportBspSplits(const BspTree &tree,
1179                                                                  const bool exportDepth)
1180{
1181        ExportBspNodeSplits(tree.GetRoot(),
1182                                                tree.GetBoundingBox(),
1183                                                exportDepth,
1184                                                tree.GetEpsilon());
1185}
1186
1187void X3dExporter::ExportBspSplits(const VspBspTree &tree,
1188                                                                  const bool exportDepth)
1189{
1190        ExportBspNodeSplits(tree.GetRoot(),
1191                                                tree.GetBoundingBox(),
1192                                                exportDepth,
1193                                                tree.GetEpsilon());
1194}
1195
1196void X3dExporter::ExportBspSplitPlanes(const BspTree &tree)
1197{
1198        std::stack<BspNode *> tStack;
1199
1200        tStack.push(tree.GetRoot());
1201 
1202        PolygonContainer polys;
1203
1204        while (!tStack.empty())
1205        {
1206                // filter polygons donw the tree
1207                BspNode *node = tStack.top();
1208            tStack.pop();       
1209               
1210                if (!node->IsLeaf())
1211                {
1212                        BspInterior *interior = dynamic_cast<BspInterior *>(node);
1213
1214                        // bounded plane is added to the polygons
1215                        polys.push_back(tree.GetBoundingBox().CrossSection(interior->GetPlane()));
1216               
1217                        // push the children on the stack
1218                        tStack.push(interior->GetBack());
1219                        tStack.push(interior->GetFront());
1220                }
1221        }
1222
1223        ExportPolygons(polys);
1224        CLEAR_CONTAINER(polys);
1225}
1226
1227
1228void X3dExporter::ExportGeometry(const ObjectContainer &objects)
1229{
1230        for (int j = 0; j < objects.size(); ++ j)
1231                ExportIntersectable(objects[j]);
1232}
1233
1234void X3dExporter::ExportBspViewCellPartition(const VspBspTree &tree,
1235                                                                                         const int maxPvs)
1236{
1237        ViewCellContainer viewCells;
1238        tree.CollectViewCells(viewCells);
1239
1240        ViewCellContainer::const_iterator it, it_end = viewCells.end();
1241
1242        if (maxPvs > 0)
1243                mUseForcedMaterial = true;
1244
1245        for (it = viewCells.begin(); it != it_end; ++ it)
1246        {
1247                if (maxPvs > 0)
1248                {
1249                        mForcedMaterial.mDiffuseColor.b = 1.0f;
1250                        float importance = (float)(*it)->GetPvs().GetSize() / (float)maxPvs;
1251
1252                        mForcedMaterial.mDiffuseColor.r = importance;
1253                        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
1254                }
1255
1256                if ((*it)->GetMesh())
1257                        ExportViewCell(*it);
1258                else
1259                {
1260                        PolygonContainer cell;
1261                        tree.ConstructGeometry(dynamic_cast<BspViewCell *>(*it), cell);
1262
1263                        ExportPolygons(cell);
1264                }
1265        }
1266}
1267
1268
1269bool
1270X3dExporter::ExportRssTree2(const RssTree &tree,
1271                                                        const Vector3 direction
1272                                                        )
1273{
1274  stack<RssTreeNode *> tStack;
1275 
1276 
1277  mUseForcedMaterial = true;
1278
1279  Vector3 dirParam;
1280
1281  dirParam.x = VssRay::GetDirParam(0, Normalize(direction));
1282  dirParam.y = VssRay::GetDirParam(1, Normalize(direction));
1283
1284  float maxImportance = 0.0f;
1285  tStack.push(tree.GetRoot());
1286  while (!tStack.empty()) {
1287       
1288        RssTreeNode *node = tStack.top();
1289    tStack.pop();
1290       
1291    if (!node->IsLeaf()) {
1292      RssTreeInterior *interior = (RssTreeInterior *)node;
1293          if (interior->axis < 3) {
1294                tStack.push(interior->front);
1295                tStack.push(interior->back);
1296          } else {
1297                if (dirParam[interior->axis-3] < interior->position)
1298                  tStack.push(interior->back);
1299                else
1300                  tStack.push(interior->front);
1301          }
1302    } else {
1303          RssTreeLeaf *leaf = (RssTreeLeaf *)node;
1304          if (tree.ValidLeaf(leaf)) {
1305                float i = leaf->GetImportance();
1306                if (i > maxImportance)
1307                  maxImportance = i;
1308          }
1309        }
1310  }
1311
1312  tStack.push(tree.GetRoot());
1313  while (!tStack.empty()) {
1314
1315        RssTreeNode *node = tStack.top();
1316    tStack.pop();
1317       
1318                       
1319    if (!node->IsLeaf()) {
1320      RssTreeInterior *interior = (RssTreeInterior *)node;
1321          if (interior->axis < 3) {
1322                tStack.push(interior->front);
1323                tStack.push(interior->back);
1324          } else {
1325                if (dirParam[interior->axis-3] < interior->position)
1326                  tStack.push(interior->back);
1327                else
1328                  tStack.push(interior->front);
1329          }
1330    } else {
1331          RssTreeLeaf *leaf = (RssTreeLeaf *)node;
1332          if (tree.ValidLeaf(leaf)) {
1333                AxisAlignedBox3 box;
1334                box = tree.GetShrankedBBox(leaf);
1335                Mesh *mesh = new Mesh;
1336                AddBoxToMesh(box, mesh);
1337               
1338                // get 4 corners of the ray directions
1339               
1340                mForcedMaterial.mDiffuseColor.b = 1.0f;
1341                mForcedMaterial.mDiffuseColor.r = leaf->GetImportance()/maxImportance;
1342                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
1343               
1344                ExportMesh(mesh);
1345                delete mesh;
1346          }
1347        }
1348  }
1349
1350  mUseForcedMaterial = false;
1351
1352  return true;
1353}
1354
1355
1356void
1357X3dExporter::ExportViewpoint(const Vector3 &point,
1358                                                         const Vector3 &direction)
1359{
1360  stream<<"<Viewpoint "<<endl;
1361 
1362  stream<<"position=\""<<point.x<<" "<<point.y<<" "<<point.z<<"\""<<endl;
1363  //  stream<<"orientation "<<direction.x<<direction.y<<direction.z<<endl;
1364 
1365  stream<<">"<<endl;
1366  stream<<"</Viewpoint>"<<endl;
1367 
1368}
Note: See TracBrowser for help on using the repository browser.