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

Revision 430, 24.9 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
124void
125SamplingPreprocessor::HoleSamplingPass()
126{
127  vector<KdLeaf *> leaves;
128  mKdTree->CollectLeaves(leaves);
129 
130  // go through all the leaves and evaluate their passing contribution
131  for (int i=0 ; i < leaves.size(); i++) {
132    KdLeaf *leaf = leaves[i];
133    cout<<leaf->mPassingRays<<endl;
134  }
135}
136
137int SamplingPreprocessor::AddObjectSamples(Intersectable *obj, const Ray &ray)
138{
139        int contributingSamples = 0;
140        int j;
141 
142        // object can be seen from the view cell => add to view cell pvs
143        for (j=0; j < ray.bspIntersections.size(); ++ j)
144        {       
145                BspLeaf *leaf = ray.bspIntersections[j].mLeaf;
146                // if ray not in unbounded space
147                if (leaf->GetViewCell() != &mUnbounded)
148                        contributingSamples +=
149                                leaf->GetViewCell()->GetPvs().AddSample(obj);
150        }
151 
152        // rays passing through this viewcell
153        if (mPass > 1)
154                for (j=1; j < ((int)ray.bspIntersections.size() - 1); ++ j)
155                {
156                        BspLeaf *leaf = ray.bspIntersections[j].mLeaf;
157
158                        if (leaf->GetViewCell() != &mUnbounded)
159                                leaf->GetViewCell()->
160                                        AddPassingRay(ray, contributingSamples ? 1 : 0);
161                }
162 
163        return contributingSamples;
164}
165
166
167int
168SamplingPreprocessor::CastRay(Intersectable *object, Ray &ray)
169{
170        int sampleContributions = 0;
171
172        long t1 = GetRealTime();
173        // cast ray to KD tree to find intersection with other objects
174        mKdTree->CastRay(ray);
175        long t2 = GetRealTime();
176
177        if (0 && object && object->GetId() > 2197) {
178                object->Describe(cout)<<endl;
179                cout<<ray<<endl;
180        }
181
182        switch(ViewCell::sHierarchy)
183        {
184        case ViewCell::BSP:
185               
186                //-- cast ray to BSP tree to get intersection with view cells
187                if (!mBspTree)
188                        break;
189               
190                mBspTree->CastRay(ray);
191                       
192                if (object)
193                        sampleContributions += AddObjectSamples(object, ray);
194                       
195                if (!ray.intersections.empty()) // second intersection found
196                {
197                        sampleContributions +=
198                                AddObjectSamples(ray.intersections[0].mObject, ray);
199                }
200                break;
201        case ViewCell::KD:
202                if (ray.kdLeaves.size())
203                {
204                        Intersectable *terminator =
205                                ray.intersections.size() ? ray.intersections[0].mObject: NULL;
206
207                        sampleContributions += AddNodeSamples(ray,
208                                                                                                                                                                        object,
209                                                                                                                                                                        terminator);
210                }
211                break;
212        case ViewCell::VSP:
213                // TODO:
214                break;
215        default:
216                Debug << "Should never come here" << endl;
217                break;
218        }
219
220        return sampleContributions;
221}
222
223//  void
224//  SamplingPreprocessor::AvsGenerateRandomRay(Ray &ray)
225//  {
226//    int objId = RandomValue(0, mObjects.size());
227//    Intersectable *object = objects[objId];
228//    object->GetRandomSurfacePoint(point, normal);
229//    direction = UniformRandomVector(normal);
230//    SetupRay(ray, point, direction);
231//  }
232
233//  void
234//  SamplingPreprocessor::AvsHandleRay(Ray &ray)
235//  {
236//    int sampleContributions = 0;
237
238//    mKdTree->CastRay(ray);
239 
240//    if (ray.leaves.size()) {
241//      sampleContributions += AddNodeSamples(object, ray, pass);
242   
243//      if (ray.intersections.size()) {
244//        sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
245//      }
246//    }
247//  }
248
249//  void
250//  SamplingPreprocessor::AvsBorderSampling(Ray &ray)
251//  {
252 
253
254//  }
255
256//  void
257//  SamplingPreprocessor::AvsPass()
258//  {
259//    Ray ray;
260//    while (1) {
261//      AvsGenerateRay(ray);
262//      HandleRay(ray);
263//      while ( !mRayQueue.empty() ) {
264//        Ray ray = mRayQueue.pop();
265//        mRayQueue.pop();
266//        AdaptiveBorderSampling(ray);
267//      }
268//    }
269 
270 
271
272//  }
273
274
275int
276SamplingPreprocessor::CastEdgeSamples(
277                                                                                                                                                        Intersectable *object,
278                                                                                                                                                        const Vector3 &point,
279                                                                                                                                                        MeshInstance *mi,
280                                                                                                                                                        const int samples
281                                                                                                                                                        )
282{
283        Ray ray;
284        int maxTries = samples*10;
285        int i;
286        int rays = 0;
287        int edgeSamplesContributions = 0;
288        for (i=0; i < maxTries && rays < samples; i++) {
289                // pickup a random face of each mesh
290                Mesh *mesh = mi->GetMesh();
291                int face = RandomValue(0, mesh->mFaces.size()-1);
292               
293                Polygon3 poly(mesh->mFaces[face], mesh);
294                poly.Scale(1.001);
295                // now extend a random edge of the face
296                int edge = RandomValue(0, poly.mVertices.size()-1);
297                float t = RandomValue(0.0f,1.0f);
298                Vector3 target = t*poly.mVertices[edge] + (1.0f-t)*poly.mVertices[(edge + 1)%
299                                                                                                                                                                                                                                                                                 poly.mVertices.size()];
300                SetupRay(ray, point, target - point, Ray::LOCAL_RAY);
301                if (!mesh->CastRay(ray, mi)) {
302                        // the rays which intersect the mesh have been discarded since they are not tangent
303                        // to the mesh
304                        rays++;
305                        edgeSamplesContributions += CastRay(object, ray);
306                }
307        }
308        return edgeSamplesContributions;
309}
310
311KdNode *
312SamplingPreprocessor::GetNodeToSample(Intersectable *object)
313{
314        int pvsSize = object->mKdPvs.GetSize();
315        KdNode *nodeToSample = NULL;
316       
317        bool samplePvsBoundary = false;
318        if (pvsSize && samplePvsBoundary) {
319                // this samples the nodes from the boundary of the current PVS
320                // mail all nodes from the pvs
321                Intersectable::NewMail();
322                KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
323               
324                for (; i != object->mKdPvs.mEntries.end(); i++) {
325                        KdNode *node = (*i).first;
326                        node->Mail();
327                }
328               
329                int maxTries = 2*pvsSize;
330                Debug << "Finding random neighbour" << endl;   
331                for (int tries = 0; tries < 10; tries++) {
332                        int index = RandomValue(0, pvsSize - 1);
333                        KdPvsData data;
334                        KdNode *node;
335                        object->mKdPvs.GetData(index, node, data);
336                        nodeToSample = mKdTree->FindRandomNeighbor(node, true);
337                        if (nodeToSample)
338                                break;
339                }
340        } else {
341                // just pickup a random node
342                //              nodeToSample = mKdTree->GetRandomLeaf(Plane3(normal, point));
343                nodeToSample = mKdTree->GetRandomLeaf();
344        }
345        return nodeToSample;
346}
347
348void
349SamplingPreprocessor::VerifyVisibility(Intersectable *object)
350{
351        // mail all nodes from the pvs
352        Intersectable::NewMail();
353        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
354        for (; i != object->mKdPvs.mEntries.end(); i++) {
355                KdNode *node = (*i).first;
356                node->Mail();
357        }
358        Debug << "Get all neighbours from PVS" << endl;
359        vector<KdNode *> invisibleNeighbors;
360        // get all neighbors of all PVS nodes
361        i = object->mKdPvs.mEntries.begin();
362        for (; i != object->mKdPvs.mEntries.end(); i++) {
363                KdNode *node = (*i).first;
364                mKdTree->FindNeighbors(node, invisibleNeighbors, true);
365                AxisAlignedBox3 box = object->GetBox();
366                for (int j=0; j < invisibleNeighbors.size(); j++) {
367                        int visibility = ComputeBoxVisibility(mSceneGraph,
368                                                              mKdTree,
369                                                              box,
370                                                              mKdTree->GetBox(invisibleNeighbors[j]),
371                                                              1e-6f);
372                        //            exit(0);
373                }
374                // now rank all the neighbors according to probability that a new
375                // sample creates some contribution
376        }
377}
378
379bool
380SamplingPreprocessor::ComputeVisibility()
381{
382 
383  // pickup an object
384  ObjectContainer objects;
385 
386  mSceneGraph->CollectObjects(&objects);
387
388  Vector3 point, normal, direction;
389  Ray ray;
390
391  long startTime = GetTime();
392 
393  int i;
394  int totalSamples = 0;
395
396  int pvsOut = Min((int)objects.size(), 10);
397  int pvsSize = 0;
398
399  RayContainer rays[10];
400
401  while (totalSamples < mTotalSamples) {
402                int passContributingSamples = 0;
403                int passSampleContributions = 0;
404                int passSamples = 0;
405                int index = 0;
406               
407                int reverseSamples = 0;
408               
409                       
410                //cout << "totalSamples: "  << totalSamples << endl;
411
412                for (i = 0; i < objects.size(); i++) {
413                                               
414                        KdNode *nodeToSample = NULL;
415                        Intersectable *object = objects[i];
416               
417                        int pvsSize = 0;
418                        if (ViewCell::sHierarchy == ViewCell::KD)
419                                pvsSize = object->mKdPvs.GetSize();
420                                               
421                       
422                        if (0 && pvsSize && mPass == 1000 ) {
423                                VerifyVisibility(object);
424                        }
425                       
426                        int faceIndex = object->GetRandomSurfacePoint(point, normal);
427                       
428                        bool viewcellSample = true;
429                        int sampleContributions;
430                        bool debug = false; //(object->GetId() >= 2199);
431                        if (viewcellSample) {
432                                //mKdTree->GetRandomLeaf(Plane3(normal, point));
433
434                                nodeToSample = GetNodeToSample(object);
435
436                                for (int k=0; k < mSamplesPerPass; k++) {
437                                        bool reverseSample = false;
438                                       
439
440                                        if (nodeToSample) {
441                                                AxisAlignedBox3 box = mKdTree->GetBox(nodeToSample);
442                                                Vector3 pointToSample = box.GetRandomPoint();
443                                                //                                              pointToSample.y = 0.9*box.Min().y + 0.1*box.Max().y;
444                                                if (object->GetRandomVisibleSurfacePoint( point, normal, pointToSample, 3 )) {
445                                                        direction = pointToSample - point;
446                                                } else {
447                                                        reverseSamples++;
448                                                        reverseSample = true;
449                                                        direction = point - pointToSample;
450                                                        point = pointToSample;
451                                                        //Debug << "point: " << pointToSample << endl;
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                Debug << "overall scene size: " << (int)objects.size() << endl;
577               
578                BspViewCellsStatistics stat;
579                mBspTree->EvaluateViewCellsStats(stat);
580                Debug << "original view cell partition:\n" << stat << endl;
581               
582                if (1) // export view cells
583                {
584                        cout << "exporting initial view cells (=leaves) ... ";
585                        Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
586                        if (exporter)
587                        {
588                                exporter->SetWireframe();
589                                exporter->ExportBspLeaves(*mBspTree, stat.maxPvs);
590                                //exporter->ExportBspViewCellPartition(*mBspTree, 0);
591                               
592                                if (1)
593                                        ExportSceneGeometry(exporter, objects);
594                                       
595                                delete exporter;
596                        }
597                        cout << "finished" << endl;
598                }
599
600                cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
601               
602                long startTime = GetTime();
603                int merged = PostprocessViewCells(mSampleRays);
604               
605                cout << "finished" << endl;
606                cout << "merged " << merged << " view cells in "
607                         << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
608
609                //-- recount pvs
610                mBspTree->EvaluateViewCellsStats(stat);
611               
612                Debug << "after post processing:\n" << stat << endl;
613
614                //-- render simulation
615               
616                RenderSimulator *rs = GetRenderSimulator();
617
618                if (rs)
619                {
620                        cout << "\nevaluating render time after merge ... ";
621                       
622                        rs->SimulateRendering();
623
624                        cout << " finished" << endl;
625
626                        cout << GetRenderSimulator()->mStat << endl;
627                        Debug << GetRenderSimulator()->mStat << endl;
628                }
629
630                if (1) // export view cells
631                {
632                        cout << "exporting view cells after merge ... ";
633                        Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
634                        if (exporter)
635                        {
636                                exporter->ExportBspViewCellPartition(*mBspTree, stat.maxPvs);
637                                //exporter->ExportBspViewCellPartition(*mBspTree, 0);
638                                delete exporter;
639                        }
640
641                        cout << "finished" << endl;
642                }
643
644                //-- visualization of the BSP splits
645                bool exportSplits = false;
646                environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
647               
648                cout << "exporting splits ... ";
649                if (exportSplits)
650                        ExportSplits(objects, mSampleRays, mVisualizationSamples);
651                cout << "finished" << endl;
652
653                // export the PVS of sample view cells
654                if (1)
655                        ExportBspPvs(objects, mSampleRays, mVisualizationSamples);
656        }
657       
658  //  HoleSamplingPass();
659        if (0) {
660                Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
661                exporter->SetExportRayDensity(true);
662                exporter->ExportKdTree(*mKdTree);
663                delete exporter;
664        }
665
666        if (mVspKdTree)
667        {
668                if (1)
669                {
670                        Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");
671                        //exporter->SetWireframe();
672                        exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize);
673
674                        Debug << "average PVS size: " << mVspKdTree->GetAvgPvsSize() << endl;
675
676                        if (0) ExportSceneGeometry(exporter, objects);
677
678                        bool exportRays = true;
679
680                        if (exportRays)
681                        {
682                                int raysSize = 2000;
683                                float prob = raysSize / (float)mVspSampleRays.size();
684               
685                                exporter->SetWireframe();
686                       
687                                VssRayContainer rays;
688                                for (int i = 0; i < mVspSampleRays.size(); ++ i)
689                                {
690                                        if (RandomValue(0,1) < prob)
691                                                rays.push_back(mVspSampleRays[i]);
692                                }
693
694                                exporter->ExportRays(rays, RgbColor(1, 0, 0));
695                        }
696
697                        delete exporter;
698                }
699
700                if (1)
701                {
702                        vector<VspKdTreeLeaf *> leafContainer;
703
704                        mVspKdTree->CollectLeaves(leafContainer);
705
706                        for (int i = 0; i < 10; ++ i)
707                        {
708                                char s[64];
709                                sprintf(s, "vsp_leaves%04d.x3d", i);
710                                Exporter *exporter = Exporter::GetExporter(s);
711
712                                // export geometry
713                                VspKdTreeLeaf *leaf = leafContainer[Random((int)leafContainer.size())];
714                                AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf);
715
716                                Material m;
717                                m.mDiffuseColor = RgbColor(0, 1, 1);
718                                exporter->SetForcedMaterial(m);
719                                exporter->SetWireframe();
720                                exporter->ExportBox(box);
721
722                                //-- export stored rays
723                                VssRayContainer vssRays;
724                                leaf->GetRays(vssRays);
725
726                                VssRayContainer rays;
727
728                                VssRayContainer::const_iterator it, it_end = vssRays.end();
729
730                                for (it = vssRays.begin(); it != it_end; ++ it)
731                                {
732                                        //if (!(*it)->mOriginObject && !(*it)->mTerminationObject)
733                        rays.push_back(*it);
734
735                                        //if (!(*it)->mOriginObject && !(*it)->mTerminationObject)
736                                        //      Debug << "ERR: " << (*it)->mOrigin << " " << (*it)->mTermination << endl;
737                                }
738
739                                exporter->ExportRays(rays, RgbColor(1, 0, 0));
740
741                                //-- export stored PVS
742                                ObjectContainer pvsObj;
743                                leaf->ExtractPvs(pvsObj);
744                               
745                                ExportSceneGeometry(exporter, pvsObj);
746
747                                delete exporter;
748                        }                       
749                }
750        }
751 
752        bool exportRays = false;
753        if (exportRays) {
754                Exporter *exporter = NULL;
755                exporter = Exporter::GetExporter("sample-rays.x3d");
756                exporter->SetWireframe();
757                exporter->ExportKdTree(*mKdTree);
758                exporter->ExportBspTree(*mBspTree);
759
760                for (i=0; i < pvsOut; i++)
761                        exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
762                exporter->SetFilled();
763               
764                delete exporter;
765        }
766
767        //-- several visualizations and statistics
768        if (1) {
769
770   for (int k=0; k < pvsOut; k++) {
771                 Intersectable *object = objects[k];
772                 char s[64];
773                 sprintf(s, "sample-pvs%04d.x3d", k);
774                 Exporter *exporter = Exporter::GetExporter(s);
775                 exporter->SetWireframe();
776                 
777                 
778                 KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
779                 Intersectable::NewMail();
780                 
781                 // avoid adding the object to the list
782                 object->Mail();
783                 ObjectContainer visibleObjects;
784                 
785                 for (; i != object->mKdPvs.mEntries.end(); i++)
786                         {
787                                 KdNode *node = (*i).first;
788                                 exporter->ExportBox(mKdTree->GetBox(node));
789                                 mKdTree->CollectObjects(node, visibleObjects);
790                         }
791                 
792                 exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
793                 exporter->SetFilled();
794                 
795                 for (int j = 0; j < visibleObjects.size(); j++)
796                         exporter->ExportIntersectable(visibleObjects[j]);
797                 
798                 
799                 Material m;
800                 m.mDiffuseColor = RgbColor(1, 0, 0);
801                 exporter->SetForcedMaterial(m);
802                 exporter->ExportIntersectable(object);
803                 
804                 delete exporter;
805         }
806  }
807 
808  return true;
809}
810
811
812void SamplingPreprocessor::ProcessVspViewCells(Ray &ray,
813                                               Intersectable *object,
814                                                                                           const int faceIndex,
815                                                                                           int &contributingSamples,
816                                                                                           int &sampleContributions)
817{
818        if (!mVspKdTree)
819        {
820                // store samples for vsp kd tree construction
821                if ((int)mVspSampleRays.size() < mVspConstructionSamples)
822                {
823                        if (object || !ray.intersections.empty())
824                        {
825                                ray.sourceObject = Ray::Intersection(0.0, object, faceIndex);
826                                VssRay *sRay = new VssRay(ray);
827                                mVspSampleRays.push_back(sRay);
828                        }
829                }
830                else
831                {
832                        // construct VSP tree using the collected samples
833                        cout << "building VSP tree from " << (int)mVspSampleRays.size() << " samples " << endl;
834                        mVspKdTree = new VspKdTree();
835                        mVspKdTree->Construct(mVspSampleRays, &mKdTree->GetBox());
836               
837                        // add contributions of saved samples to PVS
838                        //contributingSamples += mBspTree->GetStat().contributingSamples;
839                        //sampleContributions += mBspTree->GetStat().sampleContributions;
840
841                        Debug << mVspKdTree->GetStatistics();
842
843                        // throw away samples because BSP leaves not stored in order
844                        // Need ordered rays for post processing => collect new rays
845                        //CLEAR_CONTAINER(mVspSampleRays);
846                }
847        }
848        // save rays for post processing
849        /*else if (((int)mVspSampleRays.size() < mPostProcessSamples) ||
850                         ((int)mVspSampleRays.size() < mVisualizationSamples))
851        {
852                mVspSampleRays.push_back(new Ray(ray));
853        }*/
854}
855
856void SamplingPreprocessor::ProcessBspViewCells(const Ray &ray,
857                                               Intersectable *object,
858                                                                                           const int faceIndex,
859                                                                                           int &contributingSamples,
860                                                                                           int &sampleContributions)
861{
862        // save rays for bsp tree construction
863        if (!mBspTree)
864        {
865                if ((BspTree::sConstructionMethod == BspTree::FROM_SAMPLES) &&
866                        ((int)mSampleRays.size() < mBspConstructionSamples))
867                {
868                        MeshInstance *mi = dynamic_cast<MeshInstance *>(object);
869                       
870                        Ray *sRay = new Ray(ray);
871                        mSampleRays.push_back(sRay);
872               
873                        // also add origin to sample
874                        sRay->sourceObject = Ray::Intersection(0.0, object, faceIndex);
875                }
876                else
877                {
878                        // construct BSP tree using the collected samples
879                        cout << "building bsp tree from " << (int)mSampleRays.size() << " samples " << endl;
880                        BuildBspTree();
881               
882                        // add contributions of saved samples to PVS
883                        contributingSamples += mBspTree->GetStat().contributingSamples;
884                        sampleContributions += mBspTree->GetStat().sampleContributions;
885
886                        BspTreeStatistics(Debug);
887
888                        if (0) Export("vc_bsptree.x3d", false, false, true);
889
890                        // throw away samples because BSP leaves not stored in order
891                        // Need ordered rays for post processing => collect new rays
892                        CLEAR_CONTAINER(mSampleRays);
893                }
894        }
895        // save rays for post processing
896        else if (((int)mSampleRays.size() < mPostProcessSamples) ||
897                         ((int)mSampleRays.size() < mVisualizationSamples))
898        {
899                mSampleRays.push_back(new Ray(ray));
900        }
901}
902
903// merge or subdivide view cells
904int SamplingPreprocessor::PostprocessViewCells(const RayContainer &rays)
905{
906        int merged = 0;
907
908        RayContainer::const_iterator rit, rit_end = rays.end();
909        vector<Ray::BspIntersection>::const_iterator iit;
910
911        int limit = min((int)mSampleRays.size(), mPostProcessSamples);
912
913        for (int i = 0; i < limit; ++ i)
914        { 
915                Ray *ray = mSampleRays[i];
916
917                // traverse leaves stored in the rays and compare and merge consecutive
918                // leaves (i.e., the neighbors in the tree)
919                if (ray->bspIntersections.size() < 2)
920                        continue;
921
922                iit = ray->bspIntersections.begin();
923
924                BspLeaf *previousLeaf = (*iit).mLeaf;
925                ++ iit;
926               
927                for (; iit != ray->bspIntersections.end(); ++ iit)
928                {
929                        BspLeaf *leaf = (*iit).mLeaf;
930
931                        if (mBspTree->ShouldMerge(leaf, previousLeaf))
932                        {                       
933                                mBspTree->MergeViewCells(leaf, previousLeaf);
934
935                                ++ merged;
936                        }
937               
938                        previousLeaf = leaf;
939                }
940        }
941
942        return merged;
943}
Note: See TracBrowser for help on using the repository browser.