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

Revision 563, 12.5 KB checked in by bittner, 18 years ago (diff)

rss sampling changes, preprocessor::GenerateRays?

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