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

Revision 181, 6.2 KB checked in by bittner, 19 years ago (diff)

bug with find neighbors fixed

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     
85    if (pvsSize) {
86                // mail all nodes from the pvs
87                Intersectable::NewMail();
88                KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
89                for (; i != object->mKdPvs.mEntries.end(); i++) {
90                        KdNode *node = (*i).first;
91                        node->Mail();
92                }
93                int maxTries = 2*pvsSize;
94       
95                for (int tries = 0; tries < 10; tries++) {
96                        index = RandomValue(0, pvsSize - 1);
97                        KdPvsData data;
98                        object->mKdPvs.GetData(index, visibleNode, data);
99                        nodeToSample = mKdTree->FindRandomNeighbor(visibleNode, true);
100                        if (nodeToSample)
101                        break;
102                }
103        }
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       
114                vector<KdNode *> invisibleNeighbors;
115                // get all neighbors of all PVS nodes
116                i = object->mKdPvs.mEntries.begin();
117                for (; i != object->mKdPvs.mEntries.end(); i++) {
118                        KdNode *node = (*i).first;
119                        mKdTree->FindNeighbors(visibleNode, invisibleNeighbors, true);
120                }
121
122                KdPvsData data;
123                KdNode *visibleNode;
124                object->mKdPvs.GetData(index, visibleNode, data);
125                nodeToSample = mKdTree->FindRandomNeighbor(visibleNode, true);
126                if (nodeToSample)
127                        break;
128      }
129     
130
131      for (int k=0; k < mSamplesPerPass; k++) {
132                  object->GetRandomSurfacePoint(point, normal);
133                  if (nodeToSample) {
134                          int maxTries = 5;
135                          for (int tries = 0; tries < maxTries; tries++) {
136                                  direction = mKdTree->GetBox(nodeToSample).GetRandomPoint() - point;
137                                  if (DotProd(direction, normal) > Limits::Small)
138                                        break;
139                          }
140               
141                          if (tries == maxTries)
142                                  direction = UniformRandomVector(normal);
143                  } else
144                          direction = UniformRandomVector(normal);
145       
146                  // construct a ray
147                  SetupRay(ray, point, direction);
148                  mKdTree->CastRay(ray);
149
150                  if (i < pvsOut)
151                          rays[i].push_back(ray);
152       
153                  int sampleContributions = 0;
154       
155                 
156                  if (ray.leaves.size()) {
157                          sampleContributions += AddNodeSamples(object, ray);
158         
159                          if (ray.intersections.size()) {
160                                  sampleContributions += AddNodeSamples(ray.intersections[0].mObject, ray);
161                                  // check whether we can add this to the rays
162                                  for (int j = 0; j < pvsOut; j++) {
163                                          if (objects[j] == ray.intersections[0].mObject) {
164                                                  rays[j].push_back(ray);
165                                          }
166                                  }
167                          }
168               
169                          passSamples++;
170                       
171                          if (sampleContributions) {
172                                  passContributingSamples++;
173                                  passSampleContributions += sampleContributions;
174                          }
175                  }
176          }
177        }
178    totalSamples += passSamples;
179    pass++;
180   
181    int pvsSize = 0;
182    for (i=0; i < objects.size(); i++) {
183      Intersectable *object = objects[i];
184      pvsSize += object->mKdPvs.GetSize();
185    }
186   
187    cout<<"pass "<<pass<<" : t = "<<TimeDiff(startTime, GetTime())*1e-3<<"s"<<endl;
188    cout<<"#totalSamples="<<totalSamples/1000<<
189      "k   #sampleContributions="<<passSampleContributions<<
190      " ("<<100*passContributingSamples/(float)passSamples<<"%)"<<
191      " avgPVS="<<pvsSize/(float)objects.size()<<endl<<
192      "avg ray contrib="<<passSampleContributions/(float)passContributingSamples<<
193      endl;
194  }
195  bool exportRays = false;
196  if (exportRays) {
197    Exporter *exporter = NULL;
198    exporter = Exporter::GetExporter("sample-rays.x3d");
199    exporter->SetWireframe();
200    exporter->ExportKdTree(*mKdTree);
201    for (i=0; i < pvsOut; i++)
202      exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
203    exporter->SetFilled();
204    delete exporter;
205  }
206
207  if (1) {
208    for (int k=0; k < pvsOut; k++) {
209      Intersectable *object = objects[k];
210      char s[64];
211      sprintf(s, "sample-pvs%04d.x3d", k);
212      Exporter *exporter = Exporter::GetExporter(s);
213      exporter->SetWireframe();
214      KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
215      Intersectable::NewMail();
216        // avoid adding the object to the list
217      object->Mail();
218      ObjectContainer visibleObjects;
219      for (; i != object->mKdPvs.mEntries.end(); i++) {
220        KdNode *node = (*i).first;
221        exporter->ExportBox(mKdTree->GetBox(node));
222        mKdTree->CollectObjects(node, visibleObjects);
223      }
224     
225      exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
226      exporter->SetFilled();
227
228      for (int j = 0; j < visibleObjects.size(); j++)
229        exporter->ExportIntersectable(visibleObjects[j]);
230       
231      Material m;
232      m.mDiffuseColor = RgbColor(1, 0, 0);
233      exporter->SetForcedMaterial(m);
234      exporter->ExportIntersectable(object);
235     
236      delete exporter;
237    }
238   
239  }
240 
241  return true;
242}
243
244 
245
246   
Note: See TracBrowser for help on using the repository browser.