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

Revision 2353, 20.8 KB checked in by mattausch, 18 years ago (diff)

cleaned up project files

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