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

Revision 1141, 30.2 KB checked in by mattausch, 18 years ago (diff)

added kd pvs support, changed way of counting pvs

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