source: GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp @ 1990

Revision 1990, 5.5 KB checked in by mattausch, 17 years ago (diff)
Line 
1#include "InternalRayCaster.h"
2#include "VssRay.h"
3#include "KdTree.h"
4#include "Preprocessor.h"
5
6#define DEBUG_RAYCAST 0
7
8
9namespace GtpVisibilityPreprocessor {
10
11
12InternalRayCaster::InternalRayCaster(const Preprocessor &preprocessor, KdTree *kdTree):
13RayCaster(preprocessor), mKdTree(kdTree)
14{
15}
16
17
18InternalRayCaster::~InternalRayCaster()
19{
20}
21
22
23int InternalRayCaster::CastRay(const SimpleRay &simpleRay,
24                                                           VssRayContainer &vssRays,
25                                                           const AxisAlignedBox3 &box,
26                                                           const bool castDoubleRay,
27                                                           const bool pruneInvalidRays,
28                                                           const bool keepOrigin
29                                                           )
30{
31  if (simpleRay.mType == Ray::GLOBAL_RAY)
32          return CastGlobalRay(simpleRay, vssRays, box, pruneInvalidRays);
33 
34  //cout << "internal ray" << endl;
35  static Ray ray;
36  int hits = 0;
37  Intersection hitA(simpleRay.mOrigin), hitB(simpleRay.mOrigin);
38 
39  // inside test for bounding box
40  // enlarge box slightly so the view point fits for sure
41  //  AxisAlignedBox3 sbox = box;
42  //  sbox.Enlarge(Vector3(-Limits::Small));
43  // $$ JB moved here from Validate routine
44
45//   if (!box.IsInside(simpleRay.mOrigin)) {
46//      cout<<"out of box "<<simpleRay.mOrigin<<" "<<box<<endl;
47//      return 0;
48//   }
49 
50  mPreprocessor.SetupRay(ray, simpleRay.mOrigin, simpleRay.mDirection);
51  ray.mFlags &= ~Ray::CULL_BACKFACES;
52
53 
54  if (mKdTree->CastRay(ray)) {
55        hitA.mObject = ray.intersections[0].mObject;
56        hitA.mPoint = ray.Extrap(ray.intersections[0].mT);
57        hitA.mNormal = ray.intersections[0].mNormal;
58        //      cout << "hita: " << hitA.mPoint << " !obj: " << hitA.mObject << endl;
59  }
60 
61  mPreprocessor.SetupRay(ray, simpleRay.mOrigin, -simpleRay.mDirection);
62  ray.mFlags &= ~Ray::CULL_BACKFACES;
63 
64  if (castDoubleRay && mKdTree->CastRay(ray)) {
65        hitB.mObject = ray.intersections[0].mObject;
66        hitB.mPoint = ray.Extrap(ray.intersections[0].mT);
67        hitB.mNormal = ray.intersections[0].mNormal;
68  }
69 
70  return ProcessRay(
71                                        simpleRay,
72                                        hitA,
73                                        hitB,
74                                        vssRays,
75                                        box,
76                                        castDoubleRay,
77                                        pruneInvalidRays,
78                                        keepOrigin
79                                        );
80}
81
82
83int
84InternalRayCaster::CastGlobalRay(const SimpleRay &simpleRay,
85                                                                 VssRayContainer &vssRays,
86                                                                 const AxisAlignedBox3 &box,
87                                                                 const bool pruneInvalidRays
88                                                                )
89{
90  static Ray ray;
91  int hits = 0;
92  mPreprocessor.SetupRay(ray, simpleRay.mOrigin, simpleRay.mDirection);
93 
94  float tmin, tmax;
95  if (!(box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax)))
96        return 0;
97 
98  // shift the ray origin to tmin
99  //    Vector3 origin = ray.Extrap(tmin);
100  //    mPreprocessor.SetupRay(ray, origin, simpleRay.mDirection);
101  ray.SetType(Ray::GLOBAL_RAY);
102  ray.mFlags &= ~Ray::CULL_BACKFACES;
103 
104
105  VssRay *vssRay;
106 
107  if (mKdTree->CastRay(ray)) {
108        // sort intersections
109        ray.SortIntersections();
110        //      cout<<"I="<<ray.intersections.size()<<endl;
111       
112       
113        Ray::Intersection &hit = ray.intersections[0];
114       
115        if (DotProd(hit.mNormal, ray.GetDir()) < 0) {
116          //      cout<<"F:"<<tmin<<" "<<hit.mT<<endl;
117          // insert intial segment
118          vssRay = new VssRay(
119                                                  ray.Extrap(tmin),
120                                                  ray.Extrap(hit.mT),
121                                                  NULL,
122                                                  hit.mObject,
123                                                  mPreprocessor.mPass,
124                                                  simpleRay.mPdf
125                                                  );
126
127          vssRay->mFlags |= VssRay::Valid;
128          vssRay->mDistribution = simpleRay.mDistribution;
129          vssRays.push_back(vssRay);
130          ++hits;
131        }
132                               
133        hit = ray.intersections[ray.intersections.size()-1];
134        if (DotProd(hit.mNormal, ray.GetDir()) > 0) {
135          //      cout<<"L:"<<tmax<<" "<<hit.mT<<endl;
136         
137          // insert termination segment
138          vssRay = new VssRay(
139                                                  ray.Extrap(tmax),
140                                                  ray.Extrap(hit.mT),
141                                                  NULL,
142                                                  hit.mObject,
143                                                  mPreprocessor.mPass,
144                                                  simpleRay.mPdf
145                                                  );
146          vssRay->mFlags |= VssRay::Valid;
147          vssRay->mDistribution = simpleRay.mDistribution;
148          vssRays.push_back(vssRay);
149          ++hits;
150        }
151       
152        // insert the rest of segments
153        for (int i=0; i < ray.intersections.size() - 1; i++) {
154          Ray::Intersection &hitA = ray.intersections[i];
155          Ray::Intersection &hitB = ray.intersections[i + 1];
156          if (hitB.mT - hitA.mT > Limits::Small) {
157                if (DotProd(hitA.mNormal, ray.GetDir()) > 0 &&
158                        DotProd(hitB.mNormal, ray.GetDir()) < 0
159                        ) {
160                 
161                  vssRay = new VssRay(
162                                                          ray.Extrap(hitA.mT),
163                                                          ray.Extrap(hitB.mT),
164                                                          hitA.mObject,
165                                                        hitB.mObject,
166                                                          mPreprocessor.mPass,
167                                                          simpleRay.mPdf
168                                                          );
169                  vssRay->mFlags |= VssRay::Valid;
170                  vssRay->mDistribution = simpleRay.mDistribution;
171                  vssRays.push_back(vssRay);
172                  ++hits;
173                 
174                  vssRay = new VssRay(
175                                                          ray.Extrap(hitB.mT),
176                                                          ray.Extrap(hitA.mT),
177                                                          hitB.mObject,
178                                                          hitA.mObject,
179                                                          mPreprocessor.mPass,
180                                                          simpleRay.mPdf
181                                                          );
182                 
183                  vssRay->mFlags |= VssRay::Valid;
184                  vssRay->mDistribution = simpleRay.mDistribution;
185                  vssRays.push_back(vssRay);
186                  ++hits;
187                }
188          }
189        }
190  }
191 
192  return hits;
193}
194
195
196void InternalRayCaster::CastRays16(SimpleRayContainer &rays,
197                                                                   VssRayContainer &vssRays,
198                                                                   const AxisAlignedBox3 &sbox,
199                                                                   const bool castDoubleRays,
200                                                                   const bool pruneInvalidRays,
201                                                                   const bool keepOrigin)
202{
203#if DEBUG_RAYCAST
204        Debug << "C16 " << flush;
205#endif
206
207        SimpleRayContainer::const_iterator sit, sit_end = rays.end();
208
209        // no acceleration for ray bundles implemented right now
210        for (sit = rays.begin(); sit != sit_end; ++ sit)
211        {
212                CastRay(*sit, vssRays, sbox, castDoubleRays, pruneInvalidRays, keepOrigin);
213        }
214
215#if DEBUG_RAYCAST
216        Debug<<"C16F\n"<<flush;
217#endif
218}
219
220}
Note: See TracBrowser for help on using the repository browser.