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

Revision 1001, 32.1 KB checked in by mattausch, 18 years ago (diff)

added mesh instance support
improved support for occlusion queries + other extensions

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