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

Revision 2599, 23.3 KB checked in by bittner, 17 years ago (diff)

Havran ray caster updates

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