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

Revision 1141, 30.3 KB checked in by mattausch, 18 years ago (diff)

added kd pvs support, changed way of counting pvs

RevLine 
[162]1#include <stack>
2#include "common.h"
3#include "SceneGraph.h"
4#include "X3dExporter.h"
5#include "Mesh.h"
6#include "KdTree.h"
[242]7#include "ViewCellBsp.h"
8#include "ViewCell.h"
[260]9#include "Polygon3.h"
[386]10#include "VssRay.h"
[1106]11#include "VspOspTree.h"
[434]12#include "VssTree.h"
[449]13#include "VspBspTree.h"
[450]14#include "RssTree.h"
[535]15#include "Beam.h"
[162]16
[863]17namespace GtpVisibilityPreprocessor {
[449]18
[694]19
[162]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
[176]36
[1112]37
[162]38bool
[386]39X3dExporter::ExportRays(const RayContainer &rays,
[444]40                                                const float length,
41                                                const RgbColor &color)
[162]42{
[386]43  RayContainer::const_iterator ri = rays.begin();
44
[162]45  stream<<"<Shape>"<<endl;
[176]46  stream<<"<Appearance>"<<endl;
[427]47  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
[176]48    "\" />"<<endl;
49  stream<<"</Appearance>"<<endl;
50 
[209]51  stream<<"<IndexedLineSet coordIndex=\""<<endl;
[162]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++) {
[386]65    Vector3 a = (*ri)->GetLoc();
[162]66   
[176]67    Vector3 b;
68    if (length < 0)
[386]69      b = (*ri)->GetLoc() - length*(*ri)->GetDir();
[176]70    else
[386]71      if ((*ri)->intersections.size()==0)
[492]72                b = (*ri)->GetLoc() + length*(*ri)->GetDir();
[176]73      else
[492]74                b = (*ri)->Extrap((*ri)->intersections[0].mT);
[176]75   
[162]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;
[386]84
[162]85  return true;
86}
87
[1112]88
[349]89bool
[1112]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 = 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
[386]142X3dExporter::ExportRays(const VssRayContainer &rays,
[444]143                                                const RgbColor &color)
[349]144{
[386]145  VssRayContainer::const_iterator ri = rays.begin();
[349]146
147  stream<<"<Shape>"<<endl;
148  stream<<"<Appearance>"<<endl;
[427]149  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
[349]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++) {
[444]167    const Vector3 a = (*ri)->GetOrigin();
[483]168        //const Vector3 b = (*ri)->mTerminationObject ? (*ri)->GetTermination() : a + 1000 * Normalize((*ri)->GetDir());
169        const Vector3 b = (*ri)->GetTermination(); // matt: change again!!
170
[349]171    stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
[444]172        stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
[349]173  }
174 
175  stream<<"\" >"<<endl;
176  stream<<"</Coordinate>"<<endl;
177  stream<<"</IndexedLineSet>"<<endl;
178  stream<<"</Shape>"<<endl;
[386]179       
[349]180  return true;
181}
182
[162]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 
[176]193  ObjectContainer::const_iterator mi = node->mGeometry.begin();
[162]194  for (; mi != node->mGeometry.end(); mi++) {
195    // export the transform...
[176]196    ExportIntersectable(*mi);
[162]197  }
198 
199  stream<<"</Group>"<<endl;
200
201}
[176]202void
203X3dExporter::ExportIntersectable(Intersectable *object)
204{
[1001]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        }
[176]220}
[162]221
[694]222
[162]223void
[176]224X3dExporter::ExportMeshInstance(MeshInstance *object)
225{
226  // $$JB$$
[312]227  // in the future check whether the mesh was not already exported
[176]228  // and use a reference to the that mesh instead
229  ExportMesh(object->GetMesh());
230}
231
[694]232
[1001]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
[313]246void
247X3dExporter::ExportViewCells(const ViewCellContainer &viewCells)
[261]248{
[313]249        ViewCellContainer::const_iterator it, it_end = viewCells.end();
[261]250
[313]251        for (it = viewCells.begin(); it != it_end; ++ it)
[261]252                ExportViewCell(*it);
253}
[313]254
[1001]255
[373]256void
[396]257X3dExporter::ExportBspLeaves(const BspTree &tree, const int maxPvs)
[373]258{
[396]259        stack<pair<BspNode *, BspNodeGeometry *> > tStack;
260        ViewCell::NewMail();
[373]261
[396]262        BspNodeGeometry *geom = new BspNodeGeometry();
263        tree.ConstructGeometry(tree.GetRoot(), *geom);
[373]264
[396]265        tStack.push(pair<BspNode *, BspNodeGeometry *>(tree.GetRoot(), geom));
266
[1020]267        if (maxPvs)
[396]268                mUseForcedMaterial = true;
269
270        while (!tStack.empty())
[373]271        {
[396]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
[449]283                        cell->SplitGeometry(*front,
284                                                                *back,
285                                                                interior->GetPlane(),
286                                                                tree.GetBoundingBox(),
287                                                                tree.GetEpsilon());
[396]288
289                        tStack.push(pair<BspNode *, BspNodeGeometry *>(interior->GetFront(), front));
290                        tStack.push(pair<BspNode *, BspNodeGeometry *>(interior->GetBack(), back));
291                }
292                else
293                {
[1020]294                        if (maxPvs)
[396]295                        {
296                                BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
297
298                                mForcedMaterial.mDiffuseColor.b = 1.0f;
[1141]299                                const float importance =
300                                        (float)leaf->GetViewCell()->GetPvs().CountPvs() / (float)maxPvs;
[396]301
302                                mForcedMaterial.mDiffuseColor.r = importance;
303                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
304                        }
305
[678]306                        ExportPolygons(cell->GetPolys());
[396]307                }
308               
309                DEL_PTR(cell);
[373]310        }
311}
312
[176]313void
[261]314X3dExporter::ExportViewCell(ViewCell *viewCell)
[242]315{
[261]316        if (viewCell->GetMesh())
317                ExportMesh(viewCell->GetMesh());
[242]318}
319
320void
[162]321X3dExporter::ExportMesh(Mesh *mesh)
322{
323
324  stream<<"<Shape>"<<endl;
325  stream<<"<Appearance>"<<endl;
[176]326 
[162]327  // $$ tmp -> random material
328 
329  float r, g, b;
330
[176]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    }
[1001]346   
[162]347  stream<<"<Material diffuseColor=\""<<r<<" "<<g<<" "<<b<<
348    "\" specularColor=\"0.0 0.0 0.0\"/>"<<endl;
349  stream<<"</Appearance>"<<endl;
350
351
[191]352  if (mWireframe)
[427]353    stream<<"<IndexedLineSet coordIndex=\""<<endl;
[162]354  else
[465]355    //stream<<"<IndexedFaceSet ccw=\"TRUE\" coordIndex=\""<<endl;
356        stream << "<IndexedFaceSet coordIndex=\"" << endl;
[162]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<<" ";
[378]367        if (mWireframe) // final line to finish polygon
368                stream << (*face->mVertexIndices.begin()) << " ";
369
[162]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
[191]385  if (mWireframe)
[162]386    stream<<"</IndexedLineSet>"<<endl;
387  else
388    stream<<"</IndexedFaceSet>"<<endl;
389 
390  stream<<"</Shape>"<<endl;
391
392}
393
[242]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
[262]428        //-- create and write indices
[242]429        if (mWireframe)
[465]430                stream<<"<IndexedLineSet coordIndex=\""<<endl;
[242]431        else
[465]432                //stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
433                stream << "<IndexedFaceSet coordIndex=\"" << endl;
[262]434        int index = 0;
435       
436        VertexContainer::const_iterator vi; 
437       
[333]438        for (index = 0; index < (int)poly->mVertices.size(); ++ index)
[318]439                stream << index << " ";
440       
441        if (mWireframe) // final line to finish polygon
442                stream << "0 ";
443
[262]444        stream << "-1" << endl;
445        stream << "\" >" << endl;
446       
[242]447        stream << "<Coordinate  point=\"" << endl;
448 
[262]449        for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
[242]450        {
451                stream << (*vi).x << " " << (*vi).y << " " << (*vi).z;
452                stream << "," << endl;
453        }
454 
[262]455        stream << "\" >" << endl;
456        stream << "</Coordinate>" << endl;
[242]457
458        if (mWireframe)
459                stream << "</IndexedLineSet>" << endl;
460        else
461                stream << "</IndexedFaceSet>" << endl;
462 
463        stream << "</Shape>" << endl;
464}
465
[712]466
[1006]467
[313]468void X3dExporter::ExportPolygons(const PolygonContainer &polys)
[263]469{
[318]470        stream << "<Shape>" << endl;
[263]471        stream << "<Appearance>" << endl;
472 
473        // $$ tmp -> random material
474 
475        float r, g, b;
[242]476
[263]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)
[465]498                stream<<"<IndexedLineSet coordIndex=\""<<endl;
[263]499        else
[465]500                //stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
501                stream << "<IndexedFaceSet coordIndex=\"" << endl;
[263]502
503        int index = 0;
504       
505        PolygonContainer::const_iterator pit;
506
507    VertexContainer::const_iterator vi; 
508       
[313]509        for (pit = polys.begin(); pit != polys.end(); ++pit)
[263]510        {
511                Polygon3 *poly = *pit;
[318]512                int startIdx = index;
[263]513                for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
514                {
515                        stream << index ++ << " ";
516                }
[318]517
518                stream << startIdx << " ";// finish line
[263]519                stream << "-1" << endl;
520        }
521
522        stream << "\" >" << endl;
523       
524        stream << "<Coordinate  point=\"" << endl;
[318]525        for (pit = polys.begin(); pit != polys.end(); ++ pit)
[263]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
[1006]545
[162]546bool
547X3dExporter::ExportBox(const AxisAlignedBox3 &box)
548{
549  Mesh *mesh = new Mesh;
[547]550  // add 8 vertices of the box
[289]551  int index = (int)mesh->mVertices.size();
[162]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
[1006]571
[162]572bool
[242]573X3dExporter::ExportBspTree(const BspTree &tree)
[162]574{
[242]575        if (mExportRayDensity)
576        {
[263]577                return ExportBspTreeRayDensity(tree);
[242]578        }
579 
[264]580        bool savedWireframe = mWireframe;
581
582        SetWireframe();
583       
[396]584        ExportBox(tree.GetBoundingBox());
585       
[264]586        if (!savedWireframe)
587                SetFilled();
588
[373]589        // export view cells
[482]590        ExportBspLeaves(tree); 
[289]591
[263]592        return true;
[242]593}
594
[418]595
[242]596bool X3dExporter::ExportKdTree(const KdTree &tree)
597{
598         if (mExportRayDensity) {
[191]599    return ExportKdTreeRayDensity(tree);
600  }
601 
[162]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
[289]613    int index = (int)mesh->mVertices.size();
[162]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;
[1006]636
[162]637  return true;
638}
639
640
[434]641
642
[191]643bool
[438]644X3dExporter::ExportVssTree(const VssTree &tree
645                                                   )
[434]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);
[860]668                        IncludeBoxInMesh(box, *mesh);
[434]669
670                        if (tree.ValidLeaf(leaf)) {
671                               
672                                Vector3 origin = box.Center();
673                                box = tree.GetDirBBox(leaf);
674                                VssRay *ray;
675                               
[1004]676                                const int indices[][2] = {{0,0}, {0,1}, {1,1}, {1,0}};
[434]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);
[438]683                                        if (Magnitude(direction) > Limits::Small)
684                                          direction.Normalize();
685                                        else
686                                          direction = Vector3(0, 1, 0);
[435]687                                        float k = 100.0f*leaf->GetImportance();
[434]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);
[438]698  ExportRays(rays);
699  CLEAR_CONTAINER(rays);
[434]700  delete mesh;
701  return true;
702}
703
704bool
[438]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;
[860]771                IncludeBoxInMesh(box, *mesh);
[438]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
[263]791X3dExporter::ExportBspTreeRayDensity(const BspTree &tree)
792{
[311]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();
[580]812#if 0     
[311]813                        // set the mesh material according to the ray density
814                        if (vc->mPassingRays.mRays)
815                        {
[313]816                                float importance =
[438]817                                  vc->mPassingRays.mContributions / (float)vc->mPassingRays.mRays;
818                               
[311]819                                mForcedMaterial.mDiffuseColor.r = importance;
820                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
821                                ExportViewCell(vc);
[580]822
[438]823                        }
[580]824#endif
825                }
826                else
[311]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
[263]837        return true;
838}
839
840bool
[191]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
[289]859      int index = (int)mesh->mVertices.size();
[191]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}
[312]897
[329]898
[312]899struct BspSplitData
900{
[372]901        /// the current node
902        BspNode *mNode;
903
[449]904        vector<Plane3> mPlanes;
[372]905        vector<bool> mSides;
906        bool mIsFront;
[383]907        int mDepth;
[372]908
[313]909        BspSplitData(BspNode *node):
[383]910        mNode(node), mIsFront(false), mDepth(0)
[372]911        {};     
[383]912
[312]913        BspSplitData(BspNode *node,
[449]914                                vector<Plane3> planes,
[329]915                                vector<bool> sides,
[383]916                                const bool isFront,
917                                const int depth):
918        mNode(node), mPlanes(planes), mSides(sides),
919        mIsFront(isFront), mDepth(depth)
[312]920        {};
921};
922
[383]923void X3dExporter::ExportLeavesGeometry(const BspTree &tree,
924                                                                           const vector<BspLeaf *> &leaves)
[360]925{
926        vector<BspLeaf *>::const_iterator it, it_end = leaves.end();
927
928        for (it = leaves.begin(); it != it_end; ++ it)
929        {
[503]930                BspNodeGeometry geom;
931                tree.ConstructGeometry(*it, geom);
[360]932               
[678]933                ExportPolygons(geom.GetPolys());
[360]934        }
935}
936
[449]937void X3dExporter::ExportBspNodeSplits(BspNode *root,
938                                                                          const AxisAlignedBox3 &box,
939                                                                          const bool exportDepth,
940                                                                          const bool epsilon)
[372]941{
942        std::stack<BspSplitData> tStack;
943
[449]944        BspSplitData tData(root);
[372]945        tStack.push(tData);
946 
947        PolygonContainer polys;
[383]948        vector <int> depths;
[372]949
[383]950        int maxDepth = 0;
951
[372]952        while (!tStack.empty())
953        {
954                // filter polygons donw the tree
955                BspSplitData tData = tStack.top();
956            tStack.pop();       
957               
[383]958                if (tData.mNode->IsLeaf())
[372]959                {
[383]960                        if (tData.mDepth > maxDepth)
961                                maxDepth = tData.mDepth;
962                }
963                else
964                {
[372]965                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
966
[383]967                        // add current side of split plane
[449]968                        if (tData.mNode != root)
[383]969                                tData.mSides.push_back(tData.mIsFront);
[372]970
971                        // bounded plane is added to the polygons
[383]972                        Polygon3 *planePoly =
[449]973                                box.CrossSection(interior->GetPlane());
[372]974               
975                        // do all the splits with the previous planes
976                        for (int i = 0; i < (int)tData.mPlanes.size(); ++ i)
[436]977                        {                               
[449]978                                if (planePoly->ClassifyPlane(tData.mPlanes[i], epsilon)
979                                        == Polygon3::SPLIT)
[372]980                                {
981                                        Polygon3 *frontPoly = new Polygon3();
982                                        Polygon3 *backPoly = new Polygon3();
983
[449]984                                        planePoly->Split(tData.mPlanes[i],
985                                                                         *frontPoly,
986                                                                         *backPoly,
987                                                                         epsilon);
988
[372]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
[449]1006                        if (planePoly->Valid(epsilon))
[383]1007                        {
[372]1008                                polys.push_back(planePoly);
[383]1009                                depths.push_back(tData.mDepth);
1010                        }
[372]1011                        else
1012                                DEL_PTR(planePoly);
1013                       
1014                        // push the children on the stack
[383]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));
[372]1019                }
[383]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
[372]1042        CLEAR_CONTAINER(polys);
1043}
1044
[449]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
[372]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
[449]1082                        polys.push_back(tree.GetBoundingBox().CrossSection(interior->GetPlane()));
[372]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}
[440]1093
1094
[449]1095void X3dExporter::ExportGeometry(const ObjectContainer &objects)
[440]1096{
[712]1097        ObjectContainer::const_iterator oit, oit_end = objects.end();
1098
1099        if (1)
1100        {
1101                for (oit = objects.begin(); oit != oit_end; ++ oit)
1102                {
[726]1103                        if (0)
[712]1104                                SetForcedMaterial(RandomMaterial());
[726]1105                       
[712]1106                        ExportIntersectable(*oit);
1107                }
1108
1109                return;
1110        }
1111
1112        // hack: all object exported as one mesh
[685]1113        PolygonContainer polys;
[712]1114
1115        for (oit = objects.begin(); oit != oit_end; ++ oit)
1116        {
1117                polys.push_back(new Polygon3(dynamic_cast<MeshInstance *>(*oit)->GetMesh()->mVertices));
[685]1118        }
1119
1120        Mesh dummyMesh;
[712]1121        PolygonContainer::const_iterator pit, pit_end = polys.end();
[685]1122
[712]1123        for (pit = polys.begin(); pit != pit_end; ++ pit)
1124        {
[840]1125                Polygon3 *poly = (*pit);
1126                IncludePolyInMesh(*poly, dummyMesh);
[712]1127        }
1128       
[685]1129        ExportMesh(&dummyMesh);
[712]1130
[685]1131        CLEAR_CONTAINER(polys);
[440]1132}
[449]1133
1134
[450]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;
[860]1202                IncludeBoxInMesh(box, *mesh);
[450]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}
[459]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;
[535]1233
[459]1234}
[535]1235
1236
1237
1238void X3dExporter::ExportBeam(const Beam &beam, const AxisAlignedBox3 &box)
1239{
[540]1240        if (beam.mMesh)
1241        {
1242                ExportMesh(beam.mMesh);
1243                return;
1244        }
1245
[535]1246        PolygonContainer polys;
1247        //ExportBox(beam.mBox);
1248
[540]1249        const float zfar = 2.0f * Magnitude(box.Diagonal());
1250
1251        // box should not never remove part of beam polygons
[564]1252        Vector3 bmin = beam.mBox.Min() - Vector3(zfar * 2.0f);
1253        Vector3 bmax = beam.mBox.Max() + Vector3(zfar * 2.0f);
[540]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)
[535]1265        {
[540]1266                Polygon3 *poly = bbox.CrossSection(planes[i]);
1267                if (!poly->Valid(Limits::Small))
1268                        DEL_PTR(poly);
[535]1269               
[540]1270                for (int j = 0; (j < planes.size()) && poly; ++ j)
[535]1271                {
1272                        if (j != i)
1273                        {
1274                                Polygon3 *front = new Polygon3();
1275                                Polygon3 *back = new Polygon3();
1276                               
[540]1277                                poly->Split(planes[j], *front, *back, Limits::Small);
[535]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);
[685]1292}
[860]1293
[1106]1294
1295}
1296
Note: See TracBrowser for help on using the repository browser.