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

Revision 2614, 22.0 KB checked in by mattausch, 17 years ago (diff)

worked on dynamic objects

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