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

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