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

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 "ViewCellsManager.h"
10#include "RenderSimulator.h"
11
12
13namespace GtpVisibilityPreprocessor {
14
15
16SamplingPreprocessor::SamplingPreprocessor(): mPass(0)
17{
18  // this should increase coherence of the samples
19  Environment::GetSingleton()->GetIntValue("Sampling.samplesPerPass", mSamplesPerPass);
20  Environment::GetSingleton()->GetIntValue("Sampling.totalSamples", mTotalSamples);
21 
22  mStats.open("stats.log");
23}
24
25SamplingPreprocessor::~SamplingPreprocessor()
26{
27        CLEAR_CONTAINER(mSampleRays);
28        CLEAR_CONTAINER(mVssSampleRays);
29}
30
31void
32SamplingPreprocessor::SetupRay(Ray &ray,
33                                                           const Vector3 &point,
34                                                           const Vector3 &direction,
35                                                           const int type,
36                                                           const Ray::Intersection &origin)
37{
38  ray.Clear();
39 
40        ray.mFlags |= Ray::STORE_KDLEAVES | Ray::STORE_BSP_INTERSECTIONS;
41        //  cout<<point<<" "<<direction<<endl;
42
43        ray.Init(point, direction, type);
44        ray.sourceObject = origin;
45}
46
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
60 
61void
62SamplingPreprocessor::CastRays(const RayContainer &rays)
63{       
64  // cast ray to KD tree to find intersection with other objects
65  RayContainer::const_iterator it, it_end = rays.end();
66
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 
73  mViewCellsManager->ComputeSampleContributions(vssRays, true, false);
74  CLEAR_CONTAINER(vssRays);
75}
76
77int
78SamplingPreprocessor::CastRay(Ray &ray)
79{
80        // cast ray to KD tree to find intersection with other objects
81        mKdTree->CastRay(ray);
82        VssRay vssRay(ray);
83
84        mViewCellsManager->ComputeSampleContributions(vssRay, true, false);
85       
86        return vssRay.mPvsContribution;
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(
143                                                                          Intersectable *object,
144                                                                          const Vector3 &point,
145                                                                          MeshInstance *mi,
146                                                                          const int samples
147                                                                          )
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();
157                int face = (int)RandomValue(0, (Real)((int)mesh->mFaces.size() - 1));
158               
159                Polygon3 poly(mesh->mFaces[face], mesh);
160                poly.Scale(1.001f);
161                // now extend a random edge of the face
162                int edge = (int)RandomValue(0, (Real)((int)poly.mVertices.size() - 1));
163                float t = RandomValue(0.0f, 1.0f);
164                Vector3 target = t*poly.mVertices[edge] + (1.0f-t)*poly.mVertices[(edge + 1)%
165                        poly.mVertices.size()];
166                SetupRay(ray, point, target - point, Ray::LOCAL_RAY, Ray::Intersection(0, object, 0));
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++;
171                        edgeSamplesContributions += CastRay(ray);
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++) {
198                        int index = (int)RandomValue(0, (Real)(pvsSize - 1));
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 
249  /// rays per pass
250  RayContainer passRays;
251
252
253  mViewCellsManager->SetViewSpaceBox(mKdTree->GetBox());
254 
255  Vector3 point, normal, direction;
256  //Ray ray;
257
258  long startTime = GetTime();
259 
260  int i;
261  int totalSamples = 0;
262
263  int pvsSize = 0;
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               
273                for (i = 0; i < mObjects.size(); i++) {
274                                               
275                        KdNode *nodeToSample = NULL;
276                        Intersectable *object = mObjects[i];
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;
287                        //int sampleContributions;
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;
296                               
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;
308                                                        //Debug << "point: " << pointToSample << endl;
309                                                }
310                                        }
311                                        else {
312                                                direction = UniformRandomVector(normal);
313                                        }
314                                       
315                                        Ray *ray = new Ray();
316
317                                        // construct a ray
318                                        SetupRay(*ray, point, direction, Ray::LOCAL_RAY,
319                                                         Ray::Intersection(0, reverseSample ? NULL : object, faceIndex));
320
321                                        passRays.push_back(ray);
322                                       
323                                        //-- CORR matt: put block inside loop
324                                        /*if (sampleContributions) {
325                                                passContributingSamples ++;
326                                                passSampleContributions += sampleContributions;
327                                        }*/
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       
339                //-------------------
340                // cast rays for view cells construction
341                ProcessViewCells(passRays,
342                                                 mObjects,
343                                                 passSampleContributions,
344                                                 passContributingSamples);
345
346                CLEAR_CONTAINER(passRays);
347               
348                totalSamples += passSamples;
349               
350                //    if (pass>10)
351                //      HoleSamplingPass();
352   
353                mPass ++;
354       
355                pvsSize += passSampleContributions;
356               
357                float avgRayContrib = (passContributingSamples > 0) ?
358                        passSampleContributions / (float)passContributingSamples : 0;
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="
364                                 << (float)pvsSize /(float)mObjects.size() << endl
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 <<
374                        "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
375                        "#AvgRayContrib\n" << avgRayContrib << endl;
376        }
377       
378        //cout << "#totalKdPvsSize=" << mKdTree->CollectLeafPvs() << endl;
379       
380  //  HoleSamplingPass();
381        if (0) {
382                Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
383                exporter->SetExportRayDensity(true);
384                exporter->ExportKdTree(*mKdTree);
385                delete exporter;
386        }
387       
388        // construct view cells if not already constructed
389        if (!mViewCellsManager->ViewCellsConstructed())
390          mViewCellsManager->ConstructSubdivision(mObjects, mVssSampleRays);
391
392        // $$JB temporary removed
393        //      mViewCellsManager->PostProcess(objects, mSampleRays);
394       
395        //-- several visualizations and statistics
396        Debug << "view cells after post processing: " << endl;
397        mViewCellsManager->PrintStatistics(Debug);
398
399        //-- render simulation after merge
400        cout << "\nevaluating bsp view cells render time after merge ... ";
401       
402         mRenderSimulator->RenderScene();
403         SimulationStatistics ss;
404         mRenderSimulator->GetStatistics(ss);
405         
406         cout << " finished" << endl;
407         cout << ss << endl;
408         Debug << ss << endl;
409       
410        // $$JB temporary removed
411        //mViewCellsManager->Visualize(objects, mSampleRays);   
412   
413        return true;
414}
415
416void SamplingPreprocessor::ProcessViewCells(const RayContainer &newRays,
417                                                                                        const ObjectContainer &objects,
418                                                                                        int &sampleContributions,
419                                                                                        int &contributingSamples)
420{
421  // cast rays to view cells
422  CastRays(newRays);
423
424  // save rays for view cells construction
425  if (!mViewCellsManager->ViewCellsConstructed())
426        {
427          if ((int)mVssSampleRays.size() < mViewCellsManager->GetConstructionSamples())
428                {
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)));
433                }
434          else
435                {
436                  // construct view cells
437                  mViewCellsManager->ConstructSubdivision(objects, mVssSampleRays);
438                 
439                  // throw away samples
440                  //CLEAR_CONTAINER(mVssSampleRays);
441                }
442        }
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()))
446        {
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)));
451        }
452}
453
454}
Note: See TracBrowser for help on using the repository browser.