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

Revision 1233, 30.5 KB checked in by mattausch, 18 years ago (diff)
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"
[1233]11#include "HierarchyManager.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;
[1178]116  int size = (int)rays.size() + 2;
[1112]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 =
[1168]300                                        (float)leaf->GetViewCell()->GetPvs().CountObjectsInPvs() / (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
[1197]596bool X3dExporter::ExportKdTree(const KdTree &tree,
597                                                           const bool exportGeometry)
[242]598{
599         if (mExportRayDensity) {
[191]600    return ExportKdTreeRayDensity(tree);
601  }
602 
[162]603  stack<KdNode *> tStack;
604
605  tStack.push(tree.GetRoot());
606
607  Mesh *mesh = new Mesh;
608 
609  while (!tStack.empty()) {
610    KdNode *node = tStack.top();
611    tStack.pop();
612    AxisAlignedBox3 box = tree.GetBox(node);
613    // add 6 vertices of the box
[289]614    int index = (int)mesh->mVertices.size();
[162]615    for (int i=0; i < 8; i++) {
616      Vector3 v;
617      box.GetVertex(i, v);
618      mesh->mVertices.push_back(v);
619    }
620    mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
621    mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
622    mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
623
624    mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
625    mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
626    mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
627
628    if (!node->IsLeaf()) {
629      KdInterior *interior = (KdInterior *)node;
630      tStack.push(interior->mFront);
631      tStack.push(interior->mBack);
632    }
[1197]633        else if (exportGeometry)
634        {
635                SetFilled();
636                SetForcedMaterial(RandomMaterial());
637                ExportGeometry(dynamic_cast<KdLeaf *>(node)->mObjects);
638                SetWireframe();
639        }
[162]640  }
641 
642  ExportMesh(mesh);
643  delete mesh;
[1006]644
[162]645  return true;
646}
647
648
[191]649bool
[438]650X3dExporter::ExportVssTree(const VssTree &tree
651                                                   )
[434]652{
653  stack<VssTreeNode *> tStack;
654       
655  tStack.push(tree.GetRoot());
656       
657  Mesh *mesh = new Mesh;
658  VssRayContainer rays;
659       
660  while (!tStack.empty()) {
661
662                VssTreeNode *node = tStack.top();
663    tStack.pop();
664
665                       
666    if (!node->IsLeaf()) {
667      VssTreeInterior *interior = (VssTreeInterior *)node;
668      tStack.push(interior->front);
669      tStack.push(interior->back);
670    } else {
671                        VssTreeLeaf *leaf = (VssTreeLeaf *)node;
672                        AxisAlignedBox3 box;
673                        box = tree.GetBBox(leaf);
[860]674                        IncludeBoxInMesh(box, *mesh);
[434]675
676                        if (tree.ValidLeaf(leaf)) {
677                               
678                                Vector3 origin = box.Center();
679                                box = tree.GetDirBBox(leaf);
680                                VssRay *ray;
681                               
[1004]682                                const int indices[][2] = {{0,0}, {0,1}, {1,1}, {1,0}};
[434]683                                MeshInstance dummy(mesh);
684                                for (int i=0; i < 4; i++) {
685                                        //                              Vector3 v = box.GetVertex(indices[i][0], indices[i][1], 0);
686                                        Vector3 v = box.Center();
687                                       
688                                        Vector3 direction = VssRay::GetDirection(v.x, v.y);
[438]689                                        if (Magnitude(direction) > Limits::Small)
690                                          direction.Normalize();
691                                        else
692                                          direction = Vector3(0, 1, 0);
[435]693                                        float k = 100.0f*leaf->GetImportance();
[434]694                                        // get 4 corners of the ray directions
695                                       
696                                        ray = new VssRay(origin, origin + (direction*k), NULL, &dummy);
697                                        rays.push_back(ray);
698                                }
699                        }
700                }
701  }
702
703  ExportMesh(mesh);
[438]704  ExportRays(rays);
705  CLEAR_CONTAINER(rays);
[434]706  delete mesh;
707  return true;
708}
709
710bool
[438]711X3dExporter::ExportVssTree2(const VssTree &tree,
712                                                        const Vector3 direction
713                                                        )
714{
715  stack<VssTreeNode *> tStack;
716       
717
718  mUseForcedMaterial = true;
719
720  Vector3 dirParam;
721
722  dirParam.x = VssRay::GetDirParam(0, Normalize(direction));
723  dirParam.y = VssRay::GetDirParam(1, Normalize(direction));
724
725  float maxImportance = 0.0f;
726  tStack.push(tree.GetRoot());
727  while (!tStack.empty()) {
728       
729        VssTreeNode *node = tStack.top();
730    tStack.pop();
731       
732    if (!node->IsLeaf()) {
733      VssTreeInterior *interior = (VssTreeInterior *)node;
734          if (interior->axis < 3) {
735                tStack.push(interior->front);
736                tStack.push(interior->back);
737          } else {
738                if (dirParam[interior->axis-3] < interior->position)
739                  tStack.push(interior->back);
740                else
741                  tStack.push(interior->front);
742          }
743    } else {
744          VssTreeLeaf *leaf = (VssTreeLeaf *)node;
745          if (tree.ValidLeaf(leaf)) {
746                float i = leaf->GetImportance();
747                if (i > maxImportance)
748                  maxImportance = i;
749          }
750        }
751  }
752
753  tStack.push(tree.GetRoot());
754  while (!tStack.empty()) {
755
756        VssTreeNode *node = tStack.top();
757    tStack.pop();
758       
759                       
760    if (!node->IsLeaf()) {
761      VssTreeInterior *interior = (VssTreeInterior *)node;
762          if (interior->axis < 3) {
763                tStack.push(interior->front);
764                tStack.push(interior->back);
765          } else {
766                if (dirParam[interior->axis-3] < interior->position)
767                  tStack.push(interior->back);
768                else
769                  tStack.push(interior->front);
770          }
771    } else {
772          VssTreeLeaf *leaf = (VssTreeLeaf *)node;
773          if (tree.ValidLeaf(leaf)) {
774                AxisAlignedBox3 box;
775                box = tree.GetBBox(leaf);
776                Mesh *mesh = new Mesh;
[860]777                IncludeBoxInMesh(box, *mesh);
[438]778               
779                // get 4 corners of the ray directions
780               
781                mForcedMaterial.mDiffuseColor.b = 1.0f;
782                mForcedMaterial.mDiffuseColor.r = leaf->GetImportance()/maxImportance;
783                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
784               
785                ExportMesh(mesh);
786                delete mesh;
787          }
788        }
789  }
790
791  mUseForcedMaterial = false;
792
793  return true;
794}
795
796bool
[263]797X3dExporter::ExportBspTreeRayDensity(const BspTree &tree)
798{
[311]799        stack<BspNode *> tStack;
800
801        tStack.push(tree.GetRoot());
802
803        bool fm = mUseForcedMaterial;
804       
805        mUseForcedMaterial = true;
806       
807        mForcedMaterial.mDiffuseColor.g = 1.0f;
808        mForcedMaterial.mDiffuseColor.b = 1.0f;
809 
810        while (!tStack.empty())
811        {
812                BspNode *node = tStack.top();
813                tStack.pop();
814
815                if (node->IsLeaf())
816                {
817                        ViewCell *vc = dynamic_cast<BspLeaf *>(node)->GetViewCell();
[580]818#if 0     
[311]819                        // set the mesh material according to the ray density
820                        if (vc->mPassingRays.mRays)
821                        {
[313]822                                float importance =
[438]823                                  vc->mPassingRays.mContributions / (float)vc->mPassingRays.mRays;
824                               
[311]825                                mForcedMaterial.mDiffuseColor.r = importance;
826                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
827                                ExportViewCell(vc);
[580]828
[438]829                        }
[580]830#endif
831                }
832                else
[311]833                {
834                        BspInterior *interior = (BspInterior *)node;
835                        tStack.push(interior->GetFront());
836                        tStack.push(interior->GetBack());
837                }
838        }
839 
840        // restore the state of forced material
841        mUseForcedMaterial = fm;
842
[263]843        return true;
844}
845
846bool
[191]847X3dExporter::ExportKdTreeRayDensity(const KdTree &tree)
848{
849  stack<KdNode *> tStack;
850
851  tStack.push(tree.GetRoot());
852
853  bool fm = mUseForcedMaterial;
854  mUseForcedMaterial = true;
855  mForcedMaterial.mDiffuseColor.g = 1.0f;
856  mForcedMaterial.mDiffuseColor.b = 1.0f;
857  while (!tStack.empty()) {
858    KdNode *node = tStack.top();
859    tStack.pop();
860    if (node->IsLeaf()) {
861      AxisAlignedBox3 box = tree.GetBox(node);
862      Mesh *mesh = new Mesh;
863     
864      // add 6 vertices of the box
[289]865      int index = (int)mesh->mVertices.size();
[191]866      for (int i=0; i < 8; i++) {
867        Vector3 v;
868        box.GetVertex(i, v);
869        mesh->mVertices.push_back(v);
870      }
871      mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
872      mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
873      mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
874     
875      mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
876      mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
877      mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
878
879
880      // set the mesh material according to the ray density
881      KdLeaf *leaf = (KdLeaf *) node;
882      if (leaf->mPassingRays.mRays) {
883        float importance = leaf->mPassingRays.mContributions/(float)leaf->mPassingRays.mRays;
884        //      float importance = leaf->mPassingRays.mContributions/1000.0f;
885        //      float importance = leaf->mPassingRays.mRays/1000.0f;
886        ///(float)leaf->mPassingRays.mRays;
887        // mForcedMaterial.mDiffuseColor.r = log10(leaf->mPassingRays.mRays)/3.0f;
888        mForcedMaterial.mDiffuseColor.r = importance;
889        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
890        ExportMesh(mesh);
891      }
892      delete mesh;
893    } else {
894      KdInterior *interior = (KdInterior *)node;
895      tStack.push(interior->mFront);
896      tStack.push(interior->mBack);
897    }
898  }
899  // restore the state of forced material
900  mUseForcedMaterial = fm;
901  return true;
902}
[312]903
[329]904
[312]905struct BspSplitData
906{
[372]907        /// the current node
908        BspNode *mNode;
909
[449]910        vector<Plane3> mPlanes;
[372]911        vector<bool> mSides;
912        bool mIsFront;
[383]913        int mDepth;
[372]914
[313]915        BspSplitData(BspNode *node):
[383]916        mNode(node), mIsFront(false), mDepth(0)
[372]917        {};     
[383]918
[312]919        BspSplitData(BspNode *node,
[449]920                                vector<Plane3> planes,
[329]921                                vector<bool> sides,
[383]922                                const bool isFront,
923                                const int depth):
924        mNode(node), mPlanes(planes), mSides(sides),
925        mIsFront(isFront), mDepth(depth)
[312]926        {};
927};
928
[383]929void X3dExporter::ExportLeavesGeometry(const BspTree &tree,
930                                                                           const vector<BspLeaf *> &leaves)
[360]931{
932        vector<BspLeaf *>::const_iterator it, it_end = leaves.end();
933
934        for (it = leaves.begin(); it != it_end; ++ it)
935        {
[503]936                BspNodeGeometry geom;
937                tree.ConstructGeometry(*it, geom);
[360]938               
[678]939                ExportPolygons(geom.GetPolys());
[360]940        }
941}
942
[449]943void X3dExporter::ExportBspNodeSplits(BspNode *root,
944                                                                          const AxisAlignedBox3 &box,
945                                                                          const bool exportDepth,
946                                                                          const bool epsilon)
[372]947{
948        std::stack<BspSplitData> tStack;
949
[449]950        BspSplitData tData(root);
[372]951        tStack.push(tData);
952 
953        PolygonContainer polys;
[383]954        vector <int> depths;
[372]955
[383]956        int maxDepth = 0;
957
[372]958        while (!tStack.empty())
959        {
960                // filter polygons donw the tree
961                BspSplitData tData = tStack.top();
962            tStack.pop();       
963               
[383]964                if (tData.mNode->IsLeaf())
[372]965                {
[383]966                        if (tData.mDepth > maxDepth)
967                                maxDepth = tData.mDepth;
968                }
969                else
970                {
[372]971                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
972
[383]973                        // add current side of split plane
[449]974                        if (tData.mNode != root)
[383]975                                tData.mSides.push_back(tData.mIsFront);
[372]976
977                        // bounded plane is added to the polygons
[383]978                        Polygon3 *planePoly =
[449]979                                box.CrossSection(interior->GetPlane());
[372]980               
981                        // do all the splits with the previous planes
982                        for (int i = 0; i < (int)tData.mPlanes.size(); ++ i)
[436]983                        {                               
[449]984                                if (planePoly->ClassifyPlane(tData.mPlanes[i], epsilon)
985                                        == Polygon3::SPLIT)
[372]986                                {
987                                        Polygon3 *frontPoly = new Polygon3();
988                                        Polygon3 *backPoly = new Polygon3();
989
[449]990                                        planePoly->Split(tData.mPlanes[i],
991                                                                         *frontPoly,
992                                                                         *backPoly,
993                                                                         epsilon);
994
[372]995                                        DEL_PTR(planePoly);
996
997                                        if(tData.mSides[i] == true)
998                                        {
999                                                planePoly = frontPoly;
1000                                                DEL_PTR(backPoly);
1001                                        }
1002                                        else
1003                                        {
1004                                                planePoly = backPoly;
1005                                                DEL_PTR(frontPoly);
1006                                        }
1007                                }
1008                        }
1009
1010                        tData.mPlanes.push_back(interior->GetPlane()); // add plane to split planes
1011
[449]1012                        if (planePoly->Valid(epsilon))
[383]1013                        {
[372]1014                                polys.push_back(planePoly);
[383]1015                                depths.push_back(tData.mDepth);
1016                        }
[372]1017                        else
1018                                DEL_PTR(planePoly);
1019                       
1020                        // push the children on the stack
[383]1021                        tStack.push(BspSplitData(interior->GetFront(), tData.mPlanes,
1022                                                     tData.mSides, true, tData.mDepth + 1));
1023                        tStack.push(BspSplitData(interior->GetBack(), tData.mPlanes,
1024                                                     tData.mSides, false, tData.mDepth + 1));
[372]1025                }
[383]1026        }
1027
1028        if (maxDepth > 0)
1029        {       
1030                mUseForcedMaterial = true;
1031                       
1032                for (int i = 0; i < (int)polys.size(); ++ i)
1033                {
1034                        mForcedMaterial.mDiffuseColor.b = 1.0f;
1035                        float importance =  (float)depths[i]/ (float)maxDepth;
1036           
1037                        mForcedMaterial.mDiffuseColor.r = importance;
1038                        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
1039
1040                        ExportPolygon(polys[i]);
1041                }
1042        }
1043        else
1044        {
1045                ExportPolygons(polys);
1046        }
1047
[372]1048        CLEAR_CONTAINER(polys);
1049}
1050
[449]1051void X3dExporter::ExportBspSplits(const BspTree &tree,
1052                                                                  const bool exportDepth)
1053{
1054        ExportBspNodeSplits(tree.GetRoot(),
1055                                                tree.GetBoundingBox(),
1056                                                exportDepth,
1057                                                tree.GetEpsilon());
1058}
1059
1060void X3dExporter::ExportBspSplits(const VspBspTree &tree,
1061                                                                  const bool exportDepth)
1062{
1063        ExportBspNodeSplits(tree.GetRoot(),
1064                                                tree.GetBoundingBox(),
1065                                                exportDepth,
1066                                                tree.GetEpsilon());
1067}
1068
[372]1069void X3dExporter::ExportBspSplitPlanes(const BspTree &tree)
1070{
1071        std::stack<BspNode *> tStack;
1072
1073        tStack.push(tree.GetRoot());
1074 
1075        PolygonContainer polys;
1076
1077        while (!tStack.empty())
1078        {
1079                // filter polygons donw the tree
1080                BspNode *node = tStack.top();
1081            tStack.pop();       
1082               
1083                if (!node->IsLeaf())
1084                {
1085                        BspInterior *interior = dynamic_cast<BspInterior *>(node);
1086
1087                        // bounded plane is added to the polygons
[449]1088                        polys.push_back(tree.GetBoundingBox().CrossSection(interior->GetPlane()));
[372]1089               
1090                        // push the children on the stack
1091                        tStack.push(interior->GetBack());
1092                        tStack.push(interior->GetFront());
1093                }
1094        }
1095
1096        ExportPolygons(polys);
1097        CLEAR_CONTAINER(polys);
1098}
[440]1099
1100
[449]1101void X3dExporter::ExportGeometry(const ObjectContainer &objects)
[440]1102{
[712]1103        ObjectContainer::const_iterator oit, oit_end = objects.end();
1104
1105        if (1)
1106        {
1107                for (oit = objects.begin(); oit != oit_end; ++ oit)
1108                {
[726]1109                        if (0)
[712]1110                                SetForcedMaterial(RandomMaterial());
[726]1111                       
[712]1112                        ExportIntersectable(*oit);
1113                }
1114
1115                return;
1116        }
1117
1118        // hack: all object exported as one mesh
[685]1119        PolygonContainer polys;
[712]1120
1121        for (oit = objects.begin(); oit != oit_end; ++ oit)
1122        {
1123                polys.push_back(new Polygon3(dynamic_cast<MeshInstance *>(*oit)->GetMesh()->mVertices));
[685]1124        }
1125
1126        Mesh dummyMesh;
[712]1127        PolygonContainer::const_iterator pit, pit_end = polys.end();
[685]1128
[712]1129        for (pit = polys.begin(); pit != pit_end; ++ pit)
1130        {
[840]1131                Polygon3 *poly = (*pit);
1132                IncludePolyInMesh(*poly, dummyMesh);
[712]1133        }
1134       
[685]1135        ExportMesh(&dummyMesh);
[712]1136
[685]1137        CLEAR_CONTAINER(polys);
[440]1138}
[449]1139
1140
[450]1141bool
1142X3dExporter::ExportRssTree2(const RssTree &tree,
1143                                                        const Vector3 direction
1144                                                        )
1145{
1146  stack<RssTreeNode *> tStack;
1147 
1148 
1149  mUseForcedMaterial = true;
1150
1151  Vector3 dirParam;
1152
1153  dirParam.x = VssRay::GetDirParam(0, Normalize(direction));
1154  dirParam.y = VssRay::GetDirParam(1, Normalize(direction));
1155
1156  float maxImportance = 0.0f;
1157  tStack.push(tree.GetRoot());
1158  while (!tStack.empty()) {
1159       
1160        RssTreeNode *node = tStack.top();
1161    tStack.pop();
1162       
1163    if (!node->IsLeaf()) {
1164      RssTreeInterior *interior = (RssTreeInterior *)node;
1165          if (interior->axis < 3) {
1166                tStack.push(interior->front);
1167                tStack.push(interior->back);
1168          } else {
1169                if (dirParam[interior->axis-3] < interior->position)
1170                  tStack.push(interior->back);
1171                else
1172                  tStack.push(interior->front);
1173          }
1174    } else {
1175          RssTreeLeaf *leaf = (RssTreeLeaf *)node;
1176          if (tree.ValidLeaf(leaf)) {
1177                float i = leaf->GetImportance();
1178                if (i > maxImportance)
1179                  maxImportance = i;
1180          }
1181        }
1182  }
1183
1184  tStack.push(tree.GetRoot());
1185  while (!tStack.empty()) {
1186
1187        RssTreeNode *node = tStack.top();
1188    tStack.pop();
1189       
1190                       
1191    if (!node->IsLeaf()) {
1192      RssTreeInterior *interior = (RssTreeInterior *)node;
1193          if (interior->axis < 3) {
1194                tStack.push(interior->front);
1195                tStack.push(interior->back);
1196          } else {
1197                if (dirParam[interior->axis-3] < interior->position)
1198                  tStack.push(interior->back);
1199                else
1200                  tStack.push(interior->front);
1201          }
1202    } else {
1203          RssTreeLeaf *leaf = (RssTreeLeaf *)node;
1204          if (tree.ValidLeaf(leaf)) {
1205                AxisAlignedBox3 box;
1206                box = tree.GetShrankedBBox(leaf);
1207                Mesh *mesh = new Mesh;
[860]1208                IncludeBoxInMesh(box, *mesh);
[450]1209               
1210                // get 4 corners of the ray directions
1211               
1212                mForcedMaterial.mDiffuseColor.b = 1.0f;
1213                mForcedMaterial.mDiffuseColor.r = leaf->GetImportance()/maxImportance;
1214                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
1215               
1216                ExportMesh(mesh);
1217                delete mesh;
1218          }
1219        }
1220  }
1221
1222  mUseForcedMaterial = false;
1223
1224  return true;
1225}
[459]1226
1227
1228void
1229X3dExporter::ExportViewpoint(const Vector3 &point,
1230                                                         const Vector3 &direction)
1231{
1232  stream<<"<Viewpoint "<<endl;
1233 
1234  stream<<"position=\""<<point.x<<" "<<point.y<<" "<<point.z<<"\""<<endl;
1235  //  stream<<"orientation "<<direction.x<<direction.y<<direction.z<<endl;
1236 
1237  stream<<">"<<endl;
1238  stream<<"</Viewpoint>"<<endl;
[535]1239
[459]1240}
[535]1241
1242
1243
1244void X3dExporter::ExportBeam(const Beam &beam, const AxisAlignedBox3 &box)
1245{
[540]1246        if (beam.mMesh)
1247        {
1248                ExportMesh(beam.mMesh);
1249                return;
1250        }
1251
[535]1252        PolygonContainer polys;
1253        //ExportBox(beam.mBox);
1254
[540]1255        const float zfar = 2.0f * Magnitude(box.Diagonal());
1256
1257        // box should not never remove part of beam polygons
[564]1258        Vector3 bmin = beam.mBox.Min() - Vector3(zfar * 2.0f);
1259        Vector3 bmax = beam.mBox.Max() + Vector3(zfar * 2.0f);
[540]1260
1261        AxisAlignedBox3 bbox(bmin, bmax);
1262        Plane3 fplane;
1263        fplane.mNormal = -beam.mPlanes[0].mNormal;
1264
1265        fplane.mD = beam.mPlanes[0].mD - zfar - 1.0f;
1266       
1267        vector<Plane3> planes = beam.mPlanes;
1268        planes.push_back(fplane);
1269
1270        for (int i = 0; i < planes.size(); ++ i)
[535]1271        {
[540]1272                Polygon3 *poly = bbox.CrossSection(planes[i]);
1273                if (!poly->Valid(Limits::Small))
1274                        DEL_PTR(poly);
[535]1275               
[540]1276                for (int j = 0; (j < planes.size()) && poly; ++ j)
[535]1277                {
1278                        if (j != i)
1279                        {
1280                                Polygon3 *front = new Polygon3();
1281                                Polygon3 *back = new Polygon3();
1282                               
[540]1283                                poly->Split(planes[j], *front, *back, Limits::Small);
[535]1284                                DEL_PTR(poly);
1285                                DEL_PTR(front);
1286
1287                                if (!back->Valid(Limits::Small))
1288                                        DEL_PTR(back);
1289                                poly = back;
1290                        }
1291                }
1292                if (poly)
1293                        polys.push_back(poly);
1294        }
1295
1296        ExportPolygons(polys);
1297        CLEAR_CONTAINER(polys);
[685]1298}
[860]1299
[1106]1300
1301}
1302
Note: See TracBrowser for help on using the repository browser.