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

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