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

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