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

Revision 367, 21.6 KB checked in by mattausch, 19 years ago (diff)

started pvs surface area heuristics

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