source: GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp @ 1121

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