source: GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp @ 2743

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