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

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

removed compiler errors

Line 
1#include "SceneGraph.h"
2#include "KdTree.h"
3#include "SamplingPreprocessor.h"
4#include "X3dExporter.h"
5#include "Environment.h"
6SamplingPreprocessor::SamplingPreprocessor()
7{
8  // this should increase coherence of the samples
9  environment->GetIntValue("Sampling.samplesPerPass", mSamplesPerPass);
10  environment->GetIntValue("Sampling.totalSamples", mTotalSamples);
11  mKdPvsDepth = 100;
12
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  }
43 
44  return contributingSamples;
45}
46
47bool
48SamplingPreprocessor::ComputeVisibility()
49{
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;
75        int index = 0;
76    KdNode *visibleNode = NULL;
77
78    for (i =0; i < objects.size(); i++) {
79      KdNode *nodeToSample = NULL;
80      Intersectable *object = objects[i];
81
82      int pvsSize = object->mKdPvs.GetSize();
83     
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                }
102        }
103
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                }
120
121                KdPvsData data;
122                KdNode *visibleNode;
123                object->mKdPvs.GetData(index, visibleNode, data);
124                nodeToSample = mKdTree->FindRandomNeighbor(visibleNode, true);
125                if (nodeToSample)
126                        break;
127      }
128     
129
130      for (int k=0; k < mSamplesPerPass; k++) {
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);
144       
145                  // construct a ray
146                  SetupRay(ray, point, direction);
147                  mKdTree->CastRay(ray);
148
149                  if (i < pvsOut)
150                          rays[i].push_back(ray);
151       
152                  int sampleContributions = 0;
153       
154                 
155                  if (ray.leaves.size()) {
156                          sampleContributions += AddNodeSamples(object, ray);
157         
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                  }
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];
183      pvsSize += object->mKdPvs.GetSize();
184    }
185   
186    cout<<"pass "<<pass<<" : t = "<<TimeDiff(startTime, GetTime())*1e-3<<"s"<<endl;
187    cout<<"#totalSamples="<<totalSamples/1000<<
188      "k   #sampleContributions="<<passSampleContributions<<
189      " ("<<100*passContributingSamples/(float)passSamples<<"%)"<<
190      " avgPVS="<<pvsSize/(float)objects.size()<<endl<<
191      "avg ray contrib="<<passSampleContributions/(float)passContributingSamples<<
192      endl;
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 
240  return true;
241}
242
243 
244
245   
Note: See TracBrowser for help on using the repository browser.