source: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp @ 2069

Revision 2069, 19.5 KB checked in by mattausch, 17 years ago (diff)
RevLine 
[1020]1#include "SamplingStrategy.h"
2#include "Ray.h"
3#include "Intersectable.h"
4#include "Preprocessor.h"
5#include "ViewCellsManager.h"
6#include "AxisAlignedBox3.h"
[1891]7#include "RssTree.h"
[1989]8#include "Mutation.h"
[2043]9#include "PerfTimer.h"
[1020]10
[2069]11
[1020]12namespace GtpVisibilityPreprocessor {
13
[2044]14extern PerfTimer pvsTimer;
15extern PerfTimer viewCellCastTimer;
[2015]16
[1901]17//HaltonSequence SamplingStrategy::sHalton;
18
[1899]19HaltonSequence ObjectBasedDistribution::sHalton;
20HaltonSequence MixtureDistribution::sHalton;
21HaltonSequence GlobalLinesDistribution::sHalton;
22HaltonSequence SpatialBoxBasedDistribution::sHalton;
23HaltonSequence ObjectDirectionBasedDistribution::sHalton;
[1952]24HaltonSequence DirectionBasedDistribution::sHalton;
[1968]25HaltonSequence HwGlobalLinesDistribution::sHalton;
[1899]26
[1996]27HaltonSequence ViewCellBasedDistribution::sHalton;
[1899]28
[1884]29SamplingStrategy::SamplingStrategy(Preprocessor &preprocessor):
[1968]30mPreprocessor(preprocessor),
31mRatio(1.0f), 
32mTotalRays(0),
33mTotalContribution(0.0f)
34
[1520]35}
36
37
38SamplingStrategy::~SamplingStrategy()
39{
40}
41
[1771]42int
43SamplingStrategy::GenerateSamples(const int number,
[1867]44                                                                  SimpleRayContainer &rays)
[1771]45{
[1772]46        SimpleRay ray;
47        int samples = 0;
48        int i = 0;
49        const int maxTries = 20;
50        // tmp changed matt. Q: should one rejected sample
51        // terminate the whole method?
[1989]52        for (; i < number; i++)
53          {
54                int j = 0;
55                bool sampleGenerated = false;
56               
57                for (j = 0; !sampleGenerated && (j < maxTries); ++ j)
58                  {
59                        sampleGenerated = GenerateSample(ray);
60                       
61                        if (sampleGenerated)
62                          {             
63                                ++ samples;
64                                rays.push_back(ray);
65                          }
66                  }
67          }
[1520]68
[1994]69
[1992]70       
[1772]71
72        return samples;
[1771]73}
[1520]74
[1771]75
[1020]76/*********************************************************************/
77/*            Individual sampling strategies implementation          */
78/*********************************************************************/
79
80
[1867]81bool ObjectBasedDistribution::GenerateSample(SimpleRay &ray)
[1020]82{
[1883]83  Vector3 origin, direction;
84 
85  float r[5];
[1898]86  sHalton.GetNext(5, r);
[1883]87 
88  mPreprocessor.mViewCellsManager->GetViewPoint(origin,
89                                                                                                Vector3(r[2],r[3],r[4]));
90 
[1020]91
[1883]92  Vector3 point, normal;
93 
[1898]94  r[0] *= (float)mPreprocessor.mObjects.size() - 1;
[1883]95  const int i = (int)r[0];
96 
97  Intersectable *object = mPreprocessor.mObjects[i];
98 
99  // take the remainder as a parameter over objects surface
100  r[0] -= (float)i;
101 
102  object->GetRandomSurfacePoint(r[0], r[1], point, normal);
103 
104  direction = point - origin;
105 
106  const float c = Magnitude(direction);
107 
108  if (c <= Limits::Small)
109        return false;
110 
111  // $$ jb the pdf is yet not correct for all sampling methods!
112  const float pdf = 1.0f;
113 
114  direction *= 1.0f / c;
115  ray = SimpleRay(origin, direction, OBJECT_BASED_DISTRIBUTION, pdf);
116 
117  return true;
118}
[1020]119
120
[1883]121bool
122ObjectDirectionBasedDistribution::GenerateSample(SimpleRay &ray)
123{       
124  Vector3 origin, direction;
[1877]125
[1020]126
[1883]127  float r[4];
[1898]128  sHalton.GetNext(4, r);
[1877]129
[1901]130  r[0] *= (float)mPreprocessor.mObjects.size() - 1;
[1883]131  const int i = (int)r[0];
132 
133  Intersectable *object = mPreprocessor.mObjects[i];
134 
135  // take the remainder as a parameter over objects surface
136  r[0] -= (float)i;
[1020]137
[1883]138  Vector3 normal;
[1020]139
[1883]140  object->GetRandomSurfacePoint(r[0], r[1], origin, normal);
141 
142  direction = Normalize(CosineRandomVector(r[2], r[3], normal));
143 
[1899]144  origin += 1e-2f*direction;
[1883]145 
146  // $$ jb the pdf is yet not correct for all sampling methods!
147  const float pdf = 1.0f;
148 
149  ray = SimpleRay(origin, direction, OBJECT_DIRECTION_BASED_DISTRIBUTION, pdf);
150 
151  return true;
[1020]152}
153
154
[1867]155bool DirectionBasedDistribution::GenerateSample(SimpleRay &ray)
[1278]156{       
[1020]157
[1952]158  float r[5];
159  sHalton.GetNext(5, r);
[1020]160
[1952]161  Vector3 origin, direction;
162  mPreprocessor.mViewCellsManager->GetViewPoint(origin,
163                                                                                                Vector3(r[2],r[3],r[4])
164                                                                                                );
165 
166  direction = UniformRandomVector(r[0], r[1]);
167  const float c = Magnitude(direction);
168 
169  if (c <= Limits::Small)
170        return false;
171 
172  const float pdf = 1.0f;
173 
174  direction *= 1.0f / c;
175  ray = SimpleRay(origin, direction, DIRECTION_BASED_DISTRIBUTION, pdf);
176 
177  return true;
[1020]178}
179
180
[1867]181bool DirectionBoxBasedDistribution::GenerateSample(SimpleRay &ray)
[1020]182{
183        Vector3 origin, direction;
184        mPreprocessor.mViewCellsManager->GetViewPoint(origin);
185
[1297]186        const float alpha = RandomValue(0.0f, 2.0f * (float)M_PI);
187        const float beta = RandomValue((float)-M_PI * 0.5f, (float)M_PI * 0.5f);
[1020]188       
189        direction = VssRay::GetDirection(alpha, beta);
190       
191        const float c = Magnitude(direction);
192
193        if (c <= Limits::Small)
194                return false;
195
196        const float pdf = 1.0f;
197
198        direction *= 1.0f / c;
[1883]199        ray = SimpleRay(origin, direction, DIRECTION_BOX_BASED_DISTRIBUTION, pdf);
[1020]200
201        return true;
202}
203
204
[1867]205bool SpatialBoxBasedDistribution::GenerateSample(SimpleRay &ray)
[1020]206{
[1867]207  Vector3 origin, direction;
[1278]208
[1867]209  float r[6];
[1898]210  sHalton.GetNext(6, r);
[1867]211  mPreprocessor.mViewCellsManager->GetViewPoint(origin, Vector3(r[0],r[1],r[2]));
212 
213  direction = mPreprocessor.mKdTree->GetBox().GetRandomPoint(Vector3(r[3],
214                                                                                                                                         r[4],
215                                                                                                                                         r[5])
216                                                                                                                                         ) - origin;
217  //cout << "z";
218  const float c = Magnitude(direction);
219 
220  if (c <= Limits::Small)
221        return false;
222 
223  const float pdf = 1.0f;
224 
225  direction *= 1.0f / c;
[1883]226  ray = SimpleRay(origin, direction, SPATIAL_BOX_BASED_DISTRIBUTION, pdf);
[1867]227 
228  return true;
[1020]229}
230
[1695]231
[1867]232bool ReverseObjectBasedDistribution::GenerateSample(SimpleRay &ray)
[1695]233{
234        Vector3 origin, direction;
235
236        mPreprocessor.mViewCellsManager->GetViewPoint(origin);
237
238        Vector3 point;
239        Vector3 normal;
[1999]240       
[1695]241        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
242
243        Intersectable *object = mPreprocessor.mObjects[i];
244
245        object->GetRandomSurfacePoint(point, normal);
[1765]246       
[1695]247        direction = origin - point;
[1765]248       
[1695]249        // $$ jb the pdf is yet not correct for all sampling methods!
250        const float c = Magnitude(direction);
[1765]251       
252        if ((c <= Limits::Small) || (DotProd(direction, normal) < 0))
253        {
[1695]254                return false;
[1765]255        }
[1695]256
257        // $$ jb the pdf is yet not correct for all sampling methods!
258        const float pdf = 1.0f;
259        //cout << "p: " << point << " ";
260        direction *= 1.0f / c;
[1765]261        // a little offset
[1772]262        point += direction * 0.001f;
[1765]263
[1883]264        ray = SimpleRay(point, direction, REVERSE_OBJECT_BASED_DISTRIBUTION, pdf);
[1695]265       
266        return true;
267}
268
[1763]269
[1867]270bool ViewCellBorderBasedDistribution::GenerateSample(SimpleRay &ray)
[1763]271{
272        Vector3 origin, direction;
273
274        ViewCellContainer &viewCells = mPreprocessor.mViewCellsManager->GetViewCells();
275
276        Vector3 point;
277        Vector3 normal, normal2;
278       
279        const int vcIdx = (int)RandomValue(0, (float)viewCells.size() - 0.5f);
280        const int objIdx = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
281
282        Intersectable *object = mPreprocessor.mObjects[objIdx];
283        ViewCell *viewCell = viewCells[vcIdx];
284
[1769]285        //cout << "vc: " << vcIdx << endl;
286        //cout << "obj: " << objIdx << endl;
287
[1763]288        object->GetRandomSurfacePoint(point, normal);
289        viewCell->GetRandomEdgePoint(origin, normal2);
290
291        direction = point - origin;
292
293        // $$ jb the pdf is yet not correct for all sampling methods!
294        const float c = Magnitude(direction);
295
[1769]296        if ((c <= Limits::Small) /*|| (DotProd(direction, normal) < 0)*/)
[1768]297        {
[1763]298                return false;
[1768]299        }
[1763]300
301        // $$ jb the pdf is yet not correct for all sampling methods!
302        const float pdf = 1.0f;
303        //cout << "p: " << point << " ";
304        direction *= 1.0f / c;
[1883]305        ray = SimpleRay(origin, direction, VIEWCELL_BORDER_BASED_DISTRIBUTION, pdf);
[1769]306
307        //cout << "ray: " << ray.mOrigin << " " << ray.mDirection << endl;
308
[1763]309        return true;
310}
311
[1765]312
[1520]313#if 0
[1867]314bool ObjectsInteriorDistribution::GenerateSample(SimpleRay &ray)
[1020]315{
316        Vector3 origin, direction;
317
318        // get random object
319        const int i = RandomValue(0, mPreprocessor.mObjects.size() - 1);
320
321        const Intersectable *obj = mPreprocessor.mObjects[i];
322
323        // note: if we load the polygons as meshes,
324        // asymtotically every second sample is lost!
325        origin = obj->GetBox().GetRandomPoint();
326
327        // uniformly distributed direction
328        direction = UniformRandomVector();
329
330        const float c = Magnitude(direction);
331
332        if (c <= Limits::Small)
333                return false;
334
335        const float pdf = 1.0f;
336
337        direction *= 1.0f / c;
338        ray = SimpleRay(origin, direction, pdf);
339
340        return true;
[1520]341}
[1769]342
[1520]343#endif
[1771]344
[1772]345
[1867]346bool ReverseViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray)
[1772]347{
348        Vector3 origin, direction;
349
350        origin = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
351
352        Vector3 point;
353        Vector3 normal;
[1999]354       
[1772]355        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
356
357        Intersectable *object = mPreprocessor.mObjects[i];
358
359        object->GetRandomSurfacePoint(point, normal);
360       
361        direction = origin - point;
362       
363        // $$ jb the pdf is yet not correct for all sampling methods!
364        const float c = Magnitude(direction);
365       
366        if ((c <= Limits::Small) || (DotProd(direction, normal) < 0))
367        {
368                return false;
369        }
370
371        // $$ jb the pdf is yet not correct for all sampling methods!
372        const float pdf = 1.0f;
373        //cout << "p: " << point << " ";
374        direction *= 1.0f / c;
375        // a little offset
376        point += direction * 0.001f;
377
[1883]378        ray = SimpleRay(point, direction, REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION, pdf);
[1772]379       
380        return true;
381}
382
383
[1867]384bool ViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray)
[1772]385{
386        Vector3 origin, direction;
387
388        origin = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
389
390        Vector3 point;
391        Vector3 normal;
[2066]392       
[1772]393        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
394
395        Intersectable *object = mPreprocessor.mObjects[i];
396
397        object->GetRandomSurfacePoint(point, normal);
398        direction = point - origin;
399
400        // $$ jb the pdf is yet not correct for all sampling methods!
401        const float c = Magnitude(direction);
402
403        if (c <= Limits::Small)
404                return false;
405
406        // $$ jb the pdf is yet not correct for all sampling methods!
407        const float pdf = 1.0f;
408       
409        direction *= 1.0f / c;
410
411        // a little offset
412        origin += direction * 0.001f;
413
[1883]414        ray = SimpleRay(origin, direction, VIEWSPACE_BORDER_BASED_DISTRIBUTION, pdf);
[1772]415
416        return true;
417}
418
419
[1824]420bool
[1867]421GlobalLinesDistribution::GenerateSample(SimpleRay &ray)
[1824]422{
[1867]423  Vector3 origin, termination, direction;
[1824]424
[1867]425  float radius = 0.5f*Magnitude(mPreprocessor.mViewCellsManager->GetViewSpaceBox().Size());
426  Vector3 center = mPreprocessor.mViewCellsManager->GetViewSpaceBox().Center();
427
428  const int tries = 1000;
429  int i;
430  for (i=0; i < tries; i++) {
431        float r[4];
[1898]432        sHalton.GetNext(4, r);
[1824]433       
[1867]434        origin = center + (radius*UniformRandomVector(r[0], r[1]));
435        termination = center + (radius*UniformRandomVector(r[2], r[3]));
436       
[1824]437        direction = termination - origin;
[1867]438       
439       
[1824]440        // $$ jb the pdf is yet not correct for all sampling methods!
441        const float c = Magnitude(direction);
442        if (c <= Limits::Small)
[1867]443          return false;
[1824]444       
445        direction *= 1.0f / c;
[1867]446
447        // check if the ray intersects the view space box
448        static Ray ray;
449        ray.Init(origin, direction, Ray::LOCAL_RAY);   
[1824]450       
[1867]451        float tmin, tmax;
452        if (mPreprocessor.mViewCellsManager->
453                GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
454          break;
455  }
456 
457  if (i!=tries) {
[1824]458        // $$ jb the pdf is yet not correct for all sampling methods!
459        const float pdf = 1.0f;
[1867]460       
461       
[1883]462        ray = SimpleRay(origin, direction, GLOBAL_LINES_DISTRIBUTION, pdf);
[1824]463        ray.mType = Ray::GLOBAL_RAY;
464        return true;
[1867]465  }
466 
467  return false;
[1771]468}
469
[1883]470
471  // has to called before first usage
472void
473MixtureDistribution::Init()
474{
[1884]475  for (int i=0; i < mDistributions.size(); i++) {
476        // small non-zero value
477        mDistributions[i]->mRays = 1;
[1966]478        mDistributions[i]->mGeneratedRays = 1;
[1884]479        // unit contribution per ray
480        if (1 || mDistributions[i]->mType != RSS_BASED_DISTRIBUTION)
481          mDistributions[i]->mContribution = 1.0f;
482        else
483          mDistributions[i]->mContribution = 0.0f;
484  }
485  UpdateRatios();
[1824]486}
[1884]487
488void
489MixtureDistribution::Reset()
490{
491  for (int i=0; i < mDistributions.size(); i++) {
492        // small non-zero value
[1891]493        mDistributions[i]->mTotalRays = 0;
[1884]494        // unit contribution per ray
[1891]495        mDistributions[i]->mTotalContribution = 0.0f;
[1884]496  }
497  UpdateRatios();
498}
499
500// Generate a new sample according to a mixture distribution
[1883]501bool
502MixtureDistribution::GenerateSample(SimpleRay &ray)
503{
[1884]504  float r;
[1898]505  sHalton.GetNext(1, &r);
[1900]506  int i;
[1884]507  // pickup a distribution
[1900]508  for (i=0; i < mDistributions.size()-1; i++)
[1884]509        if (r < mDistributions[i]->mRatio)
510          break;
[1891]511
[1966]512  bool result = mDistributions[i]->GenerateSample(ray);
513
514  if (result)
515        mDistributions[i]->mGeneratedRays++;
516 
517  return result;
[1883]518}
[1824]519
[1883]520  // add contributions of the sample to the strategies
521void
[1884]522MixtureDistribution::ComputeContributions(VssRayContainer &vssRays)
[1883]523{
[1884]524  int i;
525 
526  VssRayContainer::iterator it = vssRays.begin();
[1883]527
[1891]528  for (i=0; i < mDistributions.size(); i++) {
529        mDistributions[i]->mContribution = 0;
530        mDistributions[i]->mRays = 0;
531  }
532
[1884]533  for(; it != vssRays.end(); ++it) {
534        VssRay *ray = *it;
[1891]535        for (i=0; i < mDistributions.size()-1; i++) {
[1884]536          if (mDistributions[i]->mType == ray->mDistribution)
537                break;
[1891]538        }
539 
[1884]540        float contribution =
[1942]541          mPreprocessor.mViewCellsManager->ComputeSampleContribution(*ray,
542                                                                                                                                 true,
543                                                                                                                                 false);
[1931]544
[1888]545        mDistributions[i]->mContribution += contribution;
[1884]546        mDistributions[i]->mRays ++;
[1900]547       
[1891]548        mDistributions[i]->mTotalContribution += contribution;
549        mDistributions[i]->mTotalRays ++;
[1884]550  }
551
[2019]552#if 0
[2015]553  pvsTimer.Entry();
554  // resort pvss
555  mPreprocessor.mViewCellsManager->SortViewCellPvs();
556  pvsTimer.Exit();
[2019]557#endif
[2044]558
[1884]559 
560  UpdateRatios();
[1966]561
[2044]562#if 1
[2043]563  cout<<"view cell cast time:"<<viewCellCastTimer.TotalTime()<<" s"<<endl;
564  cout<<"pvs time:"<<pvsTimer.TotalTime()<<" s"<<endl;
[2044]565  //  cout<<"obj time:"<<objTimer.TotalTime()<<" s"<<endl;
566#endif
[1883]567}
568
[1884]569void
[1942]570MixtureDistribution::UpdateDistributions(VssRayContainer &vssRays)
571{
572  // now update the distributions with all the rays
573  for (int i=0; i < mDistributions.size(); i++) {
574        mDistributions[i]->Update(vssRays);
575  }
576}
[1966]577
[1974]578#define RAY_CAST_TIME 0.7f
579#define VIEWCELL_CAST_TIME 0.3f
[1966]580
[1942]581void
[1884]582MixtureDistribution::UpdateRatios()
583{
584  // now compute importance (ratio) of all distributions
585  float sum = 0.0f;
586  int i;
587  for (i=0; i < mDistributions.size(); i++) {
[1891]588        cout<<i<<": c="<<mDistributions[i]->mContribution<<
589          " rays="<<mDistributions[i]->mRays<<endl;
590        float importance = 0.0f;
591        if (mDistributions[i]->mRays != 0) {
[1966]592          //importance = pow(mDistributions[i]->mContribution/mDistributions[i]->mRays, 2);
593          importance = mDistributions[i]->mContribution/
594                (RAY_CAST_TIME*mDistributions[i]->mGeneratedRays +
595                 VIEWCELL_CAST_TIME*mDistributions[i]->mRays);
[1891]596        }
[1884]597        mDistributions[i]->mRatio = importance;
598        sum += importance;
599  }
[1891]600
[1966]601  if (sum == 0.0f)
602        sum = Limits::Small;
[1974]603 
[1966]604  const float minratio = 0.01f;
[1974]605 
606  for (i=0; i < mDistributions.size(); i++) {
607        mDistributions[i]->mRatio /= sum;
608        if (mDistributions[i]->mRatio < minratio)
609          mDistributions[i]->mRatio = minratio;
610  }
[1966]611
[1974]612  // recaluate the sum after clip
[1966]613  sum = 0.0f;
[1974]614  for (i=0; i < mDistributions.size(); i++)
[1966]615        sum += mDistributions[i]->mRatio;
[1974]616
617  for (i=0; i < mDistributions.size(); i++)
618        mDistributions[i]->mRatio /= sum;
[1884]619 
620  for (i=1; i < mDistributions.size(); i++) {
[1974]621        mDistributions[i]->mRatio = mDistributions[i-1]->mRatio + mDistributions[i]->mRatio;
[1884]622  }
623 
624  cout<<"ratios: ";
[1931]625  float last = 0.0f;
626  for (i=0; i < mDistributions.size(); i++) {
627        cout<<mDistributions[i]->mRatio-last<<" ";
628        last = mDistributions[i]->mRatio;
629  }
[1884]630  cout<<endl;
[1883]631}
[1891]632
633
634
635bool
636MixtureDistribution::Construct(char *str)
637{
638  char *curr = str;
639
640  while (1) {
641        char *e = strchr(curr,'+');
642        if (e!=NULL) {
643          *e=0;
644        }
645       
646        if (strcmp(curr, "rss")==0) {
647          mDistributions.push_back(new RssBasedDistribution(mPreprocessor));
648        } else
649          if (strcmp(curr, "object")==0) {
650                mDistributions.push_back(new ObjectBasedDistribution(mPreprocessor));
651          } else
652                if (strcmp(curr, "spatial")==0) {
653                  mDistributions.push_back(new SpatialBoxBasedDistribution(mPreprocessor));
654                } else
655                  if (strcmp(curr, "global")==0) {
656                        mDistributions.push_back(new GlobalLinesDistribution(mPreprocessor));
657                  } else
658                        if (strcmp(curr, "direction")==0) {
659                          mDistributions.push_back(new DirectionBasedDistribution(mPreprocessor));
660                        } else
661                          if (strcmp(curr, "object_direction")==0) {
662                                mDistributions.push_back(new ObjectDirectionBasedDistribution(mPreprocessor));
663                          } else
664                                if (strcmp(curr, "reverse_object")==0) {
665                                  mDistributions.push_back(new ReverseObjectBasedDistribution(mPreprocessor));
666                                } else
[2044]667                                 
[1891]668                                  if (strcmp(curr, "reverse_viewspace_border")==0) {
669                                        mDistributions.push_back(new ReverseViewSpaceBorderBasedDistribution(mPreprocessor));
[1952]670                                  } else
671                                        if (strcmp(curr, "mutation")==0) {
[2048]672                                         mDistributions.push_back(new MutationBasedDistribution(mPreprocessor));
[2001]673                                        }
[1891]674       
[1952]675       
[1891]676        if (e==NULL)
677          break;
678        curr = e+1;
679  }
680
681  Init();
682  return true;
[1884]683}
[1883]684
[1966]685int
686MixtureDistribution::GenerateSamples(const int number,
687                                                                         SimpleRayContainer &rays)
688{
689  for (int i=0; i < mDistributions.size(); i++)
690        mDistributions[i]->mGeneratedRays = 0;
[1952]691
[1966]692  return SamplingStrategy::GenerateSamples(number, rays);
693}
[1952]694
[1974]695
[1966]696
[1968]697bool HwGlobalLinesDistribution::GenerateSample(SimpleRay &ray)
698{
699        Vector3 origin, termination, direction;
700
701        float radius = 0.5f *
702                Magnitude(mPreprocessor.mViewCellsManager->GetViewSpaceBox().Size());
703
704        Vector3 center = mPreprocessor.mViewCellsManager->GetViewSpaceBox().Center();
705
706        const int tries = 1000;
707        int i;
708        for (i=0; i < tries; i++)
709        {
710                float r[2];
711                sHalton.GetNext(2, r);
712
713                origin = center + (radius * UniformRandomVector(r[0], r[1]));
714                termination = center;
715               
716                if (0)
717                {
718                        // add a small offset to provide some more randomness in the sampling
719                        Vector3 offset(Random(radius * 1e-3f),
720                                                   Random(radius * 1e-3f),
721                                                   Random(radius * 1e-3f));
722                        termination += offset;
723                }
724
725                direction = termination - origin;
726
727                // $$ jb the pdf is yet not correct for all sampling methods!
728                const float c = Magnitude(direction);
729
730                if (c <= Limits::Small)
731                        return false;
732
733                direction *= 1.0f / c;
734
735                // check if the ray intersects the view space box
736                static Ray ray;
737                ray.Init(origin, direction, Ray::LOCAL_RAY);   
738
739                float tmin, tmax;
740                if (mPreprocessor.mViewCellsManager->
741                        GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
742                        break;
743        }
744
745        if (i != tries)
746        {
747                // $$ jb the pdf is yet not correct for all sampling methods!
748                const float pdf = 1.0f;
749
750                ray = SimpleRay(origin, direction, HW_GLOBAL_LINES_DISTRIBUTION, pdf);
751                ray.mType = Ray::GLOBAL_RAY;
752                return true;
753        }
754
755        return false;
[1952]756}
757
758
[1996]759bool ViewCellBasedDistribution::GenerateSample(SimpleRay &ray)
760{
761        Vector3 origin, direction;
762
763        ViewCellContainer &viewCells =
764                mPreprocessor.mViewCellsManager->GetViewCells();
765
766        Vector3 point;
[2003]767        Vector3 normal;
768               
769        //Vector normalObj;
[2000]770        // float r[1];
771        // sHalton.GetNext(1, r);
772        // const int objIdx = (int)(r[0] * (float)mPreprocessor.mObjects.size() - 1.0f);
773        // Intersectable *object = mPreprocessor.mObjects[objIdx];
774        // object->GetRandomSurfacePoint(point, normal);
775        // cout << "obj: " << objIdx << endl;
[1996]776
[2000]777        float r[2];
778        sHalton.GetNext(2, r);
[1996]779
[2000]780        direction = UniformRandomVector(r[0], r[1]);
781        const float c = Magnitude(direction);
[1996]782
[2000]783    if (c <= Limits::Small)
784                return false;
785
786        direction *= 1.0f / c;
787
788        // get point on view cell surface
[2003]789        mViewCell->GetRandomSurfacePoint(origin, normal);
[1996]790
[2000]791        //direction = point - origin;
[1996]792
793        // move a little bit back to avoid piercing through walls
794        // that bound the view cell
[2003]795        origin -= 0.01f * normal;
[1996]796
797        // $$ jb the pdf is yet not correct for all sampling methods!
798        const float pdf = 1.0f;
799
800        ray = SimpleRay(origin, direction, VIEWCELL_BASED_DISTRIBUTION, pdf);
801
802        //cout << "ray: " << ray.mOrigin << " " << ray.mDirection << endl;
803
804        return true;
[1968]805}
806
807
[1996]808}
809
810
Note: See TracBrowser for help on using the repository browser.