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

Revision 1584, 5.0 KB checked in by bittner, 18 years ago (diff)

functional ray casting - fixed computeinvdir issue

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