source: GTP/trunk/Lib/Vis/Preprocessing/src/MutualVisibility.cpp @ 1867

Revision 1867, 18.7 KB checked in by bittner, 18 years ago (diff)

merge, global lines, rss sampling updates

RevLine 
[209]1#include <assert.h>
[191]2#include <stack>
3using namespace std;
4#include "KdTree.h"
5#include "AxisAlignedBox3.h"
6#include "Ray.h"
7#include "MutualVisibility.h"
[209]8#include "Exporter.h"
9#include "Mesh.h"
10#include "Triangle3.h"
[245]11#include "SceneGraph.h"
[191]12
[863]13namespace GtpVisibilityPreprocessor {
[860]14
[191]15void
[209]16RayShaft::Init(
17               const Rectangle3 &source,
18               const Rectangle3 &target)
[191]19{
20  mDepth = 0;
21  mSource = source;
22  mTarget = target;
23}
24
25
26Vector3
[209]27RayShaft::GetIntersectionPoint(const int rayIndex,
28                               const int depth) const
[191]29{
30  Vector3 origin, direction;
[245]31  Ray ray;
32  GetRaySegment(rayIndex, ray);
33  if (depth >= mSamples[rayIndex].mIntersections.size()) {
34    cerr<<"depth of sample out of limits"<<endl;
35    exit(1);
36  }
37  return ray.Extrap(mSamples[rayIndex].mIntersections[depth].mT);
[191]38}
39
40void
[245]41RayShaft::GetRaySegment(const int i, Ray &ray) const
42{
43  Vector3 origin, direction;
44  GetRay(i, origin, direction);
45  ray.Init(origin, direction, Ray::LINE_SEGMENT);
46  if ( mSamples[i].IsValid() ) {
47    origin = ray.Extrap(mSamples[i].mMinT);
48    direction = ray.Extrap(mSamples[i].mMaxT) - origin;
49    ray.Init(origin, direction, Ray::LINE_SEGMENT);
50  }
51}
52
53void
[209]54RayShaft::GetRay(const int rayIndex,
55                 Vector3 &origin,
56                 Vector3 &direction) const
[191]57{
58 
[209]59  assert(rayIndex < 4);
60 
61  origin = mSource.mVertices[rayIndex];
62  direction = mTarget.mVertices[rayIndex] - origin;
[191]63}
64
65void
66MutualVisibilitySampler::PerformSplit(
[209]67                                      const RayShaft &sample,
[191]68                                      const bool splitSource,
[209]69                                      const int axis,
70                                      RayShaft &sample1,
71                                      RayShaft &sample2
[191]72                                      )
73{
[209]74 
[191]75
[209]76  // split the triangles
[191]77
78  if (splitSource) {
79    sample1.mTarget = sample.mTarget;
80    sample2.mTarget = sample.mTarget;
[209]81    sample.mSource.Split(
82                         axis,
83                         sample1.mSource,
84                         sample2.mSource);
[191]85  } else {
[209]86   
[191]87    sample1.mSource = sample.mSource;
88    sample2.mSource = sample.mSource;
[209]89   
90    sample.mTarget.Split(
91                         axis,
92                         sample1.mTarget,
93                         sample2.mTarget);
[191]94  }
95 
96  // split the intersections
[209]97  switch (axis) {
[191]98  case 0:
[223]99    sample1.mSamples[0].mIntersections = sample.mSamples[0].mIntersections;
100    sample1.mSamples[3].mIntersections = sample.mSamples[3].mIntersections;
[191]101   
[223]102    sample2.mSamples[1].mIntersections = sample.mSamples[1].mIntersections;
103    sample2.mSamples[2].mIntersections = sample.mSamples[2].mIntersections;
[191]104    break;
105
106  case 1:
[223]107    sample1.mSamples[0].mIntersections = sample.mSamples[0].mIntersections;
108    sample1.mSamples[1].mIntersections = sample.mSamples[1].mIntersections;
[191]109
[223]110    sample2.mSamples[2].mIntersections = sample.mSamples[2].mIntersections;
111    sample2.mSamples[3].mIntersections = sample.mSamples[3].mIntersections;
[191]112    break;
[209]113  }
[191]114
[209]115  // the intersections for the new shaft rays will be established
116  // later
[191]117  sample1.mDepth = sample2.mDepth = sample.mDepth+1;
118}
119
120float
[245]121MutualVisibilitySampler::GetSpatialAngle(const RayShaft &shaft,
[191]122                                         const Vector3 &point
123                                         )
124{
[245]125  const int sampleIndices[]={
126    0,1,2,
127    0,2,3
[191]128  };
129 
130  float sum = 0.0f;
[245]131  int i, j=0;
132
133  if (!shaft.IsValid())
134    return 2.0f*mSolidAngleThreshold;
135
[209]136  for (i=0; i < 2; i++) {
[245]137    Triangle3 triangle(shaft.GetIntersectionPoint(sampleIndices[j++], 0),
138                       shaft.GetIntersectionPoint(sampleIndices[j++], 0),
139                       shaft.GetIntersectionPoint(sampleIndices[j++], 0));
[191]140    sum += triangle.GetSpatialAngle(point);
141  }
[209]142
[191]143  return sum;
144}
145
146
147void
[245]148MutualVisibilitySampler::ComputeError(RayShaft &shaft)
[191]149{
150  // evaluate minimal error which can be achieved by more precise evaluation
151  // if this is above the threshold do not proceed further
152
[245]153  // check whether the samples pierce the same mesh
154  Intersectable::NewMail();
155  int i, j;
156  for (i=0; i < 4; i++) {
157    RaySample *sample = &shaft.mSamples[i];
158    for (j=0; j < sample->mIntersections.size(); j++)
159      sample->mIntersections[j].mObject->Mail();
160  }
161
[1867]162  //  int id = Mailable::GetThreadId();
[245]163  for (i=0; i < 4; i++) {
164    RaySample *sample = &shaft.mSamples[i];
165    for (j=0; j < sample->mIntersections.size(); j++) {
166      if (sample->mIntersections[j].mObject->IncMail() == 4) {
[1867]167                cerr<<"T";
168                shaft.mError = 0.0f;
169                return;
[245]170      }
171    }
172  }
173   
[191]174 
[245]175  float maxAngle = GetSpatialAngle(shaft,
176                                   shaft.mTarget.GetCenter());
177 
178  for (i=0; i < 3; i++) {
179    float angle = GetSpatialAngle(shaft,
180                                  shaft.mTarget.mVertices[i]);
[191]181    if (angle > maxAngle)
182      maxAngle = angle;
183  }
[245]184
185  maxAngle = MAX_FLOAT;
186  shaft.mError = maxAngle;
[191]187}
188
189
190void
[245]191MutualVisibilitySampler::ConstructInitialSamples2(
192                                                  const AxisAlignedBox3 &source,
193                                                  const AxisAlignedBox3 &target,
194                                                  vector<RayShaft *> &samples
195                                                  )
196{
197  // get all rectangles potentially visible from the source box
198  int i;
199  int sourceMask = 0;
200  for (i=0; i < 8; i++)
201    sourceMask |= source.GetFaceVisibilityMask(target.GetVertex(i));
202
203  // now for each visble source face find all visible target faces
204  for (i=0; i < 6; i++) {
205    Rectangle3 sourceFace = source.GetFace(i);
206    if ( sourceMask &(1<<i) ) {
207      int mask = target.GetFaceVisibilityMask(sourceFace);
208      // construct triangle samples for all visible rectangles
209      for (int j=0; j < 6; j++)
210        if (mask & (1<<j)) {
211          AddInitialSamples2(sourceFace, target.GetFace(j), samples);
212        }
213    }
214  }
215}
216
217void
218MutualVisibilitySampler::ConstructInitialSamples3(
219                                                  const AxisAlignedBox3 &source,
220                                                  const AxisAlignedBox3 &target,
221                                                  vector<RayShaft *> &samples
222                                                  )
223{
224  // get all rectangles potentially visible from the source box
225  int i;
226  int sourceMask = 0;
227  for (i=0; i < 8; i++)
228    sourceMask |= source.GetFaceVisibilityMask(target.GetVertex(i));
229
230  // now for each visble source face find all visible target faces
231  int face;
232  for (face=0; face < 6; face++) {
233    if ( sourceMask & (1<<face) ) {
234      Rectangle3 sourceRect = source.GetFace(face);
235
236      Vector3 targetCenter = target.Center();
237     
238      Vector3 normal = sourceRect.GetNormal();
239     
240      Plane3 sourcePlane(normal, sourceRect.GetVertex(0));
241     
242      Plane3 targetPlane(normal, target.GetVertex(0));
243
244      int i;
245      for (i=1; i < 8; i++) {
246        Vector3 v = target.GetVertex(i);
247        if (targetPlane.Distance(v) < 0)
248          targetPlane = Plane3(normal, v);
249      }
250 
251      Vector3 xBasis = Normalize(sourceRect.GetVertex(1) - sourceRect.GetVertex(0));
252      Vector3 yBasis = Normalize(sourceRect.GetVertex(3) - sourceRect.GetVertex(0));
253
254      // cast rays between the centers of the boxes
255      Vector3 targetRCenter = targetPlane.FindIntersection(sourceRect.GetCenter(),
256                                                           targetCenter);
257     
258      Rectangle3 targetRect;
259     
260      float targetDist[4];
261      targetDist[0] = targetDist[1] = targetDist[2] = targetDist[3] = 0.0f;
262     
263      // cast rays between corresponding vertices of the boxes
264      int j;
265      int intersections=0;
266      for (i=0; i < 4; i++)
267        for (j=0; j < 8; j++) {
268          Vector3 v;
269          Vector3 diff;
270          bool coplanar;
271          float dist;
272         
273          v = targetPlane.FindIntersection(sourceRect.GetVertex(i),
274                                           target.GetVertex(j),
275                                           NULL,
276                                           &coplanar);
277          if (!coplanar) {
278            // evaluate target and
279            diff = targetRCenter - v;
280            dist = DotProd(diff, xBasis);
281            if (dist < targetDist[0])
282              targetDist[0] = dist;
283            if (dist > targetDist[1])
284              targetDist[1] = dist;
285
286            dist = DotProd(diff, yBasis);
287
288            if (dist < targetDist[2])
289              targetDist[2] = dist;
290            if (dist > targetDist[3])
291              targetDist[3] = dist;
292            intersections++;
293          }
294        }
295     
296      if (intersections>=4) {
297        targetRect.mVertices[0] = targetRCenter + targetDist[0]*xBasis + targetDist[2]*yBasis;
298        targetRect.mVertices[1] = targetRCenter + targetDist[1]*xBasis + targetDist[2]*yBasis;
299        targetRect.mVertices[2] = targetRCenter + targetDist[1]*xBasis + targetDist[3]*yBasis;
300        targetRect.mVertices[3] = targetRCenter + targetDist[0]*xBasis + targetDist[3]*yBasis;
301       
302        //      cout<<sourceRect<<targetRect<<endl;
303        AddInitialSamples(sourceRect, targetRect, samples);
304      }
305    }
306  }
307}
308
309void
[191]310MutualVisibilitySampler::ConstructInitialSamples(
311                                                 const AxisAlignedBox3 &source,
312                                                 const AxisAlignedBox3 &target,
[209]313                                                 vector<RayShaft *> &samples
[191]314                                                 )
315{
[223]316  Vector3 sourceCenter = source.Center();
317  Vector3 targetCenter = target.Center();
318  Vector3 normal = Normalize(sourceCenter - targetCenter );
319 
[209]320  Plane3 sourcePlane(normal, source.GetVertex(0));
[191]321  int i;
[209]322  for (i=1; i < 8; i++) {
323    Vector3 v = source.GetVertex(i);
324    if (sourcePlane.Distance(v) > 0)
325      sourcePlane = Plane3(normal, v);
326  }
327 
[223]328  Plane3 targetPlane(normal, target.GetVertex(0));
[209]329  for (i=1; i < 8; i++) {
330    Vector3 v = target.GetVertex(i);
[223]331    if (targetPlane.Distance(v) < 0)
332      targetPlane = Plane3(normal, v);
[209]333  }
[191]334
[209]335 
336  Vector3 xBasis = CrossProd(Vector3(0,1,0), normal);
337
338  if (Magnitude(xBasis) > 1e-6)
339    xBasis.Normalize();
340  else {
[245]341    xBasis = Normalize(CrossProd(Vector3(0,0,1), normal));
[191]342  }
[209]343
344  Vector3 yBasis = Normalize( CrossProd(normal, xBasis) );
[223]345  // cast rays between the centers of the boxes
346  Vector3 targetRCenter = targetPlane.FindIntersection(sourceCenter,
347                                                       targetCenter);
[209]348 
[223]349  Vector3 sourceRCenter = sourcePlane.FindIntersection(sourceCenter,
350                                                       targetCenter);
[209]351 
[223]352
353  Rectangle3 sourceRect;
354  Rectangle3 targetRect;
355
[245]356
357  if (0) {
[223]358  float scale = Magnitude(source.Size())*0.7f;
359  sourceRect.mVertices[0] = sourceRCenter - scale*xBasis - scale*yBasis;
360  sourceRect.mVertices[1] = sourceRCenter + scale*xBasis - scale*yBasis;
361  sourceRect.mVertices[2] = sourceRCenter + scale*xBasis + scale*yBasis;
362  sourceRect.mVertices[3] = sourceRCenter - scale*xBasis + scale*yBasis;
363
364  scale = Magnitude(target.Size())*0.7f;
365  targetRect.mVertices[0] = targetRCenter - scale*xBasis - scale*yBasis;
366  targetRect.mVertices[1] = targetRCenter + scale*xBasis - scale*yBasis;
367  targetRect.mVertices[2] = targetRCenter + scale*xBasis + scale*yBasis;
368  targetRect.mVertices[3] = targetRCenter - scale*xBasis + scale*yBasis;
[245]369  }
[223]370
[245]371
372  float sourceDist[4];
373  float targetDist[4];
374  sourceDist[0] = sourceDist[1] = sourceDist[2] = sourceDist[3] = 0.0f;
375  targetDist[0] = targetDist[1] = targetDist[2] = targetDist[3] = 0.0f;
376
377  // cast rays between corresponding vertices of the boxes
378  int j;
379  for (i=0; i < 8; i++)
380    for (j=0; j < 8; j++) {
381      Vector3 v;
382      Vector3 diff;
383      bool coplanar;
384      float dist;
385      v = sourcePlane.FindIntersection(source.GetVertex(i),
386                                       target.GetVertex(j),
387                                       NULL,
388                                       &coplanar);
389      if (!coplanar) {
390        // evaluate source and
391        diff = sourceRCenter - v;
392        dist = DotProd(diff, xBasis);
393        if (dist < sourceDist[0])
394          sourceDist[0] = dist;
395        if (dist > sourceDist[1])
396          sourceDist[1] = dist;
397
398        dist = DotProd(diff, yBasis);
399        if (dist < sourceDist[2])
400          sourceDist[2] = dist;
401        if (dist > sourceDist[3])
402          sourceDist[3] = dist;
403      }
404     
405      v = targetPlane.FindIntersection(source.GetVertex(i),
406                                       target.GetVertex(j),
407                                       NULL,
408                                       &coplanar);
409      if (!coplanar) {
410        // evaluate target and
411        diff = targetRCenter - v;
412        dist = DotProd(diff, xBasis);
413        if (dist < targetDist[0])
414          targetDist[0] = dist;
415        if (dist > targetDist[1])
416          targetDist[1] = dist;
417        dist = DotProd(diff, yBasis);
418        if (dist < targetDist[2])
419          targetDist[2] = dist;
420        if (dist > targetDist[3])
421          targetDist[3] = dist;
422      }
423    }
424
425  sourceRect.mVertices[0] = sourceRCenter + sourceDist[0]*xBasis + sourceDist[2]*yBasis;
426  sourceRect.mVertices[1] = sourceRCenter + sourceDist[1]*xBasis + sourceDist[2]*yBasis;
427  sourceRect.mVertices[2] = sourceRCenter + sourceDist[1]*xBasis + sourceDist[3]*yBasis;
428  sourceRect.mVertices[3] = sourceRCenter + sourceDist[0]*xBasis + sourceDist[3]*yBasis;
429
430  targetRect.mVertices[0] = targetRCenter + targetDist[0]*xBasis + targetDist[2]*yBasis;
431  targetRect.mVertices[1] = targetRCenter + targetDist[1]*xBasis + targetDist[2]*yBasis;
432  targetRect.mVertices[2] = targetRCenter + targetDist[1]*xBasis + targetDist[3]*yBasis;
433  targetRect.mVertices[3] = targetRCenter + targetDist[0]*xBasis + targetDist[3]*yBasis;
434
435
436  cout<<sourceRect<<targetRect<<endl;
[223]437  AddInitialSamples(sourceRect, targetRect, samples);
[191]438}
439
440void
441MutualVisibilitySampler::AddInitialSamples(
442                                           const Rectangle3 &sourceRect,
443                                           const Rectangle3 &targetRect,
[209]444                                           vector<RayShaft *> &samples
[191]445                                           )
446{
447
[209]448  RayShaft *sample = new RayShaft(sourceRect,
449                                  targetRect);
450  samples.push_back(sample);
451}
[191]452
[245]453void
454MutualVisibilitySampler::AddInitialSamples2(
455                                            const Rectangle3 &sourceRect,
456                                            const Rectangle3 &targetRect,
457                                            vector<RayShaft *> &samples
458                                            )
459{
460  // align the rectangles properly
461  Rectangle3 sRect, tRect;
462  if (DotProd(sourceRect.GetNormal(), targetRect.GetNormal()) < -0.99f) {
463    int i;
464    for (i=0; i < 4; i++) {
465      tRect.mVertices[i] = targetRect.mVertices[( 7 - i )%4];
466    }
467   
468    RayShaft *sample = new RayShaft(sourceRect,
469                                    tRect);
470    samples.push_back(sample);
471  }
472 
473  return;
474 
475  float minDist = MAX_FLOAT;
476  int startI;
477  int startJ;
478  int i, j;
[191]479
[245]480 
481  for (i=0; i < 4; i++) {
482    for (j=0; j < 4; j++) {
483      float dist = Distance(sourceRect.mVertices[i], targetRect.mVertices[j]);
484      if (dist < minDist) {
485        minDist = dist;
486        startI = i;
487        startJ = j;
488      }
489    }
490  }
491  for (i=0; i < 4; i++) {
492    sRect.mVertices[i] = sourceRect.mVertices[(startI + i )%4];
493    tRect.mVertices[i] = targetRect.mVertices[(4 + startJ - i )%4];
494  }
495 
496  RayShaft *sample = new RayShaft(sRect,
497                                  tRect);
498  samples.push_back(sample);
499}
500
501
[209]502void
[245]503MutualVisibilitySampler::ExportShafts(vector<RayShaft *> &shafts,
504                                      const bool singleFile)
[209]505{
506  static int id = 0;
507  char filename[64];
508  if (id > 20)
509    return;
[245]510 
511  Exporter *exporter = NULL;
512  for (int i=0; i < shafts.size(); i++) {
513    if (!exporter) {
514      if (singleFile)
515        sprintf(filename, "shafts-single-%04d.x3d", id++);
516      else
517        sprintf(filename, "shafts%04d-%02d.x3d", id++, i);
518      exporter = Exporter::GetExporter(filename);
519    }
520   
521    exporter->SetWireframe();
[1328]522    //    exporter->ExportScene(mSceneGraph->GetRoot());
[223]523
524    exporter->ExportBox(mSource);
525    exporter->ExportBox(mTarget);
526
[209]527    exporter->SetFilled();
[191]528
[209]529
[245]530    RayShaft *shaft = shafts[i];
[209]531    Mesh *mesh = new Mesh;
[245]532    mesh->AddRectangle(shaft->mSource);
533    mesh->AddRectangle(shaft->mTarget);
[386]534    vector<Ray *> rays;
[209]535    for (int j=0; j < 4; j++) {
[386]536      Ray *ray = new Ray;
537      shaft->GetRaySegment(j, *ray);
[209]538      rays.push_back(ray);
[191]539    }
[209]540   
541    Material m = RandomMaterial();
542    exporter->SetForcedMaterial(m);
543    MeshInstance mi(mesh);
544    exporter->ExportIntersectable(&mi);
545    exporter->ExportRays(rays, -1.0f, m.mDiffuseColor);
[245]546    if (!singleFile) {
547      delete exporter;
548      exporter = NULL;
549    }
550  }
551  if (exporter)
[209]552    delete exporter;
[245]553 
[191]554}
555
556int
[223]557MutualVisibilitySampler::CastRays(RayShaft &shaft)
558{
559  Ray ray;
560  int i;
561
[245]562  for (i=0; i < 4; i++)
563    if (!shaft.mSamples[i].IsProcessed()) {
564      Vector3 origin, direction;
565      shaft.GetRay(i, origin, direction);
566      // determine intersections with the boxes
[223]567      ray.Init(origin, direction, Ray::LINE_SEGMENT);
[245]568      float stmin, stmax = 0.0f, ttmin=1.0f, ttmax;
569      bool valid = true;
570     
571      if (mUseBoxes) {
572        if (mSource.GetMinMaxT(ray, &stmin, &stmax) &&
573            mTarget.GetMinMaxT(ray, &ttmin, &ttmax)) {
574          shaft.mSamples[i].mMinT = stmax;
575          shaft.mSamples[i].mMaxT = ttmin;
576          origin = ray.Extrap(stmax);
577          direction = ray.Extrap(ttmin) - origin;
578          // reinit the ray
579          ray.Init(origin, direction, Ray::LINE_SEGMENT);
580        } else
581          valid = false;
582      } else {
583        shaft.mSamples[i].mMinT = 0.0f;
584        shaft.mSamples[i].mMaxT = 1.0f;
585      }
586      if (valid) {
587        if (!mKdTree->CastRay(ray)) {
588          cerr<<"V"<<endl;
589          return VISIBLE;
590        }
591        shaft.mSamples[i].mIntersections = ray.intersections;
592        cerr<<"I";
593      } else {
594        cerr<<"X";
595        shaft.mSamples[i].SetInvalid();
596      }
[223]597    }
598  return INVISIBLE;
599}
600
601int
[191]602MutualVisibilitySampler::ComputeVisibility()
603{
[245]604  int result = INVISIBLE;
[209]605
[223]606  vector<RayShaft *> shafts;
[245]607  ConstructInitialSamples3(mSource, mTarget, shafts);
[359]608       
[245]609  if (1)
610    ExportShafts(shafts, false);
611
[223]612  stack<RayShaft *> shaftStack;
[359]613  int i;
614  for (i=0; i < shafts.size(); i++)
[245]615    shaftStack.push(shafts[i]);
616
617  shafts.clear();
618  Ray ray;
[209]619 
[245]620// now process the shafts as long as we have something to do
[223]621  while (!shaftStack.empty()) {
622    RayShaft *shaft = shaftStack.top();
623    shaftStack.pop();
[191]624   
625//      // cast a new ray
626//      int triangleSplitEdge = SetupExtremalRay(sample, source, ray);
627   
[245]628    if (CastRays(*shaft) == VISIBLE) {
629      result = VISIBLE;
630      break;
631    }
[359]632               
[245]633    // compute error ....
634    ComputeError(*shaft);
635    cout<<shaft->mDepth<<"|";
636    if (shaft->IsValid())
637      shafts.push_back(shaft);
638
639    if (shaft->mDepth < 10 &&
[359]640                                shaft->mError > mSolidAngleThreshold) {
[245]641     
642      // generate 2 new samples
643      RayShaft *newSamples[2];
644      newSamples[0] = new RayShaft;
645      newSamples[1] = new RayShaft;
646     
647      // chose what to split
648      bool splitSource = shaft->mSource.GetArea() > shaft->mTarget.GetArea();
649      int axis;
650      if (splitSource) {
[359]651                                axis = shaft->mSource.DominantAxis();
[245]652      } else {
[359]653                                axis = shaft->mTarget.DominantAxis();
[245]654      }
655     
656      PerformSplit(*shaft, splitSource, axis, *newSamples[0], *newSamples[1]);
657      //      delete shaft;
658      shaftStack.push(newSamples[0]);
659      shaftStack.push(newSamples[1]);
660    } else {
661      // store a terminal shaft
662    }
663
[191]664  }
[245]665 
666  while (!shaftStack.empty()) {
667    RayShaft *shaft = shaftStack.top();
668    shaftStack.pop();
669    delete shaft;
670  }
[209]671
[245]672  if (0)
673    ExportShafts(shafts, true);
674
675  for (i=0; i < shafts.size(); i++) {
[223]676    delete shafts[i];
[245]677  }
678
679  return result;
[191]680}
681
[245]682MutualVisibilitySampler::MutualVisibilitySampler(SceneGraph *sceneGraph,
[359]683                                                                                                                                                                                                 KdTree *kdTree,
684                                                                                                                                                                                                 const AxisAlignedBox3 &source,
685                                                                                                                                                                                                 const AxisAlignedBox3 &target,
686                                                                                                                                                                                                 const float solidAngleThreshold)
[191]687{
[245]688  mSceneGraph = sceneGraph;
[191]689  mKdTree = kdTree;
690  mSource = source;
691  mTarget = target;
[245]692  mUseBoxes = true;
[191]693  mSolidAngleThreshold = solidAngleThreshold;
694}
695 
696
697int
[245]698ComputeBoxVisibility(SceneGraph *sceneGraph,
[359]699                                                                                 KdTree *kdTree,
700                                                                                 const AxisAlignedBox3 &source,
701                                                                                 const AxisAlignedBox3 &target,
702                                                                                 const float solidAngleThreshold)
[191]703{
[359]704  MutualVisibilitySampler
705                sampler(sceneGraph, kdTree, source, target, solidAngleThreshold);
[191]706
[209]707 
[191]708  int visibility = sampler.ComputeVisibility();
709
710  return visibility;
711 
712}
713 
[1867]714}
Note: See TracBrowser for help on using the repository browser.