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

Revision 2609, 4.9 KB checked in by mattausch, 17 years ago (diff)
RevLine 
[162]1#include "Ray.h"
[327]2#include "Plane3.h"
[426]3#include "VssRay.h"
[162]4
[2176]5using namespace std;
6
[863]7namespace GtpVisibilityPreprocessor {
[860]8
[162]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!
[1867]18  int
19  Ray::genID = 1;
20 
21 
22 
[162]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
[1584]33  //Precompute();
34  // $$ JB precomputation will be applied only when the origin/dir valueas are set
35  SetId();
[162]36}
37
38void
39Ray::Precompute()
40{
41  // initialize inverted dir
[1584]42  //  invDir.SetValue(0.0, 0.0, 0.0);
[328]43  SetId();
[1584]44  ComputeInvertedDir();
[162]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{
[485]58  const float eps = 1e-6f;
[162]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{
[1584]89  //  if ( (invDir.x != 0.0) ||
90  //       (invDir.y != 0.0) ||
91  //       (invDir.z != 0.0) )
92  //    return; // has been already precomputed
[162]93
[487]94  const float eps = 1e-6f;
95  const float invEps = 1e6f;
[162]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
[485]107    invDir.x = 1.0f / dir.x;
[162]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
[485]116    invDir.y = 1.0f / dir.y;
[162]117 
118  if (fabs(dir.z) < eps) {
[485]119    if (dir.z < 0.0f)
[162]120      invDir.z = -invEps;
121    else
122      invDir.z = invEps;
123  }
124  else
[485]125    invDir.z = 1.0f / dir.z;
[162]126
127  return;
128}
129
[191]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
[369]148void
149PassingRaySet::AddRay2(const Ray &ray,
[475]150                                           const int objects,
151                                           const int viewcells
152                                           )
[369]153{
154  int i = GetEntryIndex(ray.GetDir());
155  mRays++;
156  mContributions += objects*viewcells;
157  mDirectionalContributions[i] += objects*viewcells;
158}
159
[191]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);
[485]173  int ix = (int)((x + 1.0f)*0.5f*Resolution);
174  int iy = (int)((y + 1.0f)*0.5f*Resolution);
[191]175
176  return Resolution*(Resolution*axis + iy) + ix;
177}
178
[644]179
[428]180int Ray::ClassifyPlane(const Plane3 &plane,
181                                           const float minT,
182                                           const float maxT,
183                                           Vector3 &entP,
184                                           Vector3 &extP) const
[327]185{
[406]186        entP = Extrap(minT);
187        extP = Extrap(maxT);
[328]188 
[406]189        const int entSide = plane.Side(entP);
190        const int extSide = plane.Side(extP);
[328]191
[362]192        if (entSide < 0)
[406]193        {
[644]194                if (extSide > 0)
[362]195                {
[406]196                        return BACK_FRONT;
[362]197                }
[406]198                return BACK;
199        }
[362]200        else if (entSide > 0)
[406]201        {
[644]202                if (extSide < 0)
[406]203                        return FRONT_BACK;
[369]204                       
[406]205                return FRONT;
206        }
[362]207        else if (entSide == 0)
[406]208        {
209                if (extSide > 0)
[644]210                        return FRONT;
[406]211                else if (extSide < 0)
[644]212                        return BACK;
[406]213        }
[327]214       
[362]215        return COINCIDENT;
[327]216}
217
[366]218
[191]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;
[426]227}
228
[2609]229
230void Ray::Init(const VssRay &vssRay)
[426]231{
[2609]232        loc = vssRay.mOrigin;
233        sourceObject = Intersection(0, vssRay.GetDir(), vssRay.mOriginObject, 0);
234        mType = LOCAL_RAY;
[1584]235
[2609]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();
[466]249}
[860]250
[1199]251}
Note: See TracBrowser for help on using the repository browser.