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

Revision 1968, 21.7 KB checked in by mattausch, 18 years ago (diff)

early exit for global lines
preprocessor support

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