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

Revision 1829, 5.2 KB checked in by bittner, 18 years ago (diff)

ray caster bug fix

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