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

Revision 437, 24.8 KB checked in by mattausch, 19 years ago (diff)

detected leak in BspTree?
added specialised fast view cell bsp tree called VspBspTree?

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