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

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

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