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

Revision 2698, 21.6 KB checked in by bittner, 16 years ago (diff)

merge on nemo

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