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

Revision 218, 7.4 KB checked in by mattausch, 19 years ago (diff)

fixed line indent (was messed up with the visual studio)

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                         
110                          for (; i != object->mKdPvs.mEntries.end(); i++) {
111                                  KdNode *node = (*i).first;
112                                  node->Mail();
113                          }
114
115                          int maxTries = 2*pvsSize;
116       
117                          for (int tries = 0; tries < 10; tries++) {
118                                  index = RandomValue(0, pvsSize - 1);
119                                  KdPvsData data;
120                                  KdNode *node;
121                                  object->mKdPvs.GetData(index, node, data);
122                                  nodeToSample = mKdTree->FindRandomNeighbor(node, true);
123                                  if (nodeToSample)
124                                          break;
125                          }
126                  }
127     
128              if (0 && pvsSize && pass == 50)  {
129                          // mail all nodes from the pvs
130                          Intersectable::NewMail();
131                          KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
132                          for (; i != object->mKdPvs.mEntries.end(); i++) {
133                                  KdNode *node = (*i).first;
134                                  node->Mail();
135                          }
136
137                          vector<KdNode *> invisibleNeighbors;
138                          // get all neighbors of all PVS nodes
139                          i = object->mKdPvs.mEntries.begin();
140
141                          for (; i != object->mKdPvs.mEntries.end(); i++) {
142                                  KdNode *node = (*i).first;
143                                  mKdTree->FindNeighbors(node, invisibleNeighbors, true);
144                                  AxisAlignedBox3 box = object->GetBox();
145                                 
146                                  for (int j=0; j < invisibleNeighbors.size(); j++)
147                                  {
148                                          int visibility = ComputeBoxVisibility(mKdTree,
149                                                                                                                        box,
150                                                                                                                        mKdTree->GetBox(invisibleNeighbors[j]),
151                                                                                                                        1.0f);
152                                  }
153                                  // now rank all the neighbors according to probability that a new
154                                  // sample creates some contribution
155                          }
156                  }
157
158                  for (int k=0; k < mSamplesPerPass; k++) {
159                          object->GetRandomSurfacePoint(point, normal);
160                         
161                          if (nodeToSample) {
162                                  int maxTries = 5;
163                                 
164                                  for (int tries = 0; tries < maxTries; tries++) {
165                                          direction = mKdTree->GetBox(nodeToSample).GetRandomPoint() - point;
166
167                                          if (DotProd(direction, normal) > Limits::Small)
168                                                  break;
169                                  }
170               
171                                  if (tries == maxTries)
172                                          direction = UniformRandomVector(normal);
173                          }
174                          else
175                                  direction = UniformRandomVector(normal);
176       
177                          // construct a ray
178                          SetupRay(ray, point, direction);
179                          mKdTree->CastRay(ray);
180
181                          if (i < pvsOut)
182                                  rays[i].push_back(ray);
183       
184                          int sampleContributions = 0;
185       
186                 
187                          if (ray.leaves.size()) {
188                                  sampleContributions += AddNodeSamples(object, ray, pass);
189         
190                                  if (ray.intersections.size()) {
191                                          sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray, pass);
192                                          // check whether we can add this to the rays
193                                          for (int j = 0; j < pvsOut; j++) {
194                                                  if (objects[j] == ray.intersections[0].mObject) {
195                                                          rays[j].push_back(ray);
196                                                  }
197                                          }
198                                  }
199
200                                  passSamples++;
201                       
202                                  if (sampleContributions) {
203                                          passContributingSamples++;
204                                          passSampleContributions += sampleContributions;
205                                  }
206                          }
207                  }
208        }
209
210    totalSamples += passSamples;
211
212    //    if (pass>10)
213    //      HoleSamplingPass();
214   
215
216    pass++;
217   
218    int pvsSize = 0;
219    for (i=0; i < objects.size(); i++) {
220                Intersectable *object = objects[i];
221                pvsSize += object->mKdPvs.GetSize();
222    }
223   
224        cout << "pass " << pass<<" : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
225        cout << "#totalSamples=" << totalSamples/1000
226                 << "k   #sampleContributions=" << passSampleContributions << " ("
227                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
228                 << pvsSize/(float)objects.size() << endl
229                 << "avg ray contrib=" << passSampleContributions/(float)passContributingSamples << endl;
230  }
231
232  int totalPvsSize = mKdTree->CollectLeafPvs();
233  cout << "#totalPvsSize=" << totalPvsSize << endl;
234 
235  //  HoleSamplingPass();
236  if (1) {
237          Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
238          exporter->SetExportRayDensity(true);
239          exporter->ExportKdTree(*mKdTree);
240          delete exporter;
241  }
242 
243  bool exportRays = false;
244  if (exportRays) {
245          Exporter *exporter = NULL;
246          exporter = Exporter::GetExporter("sample-rays.x3d");
247          exporter->SetWireframe();
248          exporter->ExportKdTree(*mKdTree);
249
250          for (i=0; i < pvsOut; i++)
251                  exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
252          exporter->SetFilled();
253         
254          delete exporter;
255  }
256
257  if (1) {
258          for (int k=0; k < pvsOut; k++) {
259                  Intersectable *object = objects[k];
260                  char s[64];
261                  sprintf(s, "sample-pvs%04d.x3d", k);
262                  Exporter *exporter = Exporter::GetExporter(s);
263                  exporter->SetWireframe();
264                  KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
265                 
266                  Intersectable::NewMail();
267                 
268                  // avoid adding the object to the list
269                  object->Mail();
270                  ObjectContainer visibleObjects;
271                  for (; i != object->mKdPvs.mEntries.end(); i++) {
272                          KdNode *node = (*i).first;
273                          exporter->ExportBox(mKdTree->GetBox(node));
274                          mKdTree->CollectObjects(node, visibleObjects);
275                  }
276     
277                  exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
278                  exporter->SetFilled();
279
280                  for (int j = 0; j < visibleObjects.size(); j++)
281                          exporter->ExportIntersectable(visibleObjects[j]);
282       
283                  Material m;
284                  m.mDiffuseColor = RgbColor(1, 0, 0);
285                  exporter->SetForcedMaterial(m);
286                  exporter->ExportIntersectable(object);
287     
288                  delete exporter;
289          }
290  }
291 
292  return true;
293}
294
295 
296
297   
Note: See TracBrowser for help on using the repository browser.