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

Revision 179, 6.2 KB checked in by mattausch, 19 years ago (diff)

removed compiler errors

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