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

Revision 191, 7.2 KB checked in by bittner, 19 years ago (diff)

basic sampling strategies

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