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

Revision 2187, 19.4 KB checked in by mattausch, 17 years ago (diff)
Line 
1#include "SamplingStrategy.h"
2#include "Ray.h"
3#include "Intersectable.h"
4#include "Preprocessor.h"
5#include "ViewCellsManager.h"
6#include "AxisAlignedBox3.h"
7#include "RssTree.h"
8#include "Mutation.h"
9#include "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        mPreprocessor.mViewCellsManager->GetViewPoint(origin, Vector3(r[0],
214                                                                                                                                  r[1],
215                                                                                                                                  r[2]));
216
217        direction = mPreprocessor.mKdTree->GetBox().GetRandomPoint(Vector3(r[3],
218                                                                                                                                           r[4],
219                                                                                                                                           r[5])
220                                                                                                                                           ) - origin;
221        //cout << "z";
222        const float c = Magnitude(direction);
223
224        if (c <= Limits::Small)
225                return false;
226
227        const float pdf = 1.0f;
228
229        direction *= 1.0f / c;
230        ray = SimpleRay(origin, direction, SPATIAL_BOX_BASED_DISTRIBUTION, pdf);
231 
232        return true;
233}
234
235
236bool ReverseObjectBasedDistribution::GenerateSample(SimpleRay &ray)
237{
238        Vector3 origin, direction;
239
240        mPreprocessor.mViewCellsManager->GetViewPoint(origin);
241
242        Vector3 point;
243        Vector3 normal;
244       
245        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
246
247        Intersectable *object = mPreprocessor.mObjects[i];
248
249        object->GetRandomSurfacePoint(point, normal);
250       
251        direction = origin - point;
252       
253        // $$ jb the pdf is yet not correct for all sampling methods!
254        const float c = Magnitude(direction);
255       
256        if ((c <= Limits::Small) || (DotProd(direction, normal) < 0))
257        {
258                return false;
259        }
260
261        // $$ jb the pdf is yet not correct for all sampling methods!
262        const float pdf = 1.0f;
263       
264        direction *= 1.0f / c;
265        // a little offset
266        point += direction * 0.001f;
267
268        ray = SimpleRay(point, direction, REVERSE_OBJECT_BASED_DISTRIBUTION, pdf);
269       
270        return true;
271}
272
273
274bool ViewCellBorderBasedDistribution::GenerateSample(SimpleRay &ray)
275{
276        Vector3 origin, direction;
277
278        ViewCellContainer &viewCells = mPreprocessor.mViewCellsManager->GetViewCells();
279
280        Vector3 point;
281        Vector3 normal, normal2;
282       
283        const int vcIdx = (int)RandomValue(0, (float)viewCells.size() - 0.5f);
284        const int objIdx = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
285
286        Intersectable *object = mPreprocessor.mObjects[objIdx];
287        ViewCell *viewCell = viewCells[vcIdx];
288
289        object->GetRandomSurfacePoint(point, normal);
290        viewCell->GetRandomEdgePoint(origin, normal2);
291
292        direction = point - origin;
293
294        // $$ jb the pdf is yet not correct for all sampling methods!
295        const float c = Magnitude(direction);
296
297        if ((c <= Limits::Small) /*|| (DotProd(direction, normal) < 0)*/)
298        {
299                return false;
300        }
301
302        // $$ jb the pdf is yet not correct for all sampling methods!
303        const float pdf = 1.0f;
304        //cout << "p: " << point << " ";
305        direction *= 1.0f / c;
306        ray = SimpleRay(origin, direction, VIEWCELL_BORDER_BASED_DISTRIBUTION, pdf);
307
308        //cout << "ray: " << ray.mOrigin << " " << ray.mDirection << endl;
309
310        return true;
311}
312
313
314bool ReverseViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray)
315{
316        Vector3 origin, direction;
317
318        origin = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
319
320        Vector3 point;
321        Vector3 normal;
322       
323        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
324
325        Intersectable *object = mPreprocessor.mObjects[i];
326
327        object->GetRandomSurfacePoint(point, normal);
328       
329        direction = origin - point;
330       
331        // $$ jb the pdf is yet not correct for all sampling methods!
332        const float c = Magnitude(direction);
333       
334        if ((c <= Limits::Small) || (DotProd(direction, normal) < 0))
335        {
336                return false;
337        }
338
339        // $$ jb the pdf is yet not correct for all sampling methods!
340        const float pdf = 1.0f;
341        //cout << "p: " << point << " ";
342        direction *= 1.0f / c;
343        // a little offset
344        point += direction * 0.001f;
345
346        ray = SimpleRay(point, direction, REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION, pdf);
347       
348        return true;
349}
350
351
352bool ViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray)
353{
354        Vector3 origin, direction;
355
356        origin = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
357
358        Vector3 point;
359        Vector3 normal;
360       
361        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
362
363        Intersectable *object = mPreprocessor.mObjects[i];
364
365        object->GetRandomSurfacePoint(point, normal);
366        direction = point - origin;
367
368        // $$ jb the pdf is yet not correct for all sampling methods!
369        const float c = Magnitude(direction);
370
371        if (c <= Limits::Small)
372                return false;
373
374        // $$ jb the pdf is yet not correct for all sampling methods!
375        const float pdf = 1.0f;
376       
377        direction *= 1.0f / c;
378
379        // a little offset
380        origin += direction * 0.001f;
381
382        ray = SimpleRay(origin, direction, VIEWSPACE_BORDER_BASED_DISTRIBUTION, pdf);
383
384        return true;
385}
386
387
388bool
389GlobalLinesDistribution::GenerateSample(SimpleRay &ray)
390{
391  Vector3 origin, termination, direction;
392
393  float radius = 0.5f*Magnitude(mPreprocessor.mViewCellsManager->GetViewSpaceBox().Size());
394  Vector3 center = mPreprocessor.mViewCellsManager->GetViewSpaceBox().Center();
395
396  const int tries = 1000;
397  int i;
398  for (i=0; i < tries; i++) {
399        float r[4];
400        sHalton.GetNext(4, r);
401       
402        origin = center + (radius*UniformRandomVector(r[0], r[1]));
403        termination = center + (radius*UniformRandomVector(r[2], r[3]));
404       
405        direction = termination - origin;
406       
407       
408        // $$ jb the pdf is yet not correct for all sampling methods!
409        const float c = Magnitude(direction);
410        if (c <= Limits::Small)
411          return false;
412       
413        direction *= 1.0f / c;
414
415        // check if the ray intersects the view space box
416        static Ray ray;
417        ray.Init(origin, direction, Ray::LOCAL_RAY);   
418       
419        float tmin, tmax;
420        if (mPreprocessor.mViewCellsManager->
421                GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
422          break;
423  }
424 
425  if (i!=tries) {
426        // $$ jb the pdf is yet not correct for all sampling methods!
427        const float pdf = 1.0f;
428       
429       
430        ray = SimpleRay(origin, direction, GLOBAL_LINES_DISTRIBUTION, pdf);
431        ray.mType = Ray::GLOBAL_RAY;
432        return true;
433  }
434 
435  return false;
436}
437
438
439  // has to called before first usage
440void
441MixtureDistribution::Init()
442{
443  for (int i=0; i < mDistributions.size(); i++) {
444        // small non-zero value
445        mDistributions[i]->mRays = 1;
446        mDistributions[i]->mGeneratedRays = 1;
447        // unit contribution per ray
448        if (1 || mDistributions[i]->mType != RSS_BASED_DISTRIBUTION)
449          mDistributions[i]->mContribution = 1.0f;
450        else
451          mDistributions[i]->mContribution = 0.0f;
452  }
453  UpdateRatios();
454}
455
456void
457MixtureDistribution::Reset()
458{
459  for (int i=0; i < mDistributions.size(); i++) {
460        // small non-zero value
461        mDistributions[i]->mTotalRays = 0;
462        // unit contribution per ray
463        mDistributions[i]->mTotalContribution = 0.0f;
464  }
465  UpdateRatios();
466}
467
468// Generate a new sample according to a mixture distribution
469bool
470MixtureDistribution::GenerateSample(SimpleRay &ray)
471{
472  float r;
473
474  sHalton.GetNext(1, &r);
475  //static Halton<1> halton;
476  //  halton.GetNext(&r);
477
478  int i;
479  // pickup a distribution
480  for (i=0; i < mDistributions.size()-1; i++)
481        if (r < mDistributions[i]->mRatio)
482          break;
483
484  bool result = mDistributions[i]->GenerateSample(ray);
485
486  if (result)
487        mDistributions[i]->mGeneratedRays++;
488 
489  return result;
490}
491
492  // add contributions of the sample to the strategies
493void
494MixtureDistribution::ComputeContributions(VssRayContainer &vssRays)
495{
496  int i;
497 
498  VssRayContainer::iterator it = vssRays.begin();
499
500  for (i=0; i < mDistributions.size(); i++) {
501        mDistributions[i]->mContribution = 0;
502        mDistributions[i]->mRays = 0;
503  }
504
505  for(; it != vssRays.end(); ++it) {
506        VssRay *ray = *it;
507        for (i=0; i < mDistributions.size()-1; i++) {
508          if (mDistributions[i]->mType == ray->mDistribution)
509                break;
510        }
511 
512        float contribution =
513          mPreprocessor.mViewCellsManager->ComputeSampleContribution(*ray,
514                                                                                                                                 true,
515                                                                                                                                 false);
516
517        mDistributions[i]->mContribution += contribution;
518        mDistributions[i]->mRays ++;
519       
520        mDistributions[i]->mTotalContribution += contribution;
521        mDistributions[i]->mTotalRays ++;
522  }
523
524#if 0
525  pvsTimer.Entry();
526  // resort pvss
527  mPreprocessor.mViewCellsManager->SortViewCellPvs();
528  pvsTimer.Exit();
529#endif
530
531 
532  UpdateRatios();
533
534#if 1
535  const float vcTime = viewCellCastTimer.TotalTime();
536  const float pvsTime = pvsTimer.TotalTime();
537  const float haltonTime = haltonTimer.TotalTime();
538
539  cout << "view cell cast time: " << vcTime << " s" << endl;
540  cout << "pvs time: " << pvsTime << " s" << endl;
541  cout << "halton time: "<< haltonTime << " s" << endl;
542  // cout<<"obj time:"<<objTimer.TotalTime()<<" s"<<endl;
543
544  Debug << "view cell cast time: " << vcTime << " s" << endl;
545  Debug << "pvs time: " << pvsTime << " s" << endl;
546  Debug << "halton time: "<< haltonTime << " s" << endl;
547#endif
548}
549
550void
551MixtureDistribution::UpdateDistributions(VssRayContainer &vssRays)
552{
553  // now update the distributions with all the rays
554  for (int i=0; i < mDistributions.size(); i++) {
555        mDistributions[i]->Update(vssRays);
556  }
557}
558
559#define RAY_CAST_TIME 0.7f
560#define VIEWCELL_CAST_TIME 0.3f
561
562void
563MixtureDistribution::UpdateRatios()
564{
565  // now compute importance (ratio) of all distributions
566  float sum = 0.0f;
567  int i;
568  for (i=0; i < mDistributions.size(); i++) {
569        cout<<i<<": c="<<mDistributions[i]->mContribution<<
570          " rays="<<mDistributions[i]->mRays<<endl;
571        float importance = 0.0f;
572        if (mDistributions[i]->mRays != 0) {
573          //importance = pow(mDistributions[i]->mContribution/mDistributions[i]->mRays, 2);
574          importance = mDistributions[i]->mContribution/
575                (RAY_CAST_TIME*mDistributions[i]->mGeneratedRays +
576                 VIEWCELL_CAST_TIME*mDistributions[i]->mRays);
577        }
578        mDistributions[i]->mRatio = importance;
579        sum += importance;
580  }
581
582  if (sum == 0.0f)
583        sum = Limits::Small;
584 
585  const float minratio = 0.01f;
586 
587  for (i=0; i < mDistributions.size(); i++) {
588        mDistributions[i]->mRatio /= sum;
589        if (mDistributions[i]->mRatio < minratio)
590          mDistributions[i]->mRatio = minratio;
591  }
592
593  // recaluate the sum after clip
594  sum = 0.0f;
595  for (i=0; i < mDistributions.size(); i++)
596        sum += mDistributions[i]->mRatio;
597
598  for (i=0; i < mDistributions.size(); i++)
599        mDistributions[i]->mRatio /= sum;
600 
601  for (i=1; i < mDistributions.size(); i++) {
602        mDistributions[i]->mRatio = mDistributions[i-1]->mRatio + mDistributions[i]->mRatio;
603  }
604 
605  cout<<"ratios: ";
606  float last = 0.0f;
607  for (i=0; i < mDistributions.size(); i++) {
608        cout<<mDistributions[i]->mRatio-last<<" ";
609        last = mDistributions[i]->mRatio;
610  }
611  cout<<endl;
612}
613
614
615
616bool
617MixtureDistribution::Construct(char *str)
618{
619  char *curr = str;
620
621  while (1) {
622        char *e = strchr(curr,'+');
623        if (e!=NULL) {
624          *e=0;
625        }
626       
627        if (strcmp(curr, "rss")==0) {
628          mDistributions.push_back(new RssBasedDistribution(mPreprocessor));
629        } else
630          if (strcmp(curr, "object")==0) {
631                mDistributions.push_back(new ObjectBasedDistribution(mPreprocessor));
632          } else
633                if (strcmp(curr, "spatial")==0) {
634                  mDistributions.push_back(new SpatialBoxBasedDistribution(mPreprocessor));
635                } else
636                  if (strcmp(curr, "global")==0) {
637                        mDistributions.push_back(new GlobalLinesDistribution(mPreprocessor));
638                  } else
639                        if (strcmp(curr, "direction")==0) {
640                          mDistributions.push_back(new DirectionBasedDistribution(mPreprocessor));
641                        } else
642                          if (strcmp(curr, "object_direction")==0) {
643                                mDistributions.push_back(new ObjectDirectionBasedDistribution(mPreprocessor));
644                          } else
645                                if (strcmp(curr, "reverse_object")==0) {
646                                  mDistributions.push_back(new ReverseObjectBasedDistribution(mPreprocessor));
647                                } else
648                                 
649                                  if (strcmp(curr, "reverse_viewspace_border")==0) {
650                                        mDistributions.push_back(new ReverseViewSpaceBorderBasedDistribution(mPreprocessor));
651                                  } else
652                                        if (strcmp(curr, "mutation")==0) {
653                                         mDistributions.push_back(new MutationBasedDistribution(mPreprocessor));
654                                        }
655       
656       
657        if (e==NULL)
658          break;
659        curr = e+1;
660  }
661
662  Init();
663  return true;
664}
665
666int
667MixtureDistribution::GenerateSamples(const int number,
668                                                                         SimpleRayContainer &rays)
669{
670  for (int i=0; i < mDistributions.size(); i++)
671        mDistributions[i]->mGeneratedRays = 0;
672
673  return SamplingStrategy::GenerateSamples(number, rays);
674}
675
676
677HwGlobalLinesDistribution::HwGlobalLinesDistribution(Preprocessor &preprocessor):
678  SamplingStrategy(preprocessor)
679{
680  mType = HW_GLOBAL_LINES_DISTRIBUTION;
681  preprocessor.mUseHwGlobalLines = true;
682}
683
684bool HwGlobalLinesDistribution::GenerateSample(SimpleRay &ray)
685{
686        Vector3 origin, termination, direction;
687
688        float radius = 0.5f *
689                Magnitude(mPreprocessor.mViewCellsManager->GetViewSpaceBox().Size());
690
691        Vector3 center = mPreprocessor.mViewCellsManager->GetViewSpaceBox().Center();
692
693        const int tries = 1000;
694        int i;
695        for (i=0; i < tries; i++)
696        {
697                float r[2];
698                sHalton.GetNext(2, r);
699
700                origin = center + (radius * UniformRandomVector(r[0], r[1]));
701                termination = center;
702               
703                if (0)
704                {
705                        // add a small offset to provide some more randomness in the sampling
706                        Vector3 offset(Random(radius * 1e-3f),
707                                                   Random(radius * 1e-3f),
708                                                   Random(radius * 1e-3f));
709                        termination += offset;
710                }
711
712                direction = termination - origin;
713
714                // $$ jb the pdf is yet not correct for all sampling methods!
715                const float c = Magnitude(direction);
716
717                if (c <= Limits::Small)
718                        return false;
719
720                direction *= 1.0f / c;
721
722                // check if the ray intersects the view space box
723                static Ray ray;
724                ray.Init(origin, direction, Ray::LOCAL_RAY);   
725
726                float tmin, tmax;
727                if (mPreprocessor.mViewCellsManager->
728                        GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
729                        break;
730        }
731
732        if (i != tries)
733        {
734                // $$ jb the pdf is yet not correct for all sampling methods!
735                const float pdf = 1.0f;
736
737                ray = SimpleRay(origin, direction, HW_GLOBAL_LINES_DISTRIBUTION, pdf);
738                ray.mType = Ray::GLOBAL_RAY;
739                return true;
740        }
741
742        return false;
743}
744
745
746bool ViewCellBasedDistribution::GenerateSample(SimpleRay &ray)
747{
748        Vector3 origin, direction;
749
750        ViewCellContainer &viewCells =
751                mPreprocessor.mViewCellsManager->GetViewCells();
752
753        Vector3 point;
754        Vector3 normal;
755               
756        //Vector normalObj;
757        // float r[1];
758        // sHalton.GetNext(1, r);
759        // const int objIdx = (int)(r[0] * (float)mPreprocessor.mObjects.size() - 1.0f);
760        // Intersectable *object = mPreprocessor.mObjects[objIdx];
761        // object->GetRandomSurfacePoint(point, normal);
762        // cout << "obj: " << objIdx << endl;
763
764        float r[2];
765        sHalton.GetNext(2, r);
766
767        direction = UniformRandomVector(r[0], r[1]);
768        const float c = Magnitude(direction);
769
770    if (c <= Limits::Small)
771                return false;
772
773        direction *= 1.0f / c;
774
775        // get point on view cell surface
776        mViewCell->GetRandomSurfacePoint(origin, normal);
777
778        //direction = point - origin;
779
780        // move a little bit back to avoid piercing through walls
781        // that bound the view cell
782        origin -= 0.01f * normal;
783
784        // $$ jb the pdf is yet not correct for all sampling methods!
785        const float pdf = 1.0f;
786
787        ray = SimpleRay(origin, direction, VIEWCELL_BASED_DISTRIBUTION, pdf);
788
789        //cout << "ray: " << ray.mOrigin << " " << ray.mDirection << endl;
790
791        return true;
792}
793
794
795}
796
797
Note: See TracBrowser for help on using the repository browser.