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

Revision 2043, 19.5 KB checked in by bittner, 18 years ago (diff)

timing restored

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