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

Revision 2210, 19.6 KB checked in by mattausch, 17 years ago (diff)

improved performance of osp

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