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

Revision 477, 12.5 KB checked in by mattausch, 19 years ago (diff)

changed render simulator (probability that view cell is crossed)

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);
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  // pickup an object
245  ObjectContainer objects;
246 
247  /// rays per pass
248  RayContainer passRays;
249
250  mSceneGraph->CollectObjects(&objects);
251
252  Vector3 point, normal, direction;
253  //Ray ray;
254
255  long startTime = GetTime();
256 
257  int i;
258  int totalSamples = 0;
259
260  int pvsSize = 0;
261
262  while (totalSamples < mTotalSamples) {
263                int passContributingSamples = 0;
264                int passSampleContributions = 0;
265                int passSamples = 0;
266                int index = 0;
267               
268                int reverseSamples = 0;
269               
270                for (i = 0; i < objects.size(); i++) {
271                                               
272                        KdNode *nodeToSample = NULL;
273                        Intersectable *object = objects[i];
274               
275                        int pvsSize = 0;
276                       
277                        if (0 && pvsSize && mPass == 1000 ) {
278                                VerifyVisibility(object);
279                        }
280                       
281                        int faceIndex = object->GetRandomSurfacePoint(point, normal);
282                       
283                        bool viewcellSample = true;
284                        //int sampleContributions;
285                        bool debug = false; //(object->GetId() >= 2199);
286                        if (viewcellSample) {
287                                //mKdTree->GetRandomLeaf(Plane3(normal, point));
288
289                                nodeToSample = GetNodeToSample(object);
290
291                                for (int k=0; k < mSamplesPerPass; k++) {
292                                        bool reverseSample = false;
293                               
294                                        if (nodeToSample) {
295                                                AxisAlignedBox3 box = mKdTree->GetBox(nodeToSample);
296                                                Vector3 pointToSample = box.GetRandomPoint();
297                                                //                                              pointToSample.y = 0.9*box.Min().y + 0.1*box.Max().y;
298                                                if (object->GetRandomVisibleSurfacePoint( point, normal, pointToSample, 3 )) {
299                                                        direction = pointToSample - point;
300                                                } else {
301                                                        reverseSamples++;
302                                                        reverseSample = true;
303                                                        direction = point - pointToSample;
304                                                        point = pointToSample;
305                                                        //Debug << "point: " << pointToSample << endl;
306                                                }
307                                        }
308                                        else {
309                                                direction = UniformRandomVector(normal);
310                                        }
311                                       
312                                        Ray *ray = new Ray();
313
314                                        // construct a ray
315                                        SetupRay(*ray, point, direction, Ray::LOCAL_RAY,
316                                                         Ray::Intersection(0, reverseSample ? NULL : object, faceIndex));
317
318                                        passRays.push_back(ray);
319                                       
320                                        //-- CORR matt: put block inside loop
321                                        /*if (sampleContributions) {
322                                                passContributingSamples ++;
323                                                passSampleContributions += sampleContributions;
324                                        }*/
325                                }
326                        } else {
327                                // edge samples
328                                // get random visible mesh
329                                //                              object->GetRandomVisibleMesh(Plane3(normal, point));
330                        }
331       
332                        // CORR matt: must add all samples
333                        passSamples += mSamplesPerPass;
334                }
335       
336                //-------------------
337                // cast rays for view cells construction
338                ProcessViewCells(passRays,
339                                                 objects,
340                                                 passSampleContributions,
341                                                 passContributingSamples);
342
343                CLEAR_CONTAINER(passRays);
344               
345                totalSamples += passSamples;
346               
347                //    if (pass>10)
348                //      HoleSamplingPass();
349   
350                mPass ++;
351       
352                pvsSize += passSampleContributions;
353               
354                float avgRayContrib = (passContributingSamples > 0) ?
355                        passSampleContributions / (float)passContributingSamples : 0;
356
357                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
358                cout << "#TotalSamples=" << totalSamples/1000
359                                 << "k   #SampleContributions=" << passSampleContributions << " ("
360                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
361                                 << (float)pvsSize /(float)objects.size() << endl
362                                 << "avg ray contrib=" << avgRayContrib << endl
363                                 << "reverse samples [%]" << reverseSamples/(float)passSamples*100.0f << endl;
364
365                mStats <<
366                        "#Pass\n" <<mPass<<endl<<
367                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
368                        "#TotalSamples\n" << totalSamples<< endl<<
369                        "#SampleContributions\n" << passSampleContributions << endl <<
370                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
371                        "#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
372                        "#AvgRayContrib\n" << avgRayContrib << endl;
373        }
374       
375        //cout << "#totalKdPvsSize=" << mKdTree->CollectLeafPvs() << endl;
376       
377  //  HoleSamplingPass();
378        if (0) {
379                Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
380                exporter->SetExportRayDensity(true);
381                exporter->ExportKdTree(*mKdTree);
382                delete exporter;
383        }
384       
385        // construct view cells if not already constructed
386        if (!mViewCellsManager->ViewCellsConstructed())
387                mViewCellsManager->Construct(objects, mVssSampleRays);
388
389        // $$JB temporary removed
390        //      mViewCellsManager->PostProcess(objects, mSampleRays);
391       
392        //-- several visualizations and statistics
393        Debug << "view cells after post processing: " << endl;
394        mViewCellsManager->PrintStatistics(Debug);
395
396        //-- render simulation after merge
397        cout << "\nevaluating bsp view cells render time after merge ... ";
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->Construct(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}
Note: See TracBrowser for help on using the repository browser.