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

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

Havran ray caster updates

Line 
1#include "SamplingStrategy.h"
2#include "Ray.h"
3#include "Intersectable.h"
4#include "Preprocessor.h"
5#include "ViewCellsManager.h"
6#include "AxisAlignedBox3.h"
7#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
22
23#define MUTATION_USE_CDF 0
24
25  //#define SIL_TERMINATION_MUTATION_PROB 0.8f
26
27#define EVALUATE_MUTATION_STATS 1
28
29//#define Q_SEARCH_STEPS 3
30
31// VH - commened out !!!!! 8/1/2008
32#define SORT_RAY_ENTRIES 1
33
34// use avg ray contribution as importance
35// if 0 the importance is evaluated from the succ of mutations
36#define USE_AVG_CONTRIBUTION 1
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
48void
49MutationBasedDistribution::Update(VssRayContainer &vssRays)
50{
51  //  for (int i=0; i < mRays.size(); i++)
52  //    cout<<mRays[i].mMutations<<" ";
53  //  cout<<endl;
54  cerr<<"Mutation update..."<<endl;
55  cerr<<"rays = "<<mRays.size()<<endl;
56  if ((int)mRays.size()) {
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<<" ... "<<
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;
70  }
71  int contributingRays = 0;
72
73  int mutationRays = 0;
74  int dummyNcMutations = 0;
75  int dummyCMutations = 0;
76
77  int reverseCandidates = 0;
78
79#if 0
80  sort(mRays.begin(), mRays.end());
81  // reset the start of the buffer
82  mBufferStart = 0;
83#endif
84
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               
95                Intersectable *newObject = vssRays[i]->mTerminationObject;
96               
97                Intersectable *oldObject = mRays[vssRays[i]->mGeneratorId].mRay->mTerminationObject;
98                // the ray generated a contribution although it hits the same object
99                // mark this using a counter
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 {
111                // unref the old ray and add the new ray into the mutation buffer
112                *mRays[mBufferStart].mRay = *vssRays[i];
113                mRays[mBufferStart].mMutations = 0;
114                mRays[mBufferStart].mUnsuccessfulMutations = 0;
115                mRays[mBufferStart].ResetReverseMutation();
116                //              mRays[mBufferStart] = RayEntry(newRay);
117                mBufferStart++;
118                if (mBufferStart >= mMaxRays)
119                  mBufferStart = 0;
120          }
121        } else {
122          // the ray did not generate any contribution
123          if (vssRays[i]->mDistribution == MUTATION_BASED_DISTRIBUTION &&
124                  vssRays[i]->mGeneratorId != -1
125                  ) {
126                // check whether not to store a new backward mutation candidate
127                // this happens if the new ray is occluded significantly closer than
128                // the generator ray
129                VssRay *oldRay = mRays[vssRays[i]->mGeneratorId].mRay;
130                VssRay *newRay = vssRays[i];
131
132                Intersectable *oldObject = oldRay->mTerminationObject;
133
134                 
135                // only allow one reverse mutation per generator ray
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                 
141                  if (newDist < oldDist - oldObject->GetBox().Radius()*mReverseSamplesDistance) {
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               
155                Intersectable *newObject = vssRays[i]->mTerminationObject;
156
157                if (oldObject == newObject)
158                  dummyNcMutations++;
159#endif
160          }
161        }
162  }
163 
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;
170        cout<<"Reverse candidates:"<<100.0f*reverseCandidates/(float)mutationRays<<endl;
171  }
172 
173  float pContributingRays = contributingRays/(float)vssRays.size();
174 
175  cout<<"Ratio of contributing rays:"<<pContributingRays<<endl;
176 
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;
191       
192        for (int i=0; i < contributingRays; i++, index--) {
193          if (index < 0)
194                index = (int)mRays.size()-1;
195          mRays[index].mImportance = importance;
196        }
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;
204  mLastIndex = (int)mRays.size();
205  cout<<"Mutation candidates sorted in "<<TimeDiff(t1, GetTime())<<" ms."<<endl;
206#endif
207                                                                                                                                                                 
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<<" "<<
222        GetEntry((int)mRays.size()-1).mImportance<<endl;
223
224  cout<<"Sampling factor = "<<
225        GetEntry(0).GetSamplingFactor()<<" "<<
226        GetEntry((int)mRays.size()-1).GetSamplingFactor()<<endl;
227
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
304bool
305MutationBasedDistribution::ComputeReverseMutation(
306                                                                                                  const VssRay &oldRay,
307                                                                                                  const VssRay &newRay,
308                                                                                                  Vector3 &origin,
309                                                                                                  Vector3 &termination
310                                                                                                  )
311{
312#ifdef GTP_INTERNAL
313
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)
323
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
332  Intersectable *occluder = newRay.mTerminationObject;
333 
334  AxisAlignedBox3 box = occluder->GetBox();
335  // consider slightly larger neighborhood of the occluder
336  // in search for unocclude reverse ray
337  box.Scale(2.0f);
338  //box.Scale(200.0f);
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];
345  static Vector3 origs[packetSize];
346  // now find the silhouette along the line
347  int i;
348  float left = 0.0f;
349  float right = 1.0f;
350
351  // cast rays to find silhouette ray
352  for (int j=0; j < mSilhouetteSearchSteps; j++) {
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 );
357          origs[i] = termination;
358          // mlrtaStoreRayASEye4(&termination.x, &dirs[i].x, i);
359        }
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(),
365                                                                                          origs,
366                                                                                          dirs,
367                                                                                          hit_triangles,
368                                                                                          dist);       
369       
370        for (i=0; i < packetSize; i++) {
371          //cout<<hit_triangles[i]<<endl;
372          if (hit_triangles[i] == -1) {
373                // break on first passing ray
374            break;
375          }
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
383
384  float t = right;
385  if (right==1.0f)
386        return false;
387
388
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         
413          Intersectable *occludee =
414                oldRay.mTerminationObject;
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
431  return true;
432#else
433  cerr << "warning: reverse mutation not supported!" << endl;
434  return false;
435#endif
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
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 
473  AxisAlignedBox3 _box = box;
474  _box.Scale(1.1f);
475  // cast rays to find silhouette ray
476  for (int j=0; j < mSilhouetteSearchSteps; j++) {
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 );
481          origs[i] = origin;
482          //mlrtaStoreRayASEye4(&origin.x, &dirs[i].x, i);
483        }
484       
485        // mlrtaTraverseGroupASEye4(&box.Min().x, &box.Max().x, hit_triangles, dist);
486        assert(preprocessor->mRayCaster);
487        preprocessor->mRayCaster->CastRaysPacket4(_box.Min(),
488                                                                                          _box.Max(),
489                                                                                          origs,
490                                                                                          dirs,
491                                                                                          hit_triangles,
492                                                                                          dist);       
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;
505  }
506
507  Vector3 shift;
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
512        //cout<<"W"<<i<<endl;
513        //      return (RandomValue(1.0f, 1.5f)*radius)*line;
514        shift = right*line;
515  } else {
516        //  cout<<i<<endl;
517        shift = shifts[i];
518  }
519 
520
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 
576#else
577  //cerr << "warning: shiluette mutation not supported" << endl;
578  return Vector3(0, 0, 0);
579#endif
580 
581}
582
583
584bool
585MutationBasedDistribution::GenerateSample(SimpleRay &sray)
586{
587
588  if (mRays.size() == 0) {
589        float rr[5];
590        // use direction based distribution until we have some mutation candidates
591        Vector3 origin, direction;
592
593        for (int i=0; i < 5; i++)
594          rr[i] = RandomValue(0,1);
595       
596        mPreprocessor.mViewCellsManager->GetViewPoint(origin,
597                                                                                                  Vector3(rr[0], rr[1], rr[2]));
598       
599       
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;
605       
606        return true;
607  }
608
609  int index;
610
611#if !MUTATION_USE_CDF
612#if SORT_RAY_ENTRIES
613  // RAYS are sorted -> find mitation candidate from the tail of the buffer
614  index = mLastIndex - 1;
615  if (index < 0 || index >= mRays.size()-1) {
616        index = (int)mRays.size() - 1;
617  } else
618        if (
619                mRays[index].GetSamplingFactor() >= mRays[mLastIndex].GetSamplingFactor()) {
620          // make another round to equalize the oversampling factor
621
622          //      cout<<"R2"<<endl;
623          //      cout<<mLastIndex<<endl;
624          //      cout<<index<<endl;
625          index = (int)mRays.size() - 1;
626        }
627#else
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  }
646#endif
647#else
648
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
653  int l=0, r=(int)mRays.size()-1;
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
671  // WE HAVE THE INDEX HERE
672
673  mLastIndex = index;
674  //  Debug<<index<<" "<<mRays[index].GetSamplingFactor()<<endl;
675 
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),
680                                         MUTATION_BASED_DISTRIBUTION,
681                                         1.0f);
682       
683       
684        sray.mGeneratorId = index;
685        mRays[index].ResetReverseMutation();
686        mRays[index].mMutations++;
687        mRays[index].mUnsuccessfulMutations++;
688       
689        return true;
690  }
691
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
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);
714 
715  // mutate the origin
716  Vector3 d = ray->GetDir();
717 
718  float objectRadius = box.Radius();
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();
730
731 
732  // use probabilitistic approach to decide for the type of mutation
733  float a = RandomValue(0.0f,1.0f);
734  bool bidirectional = true;
735 
736  if (mUseSilhouetteSamples && a < mSilhouetteProb) {
737        termination += ComputeSilhouetteTerminationMutation(*ray,
738                                                                                                                origin,
739                                                                                                                box,
740                                                                                                                U, V,
741                                                                                                                2.0f*objectRadius);
742        bidirectional = false;
743  } else {
744        mRays[index].mHalton.GetNext(4, rr);
745
746        // fuzzy random mutation
747        origin += ComputeOriginMutation(*ray, U, V,
748                                                                        Vector2(rr[0], rr[1]),
749                                                                        mMutationRadiusOrigin*objectRadius);
750       
751        termination += ComputeTerminationMutation(*ray, U, V,
752                                                                                          Vector2(rr[2], rr[3]),
753                                                                                          mMutationRadiusTermination*objectRadius);
754  }
755
756  Vector3 direction = termination - origin;
757 
758  if (Magnitude(direction) < Limits::Small)
759        return false;
760 
761  // shift the origin a little bit
762#if 1
763  origin += direction*0.5f;
764#else
765  // $$JB - 14.1. 2008 increase shift to test HavranRayCaster
766  origin = 0.5f*(origin + termination);
767#endif
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;
776  sray.SetBidirectional(bidirectional);
777 
778  return true;
779}
780
781bool
782MutationBasedDistribution::GenerateMutation(const int index, SimpleRay &sray)
783{
784  VssRay *ray = mRays[index].mRay;
785
786  Intersectable *object = ray->mTerminationObject;
787 
788  AxisAlignedBox3 box = object->GetBox();
789 
790  if (GenerateMutationCandidate(index, sray, object, box)) {
791    mRays[index].mMutations++;
792        mRays[index].mUnsuccessfulMutations++;
793        return true;
794  }
795  return false;
796}
797 
798
799
800MutationBasedDistribution::MutationBasedDistribution(Preprocessor &preprocessor
801                                                                                                         ) :
802  SamplingStrategy(preprocessor)
803{
804  mType = MUTATION_BASED_DISTRIBUTION;
805  mBufferStart = 0;
806  mLastIndex = 0;
807
808  Environment::GetSingleton()->GetIntValue("Mutation.bufferSize",
809                                                                                   mMaxRays);
810 
811  mRays.reserve(mMaxRays);
812 
813  Environment::GetSingleton()->GetFloatValue("Mutation.radiusOrigin",
814                                                                                         mMutationRadiusOrigin);
815
816  Environment::GetSingleton()->GetFloatValue("Mutation.radiusTermination",
817                                                                                         mMutationRadiusTermination);
818 
819  bool useEnhancedFeatures;
820
821#ifdef GTP_INTERNAL
822  int rayCaster;
823  Environment::GetSingleton()->GetIntValue("Preprocessor.rayCastMethod",
824                                                                                   rayCaster);
825  useEnhancedFeatures = (rayCaster !=
826                                                 RayCaster::INTERNAL_RAYCASTER);
827#else
828  useEnhancedFeatures = false;
829#endif
830 
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  }
847 
848  Environment::GetSingleton()->GetBoolValue("Mutation.useSilhouetteSamples",
849                                                                                        mUseSilhouetteSamples);
850
851  Environment::GetSingleton()->GetIntValue("Mutation.silhouetteSearchSteps",
852                                                                                   mSilhouetteSearchSteps);
853 
854 
855  Environment::GetSingleton()->GetBoolValue("Mutation.usePassImportance",
856                                                                                        mUsePassImportance);
857 
858
859  Environment::GetSingleton()->GetBoolValue("Mutation.useUnsuccCountImportance",
860                                                                                        mUseUnsuccCountImportance);
861
862 
863 
864}
865
866
867
868}
Note: See TracBrowser for help on using the repository browser.