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

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

minor updates of mutation

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