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

Revision 644, 4.8 KB checked in by mattausch, 19 years ago (diff)
RevLine 
[162]1#include "Ray.h"
[327]2#include "Plane3.h"
[426]3#include "VssRay.h"
[162]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 
[328]38  SetId();
[162]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{
[485]52  const float eps = 1e-6f;
[162]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
[487]88  const float eps = 1e-6f;
89  const float invEps = 1e6f;
[162]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
[485]101    invDir.x = 1.0f / dir.x;
[162]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
[485]110    invDir.y = 1.0f / dir.y;
[162]111 
112  if (fabs(dir.z) < eps) {
[485]113    if (dir.z < 0.0f)
[162]114      invDir.z = -invEps;
115    else
116      invDir.z = invEps;
117  }
118  else
[485]119    invDir.z = 1.0f / dir.z;
[162]120
121  return;
122}
123
[191]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
[369]142void
143PassingRaySet::AddRay2(const Ray &ray,
[475]144                                           const int objects,
145                                           const int viewcells
146                                           )
[369]147{
148  int i = GetEntryIndex(ray.GetDir());
149  mRays++;
150  mContributions += objects*viewcells;
151  mDirectionalContributions[i] += objects*viewcells;
152}
153
[191]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);
[485]167  int ix = (int)((x + 1.0f)*0.5f*Resolution);
168  int iy = (int)((y + 1.0f)*0.5f*Resolution);
[191]169
170  return Resolution*(Resolution*axis + iy) + ix;
171}
172
[644]173
[428]174int Ray::ClassifyPlane(const Plane3 &plane,
175                                           const float minT,
176                                           const float maxT,
177                                           Vector3 &entP,
178                                           Vector3 &extP) const
[327]179{
[406]180        entP = Extrap(minT);
181        extP = Extrap(maxT);
[328]182 
[406]183        const int entSide = plane.Side(entP);
184        const int extSide = plane.Side(extP);
[328]185
[362]186        if (entSide < 0)
[406]187        {
[644]188                if (extSide > 0)
[362]189                {
[406]190                        return BACK_FRONT;
[362]191                }
[406]192                return BACK;
193        }
[362]194        else if (entSide > 0)
[406]195        {
[644]196                if (extSide < 0)
[406]197                        return FRONT_BACK;
[369]198                       
[406]199                return FRONT;
200        }
[362]201        else if (entSide == 0)
[406]202        {
203                if (extSide > 0)
[644]204                        return FRONT;
[406]205                else if (extSide < 0)
[644]206                        return BACK;
[406]207        }
[327]208       
[362]209        return COINCIDENT;
[327]210}
211
[366]212
[191]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;
[426]221}
222
[466]223void
224Ray::Init(const VssRay &vssRay)
[426]225{
[466]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 
[564]237  intersections.clear();
[466]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.