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

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