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

Revision 2050, 21.4 KB checked in by bittner, 18 years ago (diff)

render error

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