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

Revision 2575, 21.4 KB checked in by bittner, 17 years ago (diff)

big merge: preparation for havran ray caster, check if everything works

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