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

Revision 462, 33.0 KB checked in by mattausch, 19 years ago (diff)

worked on vsp kd view cells

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