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

Revision 1344, 29.1 KB checked in by mattausch, 18 years ago (diff)

worked on triangle processing. logical units will be created by grouping objects
using their visibility definitions.

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