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

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