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

Revision 2069, 19.5 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 pvsTimer;
15extern 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       
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 
560  UpdateRatios();
561
562#if 1
563  cout<<"view cell cast time:"<<viewCellCastTimer.TotalTime()<<" s"<<endl;
564  cout<<"pvs time:"<<pvsTimer.TotalTime()<<" s"<<endl;
565  //  cout<<"obj time:"<<objTimer.TotalTime()<<" s"<<endl;
566#endif
567}
568
569void
570MixtureDistribution::UpdateDistributions(VssRayContainer &vssRays)
571{
572  // now update the distributions with all the rays
573  for (int i=0; i < mDistributions.size(); i++) {
574        mDistributions[i]->Update(vssRays);
575  }
576}
577
578#define RAY_CAST_TIME 0.7f
579#define VIEWCELL_CAST_TIME 0.3f
580
581void
582MixtureDistribution::UpdateRatios()
583{
584  // now compute importance (ratio) of all distributions
585  float sum = 0.0f;
586  int i;
587  for (i=0; i < mDistributions.size(); i++) {
588        cout<<i<<": c="<<mDistributions[i]->mContribution<<
589          " rays="<<mDistributions[i]->mRays<<endl;
590        float importance = 0.0f;
591        if (mDistributions[i]->mRays != 0) {
592          //importance = pow(mDistributions[i]->mContribution/mDistributions[i]->mRays, 2);
593          importance = mDistributions[i]->mContribution/
594                (RAY_CAST_TIME*mDistributions[i]->mGeneratedRays +
595                 VIEWCELL_CAST_TIME*mDistributions[i]->mRays);
596        }
597        mDistributions[i]->mRatio = importance;
598        sum += importance;
599  }
600
601  if (sum == 0.0f)
602        sum = Limits::Small;
603 
604  const float minratio = 0.01f;
605 
606  for (i=0; i < mDistributions.size(); i++) {
607        mDistributions[i]->mRatio /= sum;
608        if (mDistributions[i]->mRatio < minratio)
609          mDistributions[i]->mRatio = minratio;
610  }
611
612  // recaluate the sum after clip
613  sum = 0.0f;
614  for (i=0; i < mDistributions.size(); i++)
615        sum += mDistributions[i]->mRatio;
616
617  for (i=0; i < mDistributions.size(); i++)
618        mDistributions[i]->mRatio /= sum;
619 
620  for (i=1; i < mDistributions.size(); i++) {
621        mDistributions[i]->mRatio = mDistributions[i-1]->mRatio + mDistributions[i]->mRatio;
622  }
623 
624  cout<<"ratios: ";
625  float last = 0.0f;
626  for (i=0; i < mDistributions.size(); i++) {
627        cout<<mDistributions[i]->mRatio-last<<" ";
628        last = mDistributions[i]->mRatio;
629  }
630  cout<<endl;
631}
632
633
634
635bool
636MixtureDistribution::Construct(char *str)
637{
638  char *curr = str;
639
640  while (1) {
641        char *e = strchr(curr,'+');
642        if (e!=NULL) {
643          *e=0;
644        }
645       
646        if (strcmp(curr, "rss")==0) {
647          mDistributions.push_back(new RssBasedDistribution(mPreprocessor));
648        } else
649          if (strcmp(curr, "object")==0) {
650                mDistributions.push_back(new ObjectBasedDistribution(mPreprocessor));
651          } else
652                if (strcmp(curr, "spatial")==0) {
653                  mDistributions.push_back(new SpatialBoxBasedDistribution(mPreprocessor));
654                } else
655                  if (strcmp(curr, "global")==0) {
656                        mDistributions.push_back(new GlobalLinesDistribution(mPreprocessor));
657                  } else
658                        if (strcmp(curr, "direction")==0) {
659                          mDistributions.push_back(new DirectionBasedDistribution(mPreprocessor));
660                        } else
661                          if (strcmp(curr, "object_direction")==0) {
662                                mDistributions.push_back(new ObjectDirectionBasedDistribution(mPreprocessor));
663                          } else
664                                if (strcmp(curr, "reverse_object")==0) {
665                                  mDistributions.push_back(new ReverseObjectBasedDistribution(mPreprocessor));
666                                } else
667                                 
668                                  if (strcmp(curr, "reverse_viewspace_border")==0) {
669                                        mDistributions.push_back(new ReverseViewSpaceBorderBasedDistribution(mPreprocessor));
670                                  } else
671                                        if (strcmp(curr, "mutation")==0) {
672                                         mDistributions.push_back(new MutationBasedDistribution(mPreprocessor));
673                                        }
674       
675       
676        if (e==NULL)
677          break;
678        curr = e+1;
679  }
680
681  Init();
682  return true;
683}
684
685int
686MixtureDistribution::GenerateSamples(const int number,
687                                                                         SimpleRayContainer &rays)
688{
689  for (int i=0; i < mDistributions.size(); i++)
690        mDistributions[i]->mGeneratedRays = 0;
691
692  return SamplingStrategy::GenerateSamples(number, rays);
693}
694
695
696
697bool HwGlobalLinesDistribution::GenerateSample(SimpleRay &ray)
698{
699        Vector3 origin, termination, direction;
700
701        float radius = 0.5f *
702                Magnitude(mPreprocessor.mViewCellsManager->GetViewSpaceBox().Size());
703
704        Vector3 center = mPreprocessor.mViewCellsManager->GetViewSpaceBox().Center();
705
706        const int tries = 1000;
707        int i;
708        for (i=0; i < tries; i++)
709        {
710                float r[2];
711                sHalton.GetNext(2, r);
712
713                origin = center + (radius * UniformRandomVector(r[0], r[1]));
714                termination = center;
715               
716                if (0)
717                {
718                        // add a small offset to provide some more randomness in the sampling
719                        Vector3 offset(Random(radius * 1e-3f),
720                                                   Random(radius * 1e-3f),
721                                                   Random(radius * 1e-3f));
722                        termination += offset;
723                }
724
725                direction = termination - origin;
726
727                // $$ jb the pdf is yet not correct for all sampling methods!
728                const float c = Magnitude(direction);
729
730                if (c <= Limits::Small)
731                        return false;
732
733                direction *= 1.0f / c;
734
735                // check if the ray intersects the view space box
736                static Ray ray;
737                ray.Init(origin, direction, Ray::LOCAL_RAY);   
738
739                float tmin, tmax;
740                if (mPreprocessor.mViewCellsManager->
741                        GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
742                        break;
743        }
744
745        if (i != tries)
746        {
747                // $$ jb the pdf is yet not correct for all sampling methods!
748                const float pdf = 1.0f;
749
750                ray = SimpleRay(origin, direction, HW_GLOBAL_LINES_DISTRIBUTION, pdf);
751                ray.mType = Ray::GLOBAL_RAY;
752                return true;
753        }
754
755        return false;
756}
757
758
759bool ViewCellBasedDistribution::GenerateSample(SimpleRay &ray)
760{
761        Vector3 origin, direction;
762
763        ViewCellContainer &viewCells =
764                mPreprocessor.mViewCellsManager->GetViewCells();
765
766        Vector3 point;
767        Vector3 normal;
768               
769        //Vector normalObj;
770        // float r[1];
771        // sHalton.GetNext(1, r);
772        // const int objIdx = (int)(r[0] * (float)mPreprocessor.mObjects.size() - 1.0f);
773        // Intersectable *object = mPreprocessor.mObjects[objIdx];
774        // object->GetRandomSurfacePoint(point, normal);
775        // cout << "obj: " << objIdx << endl;
776
777        float r[2];
778        sHalton.GetNext(2, r);
779
780        direction = UniformRandomVector(r[0], r[1]);
781        const float c = Magnitude(direction);
782
783    if (c <= Limits::Small)
784                return false;
785
786        direction *= 1.0f / c;
787
788        // get point on view cell surface
789        mViewCell->GetRandomSurfacePoint(origin, normal);
790
791        //direction = point - origin;
792
793        // move a little bit back to avoid piercing through walls
794        // that bound the view cell
795        origin -= 0.01f * normal;
796
797        // $$ jb the pdf is yet not correct for all sampling methods!
798        const float pdf = 1.0f;
799
800        ray = SimpleRay(origin, direction, VIEWCELL_BASED_DISTRIBUTION, pdf);
801
802        //cout << "ray: " << ray.mOrigin << " " << ray.mDirection << endl;
803
804        return true;
805}
806
807
808}
809
810
Note: See TracBrowser for help on using the repository browser.