source: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp @ 1004

Revision 1004, 12.5 KB checked in by mattausch, 18 years ago (diff)

environment as a singleton

RevLine 
[372]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"
[439]9#include "ViewCellsManager.h"
[406]10#include "RenderSimulator.h"
[372]11
[860]12
[863]13namespace GtpVisibilityPreprocessor {
[860]14
15
[411]16SamplingPreprocessor::SamplingPreprocessor(): mPass(0)
[372]17{
18  // this should increase coherence of the samples
[1004]19  Environment::GetSingleton()->GetIntValue("Sampling.samplesPerPass", mSamplesPerPass);
20  Environment::GetSingleton()->GetIntValue("Sampling.totalSamples", mTotalSamples);
[409]21 
[372]22  mStats.open("stats.log");
23}
24
25SamplingPreprocessor::~SamplingPreprocessor()
26{
27        CLEAR_CONTAINER(mSampleRays);
[440]28        CLEAR_CONTAINER(mVssSampleRays);
[372]29}
30
31void
32SamplingPreprocessor::SetupRay(Ray &ray,
[441]33                                                           const Vector3 &point,
34                                                           const Vector3 &direction,
[440]35                                                           const int type,
36                                                           const Ray::Intersection &origin)
[372]37{
[466]38  ray.Clear();
[440]39 
[374]40        ray.mFlags |= Ray::STORE_KDLEAVES | Ray::STORE_BSP_INTERSECTIONS;
[444]41        //  cout<<point<<" "<<direction<<endl;
42
43        ray.Init(point, direction, type);
[440]44        ray.sourceObject = origin;
[372]45}
46
[429]47void
48SamplingPreprocessor::HoleSamplingPass()
49{
50  vector<KdLeaf *> leaves;
51  mKdTree->CollectLeaves(leaves);
52 
53  // go through all the leaves and evaluate their passing contribution
54  for (int i=0 ; i < leaves.size(); i++) {
55    KdLeaf *leaf = leaves[i];
56    cout<<leaf->mPassingRays<<endl;
57  }
58}
59
[372]60 
[441]61void
[466]62SamplingPreprocessor::CastRays(const RayContainer &rays)
[441]63{       
[466]64  // cast ray to KD tree to find intersection with other objects
65  RayContainer::const_iterator it, it_end = rays.end();
[372]66
[466]67  VssRayContainer vssRays;
68  for (it = rays.begin(); it != it_end; ++it) {
69        mKdTree->CastRay(*(*it));
70        vssRays.push_back(new VssRay(*(*it)));
71  }
72 
[574]73  mViewCellsManager->ComputeSampleContributions(vssRays, true, false);
[466]74  CLEAR_CONTAINER(vssRays);
[372]75}
76
77int
[441]78SamplingPreprocessor::CastRay(Ray &ray)
[372]79{
80        // cast ray to KD tree to find intersection with other objects
[469]81        mKdTree->CastRay(ray);
82        VssRay vssRay(ray);
83
[574]84        mViewCellsManager->ComputeSampleContributions(vssRay, true, false);
[469]85       
86        return vssRay.mPvsContribution;
[372]87}
88
89//  void
90//  SamplingPreprocessor::AvsGenerateRandomRay(Ray &ray)
91//  {
92//    int objId = RandomValue(0, mObjects.size());
93//    Intersectable *object = objects[objId];
94//    object->GetRandomSurfacePoint(point, normal);
95//    direction = UniformRandomVector(normal);
96//    SetupRay(ray, point, direction);
97//  }
98
99//  void
100//  SamplingPreprocessor::AvsHandleRay(Ray &ray)
101//  {
102//    int sampleContributions = 0;
103
104//    mKdTree->CastRay(ray);
105 
106//    if (ray.leaves.size()) {
107//      sampleContributions += AddNodeSamples(object, ray, pass);
108   
109//      if (ray.intersections.size()) {
110//        sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
111//      }
112//    }
113//  }
114
115//  void
116//  SamplingPreprocessor::AvsBorderSampling(Ray &ray)
117//  {
118 
119
120//  }
121
122//  void
123//  SamplingPreprocessor::AvsPass()
124//  {
125//    Ray ray;
126//    while (1) {
127//      AvsGenerateRay(ray);
128//      HandleRay(ray);
129//      while ( !mRayQueue.empty() ) {
130//        Ray ray = mRayQueue.pop();
131//        mRayQueue.pop();
132//        AdaptiveBorderSampling(ray);
133//      }
134//    }
135 
136 
137
138//  }
139
140
141int
142SamplingPreprocessor::CastEdgeSamples(
[441]143                                                                          Intersectable *object,
144                                                                          const Vector3 &point,
145                                                                          MeshInstance *mi,
146                                                                          const int samples
147                                                                          )
[372]148{
149        Ray ray;
150        int maxTries = samples*10;
151        int i;
152        int rays = 0;
153        int edgeSamplesContributions = 0;
154        for (i=0; i < maxTries && rays < samples; i++) {
155                // pickup a random face of each mesh
156                Mesh *mesh = mi->GetMesh();
[477]157                int face = (int)RandomValue(0, (Real)((int)mesh->mFaces.size() - 1));
[372]158               
159                Polygon3 poly(mesh->mFaces[face], mesh);
[469]160                poly.Scale(1.001f);
[372]161                // now extend a random edge of the face
[477]162                int edge = (int)RandomValue(0, (Real)((int)poly.mVertices.size() - 1));
[469]163                float t = RandomValue(0.0f, 1.0f);
[372]164                Vector3 target = t*poly.mVertices[edge] + (1.0f-t)*poly.mVertices[(edge + 1)%
[441]165                        poly.mVertices.size()];
[440]166                SetupRay(ray, point, target - point, Ray::LOCAL_RAY, Ray::Intersection(0, object, 0));
[372]167                if (!mesh->CastRay(ray, mi)) {
168                        // the rays which intersect the mesh have been discarded since they are not tangent
169                        // to the mesh
170                        rays++;
[440]171                        edgeSamplesContributions += CastRay(ray);
[372]172                }
173        }
174        return edgeSamplesContributions;
175}
176
177KdNode *
178SamplingPreprocessor::GetNodeToSample(Intersectable *object)
179{
180        int pvsSize = object->mKdPvs.GetSize();
181        KdNode *nodeToSample = NULL;
182       
183        bool samplePvsBoundary = false;
184        if (pvsSize && samplePvsBoundary) {
185                // this samples the nodes from the boundary of the current PVS
186                // mail all nodes from the pvs
187                Intersectable::NewMail();
188                KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
189               
190                for (; i != object->mKdPvs.mEntries.end(); i++) {
191                        KdNode *node = (*i).first;
192                        node->Mail();
193                }
194               
195                int maxTries = 2*pvsSize;
196                Debug << "Finding random neighbour" << endl;   
197                for (int tries = 0; tries < 10; tries++) {
[477]198                        int index = (int)RandomValue(0, (Real)(pvsSize - 1));
[372]199                        KdPvsData data;
200                        KdNode *node;
201                        object->mKdPvs.GetData(index, node, data);
202                        nodeToSample = mKdTree->FindRandomNeighbor(node, true);
203                        if (nodeToSample)
204                                break;
205                }
206        } else {
207                // just pickup a random node
208                //              nodeToSample = mKdTree->GetRandomLeaf(Plane3(normal, point));
209                nodeToSample = mKdTree->GetRandomLeaf();
210        }
211        return nodeToSample;
212}
213
214void
215SamplingPreprocessor::VerifyVisibility(Intersectable *object)
216{
217        // mail all nodes from the pvs
218        Intersectable::NewMail();
219        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
220        for (; i != object->mKdPvs.mEntries.end(); i++) {
221                KdNode *node = (*i).first;
222                node->Mail();
223        }
224        Debug << "Get all neighbours from PVS" << endl;
225        vector<KdNode *> invisibleNeighbors;
226        // get all neighbors of all PVS nodes
227        i = object->mKdPvs.mEntries.begin();
228        for (; i != object->mKdPvs.mEntries.end(); i++) {
229                KdNode *node = (*i).first;
230                mKdTree->FindNeighbors(node, invisibleNeighbors, true);
231                AxisAlignedBox3 box = object->GetBox();
232                for (int j=0; j < invisibleNeighbors.size(); j++) {
233                        int visibility = ComputeBoxVisibility(mSceneGraph,
234                                                              mKdTree,
235                                                              box,
236                                                              mKdTree->GetBox(invisibleNeighbors[j]),
237                                                              1e-6f);
238                        //            exit(0);
239                }
240                // now rank all the neighbors according to probability that a new
241                // sample creates some contribution
242        }
243}
244
245bool
246SamplingPreprocessor::ComputeVisibility()
247{
248 
[440]249  /// rays per pass
250  RayContainer passRays;
251
[372]252
[487]253  mViewCellsManager->SetViewSpaceBox(mKdTree->GetBox());
254 
[372]255  Vector3 point, normal, direction;
[440]256  //Ray ray;
[372]257
258  long startTime = GetTime();
259 
260  int i;
261  int totalSamples = 0;
262
[414]263  int pvsSize = 0;
[372]264
265  while (totalSamples < mTotalSamples) {
266                int passContributingSamples = 0;
267                int passSampleContributions = 0;
268                int passSamples = 0;
269                int index = 0;
270               
271                int reverseSamples = 0;
272               
[492]273                for (i = 0; i < mObjects.size(); i++) {
[372]274                                               
275                        KdNode *nodeToSample = NULL;
[492]276                        Intersectable *object = mObjects[i];
[372]277               
278                        int pvsSize = 0;
279                       
280                        if (0 && pvsSize && mPass == 1000 ) {
281                                VerifyVisibility(object);
282                        }
283                       
284                        int faceIndex = object->GetRandomSurfacePoint(point, normal);
285                       
286                        bool viewcellSample = true;
[440]287                        //int sampleContributions;
[372]288                        bool debug = false; //(object->GetId() >= 2199);
289                        if (viewcellSample) {
290                                //mKdTree->GetRandomLeaf(Plane3(normal, point));
291
292                                nodeToSample = GetNodeToSample(object);
293
294                                for (int k=0; k < mSamplesPerPass; k++) {
295                                        bool reverseSample = false;
[441]296                               
[372]297                                        if (nodeToSample) {
298                                                AxisAlignedBox3 box = mKdTree->GetBox(nodeToSample);
299                                                Vector3 pointToSample = box.GetRandomPoint();
300                                                //                                              pointToSample.y = 0.9*box.Min().y + 0.1*box.Max().y;
301                                                if (object->GetRandomVisibleSurfacePoint( point, normal, pointToSample, 3 )) {
302                                                        direction = pointToSample - point;
303                                                } else {
304                                                        reverseSamples++;
305                                                        reverseSample = true;
306                                                        direction = point - pointToSample;
307                                                        point = pointToSample;
[429]308                                                        //Debug << "point: " << pointToSample << endl;
[372]309                                                }
310                                        }
311                                        else {
312                                                direction = UniformRandomVector(normal);
313                                        }
314                                       
[440]315                                        Ray *ray = new Ray();
316
[372]317                                        // construct a ray
[444]318                                        SetupRay(*ray, point, direction, Ray::LOCAL_RAY,
319                                                         Ray::Intersection(0, reverseSample ? NULL : object, faceIndex));
320
[440]321                                        passRays.push_back(ray);
[372]322                                       
323                                        //-- CORR matt: put block inside loop
[440]324                                        /*if (sampleContributions) {
[372]325                                                passContributingSamples ++;
326                                                passSampleContributions += sampleContributions;
[440]327                                        }*/
[372]328                                }
329                        } else {
330                                // edge samples
331                                // get random visible mesh
332                                //                              object->GetRandomVisibleMesh(Plane3(normal, point));
333                        }
334       
335                        // CORR matt: must add all samples
336                        passSamples += mSamplesPerPass;
337                }
338       
[441]339                //-------------------
340                // cast rays for view cells construction
341                ProcessViewCells(passRays,
[492]342                                                 mObjects,
[441]343                                                 passSampleContributions,
344                                                 passContributingSamples);
345
[440]346                CLEAR_CONTAINER(passRays);
[441]347               
[372]348                totalSamples += passSamples;
349               
350                //    if (pass>10)
351                //      HoleSamplingPass();
352   
[441]353                mPass ++;
[414]354       
[441]355                pvsSize += passSampleContributions;
[440]356               
[372]357                float avgRayContrib = (passContributingSamples > 0) ?
[451]358                        passSampleContributions / (float)passContributingSamples : 0;
[372]359
360                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
361                cout << "#TotalSamples=" << totalSamples/1000
362                                 << "k   #SampleContributions=" << passSampleContributions << " ("
363                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
[492]364                                 << (float)pvsSize /(float)mObjects.size() << endl
[372]365                                 << "avg ray contrib=" << avgRayContrib << endl
366                                 << "reverse samples [%]" << reverseSamples/(float)passSamples*100.0f << endl;
367
368                mStats <<
369                        "#Pass\n" <<mPass<<endl<<
370                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
371                        "#TotalSamples\n" << totalSamples<< endl<<
372                        "#SampleContributions\n" << passSampleContributions << endl <<
373                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
[492]374                        "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
[372]375                        "#AvgRayContrib\n" << avgRayContrib << endl;
376        }
377       
[440]378        //cout << "#totalKdPvsSize=" << mKdTree->CollectLeafPvs() << endl;
[372]379       
380  //  HoleSamplingPass();
381        if (0) {
382                Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
383                exporter->SetExportRayDensity(true);
384                exporter->ExportKdTree(*mKdTree);
[422]385                delete exporter;
386        }
[452]387       
388        // construct view cells if not already constructed
389        if (!mViewCellsManager->ViewCellsConstructed())
[574]390          mViewCellsManager->ConstructSubdivision(mObjects, mVssSampleRays);
[372]391
[466]392        // $$JB temporary removed
393        //      mViewCellsManager->PostProcess(objects, mSampleRays);
[452]394       
395        //-- several visualizations and statistics
[475]396        Debug << "view cells after post processing: " << endl;
[452]397        mViewCellsManager->PrintStatistics(Debug);
398
[448]399        //-- render simulation after merge
400        cout << "\nevaluating bsp view cells render time after merge ... ";
401       
[468]402         mRenderSimulator->RenderScene();
403         SimulationStatistics ss;
404         mRenderSimulator->GetStatistics(ss);
405         
406         cout << " finished" << endl;
407         cout << ss << endl;
408         Debug << ss << endl;
409       
[466]410        // $$JB temporary removed
411        //mViewCellsManager->Visualize(objects, mSampleRays);   
[462]412   
[441]413        return true;
[362]414}
[349]415
[441]416void SamplingPreprocessor::ProcessViewCells(const RayContainer &newRays,
[440]417                                                                                        const ObjectContainer &objects,
[441]418                                                                                        int &sampleContributions,
419                                                                                        int &contributingSamples)
[439]420{
[466]421  // cast rays to view cells
422  CastRays(newRays);
[441]423
[466]424  // save rays for view cells construction
425  if (!mViewCellsManager->ViewCellsConstructed())
[441]426        {
[466]427          if ((int)mVssSampleRays.size() < mViewCellsManager->GetConstructionSamples())
[452]428                {
[466]429                  RayContainer::const_iterator it, it_end = newRays.end();
430                 
431                  for (it = newRays.begin(); it != it_end; ++ it)
432                        mVssSampleRays.push_back(new VssRay(*(*it)));
[441]433                }
[466]434          else
[411]435                {
[466]436                  // construct view cells
[574]437                  mViewCellsManager->ConstructSubdivision(objects, mVssSampleRays);
[466]438                 
439                  // throw away samples
440                  //CLEAR_CONTAINER(mVssSampleRays);
[411]441                }
442        }
[466]443  // Need rays (with ordered intersections) for post processing => collect new rays
444  if (((int)mSampleRays.size() < mViewCellsManager->GetPostProcessSamples()) ||
445          ((int)mSampleRays.size() < mViewCellsManager->GetVisualizationSamples()))
[372]446        {
[466]447          RayContainer::const_iterator it, it_end = newRays.end();
448         
449          for (it = newRays.begin(); it != it_end; ++ it)
450                mSampleRays.push_back(new Ray(*(*it)));
[372]451        }
[362]452}
[860]453
454}
Note: See TracBrowser for help on using the repository browser.