source: trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp @ 374

Revision 374, 8.4 KB checked in by bittner, 19 years ago (diff)
Line 
1#include "SceneGraph.h"
2#include "KdTree.h"
3#include "VssPreprocessor.h"
4#include "X3dExporter.h"
5#include "Environment.h"
6#include "MutualVisibility.h"
7#include "Polygon3.h"
8#include "ViewCell.h"
9
10VssPreprocessor::VssPreprocessor():
11        mPass(0),
12        mSampleRays(NULL)
13{
14  // this should increase coherence of the samples
15  environment->GetIntValue("Sampling.samplesPerPass", mSamplesPerPass);
16  environment->GetIntValue("Sampling.totalSamples", mTotalSamples);
17  mKdPvsDepth = 100;
18  mStats.open("stats.log");
19
20}
21
22VssPreprocessor::~VssPreprocessor()
23{
24        CLEAR_CONTAINER(mSampleRays);
25}
26
27void
28VssPreprocessor::SetupRay(Ray &ray,
29                                                                                                        const Vector3 &point,
30                                                                                                        const Vector3 &direction
31                                                                                                        )
32{
33  ray.intersections.clear();
34        // do not store anything else then intersections at the ray
35        ray.kdLeaves.clear();
36        ray.mFlags = Ray::STORE_KDLEAVES;
37       
38  //  cout<<point<<" "<<direction<<endl;
39  ray.Init(point, direction, Ray::LOCAL_RAY);
40}
41
42KdNode *
43VssPreprocessor::GetNodeForPvs(KdLeaf *leaf)
44{
45  KdNode *node = leaf;
46  while (node->mParent && node->mDepth > mKdPvsDepth)
47    node = node->mParent;
48  return node;
49}
50
51
52int
53VssPreprocessor::AddNodeSamples(const Ray &ray,
54                                                                                                                                Intersectable *sObject,
55                                                                                                                                Intersectable *tObject
56                                                                                                                                )
57{
58  int contributingSamples = 0;
59  int j;
60        int objects = 0;
61        if (sObject)
62                objects++;
63        if (tObject)
64                objects++;
65       
66        if (objects) {
67                for (j=0; j < ray.kdLeaves.size(); j++) {
68                        KdNode *node = GetNodeForPvs( ray.kdLeaves[j] );
69                        if (sObject)
70                                contributingSamples += sObject->mKdPvs.AddSample(node);
71                        if (tObject)
72                                contributingSamples += tObject->mKdPvs.AddSample(node);
73                }
74        }
75       
76        for (j=1; j < ((int)ray.kdLeaves.size() - 1); j++) {
77                ray.kdLeaves[j]->AddPassingRay2(ray,
78                                                                                                                                                objects,
79                                                                                                                                                ray.kdLeaves.size()
80                                                                                                                                                );
81  }
82 
83  return contributingSamples;
84}
85
86
87
88
89int
90VssPreprocessor::CastRay(Intersectable *object,
91                                                                                                 Ray &ray
92                                                                                                 )
93{
94        int sampleContributions = 0;
95
96        long t1 = GetRealTime();
97        // cast ray to KD tree to find intersection with other objects
98        mKdTree->CastRay(ray);
99        long t2 = GetRealTime();
100
101        if (0 && object && object->GetId() > 2197) {
102                object->Describe(cout)<<endl;
103                cout<<ray<<endl;
104        }
105
106        if (ray.kdLeaves.size()) {
107                Intersectable *terminator =
108                        ray.intersections.size() ? ray.intersections[0].mObject: NULL;
109               
110                sampleContributions += AddNodeSamples(ray,
111                                                                                                                                                                        object,
112                                                                                                                                                                        terminator);
113        }
114       
115       
116        return sampleContributions;
117}
118
119
120KdNode *
121VssPreprocessor::GetNodeToSample(Intersectable *object)
122{
123        int pvsSize = object->mKdPvs.GetSize();
124        KdNode *nodeToSample = NULL;
125       
126        // just pickup a random node
127        nodeToSample = mKdTree->GetRandomLeaf();
128        return nodeToSample;
129}
130
131bool
132VssPreprocessor::ComputeVisibility()
133{
134 
135  // pickup an object
136  ObjectContainer objects;
137 
138  mSceneGraph->CollectObjects(&objects);
139
140  Vector3 point, normal, direction;
141  Ray ray;
142
143  long startTime = GetTime();
144 
145  int i;
146  int totalSamples = 0;
147
148  int pvsOut = Min((int)objects.size(), 10);
149
150  vector<Ray> rays[10];
151
152  while (totalSamples < mTotalSamples) {
153                int passContributingSamples = 0;
154                int passSampleContributions = 0;
155                int passSamples = 0;
156                int index = 0;
157               
158                int reverseSamples = 0;
159               
160                       
161                //cout << "totalSamples: "  << totalSamples << endl;
162
163                for (i = 0; i < objects.size(); i++) {
164                                               
165                        KdNode *nodeToSample = NULL;
166                        Intersectable *object = objects[i];
167               
168                        int pvsSize = 0;
169                        if (ViewCell::sHierarchy == ViewCell::KD)
170                                pvsSize = object->mKdPvs.GetSize();
171                                               
172                       
173                       
174                        int faceIndex = object->GetRandomSurfacePoint(point, normal);
175                       
176                        bool viewcellSample = true;
177                        int sampleContributions;
178                        bool debug = false; //(object->GetId() >= 2199);
179                        if (viewcellSample) {
180                                //mKdTree->GetRandomLeaf(Plane3(normal, point));
181
182                                nodeToSample = GetNodeToSample(object);
183
184                                for (int k=0; k < mSamplesPerPass; k++) {
185                                        bool reverseSample = false;
186                                       
187
188                                        if (nodeToSample) {
189                                                AxisAlignedBox3 box = mKdTree->GetBox(nodeToSample);
190                                                Vector3 pointToSample = box.GetRandomPoint();
191                                                //                                              pointToSample.y = 0.9*box.Min().y + 0.1*box.Max().y;
192                                                if (object->GetRandomVisibleSurfacePoint( point, normal, pointToSample, 3 )) {
193                                                        direction = pointToSample - point;
194                                                } else {
195                                                        reverseSamples++;
196                                                        reverseSample = true;
197                                                        direction = point - pointToSample;
198                                                        point = pointToSample;
199                                                }
200                                        }
201                                        else {
202                                                direction = UniformRandomVector(normal);
203                                        }
204                                       
205                                        // construct a ray
206                                        SetupRay(ray, point, direction);
207                                       
208                                        sampleContributions = CastRay(reverseSample ? NULL : object, ray);
209                                       
210                                        //-- CORR matt: put block inside loop
211                                        if (sampleContributions) {
212                                                passContributingSamples ++;
213                                                passSampleContributions += sampleContributions;
214                                        }
215
216                                        if ( i < pvsOut )
217                                                rays[i].push_back(ray);
218               
219                                        if (!ray.intersections.empty()) {
220                                                // check whether we can add this to the rays
221                                                for (int j = 0; j < pvsOut; j++) {
222                                                        if (objects[j] == ray.intersections[0].mObject) {
223                                                                rays[j].push_back(ray);
224                                                        }
225                                                }
226                                        }
227                                        //-------------------
228                                }
229                        } else {
230                                // edge samples
231                                // get random visible mesh
232                                //                              object->GetRandomVisibleMesh(Plane3(normal, point));
233                        }
234       
235                        // CORR matt: must add all samples
236                        passSamples += mSamplesPerPass;
237                }
238       
239                totalSamples += passSamples;
240               
241                //    if (pass>10)
242                //      HoleSamplingPass();
243   
244                mPass++;
245
246                int pvsSize = 0;
247       
248                for (i=0; i < objects.size(); i++) {
249                        Intersectable *object = objects[i];
250                        pvsSize += object->mKdPvs.GetSize();
251                }
252               
253               
254                float avgRayContrib = (passContributingSamples > 0) ?
255                        passSampleContributions/(float)passContributingSamples : 0;
256
257                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
258                cout << "#TotalSamples=" << totalSamples/1000
259                                 << "k   #SampleContributions=" << passSampleContributions << " ("
260                                 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
261                                 << pvsSize/(float)objects.size() << endl
262                                 << "avg ray contrib=" << avgRayContrib << endl
263                                 << "reverse samples [%]" << reverseSamples/(float)passSamples*100.0f << endl;
264
265                mStats <<
266                        "#Pass\n" <<mPass<<endl<<
267                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
268                        "#TotalSamples\n" << totalSamples<< endl<<
269                        "#SampleContributions\n" << passSampleContributions << endl <<
270                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
271                        "#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
272                        "#AvgRayContrib\n" << avgRayContrib << endl;
273        }
274       
275        cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
276 
277       
278        if (0) {
279                Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
280                exporter->SetExportRayDensity(true);
281                exporter->ExportKdTree(*mKdTree);
282
283                delete exporter;
284        }
285 
286        bool exportRays = false;
287        if (exportRays) {
288                Exporter *exporter = NULL;
289                exporter = Exporter::GetExporter("sample-rays.x3d");
290                exporter->SetWireframe();
291                exporter->ExportKdTree(*mKdTree);
292
293                for (i=0; i < pvsOut; i++)
294                exporter->ExportRays(rays[i], 1000, RgbColor(1, 0, 0));
295                exporter->SetFilled();
296                 
297                delete exporter;
298        }
299
300        //-- several visualizations and statistics
301        if (1) {
302                for (int k=0; k < pvsOut; k++) {
303                        Intersectable *object = objects[k];
304                        char s[64];
305                        sprintf(s, "sample-pvs%04d.x3d", k);
306                        Exporter *exporter = Exporter::GetExporter(s);
307                        exporter->SetWireframe();
308                       
309                       
310                        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
311                        Intersectable::NewMail();
312                       
313                        // avoid adding the object to the list
314                        object->Mail();
315                        ObjectContainer visibleObjects;
316                       
317                        for (; i != object->mKdPvs.mEntries.end(); i++)
318                                {
319                                        KdNode *node = (*i).first;
320                                        exporter->ExportBox(mKdTree->GetBox(node));
321                                        mKdTree->CollectObjects(node, visibleObjects);
322                                }
323                       
324                        exporter->ExportRays(rays[k], 1000, RgbColor(0, 1, 0));
325                        exporter->SetFilled();
326                       
327                        for (int j = 0; j < visibleObjects.size(); j++)
328                                exporter->ExportIntersectable(visibleObjects[j]);
329                       
330                       
331                        Material m;
332                        m.mDiffuseColor = RgbColor(1, 0, 0);
333                        exporter->SetForcedMaterial(m);
334                        exporter->ExportIntersectable(object);
335                       
336                        delete exporter;
337                }
338  }
339 
340  return true;
341}
342
Note: See TracBrowser for help on using the repository browser.