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

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