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

Revision 2116, 20.1 KB checked in by mattausch, 18 years ago (diff)

implemented hashpvs

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