source: trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp @ 487

Revision 487, 4.7 KB checked in by mattausch, 18 years ago (diff)

fixed bug in raycasting
added valid view point regions, get view point only from valid regions

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