source: GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp @ 2002

Revision 2002, 6.5 KB checked in by bittner, 18 years ago (diff)

renderer code updates for pixel error measurements

RevLine 
[1520]1#include "RayCaster.h"
2#include "VssRay.h"
3#include "Ray.h"
4#include "Preprocessor.h"
[1942]5#include "ViewCellsManager.h"
[1520]6
7
8namespace GtpVisibilityPreprocessor {
9
10
11#define DEBUG_RAYCAST 0
12
[1942]13#define EXACT_BOX_CLIPPING 0
[1520]14
15RayCaster::RayCaster(const Preprocessor &preprocessor):
16mPreprocessor(preprocessor)
17{
18}
19
20
[1521]21RayCaster::~RayCaster()
22{
23}
24
25
[1545]26VssRay *RayCaster::CastRay(const SimpleRay &simpleRay,
[1990]27                                                   const AxisAlignedBox3 &box,
[1996]28                                                   const bool castDoubleRay)
[1521]29{
[1932]30        VssRayContainer rays;
[1996]31        CastRay(simpleRay, rays, box, castDoubleRay, true);
[1932]32   
33        if (!rays.empty())
34                return rays.back();
35        else
36                return NULL;
[1521]37}
38
[1990]39
[1942]40bool
41RayCaster::ClipToViewSpaceBox(const Vector3 &origin,
42                                                          const Vector3 &termination,
43                                                          Vector3 &clippedOrigin,
44                                                          Vector3 &clippedTermination)
45{
[1952]46 
[1942]47  Ray ray(origin, termination - origin, Ray::LINE_SEGMENT);     
48  ray.Precompute();
49 
50  float tmin, tmax;
51  if ((!mPreprocessor.mViewCellsManager->
52           GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax)) ||
53          tmin>=tmax
54          )
55        return false;
[1521]56
[1942]57  if (tmin >= 1.0f || tmax <=0.0f)
58        return false;
59 
60  if (tmin > 0.0f)
61        clippedOrigin = ray.Extrap(tmin);
62  else
63        clippedOrigin = origin;
64 
65  if (tmax < 1.0f)
66        clippedTermination = ray.Extrap(tmax);
67  else
68        clippedTermination = termination;
69 
70  return true;
71}
72
[1528]73/** Checks if ray is valid, (e.g., not in empty view space or outside the view space)
74*/
[1867]75bool
76RayCaster::ValidateRay(const Vector3 &origin,
77                                           const Vector3 &direction,
78                                           const AxisAlignedBox3 &box,
79                                           Intersection &hit)
[1528]80{
[1932]81        if (!hit.mObject) 
82        {
83                // compute intersection with the scene bounding box
[1584]84#if EXACT_BOX_CLIPPING
[1932]85                static Ray ray;
86                mPreprocessor.SetupRay(ray, origin, direction);
87
88                float tmin, tmax;
89                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
90                {
91                        hit.mPoint = ray.Extrap(tmax);
92                }
93                else
94                {
95                        // cout<<" invalid hp "<<tmin<<" "<<tmax<<endl;
96                        // cout<<" box "<<box<<endl;
97                        // cout<<" origin "<<origin<<endl;
98                        // cout<<" direction "<<direction<<endl;
99                        // cout<< "inv dir"<<ray.GetInvDir()<<endl;
100                        return false;
101                }
[1584]102#else
[1932]103                hit.mPoint = origin + direction * Magnitude(box.Diagonal());
[1584]104#endif
105        }
[1932]106        else
107        {
108                if (mPreprocessor.mDetectEmptyViewSpace)
109                {
110                        if (DotProd(hit.mNormal, direction) >= -Limits::Small)
111                        {       
112                                hit.mObject = NULL;
113                                return false;
114                        }
115                }
116        }
117
118        return true;
[1528]119}
120
[1974]121void
122RayCaster::SortRays(SimpleRayContainer &rays)
123{
[1984]124  AxisAlignedBox3 box =
125        mPreprocessor.mViewCellsManager->GetViewSpaceBox();
126       
127  float b[12]={
128        box.Min().x,
129        box.Min().y,
130        box.Min().z,
131        -1,
132        -1,
133        -1,
134        box.Max().x,
135        box.Max().y,
136        box.Max().z,
137        1,
138        1,
139        1
140  };
141
142  _SortRays(rays,
143                        0,
[1990]144                        (int)rays.size()-1,
[1984]145                        0,
146                        b
147                        );
[1974]148}
149                                       
150void
151RayCaster::_SortRays(SimpleRayContainer &rays,
152                                         const int l,
153                                         const int r,
[1984]154                                         const int depth,
155                                         float box[12])
[1974]156{
157  // pick-up a pivot
[1984]158  int axis;
159 
160  float maxDiff = -1.0f;
161  // get the largest axis
162  int offset = 0;
[1990]163  int i;
[1984]164
[2002]165  // if (depth%4==0)
166  //    offset = 3;
[1984]167 
[2002]168  for (i=offset; i < offset + 3; i++) {
169        float diff = box[i + 6] - box[i];
[1984]170        if (diff > maxDiff) {
171          maxDiff = diff;
172          axis = i;
173        }
174  }
175
176  //  cout<<depth<<" "<<axis<<endl;
177 
[1990]178  i=l;
179  int j=r;
180
[1984]181  float x = (box[axis] + box[axis+6])*0.5f;
182  //  float x = rays[(l+r)/2].GetParam(axis);
[1974]183  do {
[1984]184        while(rays[i].GetParam(axis) < x && i<=j)
[1974]185          i++;
[2002]186        while(x <= rays[j].GetParam(axis) && i<=j)
[1974]187          j--;
188       
189        if (i <= j) {
190          swap(rays[i], rays[j]);
191          i++;
192          j--;
193        }
194  } while (i<=j);
195 
[2002]196  if (l + 4 < j ) {
[1984]197        // set new max
198        float save = box[axis+6];
199        box[axis+6] = x;
200        _SortRays(rays, l, j, depth+1, box);
201        box[axis+6] = save;
202  }
[1974]203 
[2002]204  if (i + 4 < r) {
[1984]205        // set new min
206        box[axis] = x;
207    _SortRays(rays, i, r, depth+1, box);
208  }
[1974]209}
210 
211                                       
[1528]212
[1867]213int
214RayCaster::ProcessRay(const SimpleRay &simpleRay,
215                                          Intersection &hitA,
216                                          Intersection &hitB,
217                                          VssRayContainer &vssRays,
218                                          const AxisAlignedBox3 &box,
219                                          const bool castDoubleRay,
[1996]220                                          const bool pruneInvalidRays)
[1520]221{
[1984]222  int hits = 0;
[1528]223
[1520]224#if DEBUG_RAYCAST
[1952]225        static int id=0;
226        Debug<<"PRA "<<id++<<endl<<flush;
[1520]227#endif
[1528]228       
[1932]229        if (pruneInvalidRays)
230        {
[1952]231          if (!hitA.mObject && !hitB.mObject) {
232                return 0;
233          }
[1520]234        }
[1966]235
[1584]236       
[1952]237        // regardless of the pruneInvalidRays setting reject rays whic degenerate to a point
[1966]238        if (EpsilonEqualV3(hitA.mPoint, hitB.mPoint, Limits::Small)) {
[1990]239                return 0;
[1966]240        }
241       
242       
[1952]243        const bool validA = ValidateRay(simpleRay.mOrigin, simpleRay.mDirection, box, hitA);
[1932]244        const bool validB = //castDoubleRay &&
[1952]245          ValidateRay(simpleRay.mOrigin, -simpleRay.mDirection, box, hitB);
[1867]246       
[1952]247       
[1757]248#if DEBUG_RAYCAST
249        Debug<<"PR1"<<flush;
250#endif
[1584]251       
[1867]252        // reset both contributions
[1952]253        if (!validA || !validB) {
254          if (pruneInvalidRays)
255                return 0;
[1867]256         
[1952]257          // reset both contributions of this ray
258          hitA.mObject = NULL;
259          hitB.mObject = NULL;
260        }
261       
[1867]262        // 8.11. 2007 JB
263        // degenerate rays checked by geometrical constraint...
264        //      !pruneInvalidRays || (hitA.mObject != hitB.mObject);
[1942]265
[1584]266       
[1757]267#if DEBUG_RAYCAST
268        Debug<<"PR2"<<flush;
269#endif
[1942]270        const bool validSample = true;
271        if (validSample) {
272          Vector3 clipA, clipB;
273          if (!ClipToViewSpaceBox(hitA.mPoint,
274                                                          hitB.mPoint,
275                                                          clipA,
276                                                          clipB))
277                return 0;
[1952]278
[1942]279          if (!pruneInvalidRays || hitA.mObject) {
280                VssRay *vssRay = new VssRay(
[1996]281                                                                        !castDoubleRay ? simpleRay.mOrigin : clipB,
[1867]282                                                                        hitA.mPoint,
283                                                                        hitB.mObject,
284                                                                        hitA.mObject,
285                                                                        mPreprocessor.mPass,
[1989]286                                                                        simpleRay.mPdf
287                                                                        );
[1932]288
[1867]289                if (validA)
[1932]290                        vssRay->mFlags |= VssRay::Valid;
291
[1883]292                vssRay->mDistribution = simpleRay.mDistribution;
[1989]293                vssRay->mGeneratorId = simpleRay.mGeneratorId;
294
[1867]295                vssRays.push_back(vssRay);
296                ++ hits;
297                //cout << "vssray 1: " << *vssRay << " " << vssRay->mTermination - vssRay->mOrigin << endl;
[1932]298        }
299
[1867]300#if DEBUG_RAYCAST
[1932]301        Debug<<"PR3"<<flush;
[1867]302#endif
303
[1942]304          if (castDoubleRay && (!pruneInvalidRays || hitB.mObject))
305                {
306                  VssRay *vssRay = new VssRay(
[1996]307                                                                          clipA,
[1942]308                                                                          hitB.mPoint,
309                                                                          hitA.mObject,
310                                                                          hitB.mObject,
311                                                                          mPreprocessor.mPass,
312                                                                          simpleRay.mPdf
313                                                                          );
314                  if (validB)
[1771]315                        vssRay->mFlags |= VssRay::Valid;
[1932]316
317                vssRay->mDistribution = simpleRay.mDistribution;
[1989]318                vssRay->mGeneratorId = simpleRay.mGeneratorId;
[1932]319                vssRays.push_back(vssRay);
320                ++ hits;
321                //cout << "vssray 2: " << *vssRay << endl;
[1942]322                }
323#if DEBUG_RAYCAST
324          Debug<<"PR4"<<flush;
325#endif
[1520]326        }
[1867]327       
[1520]328        return hits;
329}
330
[1583]331}
Note: See TracBrowser for help on using the repository browser.