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

Revision 1199, 4.8 KB checked in by bittner, 18 years ago (diff)

code merge

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
31  Precompute();
32}
33
34void
35Ray::Precompute()
36{
37  // initialize inverted dir
38  invDir.SetValue(0.0);
39 
[328]40  SetId();
[162]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{
[485]54  const float eps = 1e-6f;
[162]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
[487]90  const float eps = 1e-6f;
91  const float invEps = 1e6f;
[162]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
[485]103    invDir.x = 1.0f / dir.x;
[162]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
[485]112    invDir.y = 1.0f / dir.y;
[162]113 
114  if (fabs(dir.z) < eps) {
[485]115    if (dir.z < 0.0f)
[162]116      invDir.z = -invEps;
117    else
118      invDir.z = invEps;
119  }
120  else
[485]121    invDir.z = 1.0f / dir.z;
[162]122
123  return;
124}
125
[191]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
[369]144void
145PassingRaySet::AddRay2(const Ray &ray,
[475]146                                           const int objects,
147                                           const int viewcells
148                                           )
[369]149{
150  int i = GetEntryIndex(ray.GetDir());
151  mRays++;
152  mContributions += objects*viewcells;
153  mDirectionalContributions[i] += objects*viewcells;
154}
155
[191]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);
[485]169  int ix = (int)((x + 1.0f)*0.5f*Resolution);
170  int iy = (int)((y + 1.0f)*0.5f*Resolution);
[191]171
172  return Resolution*(Resolution*axis + iy) + ix;
173}
174
[644]175
[428]176int Ray::ClassifyPlane(const Plane3 &plane,
177                                           const float minT,
178                                           const float maxT,
179                                           Vector3 &entP,
180                                           Vector3 &extP) const
[327]181{
[406]182        entP = Extrap(minT);
183        extP = Extrap(maxT);
[328]184 
[406]185        const int entSide = plane.Side(entP);
186        const int extSide = plane.Side(extP);
[328]187
[362]188        if (entSide < 0)
[406]189        {
[644]190                if (extSide > 0)
[362]191                {
[406]192                        return BACK_FRONT;
[362]193                }
[406]194                return BACK;
195        }
[362]196        else if (entSide > 0)
[406]197        {
[644]198                if (extSide < 0)
[406]199                        return FRONT_BACK;
[369]200                       
[406]201                return FRONT;
202        }
[362]203        else if (entSide == 0)
[406]204        {
205                if (extSide > 0)
[644]206                        return FRONT;
[406]207                else if (extSide < 0)
[644]208                        return BACK;
[406]209        }
[327]210       
[362]211        return COINCIDENT;
[327]212}
213
[366]214
[191]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;
[426]223}
224
[466]225void
226Ray::Init(const VssRay &vssRay)
[426]227{
[466]228  loc = vssRay.mOrigin;
[1199]229  sourceObject = Intersection(0, vssRay.GetDir(), vssRay.mOriginObject, 0);
[466]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 
[564]239  intersections.clear();
[466]240  if (vssRay.mTerminationObject)
[1199]241        intersections.push_back(Intersection(len, -vssRay.GetDir(), vssRay.mTerminationObject, 0));
[466]242 
243  Precompute();
244}
[860]245
[1199]246}
Note: See TracBrowser for help on using the repository browser.