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

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