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

Revision 644, 4.8 KB checked in by mattausch, 18 years ago (diff)
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
173
174int Ray::ClassifyPlane(const Plane3 &plane,
175                                           const float minT,
176                                           const float maxT,
177                                           Vector3 &entP,
178                                           Vector3 &extP) const
179{
180        entP = Extrap(minT);
181        extP = Extrap(maxT);
182 
183        const int entSide = plane.Side(entP);
184        const int extSide = plane.Side(extP);
185
186        if (entSide < 0)
187        {
188                if (extSide > 0)
189                {
190                        return BACK_FRONT;
191                }
192                return BACK;
193        }
194        else if (entSide > 0)
195        {
196                if (extSide < 0)
197                        return FRONT_BACK;
198                       
199                return FRONT;
200        }
201        else if (entSide == 0)
202        {
203                if (extSide > 0)
204                        return FRONT;
205                else if (extSide < 0)
206                        return BACK;
207        }
208       
209        return COINCIDENT;
210}
211
212
213ostream &
214operator<<(ostream &s, const PassingRaySet &set)
215{
216  s<<"Ray Set #rays="<<set.mRays<<" #contributions="<<set.mContributions<<endl;
217  for (int i=0; i < 3*sqr(PassingRaySet::Resolution); i++)
218    s<<set.mDirectionalContributions[i]<<" ";
219  s<<endl;
220  return s;
221}
222
223void
224Ray::Init(const VssRay &vssRay)
225{
226  loc = vssRay.mOrigin;
227  sourceObject = Intersection(0, vssRay.mOriginObject, 0);
228  mType = LOCAL_RAY;
229 
230  float len = vssRay.Length();
231 
232  if (!len)
233        len = Limits::Small;
234 
235  dir = vssRay.GetDir() / len;
236 
237  intersections.clear();
238  if (vssRay.mTerminationObject)
239        intersections.push_back(Intersection(len, vssRay.mTerminationObject, 0));
240 
241  Precompute();
242}
Note: See TracBrowser for help on using the repository browser.