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

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