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

Revision 2698, 21.6 KB checked in by bittner, 16 years ago (diff)

merge on nemo

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