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

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