source: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp @ 547

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