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

Revision 2575, 21.4 KB checked in by bittner, 17 years ago (diff)

big merge: preparation for havran ray caster, check if everything works

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