source: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp @ 425

Revision 425, 29.5 KB checked in by mattausch, 19 years ago (diff)
Line 
1#include "SceneGraph.h"
2#include "KdTree.h"
3#include "SamplingPreprocessor.h"
4#include "X3dExporter.h"
5#include "Environment.h"
6#include "MutualVisibility.h"
7#include "Polygon3.h"
8#include "ViewCell.h"
9#include "RenderSimulator.h"
10
11SamplingPreprocessor::SamplingPreprocessor(): mPass(0)
12{
13  // this should increase coherence of the samples
14  environment->GetIntValue("Sampling.samplesPerPass", mSamplesPerPass);
15  environment->GetIntValue("Sampling.totalSamples", mTotalSamples);
16  environment->GetIntValue("BspTree.Construction.samples", mBspConstructionSamples);
17  environment->GetIntValue("VspKdTree.Construction.samples", mVspConstructionSamples);
18  environment->GetIntValue("ViewCells.PostProcessing.samples", mPostProcessSamples);
19  environment->GetIntValue("BspTree.Visualization.samples", mVisualizationSamples);
20 
21  mKdPvsDepth = 100;
22  mStats.open("stats.log");
23}
24
25SamplingPreprocessor::~SamplingPreprocessor()
26{
27        CLEAR_CONTAINER(mSampleRays);
28        CLEAR_CONTAINER(mVspSampleRays);
29}
30
31void
32SamplingPreprocessor::SetupRay(Ray &ray,
33                                                                                                                         const Vector3 &point,
34                                                                                                                         const Vector3 &direction,
35                                                                                                                         const int type)
36{
37  ray.intersections.clear();
38  ray.kdLeaves.clear();
39  ray.testedObjects.clear();
40  ray.bspIntersections.clear();
41        ray.mFlags |= Ray::STORE_KDLEAVES | Ray::STORE_BSP_INTERSECTIONS;
42  //  cout<<point<<" "<<direction<<endl;
43  ray.Init(point, direction, type);
44}
45
46KdNode *
47SamplingPreprocessor::GetNodeForPvs(KdLeaf *leaf)
48{
49  KdNode *node = leaf;
50  while (node->mParent && node->mDepth > mKdPvsDepth)
51    node = node->mParent;
52  return node;
53}
54
55bool
56SamplingPreprocessor::BuildBspTree()
57{
58        // delete old tree
59        DEL_PTR(mBspTree);
60        mBspTree = new BspTree(&mUnbounded);
61        ObjectContainer objects;
62       
63        switch (BspTree::sConstructionMethod)
64        {
65        case BspTree::FROM_INPUT_VIEW_CELLS:
66                mBspTree->SetGenerateViewCells(false);
67                mBspTree->Construct(mViewCells);
68                break;
69        case BspTree::FROM_SCENE_GEOMETRY:
70                DeleteViewCells(); // we generate new view cells
71                mBspTree->SetGenerateViewCells(true);
72                mSceneGraph->CollectObjects(&objects);
73                mBspTree->Construct(objects);
74                break;
75        case BspTree::FROM_SAMPLES:
76                DeleteViewCells(); // we generate new view cells
77                mBspTree->SetGenerateViewCells(true);
78                mBspTree->Construct(mSampleRays);
79                break;
80        default:
81                Debug << "Error: Method not available\n";
82                break;
83        }
84       
85       
86        return true;
87}
88
89int
90SamplingPreprocessor::AddNodeSamples(const Ray &ray,
91                                                                                                                                                 Intersectable *sObject,
92                                                                                                                                                 Intersectable *tObject
93                                                                                                                                                 )
94{
95  int contributingSamples = 0;
96  int j;
97        int objects = 0;
98        if (sObject)
99                objects++;
100        if (tObject)
101                objects++;
102
103        if (objects) {
104                for (j=0; j < ray.kdLeaves.size(); j++) {
105                        KdNode *node = GetNodeForPvs( ray.kdLeaves[j] );
106                        if (sObject)
107                                contributingSamples += sObject->mKdPvs.AddSample(node);
108                        if (tObject)
109                                contributingSamples += tObject->mKdPvs.AddSample(node);
110                }
111        }
112       
113        for (j=1; j < ((int)ray.kdLeaves.size() - 1); j++) {
114                ray.kdLeaves[j]->AddPassingRay2(ray,
115                                                                                                                                                objects,
116                                                                                                                                                ray.kdLeaves.size()
117                                                                                                                                                );
118  }
119 
120  return contributingSamples;
121}
122
123
124int SamplingPreprocessor::AddObjectSamples(Intersectable *obj, const Ray &ray)
125{
126        int contributingSamples = 0;
127        int j;
128 
129        // object can be seen from the view cell => add to view cell pvs
130        for (j=0; j < ray.bspIntersections.size(); ++ j)
131        {       
132                BspLeaf *leaf = ray.bspIntersections[j].mLeaf;
133                // if ray not in unbounded space
134                if (leaf->GetViewCell() != &mUnbounded)
135                        contributingSamples +=
136                                leaf->GetViewCell()->GetPvs().AddSample(obj);
137        }
138 
139        // rays passing through this viewcell
140        if (mPass > 1)
141                for (j=1; j < ((int)ray.bspIntersections.size() - 1); ++ j)
142                {
143                        BspLeaf *leaf = ray.bspIntersections[j].mLeaf;
144
145                        if (leaf->GetViewCell() != &mUnbounded)
146                                leaf->GetViewCell()->
147                                        AddPassingRay(ray, contributingSamples ? 1 : 0);
148                }
149 
150        return contributingSamples;
151}
152
153
154void
155SamplingPreprocessor::HoleSamplingPass()
156{
157  vector<KdLeaf *> leaves;
158  mKdTree->CollectLeaves(leaves);
159 
160  // go through all the leaves and evaluate their passing contribution
161  for (int i=0 ; i < leaves.size(); i++) {
162    KdLeaf *leaf = leaves[i];
163    cout<<leaf->mPassingRays<<endl;
164  }
165}
166
167
168int
169SamplingPreprocessor::CastRay(Intersectable *object, Ray &ray)
170{
171        int sampleContributions = 0;
172
173        long t1 = GetRealTime();
174        // cast ray to KD tree to find intersection with other objects
175        mKdTree->CastRay(ray);
176        long t2 = GetRealTime();
177
178        if (0 && object && object->GetId() > 2197) {
179                object->Describe(cout)<<endl;
180                cout<<ray<<endl;
181        }
182
183        switch(ViewCell::sHierarchy)
184        {
185        case ViewCell::BSP:
186               
187                //-- cast ray to BSP tree to get intersection with view cells
188                if (!mBspTree)
189                        break;
190               
191                mBspTree->CastRay(ray);
192                       
193                if (object)
194                        sampleContributions += AddObjectSamples(object, ray);
195                       
196                if (!ray.intersections.empty()) // second intersection found
197                {
198                        sampleContributions +=
199                                AddObjectSamples(ray.intersections[0].mObject, ray);
200                }
201                break;
202        case ViewCell::KD:
203                if (ray.kdLeaves.size())
204                {
205                        Intersectable *terminator =
206                                ray.intersections.size() ? ray.intersections[0].mObject: NULL;
207
208                        sampleContributions += AddNodeSamples(ray,
209                                                                                                                                                                        object,
210                                                                                                                                                                        terminator);
211                }
212                break;
213        case ViewCell::VSP:
214                // TODO:
215                break;
216        default:
217                Debug << "Should never come here" << endl;
218                break;
219        }
220
221        return sampleContributions;
222}
223
224//  void
225//  SamplingPreprocessor::AvsGenerateRandomRay(Ray &ray)
226//  {
227//    int objId = RandomValue(0, mObjects.size());
228//    Intersectable *object = objects[objId];
229//    object->GetRandomSurfacePoint(point, normal);
230//    direction = UniformRandomVector(normal);
231//    SetupRay(ray, point, direction);
232//  }
233
234//  void
235//  SamplingPreprocessor::AvsHandleRay(Ray &ray)
236//  {
237//    int sampleContributions = 0;
238
239//    mKdTree->CastRay(ray);
240 
241//    if (ray.leaves.size()) {
242//      sampleContributions += AddNodeSamples(object, ray, pass);
243   
244//      if (ray.intersections.size()) {
245//        sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
246//      }
247//    }
248//  }
249
250//  void
251//  SamplingPreprocessor::AvsBorderSampling(Ray &ray)
252//  {
253 
254
255//  }
256
257//  void
258//  SamplingPreprocessor::AvsPass()
259//  {
260//    Ray ray;
261//    while (1) {
262//      AvsGenerateRay(ray);
263//      HandleRay(ray);
264//      while ( !mRayQueue.empty() ) {
265//        Ray ray = mRayQueue.pop();
266//        mRayQueue.pop();
267//        AdaptiveBorderSampling(ray);
268//      }
269//    }
270 
271 
272
273//  }
274
275
276int
277SamplingPreprocessor::CastEdgeSamples(
278                                                                                                                                                        Intersectable *object,
279                                                                                                                                                        const Vector3 &point,
280                                                                                                                                                        MeshInstance *mi,
281                                                                                                                                                        const int samples
282                                                                                                                                                        )
283{
284        Ray ray;
285        int maxTries = samples*10;
286        int i;
287        int rays = 0;
288        int edgeSamplesContributions = 0;
289        for (i=0; i < maxTries && rays < samples; i++) {
290                // pickup a random face of each mesh
291                Mesh *mesh = mi->GetMesh();
292                int face = RandomValue(0, mesh->mFaces.size()-1);
293               
294                Polygon3 poly(mesh->mFaces[face], mesh);
295                poly.Scale(1.001);
296                // now extend a random edge of the face
297                int edge = RandomValue(0, poly.mVertices.size()-1);
298                float t = RandomValue(0.0f,1.0f);
299                Vector3 target = t*poly.mVertices[edge] + (1.0f-t)*poly.mVertices[(edge + 1)%
300                                                                                                                                                                                                                                                                                 poly.mVertices.size()];
301                SetupRay(ray, point, target - point, Ray::LOCAL_RAY);
302                if (!mesh->CastRay(ray, mi)) {
303                        // the rays which intersect the mesh have been discarded since they are not tangent
304                        // to the mesh
305                        rays++;
306                        edgeSamplesContributions += CastRay(object, ray);
307                }
308        }
309        return edgeSamplesContributions;
310}
311
312KdNode *
313SamplingPreprocessor::GetNodeToSample(Intersectable *object)
314{
315        int pvsSize = object->mKdPvs.GetSize();
316        KdNode *nodeToSample = NULL;
317       
318        bool samplePvsBoundary = false;
319        if (pvsSize && samplePvsBoundary) {
320                // this samples the nodes from the boundary of the current PVS
321                // mail all nodes from the pvs
322                Intersectable::NewMail();
323                KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
324               
325                for (; i != object->mKdPvs.mEntries.end(); i++) {
326                        KdNode *node = (*i).first;
327                        node->Mail();
328                }
329               
330                int maxTries = 2*pvsSize;
331                Debug << "Finding random neighbour" << endl;   
332                for (int tries = 0; tries < 10; tries++) {
333                        int index = RandomValue(0, pvsSize - 1);
334                        KdPvsData data;
335                        KdNode *node;
336                        object->mKdPvs.GetData(index, node, data);
337                        nodeToSample = mKdTree->FindRandomNeighbor(node, true);
338                        if (nodeToSample)
339                                break;
340                }
341        } else {
342                // just pickup a random node
343                //              nodeToSample = mKdTree->GetRandomLeaf(Plane3(normal, point));
344                nodeToSample = mKdTree->GetRandomLeaf();
345        }
346        return nodeToSample;
347}
348
349void
350SamplingPreprocessor::VerifyVisibility(Intersectable *object)
351{
352        // mail all nodes from the pvs
353        Intersectable::NewMail();
354        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
355        for (; i != object->mKdPvs.mEntries.end(); i++) {
356                KdNode *node = (*i).first;
357                node->Mail();
358        }
359        Debug << "Get all neighbours from PVS" << endl;
360        vector<KdNode *> invisibleNeighbors;
361        // get all neighbors of all PVS nodes
362        i = object->mKdPvs.mEntries.begin();
363        for (; i != object->mKdPvs.mEntries.end(); i++) {
364                KdNode *node = (*i).first;
365                mKdTree->FindNeighbors(node, invisibleNeighbors, true);
366                AxisAlignedBox3 box = object->GetBox();
367                for (int j=0; j < invisibleNeighbors.size(); j++) {
368                        int visibility = ComputeBoxVisibility(mSceneGraph,
369                                                              mKdTree,
370                                                              box,
371                                                              mKdTree->GetBox(invisibleNeighbors[j]),
372                                                              1e-6f);
373                        //            exit(0);
374                }
375                // now rank all the neighbors according to probability that a new
376                // sample creates some contribution
377        }
378}
379
380bool
381SamplingPreprocessor::ComputeVisibility()
382{
383 
384  // pickup an object
385  ObjectContainer objects;
386 
387  mSceneGraph->CollectObjects(&objects);
388
389  Vector3 point, normal, direction;
390  Ray ray;
391
392  long startTime = GetTime();
393 
394  int i;
395  int totalSamples = 0;
396
397  int pvsOut = Min((int)objects.size(), 10);
398  int pvsSize = 0;
399
400  RayContainer rays[10];
401
402  while (totalSamples < mTotalSamples) {
403                int passContributingSamples = 0;
404                int passSampleContributions = 0;
405                int passSamples = 0;
406                int index = 0;
407               
408                int reverseSamples = 0;
409               
410                       
411                //cout << "totalSamples: "  << totalSamples << endl;
412
413                for (i = 0; i < objects.size(); i++) {
414                                               
415                        KdNode *nodeToSample = NULL;
416                        Intersectable *object = objects[i];
417               
418                        int pvsSize = 0;
419                        if (ViewCell::sHierarchy == ViewCell::KD)
420                                pvsSize = object->mKdPvs.GetSize();
421                                               
422                       
423                        if (0 && pvsSize && mPass == 1000 ) {
424                                VerifyVisibility(object);
425                        }
426                       
427                        int faceIndex = object->GetRandomSurfacePoint(point, normal);
428                       
429                        bool viewcellSample = true;
430                        int sampleContributions;
431                        bool debug = false; //(object->GetId() >= 2199);
432                        if (viewcellSample) {
433                                //mKdTree->GetRandomLeaf(Plane3(normal, point));
434
435                                nodeToSample = GetNodeToSample(object);
436
437                                for (int k=0; k < mSamplesPerPass; k++) {
438                                        bool reverseSample = false;
439                                       
440
441                                        if (nodeToSample) {
442                                                AxisAlignedBox3 box = mKdTree->GetBox(nodeToSample);
443                                                Vector3 pointToSample = box.GetRandomPoint();
444                                                //                                              pointToSample.y = 0.9*box.Min().y + 0.1*box.Max().y;
445                                                if (object->GetRandomVisibleSurfacePoint( point, normal, pointToSample, 3 )) {
446                                                        direction = pointToSample - point;
447                                                } else {
448                                                        reverseSamples++;
449                                                        reverseSample = true;
450                                                        direction = point - pointToSample;
451                                                        point = pointToSample;
452                                                }
453                                        }
454                                        else {
455                                                direction = UniformRandomVector(normal);
456                                        }
457                                       
458                                        // construct a ray
459                                        SetupRay(ray, point, direction, Ray::LOCAL_RAY);
460                                       
461                                        sampleContributions = CastRay(reverseSample ? NULL : object, ray);
462                                       
463                                        //-- CORR matt: put block inside loop
464                                        if (sampleContributions) {
465                                                passContributingSamples ++;
466                                                passSampleContributions += sampleContributions;
467                                        }
468
469                                        if ( i < pvsOut ) {
470                                                Ray *nray = new Ray(ray);
471                                                rays[i].push_back(nray);
472                                        }
473               
474                                        if (!ray.intersections.empty()) {
475                                                // check whether we can add this to the rays
476                                                for (int j = 0; j < pvsOut; j++) {
477                                                        if (objects[j] == ray.intersections[0].mObject) {
478                                                                Ray *nray = new Ray(ray);
479                                                                rays[j].push_back(nray);
480                                                        }
481                                                }
482                                        }
483                                        //-------------------
484                                        if (ViewCell::sHierarchy == ViewCell::BSP)
485                                        {
486                                                ProcessBspViewCells(ray,
487                                                                                        reverseSample ? NULL : object,
488                                                                                        faceIndex,
489                                                                                        passContributingSamples,
490                                                                                        passSampleContributions);
491
492                                        }
493                                        else if (ViewCell::sHierarchy == ViewCell::VSP)
494                                        {
495                                                ProcessVspViewCells(ray,
496                                                                                        reverseSample ? NULL : object,
497                                                                                        faceIndex,
498                                                                                        passContributingSamples,
499                                                                                        passSampleContributions);
500                                        }
501                                }
502                        } else {
503                                // edge samples
504                                // get random visible mesh
505                                //                              object->GetRandomVisibleMesh(Plane3(normal, point));
506                        }
507       
508                        // CORR matt: must add all samples
509                        passSamples += mSamplesPerPass;
510                }
511       
512                totalSamples += passSamples;
513               
514                //    if (pass>10)
515                //      HoleSamplingPass();
516   
517                mPass++;
518       
519                if (ViewCell::sHierarchy == ViewCell::KD)
520                {
521                        pvsSize = 0;
522
523                        for (i=0; i < objects.size(); i++) {
524                                Intersectable *object = objects[i];
525                                pvsSize += object->mKdPvs.GetSize();
526                        }
527                }
528                else
529                        pvsSize += passSampleContributions;
530               
531                float avgRayContrib = (passContributingSamples > 0) ?
532                        passSampleContributions/(float)passContributingSamples : 0;
533
534                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
535                cout << "#TotalSamples=" << totalSamples/1000
536                                 << "k   #SampleContributions=" << passSampleContributions << " ("
537                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
538                                 << (float)pvsSize /(float)objects.size() << endl
539                                 << "avg ray contrib=" << avgRayContrib << endl
540                                 << "reverse samples [%]" << reverseSamples/(float)passSamples*100.0f << endl;
541
542                mStats <<
543                        "#Pass\n" <<mPass<<endl<<
544                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
545                        "#TotalSamples\n" << totalSamples<< endl<<
546                        "#SampleContributions\n" << passSampleContributions << endl <<
547                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
548                        "#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
549                        "#AvgRayContrib\n" << avgRayContrib << endl;
550        }
551       
552        if (ViewCell::sHierarchy == ViewCell::KD)       
553                cout << "#totalKdPvsSize=" << mKdTree->CollectLeafPvs() << endl;
554 
555        //-- render simulation
556        RenderSimulator *rs = GetRenderSimulator();
557
558        if (rs)
559        {
560                cout << "\nevaluating bsp view cells render time before merge ... ";
561
562                rs->SimulateRendering();
563       
564                cout << " finished" << endl;
565
566                cout << GetRenderSimulator()->mStat << endl;
567                Debug << GetRenderSimulator()->mStat << endl;
568        }
569
570        if (mBspTree)
571        {
572                //-- post processing of bsp view cells
573        int vcSize = 0;
574                int pvsSize = 0;
575
576                BspViewCellsStatistics stat;
577               
578                Debug << "overall scene size: " << (int)objects.size() << endl;
579                mBspTree->EvaluateViewCellsStats(stat);
580               
581                Debug << "original view cell partition:\n" << stat << endl;
582               
583                if (1) // export view cells
584                {
585                        cout << "exporting initial view cells (=leaves) ... ";
586                        Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
587                        if (exporter)
588                        {
589                                exporter->SetWireframe();
590                                exporter->ExportBspLeaves(*mBspTree, stat.maxPvs);
591                                //exporter->ExportBspViewCellPartition(*mBspTree, 0);
592                               
593                                if (1) // export scene geometry
594                                {
595                                        Material m;//= RandomMaterial();
596                                        m.mDiffuseColor = RgbColor(0, 1, 0);
597                                        exporter->SetForcedMaterial(m);
598                                        exporter->SetWireframe();
599       
600                                        for (int j = 0; j < objects.size(); ++ j)
601                                                exporter->ExportIntersectable(objects[j]);
602                                }
603                                       
604                                delete exporter;
605                        }
606                        cout << "finished" << endl;
607                }
608
609                cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
610               
611                long startTime = GetTime();
612                int merged = PostprocessViewCells(mSampleRays);
613               
614                cout << "finished" << endl;
615                cout << "merged " << merged << " view cells in "
616                         << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
617
618                //-- recount pvs
619                mBspTree->EvaluateViewCellsStats(stat);
620               
621                Debug << "after post processing:\n" << stat << endl;
622
623                //-- render simulation
624               
625                RenderSimulator *rs = GetRenderSimulator();
626
627                if (rs)
628                {
629                        cout << "\nevaluating render time after merge ... ";
630                       
631                        rs->SimulateRendering();
632
633                        cout << " finished" << endl;
634
635                        cout << GetRenderSimulator()->mStat << endl;
636                        Debug << GetRenderSimulator()->mStat << endl;
637                }
638
639                if (1) // export view cells
640                {
641                        cout << "exporting view cells after merge ... ";
642                        Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
643                        if (exporter)
644                        {
645                                exporter->ExportBspViewCellPartition(*mBspTree, stat.maxPvs);
646                                //exporter->ExportBspViewCellPartition(*mBspTree, 0);
647                                delete exporter;
648                        }
649
650                        cout << "finished" << endl;
651                }
652
653                //-- visualization of the BSP splits
654                bool exportSplits = false;
655                environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
656               
657                cout << "exporting splits ... ";
658                if (exportSplits)
659                        ExportSplits(objects);
660                cout << "finished" << endl;
661
662                // export the PVS of sample view cells
663                if (1)
664                        ExportBspPvs(objects);
665        }
666       
667  //  HoleSamplingPass();
668        if (0) {
669                Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
670                exporter->SetExportRayDensity(true);
671                exporter->ExportKdTree(*mKdTree);
672                delete exporter;
673        }
674
675        if (mVspKdTree)
676        {
677                Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");
678                exporter->SetWireframe();
679                exporter->ExportVspKdTree(*mVspKdTree, 300);
680                delete exporter;
681        }
682 
683        bool exportRays = false;
684        if (exportRays) {
685                Exporter *exporter = NULL;
686                exporter = Exporter::GetExporter("sample-rays.x3d");
687                exporter->SetWireframe();
688                exporter->ExportKdTree(*mKdTree);
689                exporter->ExportBspTree(*mBspTree);
690
691                for (i=0; i < pvsOut; i++)
692                        exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
693                exporter->SetFilled();
694               
695                delete exporter;
696        }
697
698        //-- several visualizations and statistics
699        if (1) {
700
701   for (int k=0; k < pvsOut; k++) {
702                 Intersectable *object = objects[k];
703                 char s[64];
704                 sprintf(s, "sample-pvs%04d.x3d", k);
705                 Exporter *exporter = Exporter::GetExporter(s);
706                 exporter->SetWireframe();
707                 
708                 
709                 KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
710                 Intersectable::NewMail();
711                 
712                 // avoid adding the object to the list
713                 object->Mail();
714                 ObjectContainer visibleObjects;
715                 
716                 for (; i != object->mKdPvs.mEntries.end(); i++)
717                         {
718                                 KdNode *node = (*i).first;
719                                 exporter->ExportBox(mKdTree->GetBox(node));
720                                 mKdTree->CollectObjects(node, visibleObjects);
721                         }
722                 
723                 exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
724                 exporter->SetFilled();
725                 
726                 for (int j = 0; j < visibleObjects.size(); j++)
727                         exporter->ExportIntersectable(visibleObjects[j]);
728                 
729                 
730                 Material m;
731                 m.mDiffuseColor = RgbColor(1, 0, 0);
732                 exporter->SetForcedMaterial(m);
733                 exporter->ExportIntersectable(object);
734                 
735                 delete exporter;
736         }
737  }
738 
739  return true;
740}
741
742
743void SamplingPreprocessor::ProcessVspViewCells(const Ray &ray,
744                                               Intersectable *object,
745                                                                                           const int faceIndex,
746                                                                                           int &contributingSamples,
747                                                                                           int &sampleContributions)
748{
749        if (!mVspKdTree)
750        {
751                // store samples for vsp kd tree construction
752                if ((int)mVspSampleRays.size() < mVspConstructionSamples)
753                {
754                        VssRay *sRay = new VssRay(ray);
755               
756            mVspSampleRays.push_back(sRay);
757               
758                        // also add origin to sample
759                        sRay->mOriginObject = object;
760                }
761                else
762                {
763                        // construct VSP tree using the collected samples
764                        cout << "building VSP tree from " << (int)mVspSampleRays.size() << " samples " << endl;
765                        mVspKdTree = new VspKdTree();
766                        mVspKdTree->Construct(mVspSampleRays, &mKdTree->GetBox());
767               
768                        // add contributions of saved samples to PVS
769                        //contributingSamples += mBspTree->GetStat().contributingSamples;
770                        //sampleContributions += mBspTree->GetStat().sampleContributions;
771
772                        Debug << mVspKdTree->GetStatistics();
773
774                        // throw away samples because BSP leaves not stored in order
775                        // Need ordered rays for post processing => collect new rays
776                        //CLEAR_CONTAINER(mVspSampleRays);
777                }
778        }
779        // save rays for post processing
780        /*else if (((int)mVspSampleRays.size() < mPostProcessSamples) ||
781                         ((int)mVspSampleRays.size() < mVisualizationSamples))
782        {
783                mVspSampleRays.push_back(new Ray(ray));
784        }*/
785}
786
787void SamplingPreprocessor::ProcessBspViewCells(const Ray &ray,
788                                               Intersectable *object,
789                                                                                           const int faceIndex,
790                                                                                           int &contributingSamples,
791                                                                                           int &sampleContributions)
792{
793        // save rays for bsp tree construction
794        if (!mBspTree)
795        {
796                if ((BspTree::sConstructionMethod == BspTree::FROM_SAMPLES) &&
797                        ((int)mSampleRays.size() < mBspConstructionSamples))
798                {
799                        MeshInstance *mi = dynamic_cast<MeshInstance *>(object);
800                       
801                        Ray *sRay = new Ray(ray);
802                        mSampleRays.push_back(sRay);
803               
804                        // also add origin to sample
805                        sRay->sourceObject = Ray::Intersection(0.0, object, faceIndex);
806                }
807                else
808                {
809                        // construct BSP tree using the collected samples
810                        cout << "building bsp tree from " << (int)mSampleRays.size() << " samples " << endl;
811                        BuildBspTree();
812               
813                        // add contributions of saved samples to PVS
814                        contributingSamples += mBspTree->GetStat().contributingSamples;
815                        sampleContributions += mBspTree->GetStat().sampleContributions;
816
817                        BspTreeStatistics(Debug);
818
819                        if (0) Export("vc_bsptree.x3d", false, false, true);
820
821                        // throw away samples because BSP leaves not stored in order
822                        // Need ordered rays for post processing => collect new rays
823                        CLEAR_CONTAINER(mSampleRays);
824                }
825        }
826        // save rays for post processing
827        else if (((int)mSampleRays.size() < mPostProcessSamples) ||
828                         ((int)mSampleRays.size() < mVisualizationSamples))
829        {
830                mSampleRays.push_back(new Ray(ray));
831        }
832}
833
834// merge or subdivide view cells
835int SamplingPreprocessor::PostprocessViewCells(const RayContainer &rays)
836{
837        int merged = 0;
838
839        RayContainer::const_iterator rit, rit_end = rays.end();
840        vector<Ray::BspIntersection>::const_iterator iit;
841
842        int limit = min((int)mSampleRays.size(), mPostProcessSamples);
843
844        for (int i = 0; i < limit; ++ i)
845        { 
846                Ray *ray = mSampleRays[i];
847
848                // traverse leaves stored in the rays and compare and merge consecutive
849                // leaves (i.e., the neighbors in the tree)
850                if (ray->bspIntersections.size() < 2)
851                        continue;
852
853                iit = ray->bspIntersections.begin();
854
855                BspLeaf *previousLeaf = (*iit).mLeaf;
856                ++ iit;
857               
858                for (; iit != ray->bspIntersections.end(); ++ iit)
859                {
860                        BspLeaf *leaf = (*iit).mLeaf;
861
862                        if (mBspTree->ShouldMerge(leaf, previousLeaf))
863                        {                       
864                                mBspTree->MergeViewCells(leaf, previousLeaf);
865
866                                ++ merged;
867                        }
868               
869                        previousLeaf = leaf;
870                }
871        }
872
873        return merged;
874}
875
876void SamplingPreprocessor::ExportSplits(const ObjectContainer &objects)
877{
878        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
879
880        if (exporter)
881        {       
882                Material m;
883                m.mDiffuseColor = RgbColor(1, 0, 0);
884                exporter->SetForcedMaterial(m);
885                exporter->SetWireframe();
886                exporter->ExportBspSplits(*mBspTree, true);
887
888                // take forced material, else big scenes cannot be viewed
889                m.mDiffuseColor = RgbColor(0, 1, 0);
890                exporter->SetForcedMaterial(m);
891                exporter->SetFilled();
892
893                exporter->ResetForcedMaterial();
894               
895                // export rays
896                if (0)
897                {
898                        RayContainer outRays;
899               
900                        for (int i = 0; i < mSampleRays.size(); ++ i)
901                        {
902                                // only rays piercing geometry
903                                if (!mSampleRays[i]->intersections.empty())
904                                        outRays.push_back(mSampleRays[i]);
905                        }
906                        if (BspTree::sConstructionMethod == BspTree::FROM_SAMPLES)
907                        {
908                                // export rays
909                                exporter->ExportRays(outRays, 1000, RgbColor(1, 1, 0));
910                        }
911                }
912
913                // export scene geometry
914                if (1)
915                {
916                        Material m;//= RandomMaterial();
917                        m.mDiffuseColor = RgbColor(0, 1, 0);
918                        exporter->SetForcedMaterial(m);
919            exporter->SetWireframe();
920
921                        for (int j = 0; j < objects.size(); ++ j)
922                                exporter->ExportIntersectable(objects[j]);
923                }
924
925                delete exporter;
926        }
927}
928
929inline bool vc_gt(ViewCell *a, ViewCell *b)
930{
931        return a->GetPvs().GetSize() > b->GetPvs().GetSize();
932}
933
934void SamplingPreprocessor::ExportBspPvs(const ObjectContainer &objects)
935{
936        const int leafOut = 10;
937       
938        ViewCell::NewMail();
939
940        //-- some rays for output
941        const int raysOut = min((int)mSampleRays.size(), mVisualizationSamples);
942        cout << "visualization using " << mVisualizationSamples << " samples" << endl;
943        vector<Ray *> vcRays[leafOut];
944
945        if (0){
946                //-- some random view cells and rays for output
947                vector<BspLeaf *> bspLeaves;
948
949                for (int i = 0; i < leafOut; ++ i)
950                        bspLeaves.push_back(mBspTree->GetRandomLeaf());
951               
952                for (int i = 0; i < bspLeaves.size(); ++ i)
953                {
954                        cout << "creating output for view cell " << i << " ... ";
955                        // check whether we can add the current ray to the output rays
956                        for (int k = 0; k < raysOut; ++ k)
957                        {
958                                Ray *ray = mSampleRays[k];
959
960                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
961                                {
962                                        BspLeaf *leaf = ray->bspIntersections[j].mLeaf;
963
964                                        if (bspLeaves[i]->GetViewCell() == leaf->GetViewCell())
965                                        {
966                                                vcRays[i].push_back(ray);
967                                        }
968                                }
969                        }
970
971                        Intersectable::NewMail();
972
973                        BspViewCell *vc = dynamic_cast<BspViewCell *>(bspLeaves[i]->GetViewCell());
974
975                        //bspLeaves[j]->Mail();
976                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
977
978                        Exporter *exporter = Exporter::GetExporter(s);
979                        exporter->SetFilled();
980
981                        ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin();
982
983                        exporter->SetWireframe();
984                        //exporter->SetFilled();
985
986                        Material m;//= RandomMaterial();
987                        m.mDiffuseColor = RgbColor(0, 1, 0);
988                        exporter->SetForcedMaterial(m);
989
990                        if (vc->GetMesh())
991                                exporter->ExportViewCell(vc);
992                        else
993                        {
994                                PolygonContainer cell;
995                                // export view cell geometry
996                                mBspTree->ConstructGeometry(vc, cell);
997                                exporter->ExportPolygons(cell);
998                                CLEAR_CONTAINER(cell);
999                        }
1000
1001                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
1002                                        << ", piercing rays=" << (int)vcRays[i].size() << endl;
1003
1004                        // export rays piercing this view cell
1005                        exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0));
1006
1007                        m.mDiffuseColor = RgbColor(1, 0, 0);
1008                        exporter->SetForcedMaterial(m);
1009
1010                        // exporter->SetWireframe();
1011                        exporter->SetFilled();
1012
1013                        // output PVS of view cell
1014                        for (; it != vc->GetPvs().mEntries.end(); ++ it)
1015                        {
1016                                Intersectable *intersect = (*it).first;
1017                                if (!intersect->Mailed())
1018                                {
1019                                        exporter->ExportIntersectable(intersect);
1020                                        intersect->Mail();
1021                                }                       
1022                        }
1023                               
1024                        // output rest of the objects
1025                        if (0)
1026                        {
1027                                Material m;//= RandomMaterial();
1028                                m.mDiffuseColor = RgbColor(0, 0, 1);
1029                                exporter->SetForcedMaterial(m);
1030
1031                                for (int j = 0; j < objects.size(); ++ j)
1032                                        if (!objects[j]->Mailed())
1033                                        {
1034                                                exporter->SetForcedMaterial(m);
1035                                                exporter->ExportIntersectable(objects[j]);
1036                                                objects[j]->Mail();
1037                                        }
1038                        }
1039                        DEL_PTR(exporter);
1040                        cout << "finished" << endl;
1041                }
1042        }
1043        else
1044        {
1045                ViewCellContainer viewCells;
1046
1047                mBspTree->CollectViewCells(viewCells);
1048                stable_sort(viewCells.begin(), viewCells.end(), vc_gt);
1049
1050                int limit = min(leafOut, (int)viewCells.size());
1051               
1052                for (int i = 0; i < limit; ++ i)
1053                {
1054                        cout << "creating output for view cell " << i << " ... ";
1055                       
1056            Intersectable::NewMail();
1057                        BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]);
1058
1059                        cout << "creating output for view cell " << i << " ... ";
1060                        // check whether we can add the current ray to the output rays
1061                        for (int k = 0; k < raysOut; ++ k)
1062                        {
1063                                Ray *ray = mSampleRays[k];
1064
1065                                for     (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
1066                                {
1067                                        BspLeaf *leaf = ray->bspIntersections[j].mLeaf;
1068
1069                                        if (vc == leaf->GetViewCell())
1070                                        {
1071                                                vcRays[i].push_back(ray);
1072                                        }
1073                                }
1074                        }
1075
1076                        //bspLeaves[j]->Mail();
1077                        char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
1078
1079                        Exporter *exporter = Exporter::GetExporter(s);
1080                       
1081                        exporter->SetWireframe();
1082
1083                        Material m;//= RandomMaterial();
1084                        m.mDiffuseColor = RgbColor(0, 1, 0);
1085                        exporter->SetForcedMaterial(m);
1086
1087                        if (vc->GetMesh())
1088                                exporter->ExportViewCell(vc);
1089                        else
1090                        {
1091                                PolygonContainer cell;
1092                                // export view cell
1093                                mBspTree->ConstructGeometry(vc, cell);
1094                                exporter->ExportPolygons(cell);
1095                                CLEAR_CONTAINER(cell);
1096                        }
1097
1098                       
1099                        Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
1100                                        << ", piercing rays=" << (int)vcRays[i].size() << endl;
1101
1102                       
1103                        // export rays piercing this view cell
1104                        exporter->ExportRays(vcRays[i], 1000, RgbColor(0, 1, 0));
1105       
1106                        m.mDiffuseColor = RgbColor(1, 0, 0);
1107                        exporter->SetForcedMaterial(m);
1108
1109                        ViewCellPvsMap::const_iterator it,
1110                                it_end = vc->GetPvs().mEntries.end();
1111
1112                        // output PVS of view cell
1113                        for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
1114                        {
1115                                Intersectable *intersect = (*it).first;
1116                                if (!intersect->Mailed())
1117                                {
1118                                        Material m = RandomMaterial();
1119                       
1120                                        exporter->SetForcedMaterial(m);
1121
1122                                        exporter->ExportIntersectable(intersect);
1123                                        intersect->Mail();
1124                                }                       
1125                        }
1126                               
1127                        DEL_PTR(exporter);
1128                        cout << "finished" << endl;
1129                }
1130        }
1131}
Note: See TracBrowser for help on using the repository browser.