source: GTP/trunk/Lib/Vis/Preprocessing/src/Ray.cpp @ 1584

Revision 1584, 5.0 KB checked in by bittner, 18 years ago (diff)

functional ray casting - fixed computeinvdir issue

Line 
1#include "Ray.h"
2#include "Plane3.h"
3#include "VssRay.h"
4
5namespace GtpVisibilityPreprocessor {
6
7// =========================================================
8// Ray .. static item used for generation of unique ID for
9// each instantiated ray
10
11// it has to start from 1, since 0 is default and for the first
12// ray initial value 0 will not work .. V.H.
13// The value 0 is reserved for particular purpose - the rays
14// that are converted to canonical space and thus the mailbox
15// rayID identification does not work for them!
16int
17Ray::genID = 1;
18
19// Precompute some Ray parameters. Most of them is used for
20// ropes traversal.
21
22void
23Ray::Init()
24{
25  //  if (mType == LOCAL_RAY)
26  //    intersections.reserve(1);
27  //  else
28  //    intersections.reserve(10);
29 
30  // apply the standard precomputation
31  //Precompute();
32  // $$ JB precomputation will be applied only when the origin/dir valueas are set
33  SetId();
34}
35
36void
37Ray::Precompute()
38{
39  // initialize inverted dir
40  //  invDir.SetValue(0.0, 0.0, 0.0);
41  SetId();
42  ComputeInvertedDir();
43}
44
45void
46Ray::SetLoc(const Vector3 &l)
47{
48  loc = l;
49}
50
51// make such operation to slightly change the ray direction
52// in case any component of ray direction is zero.
53void
54Ray::CorrectZeroComponents()
55{
56  const float eps = 1e-6f;
57
58  // it does change the ray direction very slightly,
59  // but the size direction vector is not practically changed
60 
61  if (fabs(dir.x) < eps) {
62    if (dir.x < 0.0)
63      dir.x = -eps;
64    else
65      dir.x = eps;
66  }
67 
68  if (fabs(dir.y) < eps) {
69    if (dir.y < 0.0)
70      dir.y = -eps;
71    else
72      dir.y = eps;
73  }
74 
75  if (fabs(dir.z) < eps) {
76    if (dir.z < 0.0)
77      dir.z = -eps;
78    else
79      dir.z = eps;
80  }
81}
82
83
84void
85Ray::ComputeInvertedDir() const
86{
87  //  if ( (invDir.x != 0.0) ||
88  //       (invDir.y != 0.0) ||
89  //       (invDir.z != 0.0) )
90  //    return; // has been already precomputed
91
92  const float eps = 1e-6f;
93  const float invEps = 1e6f;
94 
95  // it does change the ray direction very slightly,
96  // but the size direction vector is not practically changed
97 
98  if (fabs(dir.x) < eps) {
99    if (dir.x < 0.0)
100      invDir.x = -invEps;
101    else
102      invDir.x = invEps;
103  }
104  else
105    invDir.x = 1.0f / dir.x;
106 
107  if (fabs(dir.y) < eps) {
108    if (dir.y < 0.0)
109      invDir.y = -invEps;
110    else
111      invDir.y = invEps;
112  }
113  else
114    invDir.y = 1.0f / dir.y;
115 
116  if (fabs(dir.z) < eps) {
117    if (dir.z < 0.0f)
118      invDir.z = -invEps;
119    else
120      invDir.z = invEps;
121  }
122  else
123    invDir.z = 1.0f / dir.z;
124
125  return;
126}
127
128void
129PassingRaySet::Reset()
130{
131  for (int i=0; i < 3*Resolution*Resolution; i++)
132    mDirectionalContributions[i] = 0;
133  mRays = 0;
134  mContributions = 0;
135}
136 
137void
138PassingRaySet::AddRay(const Ray &ray, const int contributions)
139{
140  int i = GetEntryIndex(ray.GetDir());
141  mRays++;
142  mContributions += contributions;
143  mDirectionalContributions[i] += contributions;
144}
145
146void
147PassingRaySet::AddRay2(const Ray &ray,
148                                           const int objects,
149                                           const int viewcells
150                                           )
151{
152  int i = GetEntryIndex(ray.GetDir());
153  mRays++;
154  mContributions += objects*viewcells;
155  mDirectionalContributions[i] += objects*viewcells;
156}
157
158int
159PassingRaySet::GetEntryIndex(const Vector3 &direction) const
160{
161  // get face
162  int axis = direction.DrivingAxis();
163  Vector3 dir;
164  float k = direction[axis];
165  if ( k < 0.0f)
166    k = -k;
167
168  dir = direction/k;
169  float x, y;
170  dir.ExtractVerts(&x, &y, axis);
171  int ix = (int)((x + 1.0f)*0.5f*Resolution);
172  int iy = (int)((y + 1.0f)*0.5f*Resolution);
173
174  return Resolution*(Resolution*axis + iy) + ix;
175}
176
177
178int Ray::ClassifyPlane(const Plane3 &plane,
179                                           const float minT,
180                                           const float maxT,
181                                           Vector3 &entP,
182                                           Vector3 &extP) const
183{
184        entP = Extrap(minT);
185        extP = Extrap(maxT);
186 
187        const int entSide = plane.Side(entP);
188        const int extSide = plane.Side(extP);
189
190        if (entSide < 0)
191        {
192                if (extSide > 0)
193                {
194                        return BACK_FRONT;
195                }
196                return BACK;
197        }
198        else if (entSide > 0)
199        {
200                if (extSide < 0)
201                        return FRONT_BACK;
202                       
203                return FRONT;
204        }
205        else if (entSide == 0)
206        {
207                if (extSide > 0)
208                        return FRONT;
209                else if (extSide < 0)
210                        return BACK;
211        }
212       
213        return COINCIDENT;
214}
215
216
217ostream &
218operator<<(ostream &s, const PassingRaySet &set)
219{
220  s<<"Ray Set #rays="<<set.mRays<<" #contributions="<<set.mContributions<<endl;
221  for (int i=0; i < 3*sqr(PassingRaySet::Resolution); i++)
222    s<<set.mDirectionalContributions[i]<<" ";
223  s<<endl;
224  return s;
225}
226
227void
228Ray::Init(const VssRay &vssRay)
229{
230  loc = vssRay.mOrigin;
231  sourceObject = Intersection(0, vssRay.GetDir(), vssRay.mOriginObject, 0);
232  mType = LOCAL_RAY;
233 
234  float len = vssRay.Length();
235 
236  if (!len)
237        len = Limits::Small;
238 
239  dir = vssRay.GetDir() / len;
240 
241  intersections.clear();
242  if (vssRay.mTerminationObject)
243        intersections.push_back(Intersection(len, -vssRay.GetDir(), vssRay.mTerminationObject, 0));
244
245 
246  Precompute();
247}
248
249}
Note: See TracBrowser for help on using the repository browser.