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

Revision 257, 10.3 KB checked in by bittner, 19 years ago (diff)

preparing for edge based sampling. new data files added

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