source: GTP/trunk/Lib/Vis/Preprocessing/src/VssPreprocessor.cpp @ 1233

Revision 1233, 25.7 KB checked in by mattausch, 18 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#include "VssRay.h"
10#include "VssTree.h"
11#include "ViewCellsManager.h"
12#include "RenderSimulator.h"
13#include "Beam.h"
14#include "GlRenderer.h"
15//#include "ArchModeler2MLRT.hxx"
16#include "Intersectable.h"
17
18
19namespace GtpVisibilityPreprocessor {
20
21bool use2dSampling = false;
22bool useViewspacePlane = false;
23
24VssPreprocessor::VssPreprocessor():
25  mPass(0),
26  mVssRays(),
27  mViewSpaceBox(NULL)
28{
29  // this should increase coherence of the samples
30  Environment::GetSingleton()->GetIntValue("VssPreprocessor.samplesPerPass", mSamplesPerPass);
31  Environment::GetSingleton()->GetIntValue("VssPreprocessor.initialSamples", mInitialSamples);
32  Environment::GetSingleton()->GetIntValue("VssPreprocessor.vssSamples", mVssSamples);
33  Environment::GetSingleton()->GetIntValue("VssPreprocessor.vssSamplesPerPass", mVssSamplesPerPass);
34  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.useImportanceSampling", mUseImportanceSampling);
35 
36  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.loadInitialSamples", mLoadInitialSamples);
37  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.storeInitialSamples", mStoreInitialSamples);
38  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.useViewSpaceBox", mUseViewSpaceBox);
39  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.testBeamSampling", mTestBeamSampling);
40  Environment::GetSingleton()->GetBoolValue("VssPreprocessor.enlargeViewSpace", mEnlargeViewSpace);
41  Environment::GetSingleton()->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
42 
43  useViewspacePlane = mUseViewSpaceBox; //hack
44
45 
46  Debug << "*********** vss preprocessor options **************" << endl;
47  Debug << "use view space box=" << mUseViewSpaceBox << endl;
48  Debug << "enlarge view space=" << mEnlargeViewSpace << endl;
49  Debug << "*********** end vss preprocessor options **************" << endl;
50
51  mStats.open("stats.log");
52}
53
54
55VssPreprocessor::~VssPreprocessor()
56{
57        CLEAR_CONTAINER(mVssRays);
58        DEL_PTR(mViewSpaceBox);
59}
60
61
62void
63VssPreprocessor::SetupRay(Ray &ray,
64                                                  const Vector3 &point,
65                                                  const Vector3 &direction
66                                                  )
67{
68  ray.Clear();
69  // do not store anything else then intersections at the ray
70  ray.Init(point, direction, Ray::LOCAL_RAY);
71}
72
73
74void
75VssPreprocessor::CastRays(
76                                                  SimpleRayContainer &rays,
77                                                  VssRayContainer &vssRays
78                                                  )
79{
80        AxisAlignedBox3 &box =  mViewSpaceBox ? *mViewSpaceBox : mKdTree->GetBox();
81       
82#if 1
83        for (int i=0; i < rays.size(); i++)
84        {
85                CastRay(rays[i].mOrigin, rays[i].mDirection, vssRays, box);
86        }
87#else
88        for (int i = 0; i < rays.size(); i += 16)
89        {
90                CastRay(rays[i].mOrigin, rays[i].mDirection, vssRays, box);
91        }
92
93#endif
94}
95
96
97void VssPreprocessor::CastRays16(SimpleRayContainer &rays,
98                                                                 VssRayContainer &vssRays,
99                                                                 const AxisAlignedBox3 &sbox)
100{
101/*
102        mlrtaStoreRayAS16(const float* pforg, const float* pfdir, int j);
103
104
105        // input parameters
106        const RTVec3f& org = *reinterpret_cast<const RTVec3f*> (pforg);
107        const RTVec3f& rd  = *reinterpret_cast<const RTVec3f*> (pfdir);
108
109        int ri = j/4;
110        int ci = j%4;
111        *((float*)&ibp4.ray4X[ri].m_origin.t[0] + ci) = org[0];
112        *((float*)&ibp4.ray4X[ri].m_origin.t[1] + ci) = org[1];
113        *((float*)&ibp4.ray4X[ri].m_origin.t[2] + ci) = org[2];
114
115        *((float*)&ibp4.ray4X[ri].m_direction.t[0] + ci) = rd[0];
116        *((float*)&ibp4.ray4X[ri].m_direction.t[1] + ci) = rd[1];
117        *((float*)&ibp4.ray4X[ri].m_direction.t[2] + ci) = rd[2];
118
119        mlrtaTraverseGroupAS16(const float* bbmin, const float* bbmax, int* hit_triangles, float* dist);*/
120}
121
122
123int VssPreprocessor::CastIntelDoubleRay(
124                                                                                const Vector3 &viewPoint,
125                                                                                const Vector3 &direction,
126                                                                                VssRayContainer &vssRays,
127                                                                                const AxisAlignedBox3 &box)
128{
129        VssRay *vssRay  = NULL;
130        int hits = 0;
131
132        Vector3 pointA, pointB;
133       
134        Intersectable *objectA =
135                CastIntelSingleRay(viewPoint, direction, pointA, box);
136       
137        // cast ray into other direction
138        Intersectable *objectB =
139                CastIntelSingleRay(viewPoint, -direction, pointB, box);
140
141        const bool validSample = (objectA != objectB);
142       
143        if (validSample)
144        {       
145                if (objectA)
146                {
147                        vssRay = new VssRay(pointB,
148                                                                pointA,
149                                                                objectB,
150                                                                objectA,
151                                                                mPass);
152                        vssRays.push_back(vssRay);
153                        hits ++;
154                }
155
156                if (objectB)
157                {
158                        vssRay = new VssRay(pointA,
159                                                                pointB,
160                                                                objectA,
161                                                                objectB,
162                                                                mPass);
163                        vssRays.push_back(vssRay);
164                        hits ++;
165                }
166                //Debug << "intel ray: " << *vssRay << endl;
167        }
168//cout << "a";
169        return hits;
170}
171
172
173Intersectable *VssPreprocessor::CastIntelSingleRay(const Vector3 &viewPoint,
174                                                                                                   const Vector3 &direction,
175                                                                                                   Vector3 &tPoint,
176                                                                                                   const AxisAlignedBox3 &box
177                                                                                                   )
178{
179        AxisAlignedBox3 sbox = box;
180        sbox.Enlarge(Vector3(-Limits::Small));
181
182        if (!sbox.IsInside(viewPoint))
183                return 0;
184       
185        float pforg[3];
186        float pfdir[3];
187        double pfnorm[3];
188
189        pforg[0] = viewPoint[0]; pforg[1] = viewPoint[1]; pforg[2] = viewPoint[2];
190        pfdir[0] = direction[0]; pfdir[1] = direction[1]; pfdir[2] = direction[2];
191
192        float dist = 0;
193        const int hittriangle = -1//mlrtaIntersectAS(pforg, pfdir, pfnorm, dist);
194
195        if (hittriangle == -1)
196        {
197                static Ray ray;
198                SetupRay(ray, viewPoint, direction);
199
200                float tmin = 0, tmax;
201                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
202                {
203                        tPoint = ray.Extrap(tmax);
204                }
205
206                return NULL;
207        }
208        else
209        {
210                tPoint[0] = pforg[0] + pfdir[0] * dist;
211                tPoint[1] = pforg[1] + pfdir[1] * dist;
212                tPoint[2] = pforg[2] + pfdir[2] * dist;
213
214                return mFaceParents[hittriangle];
215        }
216}
217
218
219int
220VssPreprocessor::CastInternalRay(
221                                                                 const Vector3 &viewPoint,
222                                                                 const Vector3 &direction,
223                                                                 VssRayContainer &vssRays,
224                                                                 const AxisAlignedBox3 &box
225                                                                 )
226{
227    int hits = 0;
228        static Ray ray;
229
230        AxisAlignedBox3 sbox = box;
231        sbox.Enlarge(Vector3(-Limits::Small));
232
233        if (!sbox.IsInside(viewPoint))
234                return 0;
235       
236        SetupRay(ray, viewPoint, direction);
237       
238        // cast ray to KD tree to find intersection with other objects
239        Intersectable *objectA, *objectB;
240       
241        Vector3 pointA;
242        Vector3 pointB;
243
244        //float bsize = Magnitude(box.Size());
245        if (!mDetectEmptyViewSpace)
246                ray.mFlags &= ~Ray::CULL_BACKFACES;
247        else
248                ray.mFlags |= Ray::CULL_BACKFACES;
249
250        if (mKdTree->CastRay(ray))
251        {
252                objectA = ray.intersections[0].mObject;
253                pointA = ray.Extrap(ray.intersections[0].mT);
254        }
255        else
256        {
257                objectA = NULL;
258                // compute intersection with the scene bounding box
259                float tmin, tmax;
260                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
261                        pointA = ray.Extrap(tmax);
262                else
263                        return 0;
264        }
265
266        // matt: point A could be undefined?
267
268        // cast ray into opposite direction
269        if (1 && mDetectEmptyViewSpace) {
270                SetupRay(ray, pointA, -direction);
271        } else
272                SetupRay(ray, viewPoint, -direction);
273 
274        if (!mDetectEmptyViewSpace)
275                ray.mFlags &= ~Ray::CULL_BACKFACES;
276        else
277                ray.mFlags |= Ray::CULL_BACKFACES;
278
279        if (mKdTree->CastRay(ray))
280        {
281                objectB = ray.intersections[0].mObject;
282                pointB = ray.Extrap(ray.intersections[0].mT);
283        }
284        else
285        {
286                objectB = NULL;
287                float tmin, tmax;
288               
289                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax)
290                        pointB = ray.Extrap(tmax);
291                else
292                        return 0;
293        }
294 
295        //bool thesame = objectA && (objectA == objectB);
296       
297        //  if (objectA == NULL && objectB != NULL) {
298        if (1 && mDetectEmptyViewSpace)
299        {
300                // cast again to ensure that there is no objectA
301                SetupRay(ray, pointB, direction);
302                ray.mFlags |= Ray::CULL_BACKFACES;
303               
304                if (mKdTree->CastRay(ray))
305                {
306                        objectA = ray.intersections[0].mObject;
307                        pointA = ray.Extrap(ray.intersections[0].mT);
308                }
309        }
310
311 
312        VssRay *vssRay  = NULL;
313
314        bool validSample = (objectA != objectB);
315       
316        //if (validSample && thesame) Debug << "warning!!" << endl;
317
318        if (0 && mDetectEmptyViewSpace)
319        {   
320                // consider all samples valid
321                // check if the viewpoint lies on the line segment AB
322                if (Distance(pointA, pointB) <
323                        Distance(viewPoint, pointA) + Distance(viewPoint, pointB) - Limits::Small)
324                {
325                        validSample = false;
326                }
327        }
328       
329        if (validSample)
330        {       
331                if (objectA)
332                {
333                        vssRay = new VssRay(pointB,
334                                                                pointA,
335                                                                objectB,
336                                                                objectA,
337                                                                mPass);
338                        vssRays.push_back(vssRay);
339                        hits ++;
340                }
341
342                if (objectB)
343                {
344                        vssRay = new VssRay(pointA,
345                                                                pointB,
346                                                                objectA,
347                                                                objectB,
348                                                                mPass);
349                        vssRays.push_back(vssRay);
350                        hits ++;
351                }
352                //Debug << "internal ray: " << *vssRay << endl << endl;
353        }
354//cout << "b";
355        return hits;
356}
357
358
359int
360VssPreprocessor::CastRay(
361                                                 const Vector3 &viewPoint,
362                                                 const Vector3 &direction,
363                                                 VssRayContainer &vssRays,
364                                                 const AxisAlignedBox3 &box
365                                                 )
366{
367        switch (mRayCastMethod)
368        {
369        case INTEL_RAYCASTER:
370                return CastIntelDoubleRay(viewPoint, direction, vssRays, box);
371        case INTERNAL_RAYCASTER:
372        default:
373                return CastInternalRay(viewPoint, direction, vssRays, box);
374        }
375}
376
377
378Vector3
379VssPreprocessor::GetViewpoint(AxisAlignedBox3 *viewSpaceBox)
380{
381  AxisAlignedBox3 box;
382
383  if (viewSpaceBox)
384        box =*viewSpaceBox;
385  else
386        box = mKdTree->GetBox();
387
388  // shrink the box in the y direction
389  return box.GetRandomPoint();
390}
391
392Vector3
393VssPreprocessor::GetDirection(const Vector3 &viewpoint,
394                                                          AxisAlignedBox3 *viewSpaceBox
395                                                          )
396{
397  Vector3 point;
398  if (!use2dSampling)
399  {
400          if (0)
401          {
402                  Vector3 normal;
403                  int i = Random((int)mObjects.size());
404                  Intersectable *object = mObjects[i];
405                  object->GetRandomSurfacePoint(point, normal);
406          }
407          else
408                  point = mKdTree->GetBox().GetRandomPoint();
409        //        point = viewpoint + UniformRandomVector();
410  }
411  else
412  {
413          AxisAlignedBox3 box;
414
415          if (viewSpaceBox)
416                  box =*viewSpaceBox;
417          else
418                  box = mKdTree->GetBox();
419
420          point = box.GetRandomPoint();
421          point.y = viewpoint.y;
422  }
423
424  return point - viewpoint;
425}
426
427int
428VssPreprocessor::GenerateImportanceRays(VssTree *vssTree,
429                                                                                const int desiredSamples,
430                                                                                SimpleRayContainer &rays
431                                                                                )
432{
433  int num;
434  if (0) {
435        float minRayContribution;
436        float maxRayContribution;
437        float avgRayContribution;
438
439        vssTree->GetRayContributionStatistics(minRayContribution,
440                                                                                  maxRayContribution,
441                                                                                  avgRayContribution);
442
443        cout<<
444          "#MIN_RAY_CONTRIB\n"<<minRayContribution<<endl<<
445          "#MAX_RAY_CONTRIB\n"<<maxRayContribution<<endl<<
446          "#AVG_RAY_CONTRIB\n"<<avgRayContribution<<endl;
447
448        float p = desiredSamples/(float)(avgRayContribution*vssTree->stat.Leaves());
449        num = vssTree->GenerateRays(p, rays);
450  } else {
451        int leaves = vssTree->stat.Leaves();
452        num = vssTree->GenerateRays(desiredSamples, leaves, rays);
453  }
454
455  cout<<"Generated "<<num<<" rays."<<endl;
456
457  return num;
458}
459
460
461bool
462VssPreprocessor::ExportRays(const char *filename,
463                                                        const VssRayContainer &vssRays,
464                                                        const int number
465                                                        )
466{
467  cout<<"Exporting vss rays..."<<endl<<flush;
468
469  Exporter *exporter = NULL;
470  exporter = Exporter::GetExporter(filename);
471  exporter->SetWireframe();
472  exporter->ExportKdTree(*mKdTree);
473  exporter->SetFilled();
474  exporter->ExportScene(mSceneGraph->mRoot);
475  exporter->SetWireframe();
476
477  if (mViewSpaceBox) {
478        exporter->SetForcedMaterial(RgbColor(1,0,1));
479        exporter->ExportBox(*mViewSpaceBox);
480        exporter->ResetForcedMaterial();
481  }
482
483  VssRayContainer rays;
484  vssRays.SelectRays(number, rays);
485 
486  //exporter->ExportRays(rays, RgbColor(1, 0, 0));
487
488  delete exporter;
489
490  cout<<"done."<<endl<<flush;
491
492  return true;
493}
494
495
496bool
497VssPreprocessor::ExportVssTree(char *filename,
498                                                           VssTree *tree,
499                                                           const Vector3 &dir
500                                                           )
501{
502  Exporter *exporter = Exporter::GetExporter(filename);
503  exporter->SetFilled();
504  exporter->ExportScene(mSceneGraph->mRoot);
505  //  exporter->SetWireframe();
506  bool result = exporter->ExportVssTree2( *tree, dir );
507  delete exporter;
508  return result;
509}
510
511bool
512VssPreprocessor::ExportVssTreeLeaf(char *filename,
513                                                                   VssTree *tree,
514                                                                   VssTreeLeaf *leaf)
515{
516  Exporter *exporter = NULL;
517  exporter = Exporter::GetExporter(filename);
518  exporter->SetWireframe();
519  exporter->ExportKdTree(*mKdTree);
520
521  if (mViewSpaceBox) {
522        exporter->SetForcedMaterial(RgbColor(1,0,0));
523        exporter->ExportBox(*mViewSpaceBox);
524        exporter->ResetForcedMaterial();
525  }
526
527  exporter->SetForcedMaterial(RgbColor(0,0,1));
528  exporter->ExportBox(tree->GetBBox(leaf));
529  exporter->ResetForcedMaterial();
530
531  VssRayContainer rays[4];
532  for (int i=0; i < leaf->rays.size(); i++) {
533        int k = leaf->rays[i].GetRayClass();
534        rays[k].push_back(leaf->rays[i].mRay);
535  }
536
537  // SOURCE RAY
538  exporter->ExportRays(rays[0], RgbColor(1, 0, 0));
539  // TERMINATION RAY
540  exporter->ExportRays(rays[1], RgbColor(1, 1, 1));
541  // PASSING_RAY
542  exporter->ExportRays(rays[2], RgbColor(1, 1, 0));
543  // CONTAINED_RAY
544  exporter->ExportRays(rays[3], RgbColor(0, 0, 1));
545
546  delete exporter;
547  return true;
548}
549
550void
551VssPreprocessor::ExportVssTreeLeaves(VssTree *tree, const int number)
552{
553  vector<VssTreeLeaf *> leaves;
554  tree->CollectLeaves(leaves);
555
556  int num = 0;
557  int i;
558  float p = number / (float)leaves.size();
559  for (i=0; i < leaves.size(); i++) {
560        if (RandomValue(0,1) < p) {
561          char filename[64];
562          sprintf(filename, "vss-leaf-%04d.x3d", num);
563          ExportVssTreeLeaf(filename, tree, leaves[i]);
564          num++;
565        }
566        if (num >= number)
567          break;
568  }
569}
570
571
572void VssPreprocessor::TestBeamCasting(VssTree *tree,
573                                                                          ViewCellsManager *vm,
574                                                                          const ObjectContainer &objects)
575{
576        //debuggerWidget = new GlDebuggerWidget(renderer);
577        //  renderer->resize(640, 480);
578        //debuggerWidget->resize(640, 480);
579
580        vector<VssTreeLeaf *> leaves;
581        tree->CollectLeaves(leaves);
582
583        Exporter *exporter = Exporter::GetExporter("shafts.x3d");
584
585        exporter->SetWireframe();
586        exporter->ExportGeometry(objects);
587        exporter->SetFilled();
588        //Randomize();
589// §§matt
590//      debuggerWidget = new GlDebuggerWidget(renderer);
591
592        /*debuggerWidget->mBeam = beam;
593        debuggerWidget->mSourceObject = sourceObj;
594        debuggerWidget->mSamples = 10000;
595       
596        Debug << "showing window" << endl;
597        debuggerWidget->show();
598       
599        renderer->makeCurrent();*/
600
601        for (int i = 0; i < 10; ++ i)
602        {
603                Beam beam;
604                Intersectable *sourceObj = mObjects[5];
605
606                const int index = (int)RandomValue(0, (Real)((int)leaves.size() - 1));
607                VssTreeLeaf *leaf = leaves[index];
608
609                AxisAlignedBox3 dirBox = tree->GetDirBBox(leaf);
610                AxisAlignedBox3 box = tree->GetBBox(leaf);
611               
612                beam.Construct(box, dirBox);
613
614                // collect kd leaves and view cells
615                mKdTree->CastBeam(beam);
616                vm->CastBeam(beam);
617
618                Debug << "found " << (int)beam.mViewCells.size() << " view cells and "
619                          << (int)beam.mKdNodes.size() << " kd nodes" << endl;
620
621                BeamSampleStatistics stats;
622// §§matt
623/*              renderer->SampleBeamContributions(sourceObj,
624                                                                                  beam,
625                                                                                  200000,
626                                                                                  stats);
627
628                char s[64]; sprintf(s, "shaft%04d.png", i);
629
630                QImage image = renderer->toImage();
631                image.save(s, "PNG");
632                Debug << "beam statistics: " << stats << endl << endl;
633*/
634                if (1)
635                {
636                        AxisAlignedBox3 sbox = mSceneGraph->GetBox();
637                        Vector3 bmin = sbox.Min() - 150.0f;
638                        Vector3 bmax = sbox.Max() + 150.0f;
639                        AxisAlignedBox3 vbox(bmin, bmax);
640               
641                        exporter->ExportBeam(beam, vbox);
642                }
643
644                bool exportViewCells = false;
645               
646                if (exportViewCells)
647                {
648                        ViewCellContainer::const_iterator it, it_end = beam.mViewCells.end();
649                       
650                        for (it = beam.mViewCells.begin(); it != beam.mViewCells.end(); ++ it)
651                        {
652                                BspNodeGeometry geom;
653                                AxisAlignedBox3 vbox;
654                                vbox.Initialize();
655                                vbox.Include((*it)->GetMesh());
656                       
657                                exporter->SetWireframe();
658                                exporter->ExportBox(vbox);
659                                exporter->SetFilled();
660                                exporter->ExportViewCell(*it);
661                        }
662
663                        /*vector<KdNode *>::const_iterator it, it_end = beam.mKdNodes.end();
664                       
665                        for (it = beam.mKdNodes.begin(); it != beam.mKdNodes.end(); ++ it)
666                        {
667                                exporter->ExportBox(mKdTree->GetBox((*it)));
668                        }*/
669                }
670        }
671        /*while (1)
672        { debuggerWidget->repaint();
673        };*/
674        delete exporter;
675}
676
677
678float
679VssPreprocessor::GetAvgPvsSize(VssTree *tree,
680                                                           const vector<AxisAlignedBox3> &viewcells
681                                                           )
682{
683  vector<AxisAlignedBox3>::const_iterator it, it_end = viewcells.end();
684
685  int sum = 0;
686  for (it = viewcells.begin(); it != it_end; ++ it)
687        sum += tree->GetPvsSize(*it);
688
689  return sum/(float)viewcells.size();
690}
691
692bool
693VssPreprocessor::ComputeVisibility()
694{
695        Debug << "type: vss" << endl;
696
697  long startTime = GetTime();
698
699  int totalSamples = 0;
700
701
702  AxisAlignedBox3 box(mKdTree->GetBox());
703 
704  if (!useViewspacePlane) {
705        float size = 0.05f;
706        float s = 0.5f - size;
707        float olds = Magnitude(box.Size());
708        box.Enlarge(box.Size()*Vector3(-s));
709        Vector3 translation = Vector3(-olds*0.1f, 0, 0);
710        box.SetMin(box.Min() + translation);
711        box.SetMax(box.Max() + translation);
712  } else {
713
714        // sample city like heights
715        box.SetMin(1, box.Min(1) + box.Size(1)*0.2f);
716        box.SetMax(1, box.Min(1) + box.Size(1)*0.3f);
717  }
718
719  if (use2dSampling)
720        box.SetMax(1, box.Min(1));
721
722  cout << "use view space box=" << mUseViewSpaceBox << endl;
723
724 
725  if (mUseViewSpaceBox)
726  {
727        //mViewSpaceBox = ConstructViewSpaceBox();
728
729          if (!mEnlargeViewSpace)
730          {
731                  mViewSpaceBox = new AxisAlignedBox3(box);
732          }
733          else
734          {
735                  mViewSpaceBox = new AxisAlignedBox3(mKdTree->GetBox());
736
737                  if (0)
738                  {
739                          // HACK: enlarge in y directon
740                          Vector3 size = mViewSpaceBox->Size();
741                       
742                          size[1] *= 1.25;
743                          Vector3 enlarge(size[0] * 0.25f, size[1] * 0.0f, size[2] * 0.25f);
744                          //Vector3 enlarge(size[0] * 4.0f, 0.0f, 0.0f);
745
746                          mViewSpaceBox->Enlarge(enlarge);
747                          mViewSpaceBox->SetMax(mViewSpaceBox->Max() + enlarge);
748                  }
749                  else
750                  {
751                          AxisAlignedBox3 tbox(*mViewSpaceBox);
752
753                          Vector3 size = mViewSpaceBox->Size();
754                          tbox.SetMax(0, mViewSpaceBox->Max(0) + size[0] * 0.5);
755                          tbox.SetMin(0, mViewSpaceBox->Min(0) + size[0]);
756                          *mViewSpaceBox = tbox;
757
758                          // $$ JB temporary
759                          /*AxisAlignedBox3 tempbox = *mViewSpaceBox;
760                         
761                          float s = tempbox.Size(0);
762                         
763                          tempbox.Scale(0.8f);
764                          tempbox.SetMax(0, box.Max(0) + s*0.8f);
765                          tempbox.SetMin(0, box.Min(0) + s*0.8f);
766                          *mViewSpaceBox = tempbox;*/
767                  }             
768          }
769          //Debug << "view space box: " << *mViewSpaceBox << endl;
770  }
771  else
772  {
773          mViewSpaceBox = NULL;
774  }
775 
776  AxisAlignedBox3 vbox = mViewSpaceBox ? *mViewSpaceBox : mKdTree->GetBox();
777
778  mSceneGraph->CollectObjects(&mObjects);
779
780  //-- load view cells from file if requested
781  if (!mLoadViewCells)
782  {
783          mViewCellsManager->SetViewSpaceBox(vbox);
784          // construct view cells using it's own set of samples
785          mViewCellsManager->Construct(this);
786
787          //-- several visualizations and statistics
788          Debug << "view cells construction finished: " << endl;
789          mViewCellsManager->PrintStatistics(Debug);
790  }
791  else
792  {     
793          VssRayContainer dummies;
794          mViewCellsManager->Visualize(mObjects, dummies);
795          mViewCellsManager->ExportViewCells("test.xml", mViewCellsManager->GetExportPvs(), mObjects);
796  }
797
798  VssTree *vssTree = NULL;
799 
800
801  long initialTime = GetTime();
802
803  if (mLoadInitialSamples)
804  {
805          cout << "Loading samples from file ... ";
806          LoadSamples(mVssRays, mObjects);
807          cout << "finished\n" << endl;
808          totalSamples = (int)mVssRays.size();
809  }
810  else
811  {
812       
813        while (totalSamples < mInitialSamples) {
814                int passContributingSamples = 0;
815                int passSampleContributions = 0;
816                int passSamples = 0;
817
818                int index = 0;
819
820                int sampleContributions;
821
822                int s = Min(mSamplesPerPass, mInitialSamples);
823                for (int k=0; k < s; k++) {
824                        // changed by matt
825                        Vector3 viewpoint;
826                        //                      viewpoint = GetViewpoint(mViewSpaceBox);
827                        mViewCellsManager->GetViewPoint(viewpoint);
828                        Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
829
830                        sampleContributions = CastRay(viewpoint, direction, mVssRays, vbox);
831
832                        if (sampleContributions) {
833                                passContributingSamples ++;
834                                passSampleContributions += sampleContributions;
835                        }
836                        passSamples++;
837                        totalSamples++;
838                }
839
840                mPass++;
841                int pvsSize = 0;
842                float avgRayContrib = (passContributingSamples > 0) ?
843                        passSampleContributions/(float)passContributingSamples : 0;
844
845                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
846                cout << "#TotalSamples=" << totalSamples/1000
847                        << "#SampleContributions=" << passSampleContributions << " ("
848                        << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
849                        << pvsSize/(float)mObjects.size() << endl
850                        << "avg ray contrib=" << avgRayContrib << endl;
851
852                mStats <<
853                        "#Pass\n" <<mPass<<endl<<
854                        "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
855                        "#TotalSamples\n" << totalSamples<< endl<<
856                        "#SampleContributions\n" << passSampleContributions << endl <<
857                        "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
858                        "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
859                        "#AvgRayContrib\n" << avgRayContrib << endl;
860          }
861 
862          cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
863
864
865         
866  }
867 
868
869  cout << "#totalRayStackSize=" << (int)mVssRays.size() << endl << flush;
870  Debug << (int)mVssRays.size() << " rays generated in "
871            << TimeDiff(initialTime, GetTime()) * 1e-3 << " seconds" << endl;
872
873  if (mStoreInitialSamples)
874  {
875          cout << "Writing " << (int)mVssRays.size() << " samples to file ... ";
876          ExportSamples(mVssRays);
877          cout << "finished\n" << endl;
878
879          /*VssRayContainer dummyRays;
880          LoadSamples(dummyRays, mObjects);
881          Debug << "rays " << (int)mVssRays.size() << " " << dummyRays.size() << endl;
882
883          for (int i = 0; i < (int)mVssRays.size(); ++ i)
884          {
885                  Debug << mVssRays[i]->GetOrigin() << " " << mVssRays[i]->GetTermination() << " " << mVssRays[i]->mOriginObject << " " << mVssRays[i]->mTerminationObject << endl;
886                  Debug << dummyRays[i]->GetOrigin() << " " << dummyRays[i]->GetTermination() << " " << dummyRays[i]->mOriginObject << " " << dummyRays[i]->mTerminationObject << endl << endl;
887          }*/
888  }
889
890 
891  //int numExportRays = 2000;
892  int numExportRays = 0;
893
894  if (numExportRays) {
895        char filename[64];
896        sprintf(filename, "vss-rays-initial.x3d");
897        ExportRays(filename, mVssRays, numExportRays);
898  }
899
900  vssTree = new VssTree;
901  // viewcells = Construct(mVssRays);
902
903  vssTree->Construct(mVssRays, mViewSpaceBox);
904  cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
905
906  ExportRays("kdtree.x3d", mVssRays, 10);
907
908  if (0)
909  {
910          ExportVssTree("vss-tree-100.x3d", vssTree, Vector3(1,0,0));
911          ExportVssTree("vss-tree-001.x3d", vssTree, Vector3(0,0,1));
912          ExportVssTree("vss-tree-101.x3d", vssTree, Vector3(1,0,1));
913          ExportVssTree("vss-tree-101m.x3d", vssTree, Vector3(-1,0,-1));
914          ExportVssTreeLeaves(vssTree, 10);
915  }
916
917  // viewcells->UpdatePVS(newVssRays);
918  // get viewcells as kd tree boxes
919  vector<AxisAlignedBox3> kdViewcells;
920  if (0) {
921        vector<KdLeaf *> leaves;
922        mKdTree->CollectLeaves(leaves);
923        vector<KdLeaf *>::const_iterator it;
924        int targetLeaves = 50;
925        float prob = targetLeaves/(float)leaves.size();
926        for (it = leaves.begin(); it != leaves.end(); ++it)
927          if (RandomValue(0.0f,1.0f) < prob)
928                kdViewcells.push_back(mKdTree->GetBox(*it));
929
930        float avgPvs = GetAvgPvsSize(vssTree, kdViewcells);
931        cout<<"Initial average PVS size = "<<avgPvs<<endl;
932  }
933
934
935  int samples = 0;
936  int pass = 0;
937
938 
939  // cast view cell samples
940  while (samples < mVssSamples)
941  {
942       
943        int num = mVssSamplesPerPass;
944        SimpleRayContainer rays;
945        VssRayContainer vssRays;
946
947        if (!mUseImportanceSampling) {
948          for (int j=0; j < num; j++) {
949            // changed by matt
950                //Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
951                Vector3 viewpoint;
952                mViewCellsManager->GetViewPoint(viewpoint);
953                Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
954                rays.push_back(SimpleRay(viewpoint, direction));
955          }
956        } else {
957          num = GenerateImportanceRays(vssTree, num, rays);
958        }
959
960        for (int i=0; i < rays.size(); i++)
961          CastRay(rays[i].mOrigin, rays[i].mDirection, vssRays, vbox);
962
963        vssTree->AddRays(vssRays);
964
965        if (0) {
966          int subdivided = vssTree->UpdateSubdivision();
967          cout<<"subdivided leafs = "<<subdivided<<endl;
968        }
969
970        float avgPvs = GetAvgPvsSize(vssTree, kdViewcells);
971        cout<<"Average PVS size = "<<avgPvs<<endl;
972
973        /// compute view cell contribution of rays
974        mViewCellsManager->ComputeSampleContributions(vssRays, true, false);
975       
976        if (numExportRays) {
977          char filename[64];
978          if (mUseImportanceSampling)
979                sprintf(filename, "vss-rays-i%04d.x3d", pass);
980          else
981                sprintf(filename, "vss-rays-%04d.x3d", pass);
982
983          ExportRays(filename, vssRays, numExportRays);
984        }
985
986        samples+=num;
987        float pvs = vssTree->GetAvgPvsSize();
988        cout<<"*****************************\n";
989        cout<<samples<<" avgPVS ="<<pvs<<endl;
990        cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
991        cout<<"*****************************\n";
992//      if (samples >= mVssSamples) break;
993        pass ++;
994  }
995
996  if (mTestBeamSampling && mUseGlRenderer)
997  {     
998          TestBeamCasting(vssTree, mViewCellsManager, mObjects);
999  }
1000
1001  if (0)  Debug << vssTree->stat << endl;
1002
1003  if (0)
1004  {
1005        VssRayContainer viewCellRays;
1006        // compute rays used for view cells construction
1007        const int numRays = mViewCellsManager->GetVisualizationSamples();
1008        vssTree->CollectRays(viewCellRays, numRays);
1009  }
1010
1011  //-- render simulation after merge
1012  cout << "\nevaluating bsp view cells render time after sampling ... ";
1013  Debug << "\nStatistics after sampling: " << endl;
1014
1015  mRenderSimulator->RenderScene();
1016  SimulationStatistics ss;
1017  mRenderSimulator->GetStatistics(ss);
1018 
1019  cout << " finished" << endl;
1020  cout << ss << endl;
1021  Debug << ss << endl;
1022
1023  delete vssTree;
1024 
1025  return true;
1026}
1027
1028}
Note: See TracBrowser for help on using the repository browser.