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

Revision 1867, 10.4 KB checked in by bittner, 18 years ago (diff)

merge, global lines, rss sampling updates

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