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

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

fixed bug in raycasting
added valid view point regions, get view point only from valid regions

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  mViewCellsManager->SetViewSpaceBox(mKdTree->GetBox());
253 
254  Vector3 point, normal, direction;
255  //Ray ray;
256
257  long startTime = GetTime();
258 
259  int i;
260  int totalSamples = 0;
261
262  int pvsSize = 0;
263
264  while (totalSamples < mTotalSamples) {
265                int passContributingSamples = 0;
266                int passSampleContributions = 0;
267                int passSamples = 0;
268                int index = 0;
269               
270                int reverseSamples = 0;
271               
272                for (i = 0; i < objects.size(); i++) {
273                                               
274                        KdNode *nodeToSample = NULL;
275                        Intersectable *object = objects[i];
276               
277                        int pvsSize = 0;
278                       
279                        if (0 && pvsSize && mPass == 1000 ) {
280                                VerifyVisibility(object);
281                        }
282                       
283                        int faceIndex = object->GetRandomSurfacePoint(point, normal);
284                       
285                        bool viewcellSample = true;
286                        //int sampleContributions;
287                        bool debug = false; //(object->GetId() >= 2199);
288                        if (viewcellSample) {
289                                //mKdTree->GetRandomLeaf(Plane3(normal, point));
290
291                                nodeToSample = GetNodeToSample(object);
292
293                                for (int k=0; k < mSamplesPerPass; k++) {
294                                        bool reverseSample = false;
295                               
296                                        if (nodeToSample) {
297                                                AxisAlignedBox3 box = mKdTree->GetBox(nodeToSample);
298                                                Vector3 pointToSample = box.GetRandomPoint();
299                                                //                                              pointToSample.y = 0.9*box.Min().y + 0.1*box.Max().y;
300                                                if (object->GetRandomVisibleSurfacePoint( point, normal, pointToSample, 3 )) {
301                                                        direction = pointToSample - point;
302                                                } else {
303                                                        reverseSamples++;
304                                                        reverseSample = true;
305                                                        direction = point - pointToSample;
306                                                        point = pointToSample;
307                                                        //Debug << "point: " << pointToSample << endl;
308                                                }
309                                        }
310                                        else {
311                                                direction = UniformRandomVector(normal);
312                                        }
313                                       
314                                        Ray *ray = new Ray();
315
316                                        // construct a ray
317                                        SetupRay(*ray, point, direction, Ray::LOCAL_RAY,
318                                                         Ray::Intersection(0, reverseSample ? NULL : object, faceIndex));
319
320                                        passRays.push_back(ray);
321                                       
322                                        //-- CORR matt: put block inside loop
323                                        /*if (sampleContributions) {
324                                                passContributingSamples ++;
325                                                passSampleContributions += sampleContributions;
326                                        }*/
327                                }
328                        } else {
329                                // edge samples
330                                // get random visible mesh
331                                //                              object->GetRandomVisibleMesh(Plane3(normal, point));
332                        }
333       
334                        // CORR matt: must add all samples
335                        passSamples += mSamplesPerPass;
336                }
337       
338                //-------------------
339                // cast rays for view cells construction
340                ProcessViewCells(passRays,
341                                                 objects,
342                                                 passSampleContributions,
343                                                 passContributingSamples);
344
345                CLEAR_CONTAINER(passRays);
346               
347                totalSamples += passSamples;
348               
349                //    if (pass>10)
350                //      HoleSamplingPass();
351   
352                mPass ++;
353       
354                pvsSize += passSampleContributions;
355               
356                float avgRayContrib = (passContributingSamples > 0) ?
357                        passSampleContributions / (float)passContributingSamples : 0;
358
359                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
360                cout << "#TotalSamples=" << totalSamples/1000
361                                 << "k   #SampleContributions=" << passSampleContributions << " ("
362                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
363                                 << (float)pvsSize /(float)objects.size() << endl
364                                 << "avg ray contrib=" << avgRayContrib << endl
365                                 << "reverse samples [%]" << reverseSamples/(float)passSamples*100.0f << endl;
366
367                mStats <<
368                        "#Pass\n" <<mPass<<endl<<
369                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
370                        "#TotalSamples\n" << totalSamples<< endl<<
371                        "#SampleContributions\n" << passSampleContributions << endl <<
372                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
373                        "#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
374                        "#AvgRayContrib\n" << avgRayContrib << endl;
375        }
376       
377        //cout << "#totalKdPvsSize=" << mKdTree->CollectLeafPvs() << endl;
378       
379  //  HoleSamplingPass();
380        if (0) {
381                Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
382                exporter->SetExportRayDensity(true);
383                exporter->ExportKdTree(*mKdTree);
384                delete exporter;
385        }
386       
387        // construct view cells if not already constructed
388        if (!mViewCellsManager->ViewCellsConstructed())
389                mViewCellsManager->Construct(objects, mVssSampleRays);
390
391        // $$JB temporary removed
392        //      mViewCellsManager->PostProcess(objects, mSampleRays);
393       
394        //-- several visualizations and statistics
395        Debug << "view cells after post processing: " << endl;
396        mViewCellsManager->PrintStatistics(Debug);
397
398        //-- render simulation after merge
399        cout << "\nevaluating bsp view cells render time after merge ... ";
400                 
401         //-- render simulation after merge
402        cout << "\nevaluating bsp view cells render time after merge ... ";
403       
404         mRenderSimulator->RenderScene();
405         SimulationStatistics ss;
406         mRenderSimulator->GetStatistics(ss);
407         
408         cout << " finished" << endl;
409         cout << ss << endl;
410         Debug << ss << endl;
411       
412        // $$JB temporary removed
413        //mViewCellsManager->Visualize(objects, mSampleRays);   
414   
415        return true;
416}
417
418void SamplingPreprocessor::ProcessViewCells(const RayContainer &newRays,
419                                                                                        const ObjectContainer &objects,
420                                                                                        int &sampleContributions,
421                                                                                        int &contributingSamples)
422{
423  // cast rays to view cells
424  CastRays(newRays);
425
426  // save rays for view cells construction
427  if (!mViewCellsManager->ViewCellsConstructed())
428        {
429          if ((int)mVssSampleRays.size() < mViewCellsManager->GetConstructionSamples())
430                {
431                  RayContainer::const_iterator it, it_end = newRays.end();
432                 
433                  for (it = newRays.begin(); it != it_end; ++ it)
434                        mVssSampleRays.push_back(new VssRay(*(*it)));
435                }
436          else
437                {
438                  // construct view cells
439                  mViewCellsManager->Construct(objects, mVssSampleRays);
440                 
441                  // throw away samples
442                  //CLEAR_CONTAINER(mVssSampleRays);
443                }
444        }
445  // Need rays (with ordered intersections) for post processing => collect new rays
446  if (((int)mSampleRays.size() < mViewCellsManager->GetPostProcessSamples()) ||
447          ((int)mSampleRays.size() < mViewCellsManager->GetVisualizationSamples()))
448        {
449          RayContainer::const_iterator it, it_end = newRays.end();
450         
451          for (it = newRays.begin(); it != it_end; ++ it)
452                mSampleRays.push_back(new Ray(*(*it)));
453        }
454}
Note: See TracBrowser for help on using the repository browser.