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

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