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

Revision 1966, 20.2 KB checked in by bittner, 18 years ago (diff)

samplign preprocessor updates, merge

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