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

Revision 1883, 11.0 KB checked in by bittner, 18 years ago (diff)

mixture distribution initial coding

Line 
1#include "SamplingStrategy.h"
2#include "Ray.h"
3#include "Intersectable.h"
4#include "Preprocessor.h"
5#include "ViewCellsManager.h"
6#include "AxisAlignedBox3.h"
7
8
9namespace GtpVisibilityPreprocessor {
10
11
12SamplingStrategy::SamplingStrategy(const Preprocessor &preprocessor):
13  mPreprocessor(preprocessor), mRatio(1.0f),  mTotalRays(0), mTotalContribution(0.0f)
14{
15 
16}
17
18
19SamplingStrategy::~SamplingStrategy()
20{
21}
22
23int
24SamplingStrategy::GenerateSamples(const int number,
25                                                                  SimpleRayContainer &rays)
26{
27        SimpleRay ray;
28        int samples = 0;
29        int i = 0;
30        const int maxTries = 20;
31        // tmp changed matt. Q: should one rejected sample
32        // terminate the whole method?
33        if (0)
34        {
35                for (; i < number; i++) {
36                        if (!GenerateSample(ray))
37                                return i;
38                        rays.push_back(ray);
39                }
40        }
41        else
42        {
43                for (; i < number; i++)
44                {
45                        int j = 0;
46                        bool sampleGenerated = false;
47
48                        for (j = 0; !sampleGenerated && (j < maxTries); ++ j)
49                        {
50                                sampleGenerated = GenerateSample(ray);
51
52                                if (sampleGenerated)
53                                {               
54                                        ++ samples;
55                                        rays.push_back(ray);
56                                }
57                        }
58                }
59        }
60       
61        return samples;
62}
63
64
65/*********************************************************************/
66/*            Individual sampling strategies implementation          */
67/*********************************************************************/
68
69
70bool ObjectBasedDistribution::GenerateSample(SimpleRay &ray)
71{
72  Vector3 origin, direction;
73 
74  float r[5];
75  mHalton.GetNext(5, r);
76 
77  mPreprocessor.mViewCellsManager->GetViewPoint(origin,
78                                                                                                Vector3(r[2],r[3],r[4]));
79 
80
81  Vector3 point, normal;
82 
83  r[0] *= mPreprocessor.mObjects.size()-1;
84  const int i = (int)r[0];
85 
86  Intersectable *object = mPreprocessor.mObjects[i];
87 
88  // take the remainder as a parameter over objects surface
89  r[0] -= (float)i;
90 
91  object->GetRandomSurfacePoint(r[0], r[1], point, normal);
92 
93  direction = point - origin;
94 
95  const float c = Magnitude(direction);
96 
97  if (c <= Limits::Small)
98        return false;
99 
100  // $$ jb the pdf is yet not correct for all sampling methods!
101  const float pdf = 1.0f;
102 
103  direction *= 1.0f / c;
104  ray = SimpleRay(origin, direction, OBJECT_BASED_DISTRIBUTION, pdf);
105 
106  return true;
107}
108
109
110bool
111ObjectDirectionBasedDistribution::GenerateSample(SimpleRay &ray)
112{       
113  Vector3 origin, direction;
114
115
116  float r[4];
117  mHalton.GetNext(4, r);
118
119  r[0] *= mPreprocessor.mObjects.size()-1;
120  const int i = (int)r[0];
121 
122  Intersectable *object = mPreprocessor.mObjects[i];
123 
124  // take the remainder as a parameter over objects surface
125  r[0] -= (float)i;
126
127  Vector3 normal;
128
129  object->GetRandomSurfacePoint(r[0], r[1], origin, normal);
130 
131  direction = Normalize(CosineRandomVector(r[2], r[3], normal));
132 
133  origin += 1e-2*direction;
134 
135  // $$ jb the pdf is yet not correct for all sampling methods!
136  const float pdf = 1.0f;
137 
138  ray = SimpleRay(origin, direction, OBJECT_DIRECTION_BASED_DISTRIBUTION, pdf);
139 
140  return true;
141}
142
143
144bool DirectionBasedDistribution::GenerateSample(SimpleRay &ray)
145{       
146        Vector3 origin, direction;
147        mPreprocessor.mViewCellsManager->GetViewPoint(origin);
148         
149        direction = UniformRandomVector();
150        const float c = Magnitude(direction);
151
152        if (c <= Limits::Small)
153                return false;
154
155        const float pdf = 1.0f;
156
157        direction *= 1.0f / c;
158        ray = SimpleRay(origin, direction, DIRECTION_BASED_DISTRIBUTION, pdf);
159
160        return true;
161}
162
163
164bool DirectionBoxBasedDistribution::GenerateSample(SimpleRay &ray)
165{
166        Vector3 origin, direction;
167        mPreprocessor.mViewCellsManager->GetViewPoint(origin);
168
169        const float alpha = RandomValue(0.0f, 2.0f * (float)M_PI);
170        const float beta = RandomValue((float)-M_PI * 0.5f, (float)M_PI * 0.5f);
171       
172        direction = VssRay::GetDirection(alpha, beta);
173       
174        const float c = Magnitude(direction);
175
176        if (c <= Limits::Small)
177                return false;
178
179        const float pdf = 1.0f;
180
181        direction *= 1.0f / c;
182        ray = SimpleRay(origin, direction, DIRECTION_BOX_BASED_DISTRIBUTION, pdf);
183
184        return true;
185}
186
187
188bool SpatialBoxBasedDistribution::GenerateSample(SimpleRay &ray)
189{
190  Vector3 origin, direction;
191
192  float r[6];
193  mHalton.GetNext(6, r);
194  mPreprocessor.mViewCellsManager->GetViewPoint(origin, Vector3(r[0],r[1],r[2]));
195 
196  direction = mPreprocessor.mKdTree->GetBox().GetRandomPoint(Vector3(r[3],
197                                                                                                                                         r[4],
198                                                                                                                                         r[5])
199                                                                                                                                         ) - origin;
200  //cout << "z";
201  const float c = Magnitude(direction);
202 
203  if (c <= Limits::Small)
204        return false;
205 
206  const float pdf = 1.0f;
207 
208  direction *= 1.0f / c;
209  ray = SimpleRay(origin, direction, SPATIAL_BOX_BASED_DISTRIBUTION, pdf);
210 
211  return true;
212}
213
214
215bool ReverseObjectBasedDistribution::GenerateSample(SimpleRay &ray)
216{
217        Vector3 origin, direction;
218
219        mPreprocessor.mViewCellsManager->GetViewPoint(origin);
220
221        Vector3 point;
222        Vector3 normal;
223        //cout << "y";
224        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
225
226        Intersectable *object = mPreprocessor.mObjects[i];
227
228        object->GetRandomSurfacePoint(point, normal);
229       
230        direction = origin - point;
231       
232        // $$ jb the pdf is yet not correct for all sampling methods!
233        const float c = Magnitude(direction);
234       
235        if ((c <= Limits::Small) || (DotProd(direction, normal) < 0))
236        {
237                return false;
238        }
239
240        // $$ jb the pdf is yet not correct for all sampling methods!
241        const float pdf = 1.0f;
242        //cout << "p: " << point << " ";
243        direction *= 1.0f / c;
244        // a little offset
245        point += direction * 0.001f;
246
247        ray = SimpleRay(point, direction, REVERSE_OBJECT_BASED_DISTRIBUTION, pdf);
248       
249        return true;
250}
251
252
253bool ViewCellBorderBasedDistribution::GenerateSample(SimpleRay &ray)
254{
255        Vector3 origin, direction;
256
257        ViewCellContainer &viewCells = mPreprocessor.mViewCellsManager->GetViewCells();
258
259        Vector3 point;
260        Vector3 normal, normal2;
261       
262        const int vcIdx = (int)RandomValue(0, (float)viewCells.size() - 0.5f);
263        const int objIdx = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
264
265        Intersectable *object = mPreprocessor.mObjects[objIdx];
266        ViewCell *viewCell = viewCells[vcIdx];
267
268        //cout << "vc: " << vcIdx << endl;
269        //cout << "obj: " << objIdx << endl;
270
271        object->GetRandomSurfacePoint(point, normal);
272        viewCell->GetRandomEdgePoint(origin, normal2);
273
274        direction = point - origin;
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)*/)
280        {
281                return false;
282        }
283
284        // $$ jb the pdf is yet not correct for all sampling methods!
285        const float pdf = 1.0f;
286        //cout << "p: " << point << " ";
287        direction *= 1.0f / c;
288        ray = SimpleRay(origin, direction, VIEWCELL_BORDER_BASED_DISTRIBUTION, pdf);
289
290        //cout << "ray: " << ray.mOrigin << " " << ray.mDirection << endl;
291
292        return true;
293}
294
295
296#if 0
297bool ObjectsInteriorDistribution::GenerateSample(SimpleRay &ray)
298{
299        Vector3 origin, direction;
300
301        // get random object
302        const int i = RandomValue(0, mPreprocessor.mObjects.size() - 1);
303
304        const Intersectable *obj = mPreprocessor.mObjects[i];
305
306        // note: if we load the polygons as meshes,
307        // asymtotically every second sample is lost!
308        origin = obj->GetBox().GetRandomPoint();
309
310        // uniformly distributed direction
311        direction = UniformRandomVector();
312
313        const float c = Magnitude(direction);
314
315        if (c <= Limits::Small)
316                return false;
317
318        const float pdf = 1.0f;
319
320        direction *= 1.0f / c;
321        ray = SimpleRay(origin, direction, pdf);
322
323        return true;
324}
325
326#endif
327
328
329bool ReverseViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray)
330{
331        Vector3 origin, direction;
332
333        origin = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
334
335        Vector3 point;
336        Vector3 normal;
337        //cout << "y";
338        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
339
340        Intersectable *object = mPreprocessor.mObjects[i];
341
342        object->GetRandomSurfacePoint(point, normal);
343       
344        direction = origin - point;
345       
346        // $$ jb the pdf is yet not correct for all sampling methods!
347        const float c = Magnitude(direction);
348       
349        if ((c <= Limits::Small) || (DotProd(direction, normal) < 0))
350        {
351                return false;
352        }
353
354        // $$ jb the pdf is yet not correct for all sampling methods!
355        const float pdf = 1.0f;
356        //cout << "p: " << point << " ";
357        direction *= 1.0f / c;
358        // a little offset
359        point += direction * 0.001f;
360
361        ray = SimpleRay(point, direction, REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION, pdf);
362       
363        return true;
364}
365
366
367bool ViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray)
368{
369        Vector3 origin, direction;
370
371        origin = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
372
373        Vector3 point;
374        Vector3 normal;
375        //cout << "w";
376        const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
377
378        Intersectable *object = mPreprocessor.mObjects[i];
379
380        object->GetRandomSurfacePoint(point, normal);
381        direction = point - origin;
382
383        // $$ jb the pdf is yet not correct for all sampling methods!
384        const float c = Magnitude(direction);
385
386        if (c <= Limits::Small)
387                return false;
388
389        // $$ jb the pdf is yet not correct for all sampling methods!
390        const float pdf = 1.0f;
391       
392        direction *= 1.0f / c;
393
394        // a little offset
395        origin += direction * 0.001f;
396
397        ray = SimpleRay(origin, direction, VIEWSPACE_BORDER_BASED_DISTRIBUTION, pdf);
398
399        return true;
400}
401
402
403bool
404RssBasedDistribution::GenerateSample(SimpleRay &ray)
405{
406  return false;
407}
408
409
410bool
411GlobalLinesDistribution::GenerateSample(SimpleRay &ray)
412{
413  Vector3 origin, termination, direction;
414
415  float radius = 0.5f*Magnitude(mPreprocessor.mViewCellsManager->GetViewSpaceBox().Size());
416  Vector3 center = mPreprocessor.mViewCellsManager->GetViewSpaceBox().Center();
417
418  const int tries = 1000;
419  int i;
420  for (i=0; i < tries; i++) {
421        float r[4];
422        mHalton.GetNext(4, r);
423       
424        origin = center + (radius*UniformRandomVector(r[0], r[1]));
425        termination = center + (radius*UniformRandomVector(r[2], r[3]));
426       
427        direction = termination - origin;
428       
429       
430        // $$ jb the pdf is yet not correct for all sampling methods!
431        const float c = Magnitude(direction);
432        if (c <= Limits::Small)
433          return false;
434       
435        direction *= 1.0f / c;
436
437        // check if the ray intersects the view space box
438        static Ray ray;
439        ray.Init(origin, direction, Ray::LOCAL_RAY);   
440       
441        float tmin, tmax;
442        if (mPreprocessor.mViewCellsManager->
443                GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
444          break;
445  }
446 
447  if (i!=tries) {
448        // $$ jb the pdf is yet not correct for all sampling methods!
449        const float pdf = 1.0f;
450       
451       
452        ray = SimpleRay(origin, direction, GLOBAL_LINES_DISTRIBUTION, pdf);
453        ray.mType = Ray::GLOBAL_RAY;
454        return true;
455  }
456 
457  return false;
458}
459
460
461  // has to called before first usage
462void
463MixtureDistribution::Init()
464{
465 
466}
467 
468  // Generate a new sample according to a mixture distribution
469bool
470MixtureDistribution::GenerateSample(SimpleRay &ray)
471{
472
473  return false;
474}
475
476  // add contributions of the sample to the strategies
477void
478MixtureDistribution::UpdateContributions(VssRayContainer &vssRays)
479{
480
481}
482
483}
484
485
Note: See TracBrowser for help on using the repository browser.