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

Revision 245, 9.1 KB checked in by bittner, 19 years ago (diff)

Merged sources with ViewCellBsp?

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
8SamplingPreprocessor::SamplingPreprocessor()
9{
10  // this should increase coherence of the samples
11  environment->GetIntValue("Sampling.samplesPerPass", mSamplesPerPass);
12  environment->GetIntValue("Sampling.totalSamples", mTotalSamples);
13  mKdPvsDepth = 100;
14  mStats.open("stats.log");
15
16}
17
18void
19SamplingPreprocessor::SetupRay(Ray &ray, const Vector3 &point, const Vector3 &direction)
20{
21  ray.intersections.clear();
22  ray.leaves.clear();
23  ray.meshes.clear();
24  //  cout<<point<<" "<<direction<<endl;
25  ray.Init(point, direction, Ray::LOCAL_RAY);
26}
27
28KdNode *
29SamplingPreprocessor::GetNodeForPvs(KdLeaf *leaf)
30{
31  KdNode *node = leaf;
32  while (node->mParent && node->mDepth > mKdPvsDepth)
33    node = node->mParent;
34  return node;
35}
36
37int
38SamplingPreprocessor::AddNodeSamples(Intersectable *object,
39                                     const Ray &ray,
40                                     const int pass)
41{
42  int contributingSamples = 0;
43  int j;
44  for (j=0; j < ray.leaves.size(); j++) {
45    KdNode *node = GetNodeForPvs( ray.leaves[j] );
46    contributingSamples += object->mKdPvs.AddNodeSample(node);
47  }
48 
49  if (pass > 10)
50    for (j=1; j < ray.leaves.size() - 1; j++) {
51      ray.leaves[j]->AddPassingRay(ray, contributingSamples ? 1 : 0);
52    }
53 
54  return contributingSamples;
55}
56
57
58void
59SamplingPreprocessor::HoleSamplingPass()
60{
61  vector<KdLeaf *> leaves;
62  mKdTree->CollectLeaves(leaves);
63 
64  // go through all the leaves and evaluate their passing contribution
65  for (int i=0 ; i < leaves.size(); i++) {
66    KdLeaf *leaf = leaves[i];
67    cout<<leaf->mPassingRays<<endl;
68  }
69}
70
71//  void
72//  SamplingPreprocessor::AvsGenerateRandomRay(Ray &ray)
73//  {
74//    int objId = RandomValue(0, mObjects.size());
75//    Intersectable *object = objects[objId];
76//    object->GetRandomSurfacePoint(point, normal);
77//    direction = UniformRandomVector(normal);
78//    SetupRay(ray, point, direction);
79//  }
80
81//  void
82//  SamplingPreprocessor::AvsHandleRay(Ray &ray)
83//  {
84//    int sampleContributions = 0;
85
86//    mKdTree->CastRay(ray);
87 
88//    if (ray.leaves.size()) {
89//      sampleContributions += AddNodeSamples(object, ray, pass);
90   
91//      if (ray.intersections.size()) {
92//        sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
93//      }
94//    }
95//  }
96
97//  void
98//  SamplingPreprocessor::AvsBorderSampling(Ray &ray)
99//  {
100 
101
102//  }
103
104//  void
105//  SamplingPreprocessor::AvsPass()
106//  {
107//    Ray ray;
108//    while (1) {
109//      AvsGenerateRay(ray);
110//      HandleRay(ray);
111//      while ( !mRayQueue.empty() ) {
112//        Ray ray = mRayQueue.pop();
113//        mRayQueue.pop();
114//        AdaptiveBorderSampling(ray);
115//      }
116//    }
117 
118 
119
120//  }
121
122
123
124bool
125SamplingPreprocessor::ComputeVisibility()
126{
127 
128  // pickup an object
129  ObjectContainer objects;
130 
131  mSceneGraph->CollectObjects(&objects);
132
133  Vector3 point, normal, direction;
134  Ray ray;
135
136  long startTime = GetTime();
137 
138  int i;
139  int pass = 0;
140  int totalSamples = 0;
141
142  int pvsOut = Min((int)objects.size(), 10);
143 
144  vector<Ray> rays[10];
145 
146  while (totalSamples < mTotalSamples)
147    {
148      int passContributingSamples = 0;
149      int passSampleContributions = 0;
150      int passSamples = 0;
151      int index = 0;
152
153      for (i =0; i < objects.size(); i++) {
154        KdNode *nodeToSample = NULL;
155        Intersectable *object = objects[i];
156       
157        int pvsSize = object->mKdPvs.GetSize();
158
159
160
161        if (0 && pvsSize) {
162          // mail all nodes from the pvs
163          Intersectable::NewMail();
164          KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
165                         
166          for (; i != object->mKdPvs.mEntries.end(); i++) {
167            KdNode *node = (*i).first;
168            node->Mail();
169          }
170
171          int maxTries = 2*pvsSize;
172       
173          for (int tries = 0; tries < 10; tries++) {
174            index = RandomValue(0, pvsSize - 1);
175            KdPvsData data;
176            KdNode *node;
177            object->mKdPvs.GetData(index, node, data);
178            nodeToSample = mKdTree->FindRandomNeighbor(node, true);
179            if (nodeToSample)
180              break;
181          }
182        }
183       
184        if (0 && pvsSize && pass == 1000 ) {
185          // mail all nodes from the pvs
186          Intersectable::NewMail();
187          KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
188          for (; i != object->mKdPvs.mEntries.end(); i++) {
189            KdNode *node = (*i).first;
190            node->Mail();
191          }
192       
193          vector<KdNode *> invisibleNeighbors;
194          // get all neighbors of all PVS nodes
195          i = object->mKdPvs.mEntries.begin();
196          for (; i != object->mKdPvs.mEntries.end(); i++) {
197            KdNode *node = (*i).first;
198            mKdTree->FindNeighbors(node, invisibleNeighbors, true);
199            AxisAlignedBox3 box = object->GetBox();
200            for (int j=0; j < invisibleNeighbors.size(); j++) {
201              int visibility = ComputeBoxVisibility(mSceneGraph,
202                                                    mKdTree,
203                                                    box,
204                                                    mKdTree->GetBox(invisibleNeighbors[j]),
205                                                    1e-6f);
206              //              exit(0);
207            }
208            // now rank all the neighbors according to probability that a new
209            // sample creates some contribution
210          }
211        }
212
213        object->GetRandomSurfacePoint(point, normal);
214        nodeToSample = mKdTree->GetRandomLeaf(Plane3(normal, point));
215
216        for (int k=0; k < mSamplesPerPass; k++) {
217         
218          if (nodeToSample) {
219            int maxTries = 5;
220           
221            for (int tries = 0; tries < maxTries; tries++) {
222              direction = mKdTree->GetBox(nodeToSample).GetRandomPoint() - point;
223             
224              if (DotProd(direction, normal) > Limits::Small)
225                break;
226            }
227           
228            if (tries == maxTries)
229              direction = UniformRandomVector(normal);
230          }
231          else {
232            direction = UniformRandomVector(normal);
233          }
234         
235          // construct a ray
236          SetupRay(ray, point, direction);
237          mKdTree->CastRay(ray);
238         
239          if ( i < pvsOut )
240            rays[i].push_back(ray);
241         
242          int sampleContributions = 0;
243         
244          if (ray.leaves.size()) {
245            sampleContributions += AddNodeSamples(object, ray, pass);
246           
247            if (ray.intersections.size()) {
248              sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
249              // check whether we can add this to the rays
250              for (int j = 0; j < pvsOut; j++) {
251                if (objects[j] == ray.intersections[0].mObject) {
252                  rays[j].push_back(ray);
253                }
254              }
255            }
256
257            passSamples++;
258                       
259            if (sampleContributions) {
260              passContributingSamples++;
261              passSampleContributions += sampleContributions;
262            }
263          }
264        }
265      }
266
267      totalSamples += passSamples;
268
269      //    if (pass>10)
270      //      HoleSamplingPass();
271   
272
273      pass++;
274   
275      int pvsSize = 0;
276      for (i=0; i < objects.size(); i++) {
277        Intersectable *object = objects[i];
278        pvsSize += object->mKdPvs.GetSize();
279      }
280   
281      cout << "#Pass " << pass<<" : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
282      cout << "#TotalSamples=" << totalSamples/1000
283           << "k   #SampleContributions=" << passSampleContributions << " ("
284           << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
285           << pvsSize/(float)objects.size() << endl
286           << "avg ray contrib=" << passSampleContributions/(float)passContributingSamples << endl;
287
288
289      mStats <<
290        "#Pass\n" <<pass<<endl<<
291        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
292        "#TotalSamples\n" << totalSamples<< endl<<
293        "#SampleContributions\n" << passSampleContributions << endl <<
294        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
295        "#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
296        "#AvgRayContrib\n" << passSampleContributions/(float)passContributingSamples << endl;
297    }
298
299  int totalPvsSize = mKdTree->CollectLeafPvs();
300  cout << "#totalPvsSize=" << totalPvsSize << endl;
301 
302  //  HoleSamplingPass();
303  if (1) {
304    Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
305    exporter->SetExportRayDensity(true);
306    exporter->ExportKdTree(*mKdTree);
307        exporter->ExportBspTree(*mBspTree);
308
309    delete exporter;
310  }
311 
312  bool exportRays = false;
313  if (exportRays) {
314    Exporter *exporter = NULL;
315    exporter = Exporter::GetExporter("sample-rays.x3d");
316    exporter->SetWireframe();
317    exporter->ExportKdTree(*mKdTree);
318        exporter->ExportBspTree(*mBspTree);
319
320    for (i=0; i < pvsOut; i++)
321      exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
322    exporter->SetFilled();
323         
324    delete exporter;
325  }
326
327  if (1) {
328    for (int k=0; k < pvsOut; k++) {
329      Intersectable *object = objects[k];
330      char s[64];
331      sprintf(s, "sample-pvs%04d.x3d", k);
332      Exporter *exporter = Exporter::GetExporter(s);
333      exporter->SetWireframe();
334      KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
335                 
336      Intersectable::NewMail();
337                 
338      // avoid adding the object to the list
339      object->Mail();
340      ObjectContainer visibleObjects;
341      for (; i != object->mKdPvs.mEntries.end(); i++) {
342        KdNode *node = (*i).first;
343        exporter->ExportBox(mKdTree->GetBox(node));
344        mKdTree->CollectObjects(node, visibleObjects);
345      }
346     
347      exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
348      exporter->SetFilled();
349
350      for (int j = 0; j < visibleObjects.size(); j++)
351        exporter->ExportIntersectable(visibleObjects[j]);
352       
353      Material m;
354      m.mDiffuseColor = RgbColor(1, 0, 0);
355      exporter->SetForcedMaterial(m);
356      exporter->ExportIntersectable(object);
357     
358      delete exporter;
359    }
360  }
361 
362  return true;
363}
364
365 
366
367   
Note: See TracBrowser for help on using the repository browser.