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

Revision 1233, 30.5 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 "HierarchyManager.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                                                           const bool exportGeometry)
598{
599         if (mExportRayDensity) {
600    return ExportKdTreeRayDensity(tree);
601  }
602 
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
614    int index = (int)mesh->mVertices.size();
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    }
633        else if (exportGeometry)
634        {
635                SetFilled();
636                SetForcedMaterial(RandomMaterial());
637                ExportGeometry(dynamic_cast<KdLeaf *>(node)->mObjects);
638                SetWireframe();
639        }
640  }
641 
642  ExportMesh(mesh);
643  delete mesh;
644
645  return true;
646}
647
648
649bool
650X3dExporter::ExportVssTree(const VssTree &tree
651                                                   )
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);
674                        IncludeBoxInMesh(box, *mesh);
675
676                        if (tree.ValidLeaf(leaf)) {
677                               
678                                Vector3 origin = box.Center();
679                                box = tree.GetDirBBox(leaf);
680                                VssRay *ray;
681                               
682                                const int indices[][2] = {{0,0}, {0,1}, {1,1}, {1,0}};
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);
689                                        if (Magnitude(direction) > Limits::Small)
690                                          direction.Normalize();
691                                        else
692                                          direction = Vector3(0, 1, 0);
693                                        float k = 100.0f*leaf->GetImportance();
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);
704  ExportRays(rays);
705  CLEAR_CONTAINER(rays);
706  delete mesh;
707  return true;
708}
709
710bool
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;
777                IncludeBoxInMesh(box, *mesh);
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
797X3dExporter::ExportBspTreeRayDensity(const BspTree &tree)
798{
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();
818#if 0     
819                        // set the mesh material according to the ray density
820                        if (vc->mPassingRays.mRays)
821                        {
822                                float importance =
823                                  vc->mPassingRays.mContributions / (float)vc->mPassingRays.mRays;
824                               
825                                mForcedMaterial.mDiffuseColor.r = importance;
826                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
827                                ExportViewCell(vc);
828
829                        }
830#endif
831                }
832                else
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
843        return true;
844}
845
846bool
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
865      int index = (int)mesh->mVertices.size();
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}
903
904
905struct BspSplitData
906{
907        /// the current node
908        BspNode *mNode;
909
910        vector<Plane3> mPlanes;
911        vector<bool> mSides;
912        bool mIsFront;
913        int mDepth;
914
915        BspSplitData(BspNode *node):
916        mNode(node), mIsFront(false), mDepth(0)
917        {};     
918
919        BspSplitData(BspNode *node,
920                                vector<Plane3> planes,
921                                vector<bool> sides,
922                                const bool isFront,
923                                const int depth):
924        mNode(node), mPlanes(planes), mSides(sides),
925        mIsFront(isFront), mDepth(depth)
926        {};
927};
928
929void X3dExporter::ExportLeavesGeometry(const BspTree &tree,
930                                                                           const vector<BspLeaf *> &leaves)
931{
932        vector<BspLeaf *>::const_iterator it, it_end = leaves.end();
933
934        for (it = leaves.begin(); it != it_end; ++ it)
935        {
936                BspNodeGeometry geom;
937                tree.ConstructGeometry(*it, geom);
938               
939                ExportPolygons(geom.GetPolys());
940        }
941}
942
943void X3dExporter::ExportBspNodeSplits(BspNode *root,
944                                                                          const AxisAlignedBox3 &box,
945                                                                          const bool exportDepth,
946                                                                          const bool epsilon)
947{
948        std::stack<BspSplitData> tStack;
949
950        BspSplitData tData(root);
951        tStack.push(tData);
952 
953        PolygonContainer polys;
954        vector <int> depths;
955
956        int maxDepth = 0;
957
958        while (!tStack.empty())
959        {
960                // filter polygons donw the tree
961                BspSplitData tData = tStack.top();
962            tStack.pop();       
963               
964                if (tData.mNode->IsLeaf())
965                {
966                        if (tData.mDepth > maxDepth)
967                                maxDepth = tData.mDepth;
968                }
969                else
970                {
971                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
972
973                        // add current side of split plane
974                        if (tData.mNode != root)
975                                tData.mSides.push_back(tData.mIsFront);
976
977                        // bounded plane is added to the polygons
978                        Polygon3 *planePoly =
979                                box.CrossSection(interior->GetPlane());
980               
981                        // do all the splits with the previous planes
982                        for (int i = 0; i < (int)tData.mPlanes.size(); ++ i)
983                        {                               
984                                if (planePoly->ClassifyPlane(tData.mPlanes[i], epsilon)
985                                        == Polygon3::SPLIT)
986                                {
987                                        Polygon3 *frontPoly = new Polygon3();
988                                        Polygon3 *backPoly = new Polygon3();
989
990                                        planePoly->Split(tData.mPlanes[i],
991                                                                         *frontPoly,
992                                                                         *backPoly,
993                                                                         epsilon);
994
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
1012                        if (planePoly->Valid(epsilon))
1013                        {
1014                                polys.push_back(planePoly);
1015                                depths.push_back(tData.mDepth);
1016                        }
1017                        else
1018                                DEL_PTR(planePoly);
1019                       
1020                        // push the children on the stack
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));
1025                }
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
1048        CLEAR_CONTAINER(polys);
1049}
1050
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
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
1088                        polys.push_back(tree.GetBoundingBox().CrossSection(interior->GetPlane()));
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}
1099
1100
1101void X3dExporter::ExportGeometry(const ObjectContainer &objects)
1102{
1103        ObjectContainer::const_iterator oit, oit_end = objects.end();
1104
1105        if (1)
1106        {
1107                for (oit = objects.begin(); oit != oit_end; ++ oit)
1108                {
1109                        if (0)
1110                                SetForcedMaterial(RandomMaterial());
1111                       
1112                        ExportIntersectable(*oit);
1113                }
1114
1115                return;
1116        }
1117
1118        // hack: all object exported as one mesh
1119        PolygonContainer polys;
1120
1121        for (oit = objects.begin(); oit != oit_end; ++ oit)
1122        {
1123                polys.push_back(new Polygon3(dynamic_cast<MeshInstance *>(*oit)->GetMesh()->mVertices));
1124        }
1125
1126        Mesh dummyMesh;
1127        PolygonContainer::const_iterator pit, pit_end = polys.end();
1128
1129        for (pit = polys.begin(); pit != pit_end; ++ pit)
1130        {
1131                Polygon3 *poly = (*pit);
1132                IncludePolyInMesh(*poly, dummyMesh);
1133        }
1134       
1135        ExportMesh(&dummyMesh);
1136
1137        CLEAR_CONTAINER(polys);
1138}
1139
1140
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;
1208                IncludeBoxInMesh(box, *mesh);
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}
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;
1239
1240}
1241
1242
1243
1244void X3dExporter::ExportBeam(const Beam &beam, const AxisAlignedBox3 &box)
1245{
1246        if (beam.mMesh)
1247        {
1248                ExportMesh(beam.mMesh);
1249                return;
1250        }
1251
1252        PolygonContainer polys;
1253        //ExportBox(beam.mBox);
1254
1255        const float zfar = 2.0f * Magnitude(box.Diagonal());
1256
1257        // box should not never remove part of beam polygons
1258        Vector3 bmin = beam.mBox.Min() - Vector3(zfar * 2.0f);
1259        Vector3 bmax = beam.mBox.Max() + Vector3(zfar * 2.0f);
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)
1271        {
1272                Polygon3 *poly = bbox.CrossSection(planes[i]);
1273                if (!poly->Valid(Limits::Small))
1274                        DEL_PTR(poly);
1275               
1276                for (int j = 0; (j < planes.size()) && poly; ++ j)
1277                {
1278                        if (j != i)
1279                        {
1280                                Polygon3 *front = new Polygon3();
1281                                Polygon3 *back = new Polygon3();
1282                               
1283                                poly->Split(planes[j], *front, *back, Limits::Small);
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);
1298}
1299
1300
1301}
1302
Note: See TracBrowser for help on using the repository browser.