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

Revision 459, 32.0 KB checked in by bittner, 19 years ago (diff)

merge

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