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

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