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

Revision 473, 12.4 KB checked in by mattausch, 19 years ago (diff)

worked on new features,
removed Random Bug (took only 32000 values),
removed bug when choosing new candidates (totally wrong)
introduced new candidate plane method
implemented priority queue for vsp bsp

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, (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, (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, 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        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.