source: GTP/trunk/Lib/Vis/Preprocessing/src/Mutation.cpp @ 2590

Revision 2590, 21.3 KB checked in by bittner, 17 years ago (diff)

minor edits

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#include "RssTree.h"
8#include "Vector2.h"
9#include "RndGauss.h"
10#include "Mutation.h"
11#include "Exporter.h"
12#include "Environment.h"
13#include "RayCaster.h"
14
15#ifdef GTP_INTERNAL
16#include "ArchModeler2MLRT.hxx"
17#endif
18
19namespace GtpVisibilityPreprocessor {
20
21#define MUTATION_USE_CDF 0
22
23  //#define SIL_TERMINATION_MUTATION_PROB 0.8f
24
25#define EVALUATE_MUTATION_STATS 1
26
27//#define Q_SEARCH_STEPS 3
28
29// VH - commened out !!!!! 8/1/2008
30#define SORT_RAY_ENTRIES 1
31
32// use avg ray contribution as importance
33// if 0 the importance is evaluated from the succ of mutations
34#define USE_AVG_CONTRIBUTION 1
35
36MutationBasedDistribution::RayEntry &
37MutationBasedDistribution::GetEntry(const int index)
38{
39#if SORT_RAY_ENTRIES
40  return mRays[index];
41#else
42  return mRays[(mBufferStart+index)%mRays.size()];
43#endif
44}
45
46void
47MutationBasedDistribution::Update(VssRayContainer &vssRays)
48{
49  //  for (int i=0; i < mRays.size(); i++)
50  //    cout<<mRays[i].mMutations<<" ";
51  //  cout<<endl;
52  cerr<<"Mutation update..."<<endl;
53  cerr<<"rays = "<<mRays.size()<<endl;
54  if ((int)mRays.size()) {
55        cerr<<"Oversampling factors = "<<
56          GetEntry(0).mMutations<<" "<<
57          GetEntry(1).mMutations<<" "<<
58          GetEntry(2).mMutations<<" "<<
59          GetEntry(3).mMutations<<" "<<
60          GetEntry(4).mMutations<<" "<<
61          GetEntry(5).mMutations<<" ... "<<
62          GetEntry((int)mRays.size()-6).mMutations<<" "<<
63          GetEntry((int)mRays.size()-5).mMutations<<" "<<
64          GetEntry((int)mRays.size()-4).mMutations<<" "<<
65          GetEntry((int)mRays.size()-3).mMutations<<" "<<
66          GetEntry((int)mRays.size()-2).mMutations<<" "<<
67          GetEntry((int)mRays.size()-1).mMutations<<endl;
68  }
69  int contributingRays = 0;
70
71  int mutationRays = 0;
72  int dummyNcMutations = 0;
73  int dummyCMutations = 0;
74
75  int reverseCandidates = 0;
76
77#if 0
78  sort(mRays.begin(), mRays.end());
79  // reset the start of the buffer
80  mBufferStart = 0;
81#endif
82
83  for (int i=0; i < vssRays.size(); i++) {
84        if (vssRays[i]->mPvsContribution) {
85          // reset the counter of unsuccsseful mutation for a generating ray (if it exists)
86          if (vssRays[i]->mDistribution == MUTATION_BASED_DISTRIBUTION &&
87                  vssRays[i]->mGeneratorId != -1
88                  ) {
89                mRays[vssRays[i]->mGeneratorId].mUnsuccessfulMutations = 0;
90#if EVALUATE_MUTATION_STATS
91                mutationRays++;
92               
93                Intersectable *newObject = vssRays[i]->mTerminationObject;
94
95                Intersectable *oldObject = mRays[vssRays[i]->mGeneratorId].mRay->mTerminationObject;
96               
97                if (oldObject == newObject)
98                  dummyCMutations++;
99#endif
100          }
101          contributingRays++;
102          if (mRays.size() < mMaxRays) {
103                VssRay *newRay = new VssRay(*vssRays[i]);
104                // add this ray
105                newRay->Ref();
106                mRays.push_back(RayEntry(newRay));
107          } else {
108                // unref the old ray
109                *mRays[mBufferStart].mRay = *vssRays[i];
110                mRays[mBufferStart].mMutations = 0;
111                mRays[mBufferStart].mUnsuccessfulMutations = 0;
112                mRays[mBufferStart].ResetReverseMutation();
113                //              mRays[mBufferStart] = RayEntry(newRay);
114                mBufferStart++;
115                if (mBufferStart >= mMaxRays)
116                  mBufferStart = 0;
117          }
118        } else {
119          if (vssRays[i]->mDistribution == MUTATION_BASED_DISTRIBUTION &&
120                  vssRays[i]->mGeneratorId != -1
121                  ) {
122                // check whether not to store a new backward mutation candidate
123                VssRay *oldRay = mRays[vssRays[i]->mGeneratorId].mRay;
124                VssRay *newRay = vssRays[i];
125
126
127                Intersectable *oldObject = oldRay->mTerminationObject;
128               
129
130                if (!mRays[newRay->mGeneratorId].HasReverseMutation()) {
131                  if (DotProd(oldRay->GetDir(), newRay->GetDir()) > 0.0f) {
132                  float oldDist = Magnitude(oldRay->mTermination - newRay->mOrigin);
133                  float newDist = Magnitude(newRay->mTermination - newRay->mOrigin);
134                 
135                  if (newDist < oldDist - oldObject->GetBox().Radius()*mReverseSamplesDistance) {
136                        Vector3 origin, termination;
137                        if (ComputeReverseMutation(*oldRay, *newRay, origin, termination)) {
138                          mRays[newRay->mGeneratorId].SetReverseMutation(origin, termination);
139                        }
140                       
141                        reverseCandidates++;
142                        //mReverseCandidates
143                  }
144                  }
145                }
146#if EVALUATE_MUTATION_STATS
147                mutationRays++;
148               
149                Intersectable *newObject = vssRays[i]->mTerminationObject;
150
151
152                if (oldObject == newObject)
153                  dummyNcMutations++;
154#endif
155          }
156        }
157  }
158 
159  if (mutationRays) {
160        cout<<"Mutated rays:"<<mutationRays<<endl;
161        cout<<"Dummy mutations ratio:"<<100.0f*(dummyCMutations + dummyNcMutations)/
162          (float)mutationRays<<"%"<<endl;
163        cout<<"Dummy NC mutations ratio:"<<100.0f*dummyNcMutations/(float)mutationRays<<"%"<<endl;
164        cout<<"Dummy C mutations ratio:"<<100.0f*dummyCMutations/(float)mutationRays<<"%"<<endl;
165        cout<<"Reverse candidates:"<<reverseCandidates<<endl;
166  }
167 
168  float pContributingRays = contributingRays/(float)vssRays.size();
169 
170  cout<<"Percentage of contributing rays:"<<pContributingRays<<endl;
171 
172  if (mUseUnsuccCountImportance) {
173        // use unsucc mutation samples as feedback on importance
174        for (int i=0; i < mRays.size(); i++) {
175          const float  minImportance = 0.1f;
176          const int minImportanceSamples = 20;
177          mRays[i].mImportance = minImportance +
178                (1-minImportance)*exp(-3.0f*mRays[i].mUnsuccessfulMutations/minImportanceSamples);
179        }
180  } else {
181        float importance = 1.0f;
182        if (mUsePassImportance)
183          importance = 1.0f/(pContributingRays + 1e-5);
184        // set this values for last contributingRays
185        int index = mBufferStart - 1;
186       
187        for (int i=0; i < contributingRays; i++, index--) {
188          if (index < 0)
189                index = (int)mRays.size()-1;
190          mRays[index].mImportance = importance;
191        }
192  }
193 
194#if SORT_RAY_ENTRIES
195  long t1 = GetTime();
196  sort(mRays.begin(), mRays.end());
197  // reset the start of the buffer
198  mBufferStart = 0;
199  mLastIndex = (int)mRays.size();
200  cout<<"Mutation candidates sorted in "<<TimeDiff(t1, GetTime())<<" ms."<<endl;
201#endif
202                                                                                                                                                                 
203#if MUTATION_USE_CDF
204  // compute cdf
205  mRays[0].mCdf = mRays[0].mImportance/(mRays[0].mMutations+1);
206  for (int i=1; i < mRays.size(); i++)
207        mRays[i].mCdf = mRays[i-1].mCdf + mRays[i].mImportance/(mRays[i].mMutations+1);
208 
209  float scale = 1.0f/mRays[i-1].mCdf;
210  for (i=0; i < mRays.size(); i++) {
211        mRays[i].mCdf *= scale;
212  }
213#endif
214 
215  cout<<"Importance = "<<
216        GetEntry(0).mImportance<<" "<<
217        GetEntry((int)mRays.size()-1).mImportance<<endl;
218
219  cout<<"Sampling factor = "<<
220        GetEntry(0).GetSamplingFactor()<<" "<<
221        GetEntry((int)mRays.size()-1).GetSamplingFactor()<<endl;
222
223  cerr<<"Mutation update done."<<endl;
224}
225
226
227Vector3
228MutationBasedDistribution::ComputeOriginMutation(const VssRay &ray,
229                                                                                                 const Vector3 &U,
230                                                                                                 const Vector3 &V,
231                                                                                                 const Vector2 vr2,
232                                                                                                 const float radius
233                                                                                                 )
234{
235#if 0
236  Vector3 v;
237  if (d.DrivingAxis() == 0)
238        v = Vector3(0, r[0]-0.5f, r[1]-0.5f);
239  else
240        if (d.DrivingAxis() == 1)
241          v = Vector3(r[0]-0.5f, 0, r[1]-0.5f);
242        else
243          v = Vector3(r[0]-0.5f, r[1]-0.5f, 0);
244  return v*(2*radius);
245#endif
246#if 0
247  return (U*(r[0] - 0.5f) + V*(r[1] - 0.5f))*(2*radius);
248#endif
249
250
251  // Output random variable
252  Vector2 gaussvec2;
253 
254  // Here we apply transform to gaussian, so 2D bivariate
255  // normal distribution
256  //  float sigma = ComputeSigmaFromRadius(radius);
257  float sigma = radius;
258  GaussianOn2D(vr2,
259                           sigma, // input
260                           gaussvec2);  // output
261
262       
263    // Here we tranform the point correctly to 3D space using base
264    // vectors of the 3D space defined by the direction
265    Vector3 shift = gaussvec2.xx * U + gaussvec2.yy * V;
266       
267        //      cout<<shift<<endl;
268        return shift;
269}
270
271Vector3
272MutationBasedDistribution::ComputeTerminationMutation(const VssRay &ray,
273                                                                                                          const Vector3 &U,
274                                                                                                          const Vector3 &V,
275                                                                                                          const Vector2 vr2,
276                                                                                                          const float radius
277                                                                                                          )
278{
279#if 0
280  return (U*(vr2.xx - 0.5f) + V*(vr2.yy - 0.5f))*(4.0f*radius);
281#endif
282  Vector2 gaussvec2;
283#if 1
284  float sigma = radius;
285  GaussianOn2D(vr2,
286                           sigma, // input
287                           gaussvec2);  // output
288  Vector3 shift = gaussvec2.xx * U + gaussvec2.yy * V;
289  //    cout<<shift<<endl;
290  return shift;
291#endif
292#if 0
293  // Here we estimate standard deviation (sigma) from radius
294  float sigma = 1.1f*ComputeSigmaFromRadius(radius);
295  Vector3 vr3(vr2.xx, vr2.yy, RandomValue(0,1));
296  PolarGaussianOnDisk(vr3,
297                                          sigma,
298                                          radius, // input
299                                          gaussvec2); // output
300 
301  // Here we tranform the point correctly to 3D space using base
302  // vectors of the 3D space defined by the direction
303  Vector3 shift = gaussvec2.xx * U + gaussvec2.yy * V;
304 
305  //    cout<<shift<<endl;
306  return shift;
307#endif
308}
309
310bool
311MutationBasedDistribution::ComputeReverseMutation(
312                                                                                                  const VssRay &oldRay,
313                                                                                                  const VssRay &newRay,
314                                                                                                  Vector3 &origin,
315                                                                                                  Vector3 &termination
316                                                                                                  )
317{
318#ifdef GTP_INTERNAL
319
320  // first reconstruct the termination point
321  Vector3 oldDir = Normalize(oldRay.GetDir());
322  Plane3 oldPlane(oldDir, oldRay.mTermination);
323 
324  termination = oldPlane.FindIntersection(newRay.mOrigin,
325                                                                                  newRay.mTermination);
326 
327  // now find the new origin of the ray by casting ray backward from the termination and termining
328  // silhouette point with respect to the occluding object (object containing the newRay termination)
329
330  Plane3 newPlane(oldDir, newRay.mTermination);
331
332  Vector3 oldPivot = newPlane.FindIntersection(oldRay.mOrigin,
333                                                                                           oldRay.mTermination);
334
335  Vector3 newPivot = newRay.mTermination;
336  Vector3 line = 2.0f*(oldPivot - newPivot);
337
338  Intersectable *occluder = newRay.mTerminationObject;
339 
340  AxisAlignedBox3 box = occluder->GetBox();
341  box.Scale(2.0f);
342 
343  const int packetSize = 4;
344  static int hit_triangles[packetSize];
345  static float dist[packetSize];
346  static Vector3 dirs[packetSize];
347  static Vector3 shifts[packetSize];
348  static Vector3 origs[packetSize];
349  // now find the silhouette along the line
350  int i;
351  float left = 0.0f;
352  float right = 1.0f;
353
354  // cast rays to find silhouette ray
355  for (int j=0; j < mSilhouetteSearchSteps; j++) {
356        for (i=0; i < packetSize; i++) {
357          float r = left + (i+1)*(right-left)/(packetSize+1);
358          shifts[i] = r*line;
359          dirs[i] = Normalize(newPivot + shifts[i] - termination );
360          origs[i] = termination;
361          // mlrtaStoreRayASEye4(&termination.x, &dirs[i].x, i);
362        }
363
364        // mlrtaTraverseGroupASEye4(&box.Min().x, &box.Max().x, hit_triangles, dist);
365        assert(preprocessor->mRayCaster);
366        preprocessor->mRayCaster->CastRaysPacket4(box.Min(),
367                                                                                          box.Max(),
368                                                                                          origs,
369                                                                                          dirs,
370                                                                                          hit_triangles,
371                                                                                          dist);       
372       
373        for (i=0; i < packetSize; i++) {
374          //cout<<hit_triangles[i]<<endl;
375          if (hit_triangles[i] == -1) {
376                // break on first passing ray
377            break;
378          }
379        }
380        float rr = left + (i+1)*(right-left)/(packetSize+1);
381        float rl = left + i*(right-left)/(packetSize+1);
382        left = rl;
383        right = rr;
384  }
385
386  float t = right;
387  if (right==1.0f)
388        return false;
389 
390  if (i == packetSize)
391        origin = newPivot + right*line;
392  else
393        origin = newPivot + shifts[i];
394
395  if (0) {
396       
397        static VssRayContainer rRays;
398        static int counter = 0;
399        char filename[256];
400
401        if (counter < 50) {
402          sprintf(filename, "reverse_rays_%03d.x3d", counter++);
403         
404          VssRay tRay(origin, termination, NULL, NULL);
405          rRays.push_back((VssRay *)&oldRay);
406          rRays.push_back((VssRay *)&newRay);
407          rRays.push_back(&tRay);
408         
409          Exporter *exporter = NULL;
410          exporter = Exporter::GetExporter(filename);
411         
412          exporter->SetFilled();
413         
414          Intersectable *occludee =
415                oldRay.mTerminationObject;
416         
417          exporter->SetForcedMaterial(RgbColor(0,0,1));
418          exporter->ExportIntersectable(occluder);
419          exporter->SetForcedMaterial(RgbColor(0,1,0));
420          exporter->ExportIntersectable(occludee);
421          exporter->ResetForcedMaterial();
422         
423          exporter->SetWireframe();
424         
425         
426          exporter->ExportRays(rRays, RgbColor(1, 0, 0));
427          delete exporter;
428          rRays.clear();
429        }
430  }
431
432#else
433  cerr << "warning: reverse mutation not supported!" << endl;
434#endif
435 
436  return true;
437 
438  // now the origin and termination is swapped compred to the generator ray
439  // swap(origin, termination);???
440  // -> perhaps not neccessary as the reverse mutation wil only be used once!
441}
442
443Vector3
444MutationBasedDistribution::ComputeSilhouetteTerminationMutation(const VssRay &ray,
445                                                                                                                                const Vector3 &origin,
446                                                                                                                                const AxisAlignedBox3 &box,
447                                                                                                                                const Vector3 &U,
448                                                                                                                                const Vector3 &V,
449                                                                                                                                const float radius
450                                                                                                                                )
451{
452#ifdef GTP_INTERNAL
453
454  const int packetSize = 4;
455  static int hit_triangles[packetSize];
456  static float dist[packetSize];
457  static Vector3 dirs[packetSize];
458  static Vector3 shifts[packetSize];
459  static Vector3 origs[packetSize];
460  // mutate the
461  float alpha = RandomValue(0.0f, Real(2.0*M_PI));
462  //float alpha = vr2.x*2.0f*M_PI;
463 
464  // direction along which we will mutate the ray
465  Vector3 line = sin(alpha)*U + cos(alpha)*V;
466 
467  //  cout<<line<<endl;
468  // create 16 rays along the selected dir
469  int i;
470  float left = 0.0f;
471  float right = radius;
472  // cast rays to find silhouette ray
473  for (int j=0; j < mSilhouetteSearchSteps; j++) {
474        for (i=0; i < packetSize; i++) {
475          float r = left + (i+1)*(right-left)/(packetSize+1);
476          shifts[i] = r*line;
477          dirs[i] = Normalize(ray.mTermination + shifts[i] - origin );
478          origs[i] = origin;
479          //mlrtaStoreRayASEye4(&origin.x, &dirs[i].x, i);
480        }
481       
482        // mlrtaTraverseGroupASEye4(&box.Min().x, &box.Max().x, hit_triangles, dist);
483        assert(preprocessor->mRayCaster);
484        preprocessor->mRayCaster->CastRaysPacket4(box.Min(), box.Max(),
485                                                  origs, dirs, hit_triangles, dist);       
486       
487        for (i=0; i < packetSize; i++) {
488          if (hit_triangles[i] == -1) {
489                //        if (hit_triangles[i] == -1 || !box.IsInside(origin + dist[i]*dirs[i])) {
490                // break on first passing ray
491                break;
492          }
493        }
494        float rr = left + (i+1)*(right-left)/(packetSize+1);
495        float rl = left + i*(right-left)/(packetSize+1);
496        left = rl;
497        right = rr;
498  }
499 
500  if (i == packetSize) {
501        //      cerr<<"Warning: hit the same box here should never happen!"<<endl;
502        // shift the ray even a bit more
503        //cout<<"W"<<i<<endl;
504        //      return (RandomValue(1.0f, 1.5f)*radius)*line;
505        return right*line;
506  }
507 
508  //  cout<<i<<endl;
509  return shifts[i];
510
511#else
512        cerr << "warning: shiluette mutation not supported" << endl;
513        return Vector3(0, 0, 0);
514#endif
515 
516}
517
518
519bool
520MutationBasedDistribution::GenerateSample(SimpleRay &sray)
521{
522
523  if (mRays.size() == 0) {
524        float rr[5];
525        // use direction based distribution
526        Vector3 origin, direction;
527
528        for (int i=0; i < 5; i++)
529          rr[i] = RandomValue(0,1);
530       
531        mPreprocessor.mViewCellsManager->GetViewPoint(origin,
532                                                                                                  Vector3(rr[0], rr[1], rr[2]));
533       
534
535        direction = UniformRandomVector(rr[3], rr[4]);
536       
537        const float pdf = 1.0f;
538        sray = SimpleRay(origin, direction, MUTATION_BASED_DISTRIBUTION, pdf);
539        sray.mGeneratorId = -1;
540
541        return true;
542  }
543
544  int index;
545
546#if !MUTATION_USE_CDF
547#if SORT_RAY_ENTRIES
548  index = mLastIndex - 1;
549  if (index < 0 || index >= mRays.size()-1) {
550        index = (int)mRays.size() - 1;
551  } else
552        if (
553                mRays[index].GetSamplingFactor() >= mRays[mLastIndex].GetSamplingFactor()) {
554          // make another round
555
556          //      cout<<"R2"<<endl;
557          //      cout<<mLastIndex<<endl;
558          //      cout<<index<<endl;
559          index = (int)mRays.size() - 1;
560        }
561#else
562  // get tail of the buffer
563  index = (mLastIndex+1)%mRays.size();
564  if (mRays[index].GetSamplingFactor() >
565          mRays[mLastIndex].GetSamplingFactor()) {
566        // search back for index where this is valid
567        index = (mLastIndex - 1 + mRays.size())%mRays.size();
568        for (int i=0; i < mRays.size(); i++) {
569         
570          //      if (mRays[index].mMutations > mRays[mLastIndex].mMutations)
571          //            break;
572          if (mRays[index].GetSamplingFactor() >
573                  mRays[mLastIndex].GetSamplingFactor() )
574                break;
575          index = (index - 1 + mRays.size())%mRays.size();
576        }
577        // go one step back
578        index = (index+1)%mRays.size();
579  }
580#endif
581#else
582  static HaltonSequence iHalton;
583  iHalton.GetNext(1, rr);
584  //rr[0] = RandomValue(0,1);
585  // use binary search to find index with this cdf
586  int l=0, r=(int)mRays.size()-1;
587  while(l<r) {
588        int i = (l+r)/2;
589        if (rr[0] < mRays[i].mCdf )
590          r = i;
591        else
592          l = i+1;
593  }
594  index = l;
595  //  if (rr[0] >= mRays[r].mCdf)
596  //    index = r;
597  //  else
598  //    index = l;
599       
600       
601#endif
602  //  cout<<index<<" "<<rr[0]<<" "<<mRays[index].mCdf<<" "<<mRays[(index+1)%mRays.size()].mCdf<<endl;
603
604  mLastIndex = index;
605  //  Debug<<index<<" "<<mRays[index].GetSamplingFactor()<<endl;
606 
607  if (mRays[index].HasReverseMutation()) {
608        //cout<<"R "<<mRays[index].mutatedOrigin<<" "<<mRays[index].mutatedTermination<<endl;
609        sray = SimpleRay(mRays[index].mutatedOrigin,
610                                         Normalize(mRays[index].mutatedTermination - mRays[index].mutatedOrigin),
611                                         MUTATION_BASED_DISTRIBUTION,
612                                         1.0f);
613       
614       
615        sray.mGeneratorId = index;
616        mRays[index].ResetReverseMutation();
617        mRays[index].mMutations++;
618        mRays[index].mUnsuccessfulMutations++;
619       
620        return true;
621  }
622
623  return GenerateMutation(index, sray);
624}
625
626
627
628
629
630bool
631MutationBasedDistribution::GenerateMutationCandidate(const int index,
632                                                                                                         SimpleRay &sray,
633                                                                                                         Intersectable *object,
634                                                                                                         const AxisAlignedBox3 &box
635                                                                                                         )
636{
637  float rr[4];
638
639  VssRay *ray = mRays[index].mRay;
640
641  //  rr[0] = RandomValue(0.0f,0.99999f);
642  //  rr[1] = RandomValue(0.0f,0.99999f);
643  //  rr[2] = RandomValue(0.0f,0.99999f);
644  //  rr[3] = RandomValue(0.0f,0.99999f);
645 
646  // mutate the origin
647  Vector3 d = ray->GetDir();
648 
649  float objectRadius = box.Radius();
650  //  cout<<objectRadius<<endl;
651  if (objectRadius < Limits::Small)
652        return false;
653 
654  // Compute right handed coordinate system from direction
655  Vector3 U, V;
656  Vector3 nd = Normalize(d);
657  nd.RightHandedBase(U, V);
658 
659  Vector3 origin = ray->mOrigin;
660  Vector3 termination = ray->mTermination; //box.Center(); //ray->mTermination; //box.Center();
661
662 
663  // use probabilitistic approach to decide for the type of mutation
664  float a = RandomValue(0.0f,1.0f);
665  bool bidirectional = true;
666 
667  if (mUseSilhouetteSamples && a < mSilhouetteProb) {
668       
669        termination += ComputeSilhouetteTerminationMutation(*ray,
670                                                                                                                origin,
671                                                                                                                box,
672                                                                                                                U, V,
673                                                                                                                2.0f*objectRadius);
674        bidirectional = false;
675  } else {
676        mRays[index].mHalton.GetNext(4, rr);
677
678        // fuzzy random mutation
679        origin += ComputeOriginMutation(*ray, U, V,
680                                                                        Vector2(rr[0], rr[1]),
681                                                                        mMutationRadiusOrigin*objectRadius);
682       
683        termination += ComputeTerminationMutation(*ray, U, V,
684                                                                                          Vector2(rr[2], rr[3]),
685                                                                                          mMutationRadiusTermination*objectRadius);
686  }
687
688  Vector3 direction = termination - origin;
689 
690  if (Magnitude(direction) < Limits::Small)
691        return false;
692 
693  // shift the origin a little bit
694  origin += direction*0.5f;
695 
696  direction.Normalize();
697 
698  // $$ jb the pdf is yet not correct for all sampling methods!
699  const float pdf = 1.0f;
700 
701  sray = SimpleRay(origin, direction, MUTATION_BASED_DISTRIBUTION, pdf);
702  sray.mGeneratorId = index;
703  sray.SetBidirectional(bidirectional);
704 
705  return true;
706}
707
708bool
709MutationBasedDistribution::GenerateMutation(const int index, SimpleRay &sray)
710{
711  VssRay *ray = mRays[index].mRay;
712
713  Intersectable *object = ray->mTerminationObject;
714 
715  AxisAlignedBox3 box = object->GetBox();
716 
717  if (GenerateMutationCandidate(index, sray, object, box)) {
718    mRays[index].mMutations++;
719        mRays[index].mUnsuccessfulMutations++;
720
721        return true;
722  }
723  return false;
724}
725 
726
727
728MutationBasedDistribution::MutationBasedDistribution(Preprocessor &preprocessor
729                                                                                                         ) :
730  SamplingStrategy(preprocessor)
731{
732  mType = MUTATION_BASED_DISTRIBUTION;
733  mBufferStart = 0;
734  mLastIndex = 0;
735
736  Environment::GetSingleton()->GetIntValue("Mutation.bufferSize",
737                                                                                   mMaxRays);
738 
739  mRays.reserve(mMaxRays);
740 
741  Environment::GetSingleton()->GetFloatValue("Mutation.radiusOrigin",
742                                                                                         mMutationRadiusOrigin);
743
744  Environment::GetSingleton()->GetFloatValue("Mutation.radiusTermination",
745                                                                                         mMutationRadiusTermination);
746 
747  bool useEnhancedFeatures;
748
749#ifdef GTP_INTERNAL
750  int rayCaster;
751  Environment::GetSingleton()->GetIntValue("Preprocessor.rayCastMethod",
752                                                                                   rayCaster);
753  useEnhancedFeatures = (rayCaster !=
754                                                 RayCaster::INTERNAL_RAYCASTER);
755#else
756  useEnhancedFeatures = false;
757#endif
758 
759  if (useEnhancedFeatures) {
760        Environment::GetSingleton()->GetBoolValue("Mutation.useReverseSamples",
761                                                                                          mUseReverseSamples);
762       
763        Environment::GetSingleton()->GetFloatValue("Mutation.reverseSamplesDistance",
764
765                                                                                           mReverseSamplesDistance);
766
767        Environment::GetSingleton()->GetFloatValue("Mutation.silhouetteProb",
768                                                                                           mSilhouetteProb);
769
770  } else {
771        mUseReverseSamples = false;
772        mReverseSamplesDistance = 1e20f;
773        mSilhouetteProb = 0.0f;
774  }
775 
776  Environment::GetSingleton()->GetBoolValue("Mutation.useSilhouetteSamples",
777                                                                                        mUseSilhouetteSamples);
778
779  Environment::GetSingleton()->GetIntValue("Mutation.silhouetteSearchSteps",
780                                                                                   mSilhouetteSearchSteps);
781 
782 
783  Environment::GetSingleton()->GetBoolValue("Mutation.usePassImportance",
784                                                                                        mUsePassImportance);
785 
786
787  Environment::GetSingleton()->GetBoolValue("Mutation.useUnsuccCountImportance",
788                                                                                        mUseUnsuccCountImportance);
789
790 
791 
792}
793
794
795
796}
Note: See TracBrowser for help on using the repository browser.