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

Revision 863, 4.8 KB checked in by mattausch, 18 years ago (diff)

working on preprocessor integration
added iv stuff

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