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

Revision 2582, 21.4 KB checked in by bittner, 16 years ago (diff)

Havran Ray Caster compiles and links, but still does not work

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