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

Revision 2582, 21.4 KB checked in by bittner, 16 years ago (diff)

Havran Ray Caster compiles and links, but still does not work

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