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

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