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

Revision 2066, 19.5 KB checked in by mattausch, 17 years ago (diff)

worked on integration manual

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