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

Revision 1221, 25.7 KB checked in by mattausch, 18 years ago (diff)

added intel ray tracing

RevLine 
[372]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"
[376]9#include "VssRay.h"
[382]10#include "VssTree.h"
[439]11#include "ViewCellsManager.h"
[452]12#include "RenderSimulator.h"
[531]13#include "Beam.h"
14#include "GlRenderer.h"
[1221]15#include "ArchModeler2MLRT.hxx"
16#include "Intersectable.h"
[372]17
[1221]18
[863]19namespace GtpVisibilityPreprocessor {
[860]20
[427]21bool use2dSampling = false;
[534]22bool useViewspacePlane = false;
[427]23
[372]24VssPreprocessor::VssPreprocessor():
[434]25  mPass(0),
[1002]26  mVssRays(),
27  mViewSpaceBox(NULL)
[372]28{
29  // this should increase coherence of the samples
[1004]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);
[574]35 
[1004]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);
[694]42 
[508]43  useViewspacePlane = mUseViewSpaceBox; //hack
[490]44
[675]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
[372]51  mStats.open("stats.log");
52}
53
[685]54
[372]55VssPreprocessor::~VssPreprocessor()
56{
[674]57        CLEAR_CONTAINER(mVssRays);
58        DEL_PTR(mViewSpaceBox);
[372]59}
60
[685]61
[372]62void
[468]63VssPreprocessor::SetupRay(Ray &ray,
64                                                  const Vector3 &point,
[434]65                                                  const Vector3 &direction
66                                                  )
[372]67{
[466]68  ray.Clear();
[434]69  // do not store anything else then intersections at the ray
[374]70  ray.Init(point, direction, Ray::LOCAL_RAY);
[372]71}
72
[574]73
74void
75VssPreprocessor::CastRays(
76                                                  SimpleRayContainer &rays,
77                                                  VssRayContainer &vssRays
78                                                  )
79{
[1221]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
[574]94}
95
96
[1221]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 = 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
[386]219int
[1221]220VssPreprocessor::CastInternalRay(
221                                                                 const Vector3 &viewPoint,
222                                                                 const Vector3 &direction,
223                                                                 VssRayContainer &vssRays,
224                                                                 const AxisAlignedBox3 &box
225                                                                 )
[372]226{
[499]227    int hits = 0;
[675]228        static Ray ray;
[1221]229
[675]230        AxisAlignedBox3 sbox = box;
231        sbox.Enlarge(Vector3(-Limits::Small));
[1221]232
[675]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;
[767]240       
[694]241        Vector3 pointA;
242        Vector3 pointB;
243
[767]244        //float bsize = Magnitude(box.Size());
[589]245        if (!mDetectEmptyViewSpace)
[675]246                ray.mFlags &= ~Ray::CULL_BACKFACES;
[589]247        else
[675]248                ray.mFlags |= Ray::CULL_BACKFACES;
[589]249
[675]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        }
[386]265
[694]266        // matt: point A could be undefined?
[1221]267
268        // cast ray into opposite direction
[694]269        if (1 && mDetectEmptyViewSpace) {
[675]270                SetupRay(ray, pointA, -direction);
271        } else
272                SetupRay(ray, viewPoint, -direction);
[534]273 
[675]274        if (!mDetectEmptyViewSpace)
275                ray.mFlags &= ~Ray::CULL_BACKFACES;
276        else
277                ray.mFlags |= Ray::CULL_BACKFACES;
[589]278
[675]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        }
[534]294 
[694]295        //bool thesame = objectA && (objectA == objectB);
296       
[675]297        //  if (objectA == NULL && objectB != NULL) {
[694]298        if (1 && mDetectEmptyViewSpace)
[675]299        {
300                // cast again to ensure that there is no objectA
301                SetupRay(ray, pointB, direction);
[693]302                ray.mFlags |= Ray::CULL_BACKFACES;
[675]303               
304                if (mKdTree->CastRay(ray))
305                {
306                        objectA = ray.intersections[0].mObject;
307                        pointA = ray.Extrap(ray.intersections[0].mT);
308                }
[434]309        }
[534]310
[499]311 
[675]312        VssRay *vssRay  = NULL;
[386]313
[675]314        bool validSample = (objectA != objectB);
[694]315       
316        //if (validSample && thesame) Debug << "warning!!" << endl;
[675]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                }
[386]327        }
[499]328       
[675]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                }
[1221]352                //Debug << "internal ray: " << *vssRay << endl << endl;
[434]353        }
[1221]354//cout << "b";
[675]355        return hits;
[372]356}
357
358
[1221]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
[376]378Vector3
[382]379VssPreprocessor::GetViewpoint(AxisAlignedBox3 *viewSpaceBox)
[372]380{
[434]381  AxisAlignedBox3 box;
[468]382
[434]383  if (viewSpaceBox)
384        box =*viewSpaceBox;
[468]385  else
[434]386        box = mKdTree->GetBox();
[468]387
[434]388  // shrink the box in the y direction
389  return box.GetRandomPoint();
[372]390}
391
[376]392Vector3
[427]393VssPreprocessor::GetDirection(const Vector3 &viewpoint,
[434]394                                                          AxisAlignedBox3 *viewSpaceBox
395                                                          )
[372]396{
[434]397  Vector3 point;
[600]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();
[534]409        //        point = viewpoint + UniformRandomVector();
[600]410  }
411  else
412  {
413          AxisAlignedBox3 box;
[534]414
[600]415          if (viewSpaceBox)
416                  box =*viewSpaceBox;
417          else
418                  box = mKdTree->GetBox();
[468]419
[600]420          point = box.GetRandomPoint();
421          point.y = viewpoint.y;
[434]422  }
[468]423
[434]424  return point - viewpoint;
[372]425}
426
[401]427int
[427]428VssPreprocessor::GenerateImportanceRays(VssTree *vssTree,
[434]429                                                                                const int desiredSamples,
430                                                                                SimpleRayContainer &rays
431                                                                                )
[401]432{
[434]433  int num;
434  if (0) {
435        float minRayContribution;
436        float maxRayContribution;
437        float avgRayContribution;
[468]438
[434]439        vssTree->GetRayContributionStatistics(minRayContribution,
440                                                                                  maxRayContribution,
441                                                                                  avgRayContribution);
[468]442
[434]443        cout<<
444          "#MIN_RAY_CONTRIB\n"<<minRayContribution<<endl<<
445          "#MAX_RAY_CONTRIB\n"<<maxRayContribution<<endl<<
446          "#AVG_RAY_CONTRIB\n"<<avgRayContribution<<endl;
[468]447
[434]448        float p = desiredSamples/(float)(avgRayContribution*vssTree->stat.Leaves());
449        num = vssTree->GenerateRays(p, rays);
450  } else {
[534]451        int leaves = vssTree->stat.Leaves();
[434]452        num = vssTree->GenerateRays(desiredSamples, leaves, rays);
453  }
[468]454
[434]455  cout<<"Generated "<<num<<" rays."<<endl;
[468]456
[434]457  return num;
[427]458}
[376]459
460
[427]461bool
462VssPreprocessor::ExportRays(const char *filename,
[434]463                                                        const VssRayContainer &vssRays,
464                                                        const int number
465                                                        )
[427]466{
[434]467  cout<<"Exporting vss rays..."<<endl<<flush;
[468]468
[434]469  Exporter *exporter = NULL;
470  exporter = Exporter::GetExporter(filename);
[1074]471  exporter->SetWireframe();
472  exporter->ExportKdTree(*mKdTree);
[434]473  exporter->SetFilled();
474  exporter->ExportScene(mSceneGraph->mRoot);
475  exporter->SetWireframe();
[427]476
[434]477  if (mViewSpaceBox) {
[438]478        exporter->SetForcedMaterial(RgbColor(1,0,1));
[434]479        exporter->ExportBox(*mViewSpaceBox);
480        exporter->ResetForcedMaterial();
481  }
[468]482
[534]483  VssRayContainer rays;
484  vssRays.SelectRays(number, rays);
485 
[685]486  //exporter->ExportRays(rays, RgbColor(1, 0, 0));
[468]487
[434]488  delete exporter;
[401]489
[434]490  cout<<"done."<<endl<<flush;
[427]491
[434]492  return true;
[401]493}
494
495
[372]496bool
[434]497VssPreprocessor::ExportVssTree(char *filename,
[438]498                                                           VssTree *tree,
499                                                           const Vector3 &dir
500                                                           )
[434]501{
502  Exporter *exporter = Exporter::GetExporter(filename);
503  exporter->SetFilled();
504  exporter->ExportScene(mSceneGraph->mRoot);
[438]505  //  exporter->SetWireframe();
506  bool result = exporter->ExportVssTree2( *tree, dir );
[434]507  delete exporter;
508  return result;
509}
510
511bool
[427]512VssPreprocessor::ExportVssTreeLeaf(char *filename,
[434]513                                                                   VssTree *tree,
514                                                                   VssTreeLeaf *leaf)
[427]515{
[434]516  Exporter *exporter = NULL;
517  exporter = Exporter::GetExporter(filename);
518  exporter->SetWireframe();
519  exporter->ExportKdTree(*mKdTree);
[468]520
[434]521  if (mViewSpaceBox) {
522        exporter->SetForcedMaterial(RgbColor(1,0,0));
523        exporter->ExportBox(*mViewSpaceBox);
[427]524        exporter->ResetForcedMaterial();
[434]525  }
[468]526
[434]527  exporter->SetForcedMaterial(RgbColor(0,0,1));
528  exporter->ExportBox(tree->GetBBox(leaf));
529  exporter->ResetForcedMaterial();
[468]530
[434]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  }
[468]536
[434]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));
[427]545
[434]546  delete exporter;
547  return true;
[427]548}
549
550void
551VssPreprocessor::ExportVssTreeLeaves(VssTree *tree, const int number)
552{
[434]553  vector<VssTreeLeaf *> leaves;
554  tree->CollectLeaves(leaves);
[427]555
[434]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++;
[427]565        }
[434]566        if (num >= number)
567          break;
568  }
[427]569}
570
[685]571
[535]572void VssPreprocessor::TestBeamCasting(VssTree *tree,
573                                                                          ViewCellsManager *vm,
574                                                                          const ObjectContainer &objects)
[530]575{
[540]576        //debuggerWidget = new GlDebuggerWidget(renderer);
577        //  renderer->resize(640, 480);
578        //debuggerWidget->resize(640, 480);
579
[531]580        vector<VssTreeLeaf *> leaves;
581        tree->CollectLeaves(leaves);
[530]582
[535]583        Exporter *exporter = Exporter::GetExporter("shafts.x3d");
584
585        exporter->SetWireframe();
[540]586        exporter->ExportGeometry(objects);
[535]587        exporter->SetFilled();
588        //Randomize();
[1145]589// §§matt
590//      debuggerWidget = new GlDebuggerWidget(renderer);
[540]591
592        /*debuggerWidget->mBeam = beam;
593        debuggerWidget->mSourceObject = sourceObj;
594        debuggerWidget->mSamples = 10000;
595       
596        Debug << "showing window" << endl;
[1145]597        debuggerWidget->show();
[540]598       
[1145]599        renderer->makeCurrent();*/
[540]600
601        for (int i = 0; i < 10; ++ i)
[530]602        {
[540]603                Beam beam;
604                Intersectable *sourceObj = mObjects[5];
605
[531]606                const int index = (int)RandomValue(0, (Real)((int)leaves.size() - 1));
607                VssTreeLeaf *leaf = leaves[index];
[530]608
[535]609                AxisAlignedBox3 dirBox = tree->GetDirBBox(leaf);
[531]610                AxisAlignedBox3 box = tree->GetBBox(leaf);
[532]611               
[535]612                beam.Construct(box, dirBox);
[532]613
614                // collect kd leaves and view cells
615                mKdTree->CastBeam(beam);
616                vm->CastBeam(beam);
617
[577]618                Debug << "found " << (int)beam.mViewCells.size() << " view cells and "
619                          << (int)beam.mKdNodes.size() << " kd nodes" << endl;
[532]620
[530]621                BeamSampleStatistics stats;
[1145]622// §§matt
623/*              renderer->SampleBeamContributions(sourceObj,
[589]624                                                                                  beam,
625                                                                                  200000,
[531]626                                                                                  stats);
[530]627
[540]628                char s[64]; sprintf(s, "shaft%04d.png", i);
629
630                QImage image = renderer->toImage();
631                image.save(s, "PNG");
[532]632                Debug << "beam statistics: " << stats << endl << endl;
[1145]633*/
[540]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);
[535]640               
[540]641                        exporter->ExportBeam(beam, vbox);
642                }
[535]643
[540]644                bool exportViewCells = false;
[535]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();
[538]655                                vbox.Include((*it)->GetMesh());
656                       
657                                exporter->SetWireframe();
[535]658                                exporter->ExportBox(vbox);
[538]659                                exporter->SetFilled();
660                                exporter->ExportViewCell(*it);
[535]661                        }
[538]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                        }*/
[535]669                }
[530]670        }
[540]671        /*while (1)
672        { debuggerWidget->repaint();
673        };*/
[535]674        delete exporter;
[530]675}
676
[540]677
[434]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);
[468]688
[434]689  return sum/(float)viewcells.size();
690}
691
[427]692bool
[372]693VssPreprocessor::ComputeVisibility()
694{
[579]695        Debug << "type: vss" << endl;
[468]696
[372]697  long startTime = GetTime();
[468]698
[372]699  int totalSamples = 0;
700
701
[1002]702  AxisAlignedBox3 box(mKdTree->GetBox());
[534]703 
[434]704  if (!useViewspacePlane) {
[446]705        float size = 0.05f;
[434]706        float s = 0.5f - size;
[1002]707        float olds = Magnitude(box.Size());
708        box.Enlarge(box.Size()*Vector3(-s));
[434]709        Vector3 translation = Vector3(-olds*0.1f, 0, 0);
[1002]710        box.SetMin(box.Min() + translation);
711        box.SetMax(box.Max() + translation);
[434]712  } else {
[468]713
[434]714        // sample city like heights
[1002]715        box.SetMin(1, box.Min(1) + box.Size(1)*0.2f);
716        box.SetMax(1, box.Min(1) + box.Size(1)*0.3f);
[434]717  }
[427]718
[434]719  if (use2dSampling)
[1002]720        box.SetMax(1, box.Min(1));
[468]721
[1221]722  cout << "use view space box=" << mUseViewSpaceBox << endl;
[579]723
[1076]724 
[501]725  if (mUseViewSpaceBox)
[487]726  {
[1221]727        //mViewSpaceBox = ConstructViewSpaceBox();
728
[674]729          if (!mEnlargeViewSpace)
[654]730          {
[1002]731                  mViewSpaceBox = new AxisAlignedBox3(box);
[654]732          }
[598]733          else
734          {
[750]735                  mViewSpaceBox = new AxisAlignedBox3(mKdTree->GetBox());
[677]736
[1052]737                  if (0)
[750]738                  {
[1052]739                          // HACK: enlarge in y directon
[750]740                          Vector3 size = mViewSpaceBox->Size();
[1052]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);
[598]745
[1052]746                          mViewSpaceBox->Enlarge(enlarge);
[750]747                          mViewSpaceBox->SetMax(mViewSpaceBox->Max() + enlarge);
748                  }
749                  else
750                  {
[1052]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
[750]758                          // $$ JB temporary
[1052]759                          /*AxisAlignedBox3 tempbox = *mViewSpaceBox;
[750]760                         
[1002]761                          float s = tempbox.Size(0);
[750]762                         
[1002]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);
[1052]766                          *mViewSpaceBox = tempbox;*/
[750]767                  }             
[598]768          }
769          //Debug << "view space box: " << *mViewSpaceBox << endl;
[487]770  }
[434]771  else
[487]772  {
[579]773          mViewSpaceBox = NULL;
[487]774  }
[534]775 
[577]776  AxisAlignedBox3 vbox = mViewSpaceBox ? *mViewSpaceBox : mKdTree->GetBox();
777
[590]778  mSceneGraph->CollectObjects(&mObjects);
779
[518]780  //-- load view cells from file if requested
[577]781  if (!mLoadViewCells)
[574]782  {
[577]783          mViewCellsManager->SetViewSpaceBox(vbox);
[574]784          // construct view cells using it's own set of samples
785          mViewCellsManager->Construct(this);
[518]786
[574]787          //-- several visualizations and statistics
[587]788          Debug << "view cells construction finished: " << endl;
[574]789          mViewCellsManager->PrintStatistics(Debug);
790  }
[590]791  else
[651]792  {     
[590]793          VssRayContainer dummies;
794          mViewCellsManager->Visualize(mObjects, dummies);
[931]795          mViewCellsManager->ExportViewCells("test.xml", mViewCellsManager->GetExportPvs(), mObjects);
[590]796  }
[401]797
[651]798  VssTree *vssTree = NULL;
[590]799 
[468]800
[490]801  long initialTime = GetTime();
[468]802
[490]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  {
[534]812       
813        while (totalSamples < mInitialSamples) {
[490]814                int passContributingSamples = 0;
815                int passSampleContributions = 0;
816                int passSamples = 0;
[468]817
[490]818                int index = 0;
[468]819
[490]820                int sampleContributions;
[468]821
[490]822                int s = Min(mSamplesPerPass, mInitialSamples);
823                for (int k=0; k < s; k++) {
824                        // changed by matt
825                        Vector3 viewpoint;
[534]826                        //                      viewpoint = GetViewpoint(mViewSpaceBox);
[490]827                        mViewCellsManager->GetViewPoint(viewpoint);
828                        Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
[534]829
[1221]830                        sampleContributions = CastRay(viewpoint, direction, mVssRays, vbox);
[468]831
[490]832                        if (sampleContributions) {
833                                passContributingSamples ++;
834                                passSampleContributions += sampleContributions;
835                        }
836                        passSamples++;
837                        totalSamples++;
838                }
[468]839
[490]840                mPass++;
841                int pvsSize = 0;
842                float avgRayContrib = (passContributingSamples > 0) ?
843                        passSampleContributions/(float)passContributingSamples : 0;
[468]844
[490]845                cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
846                cout << "#TotalSamples=" << totalSamples/1000
[651]847                        << "#SampleContributions=" << passSampleContributions << " ("
[490]848                        << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
849                        << pvsSize/(float)mObjects.size() << endl
850                        << "avg ray contrib=" << avgRayContrib << endl;
[468]851
[490]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;
[534]863
864
865         
[490]866  }
[564]867 
868
[490]869  cout << "#totalRayStackSize=" << (int)mVssRays.size() << endl << flush;
870  Debug << (int)mVssRays.size() << " rays generated in "
871            << TimeDiff(initialTime, GetTime()) * 1e-3 << " seconds" << endl;
[401]872
[490]873  if (mStoreInitialSamples)
874  {
875          cout << "Writing " << (int)mVssRays.size() << " samples to file ... ";
[508]876          ExportSamples(mVssRays);
[490]877          cout << "finished\n" << endl;
[491]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          }*/
[434]888  }
[468]889
[534]890 
[712]891  //int numExportRays = 2000;
892  int numExportRays = 0;
[372]893
[434]894  if (numExportRays) {
895        char filename[64];
896        sprintf(filename, "vss-rays-initial.x3d");
897        ExportRays(filename, mVssRays, numExportRays);
898  }
[468]899
[434]900  vssTree = new VssTree;
901  // viewcells = Construct(mVssRays);
[468]902
[434]903  vssTree->Construct(mVssRays, mViewSpaceBox);
904  cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
[468]905
[1074]906  ExportRays("kdtree.x3d", mVssRays, 10);
907
[465]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  }
[430]916
[434]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));
[468]929
[434]930        float avgPvs = GetAvgPvsSize(vssTree, kdViewcells);
931        cout<<"Initial average PVS size = "<<avgPvs<<endl;
932  }
933
[468]934
[434]935  int samples = 0;
936  int pass = 0;
[448]937
[535]938 
[448]939  // cast view cell samples
[557]940  while (samples < mVssSamples)
941  {
942       
[434]943        int num = mVssSamplesPerPass;
944        SimpleRayContainer rays;
945        VssRayContainer vssRays;
[468]946
[434]947        if (!mUseImportanceSampling) {
948          for (int j=0; j < num; j++) {
[487]949            // changed by matt
950                //Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
951                Vector3 viewpoint;
952                mViewCellsManager->GetViewPoint(viewpoint);
[434]953                Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
954                rays.push_back(SimpleRay(viewpoint, direction));
955          }
956        } else {
957          num = GenerateImportanceRays(vssTree, num, rays);
958        }
[468]959
[434]960        for (int i=0; i < rays.size(); i++)
[1221]961          CastRay(rays[i].mOrigin, rays[i].mDirection, vssRays, vbox);
[468]962
[434]963        vssTree->AddRays(vssRays);
[468]964
[434]965        if (0) {
966          int subdivided = vssTree->UpdateSubdivision();
967          cout<<"subdivided leafs = "<<subdivided<<endl;
968        }
[427]969
[434]970        float avgPvs = GetAvgPvsSize(vssTree, kdViewcells);
971        cout<<"Average PVS size = "<<avgPvs<<endl;
[430]972
[517]973        /// compute view cell contribution of rays
[574]974        mViewCellsManager->ComputeSampleContributions(vssRays, true, false);
[517]975       
[434]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);
[468]982
[434]983          ExportRays(filename, vssRays, numExportRays);
[401]984        }
[386]985
[434]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";
[557]992//      if (samples >= mVssSamples) break;
993        pass ++;
[434]994  }
[448]995
[574]996  if (mTestBeamSampling && mUseGlRenderer)
997  {     
998          TestBeamCasting(vssTree, mViewCellsManager, mObjects);
[553]999  }
1000
[1221]1001  if (0)  Debug << vssTree->stat << endl;
[468]1002
[574]1003  if (0)
1004  {
1005        VssRayContainer viewCellRays;
[1221]1006        // compute rays used for view cells construction
[574]1007        const int numRays = mViewCellsManager->GetVisualizationSamples();
1008        vssTree->CollectRays(viewCellRays, numRays);
[540]1009  }
[535]1010
[452]1011  //-- render simulation after merge
[574]1012  cout << "\nevaluating bsp view cells render time after sampling ... ";
[605]1013  Debug << "\nStatistics after sampling: " << endl;
1014
[468]1015  mRenderSimulator->RenderScene();
1016  SimulationStatistics ss;
1017  mRenderSimulator->GetStatistics(ss);
[474]1018 
[452]1019  cout << " finished" << endl;
1020  cout << ss << endl;
1021  Debug << ss << endl;
[468]1022
[434]1023  delete vssTree;
[475]1024 
[434]1025  return true;
[466]1026}
[697]1027
[860]1028}
Note: See TracBrowser for help on using the repository browser.