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

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