source: GTP/trunk/Lib/Vis/Preprocessing/src/ReverseGvs.cpp @ 2727

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