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

Revision 1932, 4.1 KB checked in by mattausch, 18 years ago (diff)
Line 
1#include "RayCaster.h"
2#include "VssRay.h"
3#include "Ray.h"
4#include "Preprocessor.h"
5
6
7namespace GtpVisibilityPreprocessor {
8
9
10#define DEBUG_RAYCAST 0
11
12#define EXACT_BOX_CLIPPING 1
13
14RayCaster::RayCaster(const Preprocessor &preprocessor):
15mPreprocessor(preprocessor)
16{
17}
18
19
20RayCaster::~RayCaster()
21{
22}
23
24
25VssRay *RayCaster::CastRay(const SimpleRay &simpleRay,
26                                                   const AxisAlignedBox3 &box)
27                                                   //const bool castDoubleRay)
28{
29        // note: make no sense otherwise
30        const bool castDoubleRay = false;
31        VssRayContainer rays;
32        CastRay(simpleRay, rays, box, castDoubleRay);
33   
34        if (!rays.empty())
35                return rays.back();
36        else
37                return NULL;
38}
39
40
41/** Checks if ray is valid, (e.g., not in empty view space or outside the view space)
42*/
43bool
44RayCaster::ValidateRay(const Vector3 &origin,
45                                           const Vector3 &direction,
46                                           const AxisAlignedBox3 &box,
47                                           Intersection &hit)
48{
49        if (!hit.mObject) 
50        {
51                // compute intersection with the scene bounding box
52#if EXACT_BOX_CLIPPING
53                static Ray ray;
54                mPreprocessor.SetupRay(ray, origin, direction);
55
56                float tmin, tmax;
57                if (box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
58                {
59                        hit.mPoint = ray.Extrap(tmax);
60                }
61                else
62                {
63                        // cout<<" invalid hp "<<tmin<<" "<<tmax<<endl;
64                        // cout<<" box "<<box<<endl;
65                        // cout<<" origin "<<origin<<endl;
66                        // cout<<" direction "<<direction<<endl;
67                        // cout<< "inv dir"<<ray.GetInvDir()<<endl;
68                        return false;
69                }
70#else
71                hit.mPoint = origin + direction * Magnitude(box.Diagonal());
72#endif
73        }
74        else
75        {
76                if (mPreprocessor.mDetectEmptyViewSpace)
77                {
78                        if (DotProd(hit.mNormal, direction) >= -Limits::Small)
79                        {       
80                                hit.mObject = NULL;
81                                return false;
82                        }
83                }
84        }
85
86        return true;
87}
88
89
90int
91RayCaster::ProcessRay(const SimpleRay &simpleRay,
92                                          Intersection &hitA,
93                                          Intersection &hitB,
94                                          VssRayContainer &vssRays,
95                                          const AxisAlignedBox3 &box,
96                                          const bool castDoubleRay,
97                                          const bool pruneInvalidRays)
98{
99        int hits = 0;
100
101#if DEBUG_RAYCAST
102        Debug<<"PRA"<<flush;
103#endif
104
105        // regardless of the pruneInvalidRays setting reject rays whic degenerate to a point
106        //      if (EpsilonEqualV3(hitA.mPoint, hitB.mPoint, Limits::Small))
107        //        return 0;
108       
109        if (pruneInvalidRays)
110        {
111                if (!hitA.mObject && !hitB.mObject)
112                {
113                        return 0;
114                }
115        }
116       
117        const bool validA =
118          ValidateRay(simpleRay.mOrigin, simpleRay.mDirection, box, hitA);
119       
120        // note: should we check for backward valitidy also for single rays?
121        const bool validB = //castDoubleRay &&
122                ValidateRay(simpleRay.mOrigin, -simpleRay.mDirection, box, hitB);
123       
124#if DEBUG_RAYCAST
125        Debug<<"PR1"<<flush;
126#endif
127       
128        // reset both contributions
129        if (!validA || !validB)
130        {
131                if (pruneInvalidRays)
132                        return 0;
133               
134                // reset both contributions of this ray
135                hitA.mObject = NULL;
136                hitB.mObject = NULL;
137        }
138         
139        // 8.11. 2007 JB
140        // degenerate rays checked by geometrical constraint...
141        //      !pruneInvalidRays || (hitA.mObject != hitB.mObject);
142       
143#if DEBUG_RAYCAST
144        Debug<<"PR2"<<flush;
145#endif
146
147        if (!pruneInvalidRays || hitA.mObject)
148        {
149                VssRay *vssRay = new VssRay(hitB.mPoint,
150                                                                        hitA.mPoint,
151                                                                        hitB.mObject,
152                                                                        hitA.mObject,
153                                                                        mPreprocessor.mPass,
154                                                                        simpleRay.mPdf);
155
156                if (validA)
157                        vssRay->mFlags |= VssRay::Valid;
158
159                vssRay->mDistribution = simpleRay.mDistribution;
160                vssRays.push_back(vssRay);
161                ++ hits;
162                //cout << "vssray 1: " << *vssRay << " " << vssRay->mTermination - vssRay->mOrigin << endl;
163        }
164
165#if DEBUG_RAYCAST
166        Debug<<"PR3"<<flush;
167#endif
168
169        if (castDoubleRay && (!pruneInvalidRays || hitB.mObject))
170        {
171                VssRay *vssRay = new VssRay(hitA.mPoint,
172                                                                        hitB.mPoint,
173                                                                        hitA.mObject,
174                                                                        hitB.mObject,
175                                                                        mPreprocessor.mPass,
176                                                                        simpleRay.mPdf);
177
178                if (validB)
179                        vssRay->mFlags |= VssRay::Valid;
180
181                vssRay->mDistribution = simpleRay.mDistribution;
182                vssRays.push_back(vssRay);
183                ++ hits;
184                //cout << "vssray 2: " << *vssRay << endl;
185        }
186       
187#if DEBUG_RAYCAST
188        Debug<<"PR4"<<flush;
189#endif
190
191        return hits;
192}
193
194}
Note: See TracBrowser for help on using the repository browser.