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

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