HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UT_BoundingRectImpl.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_BoundingRectImpl.h (UT Library, C++)
7  *
8  * COMMENTS: Implementation for UT_BoundingRect
9  */
10 
11 #ifndef __UT_BoundingRectImpl_H__
12 #define __UT_BoundingRectImpl_H__
13 
14 #include <limits>
15 
16 #define FASTBOX(idx) \
17  ray = T(1.0) / (v1(idx) - v0(idx)); \
18  positive = (ray > T(0.0)); \
19  t1 = (vals[idx][ positive] - v0(idx))*ray; \
20  if (t1 < tmax) { if (t1 < tmin) return 0; else tmax = t1; } \
21  t1 = (vals[idx][1-positive] - v0(idx))*ray; \
22  if (t1 > tmin) { if (t1 > tmax) return 0; else tmin = t1; }
23 
24 template <typename T>
25 inline int
27  const UT_Vector2T<T> &v0,
28  const UT_Vector2T<T> &v1) const
29 {
30  T tmin, tmax;
31  T ray;
32  T t1;
33  int positive;
34 
35  tmin = 0;
36  tmax = 1;
37 
38  FASTBOX(0)
39  FASTBOX(1)
40 
41  return 1;
42 }
43 
44 #undef FASTBOX
45 
46 template <typename T>
47 inline int
49  const UT_Vector2T<T> &v0,
50  const UT_Vector2T<T> &v1,
51  const UT_Vector2T<T> &v2) const
52 {
53  bool v0eqv1 = v0.isEqual(v1);
54  bool v0eqv2 = v0.isEqual(v2);
55  bool v1eqv2 = v1.isEqual(v2);
56 
57  // If any triangle edge intersects the rectangle, we intersect.
58  if ((!v0eqv1 && intersects(v0, v1)) ||
59  (!v1eqv2 && intersects(v1, v2)) ||
60  (!v0eqv2 && intersects(v2, v0)))
61  return 1;
62 
63  // If any two (or more) vertices are the same, the line intersection
64  // tests are all we need to do. The rectangle can't be inside a
65  // degenerate triangle.
66  if (v0eqv1 || v0eqv2 || v1eqv2)
67  return 0;
68 
69  UT_Vector2T<T> l01, l12, l20;
70  T cp0, cp1, cp2;
71 
72  l01 = v1 - v0;
73  l12 = v2 - v1;
74  l20 = v0 - v2;
75  cp0 = cross(l01, v2 - v0);
76  cp1 = cross(l12, v0 - v1);
77  cp2 = cross(l20, v1 - v2);
78 
79  // Another check for degeneracy if all three points are in a line.
80  if (cp0 == 0.0 || cp1 == 0.0 || cp2 == 0.0)
81  return 0;
82 
83  // The only other way we could have intersection is if the rectangle is
84  // completely enclosed by the triangle. To test for this case, just test
85  // whether the center of the rectangle is inside the triangle by testing
86  // that the center point is on the same side of each edge as the extra
87  // vertex opposite each edge.
88  UT_Vector2T<T> center(centerX(), centerY());
89  if (cp0 * cross(l01, center - v0) >= 0.0 &&
90  cp1 * cross(l12, center - v1) >= 0.0 &&
91  cp2 * cross(l20, center - v2) >= 0.0)
92  return 1;
93 
94  return 0;
95 }
96 
97 template <typename T>
98 inline void
99 UT_BoundingRectT<T>::project(T &x, T &y, int *touchx, int *touchy) const
100 {
101  int inx, iny;
102  T newx, newy, dx, dy;
103 
104  inx = iny = 0;
105 
106  // Calculate the values for the X direction
107  if(x < vals[0][0])
108  newx = vals[0][0];
109  else if(x > vals[0][1])
110  newx = vals[0][1];
111  else
112  {
113  inx = 1;
114  newx = ((x-vals[0][0]) < (vals[0][1]-x)) ? vals[0][0] : vals[0][1];
115  dx = (newx - x > 0.0) ? newx - x : x - newx;
116  }
117 
118  // Calculate the values for the Y direction
119  if(y < vals[1][0])
120  newy = vals[1][0];
121  else if(y > vals[1][1])
122  newy = vals[1][1];
123  else
124  {
125  iny = 1;
126  newy = ((y-vals[1][0]) < (vals[1][1]-y)) ? vals[1][0] : vals[1][1];
127  dy = (newy - y > 0.0) ? newy - y : y - newy;
128  }
129 
130  if(inx)
131  {
132  if(iny)
133  {
134  if(dx < dy)
135  {
136  x = newx;
137  if (touchx) *touchx = 1;
138  }
139  else
140  {
141  y = newy;
142  if (touchy) *touchy = 1;
143  }
144  }
145  else
146  {
147  y = newy;
148  if (touchy) *touchy = 1;
149  }
150  }
151  else
152  {
153  x = newx;
154  if (touchx) *touchx = 1;
155  if(!iny)
156  {
157  y = newy;
158  if (touchy) *touchy = 1;
159  }
160  }
161 }
162 
163 #define TESTFACE(face, min, face1) \
164  t = (vals[face][min] - o(face)) * invd(face); \
165  if (t >= (T)0 && t < tmin) \
166  { \
167  t1 = o(face1) + t*d(face1); \
168  if (t1 >= vals[face1][0] && t1 <= vals[face1][1]) \
169  { \
170  tmin = t; \
171  found = face; \
172  } \
173  }
174 
175 template <typename T>
176 inline int
178  const UT_Vector2T<T> &o, const UT_Vector2T<T> &d,
179  T maxdist, T *dist, UT_Vector2T<T> *xsect) const
180 {
181  UT_Vector2T<T> invd;
182  T t, t1, tmin;
183  int found;
184 
185  found = -1;
186  tmin = maxdist;
187  invd = 1.0/d;
188 
189  TESTFACE(0, 0, 1)
190  TESTFACE(0, 1, 1)
191 
192  TESTFACE(1, 0, 0)
193  TESTFACE(1, 1, 0)
194 
195  if (found == -1) return 0;
196 
197  if (dist) *dist = tmin;
198  if (xsect) *xsect = o + tmin*d;
199 
200  return 1;
201 }
202 
203 #undef TESTFACE
204 
205 #endif // __UT_BoundingRectImpl_H__
#define FASTBOX(idx)
GA_API const UT_StringHolder dist
GLint y
Definition: glcorearb.h:102
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:817
2D Vector class.
Definition: UT_Vector2.h:137
#define TESTFACE(face, min, face1)
int intersectRay(const UT_Vector2T< T > &orig, const UT_Vector2T< T > &dir, T tmax=1E17, T *distance=0, UT_Vector2T< T > *xsect=0) const
void project(T &x, T &y, int *touchx=0, int *touchy=0) const
GLfloat v0
Definition: glcorearb.h:815
SYS_FORCE_INLINE bool isEqual(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that, S tol=S(SYS_FTOLERANCE)) const
bool intersects(const Box< Vec3< T > > &b, const Line3< T > &r, Vec3< T > &ip)
Definition: ImathBoxAlgo.h:728
GLint GLenum GLint x
Definition: glcorearb.h:408
GLfloat GLfloat v1
Definition: glcorearb.h:816
int intersects(const UT_Vector2T< T > &v0, const UT_Vector2T< T > &v1, const UT_Vector2T< T > &v2) const
SIM_DerVector3 cross(const SIM_DerVector3 &lhs, const SIM_DerVector3 &rhs)