source: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp @ 1112

Revision 1112, 11.4 KB checked in by bittner, 18 years ago (diff)

Merge with Olivers code

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