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

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