HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ray.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef GF_RAY_H
25 #define GF_RAY_H
26 
27 /// \file gf/ray.h
28 /// \ingroup group_gf_BasicGeometry
29 
30 #include "pxr/pxr.h"
31 #include "pxr/base/gf/matrix4d.h"
32 #include "pxr/base/gf/api.h"
33 
34 #include <float.h>
35 #include <limits>
36 #include <iosfwd>
37 
39 
40 class GfLine;
41 class GfLineSeg;
42 class GfPlane;
43 class GfRange3d;
44 
45 /// \class GfRay
46 /// \ingroup group_gf_BasicGeometry
47 ///
48 /// Basic type: Ray used for intersection testing
49 ///
50 /// This class represents a three-dimensional ray in space, typically
51 /// used for intersection testing. It consists of an origin and a
52 /// direction.
53 ///
54 /// Note that by default a \c GfRay does not normalize its direction
55 /// vector to unit length.
56 ///
57 /// Note for ray intersections, the start point is included in the computations,
58 /// i.e., a distance of zero is defined to be intersecting.
59 ///
60 class GfRay {
61 
62  public:
63 
64  /// The default constructor leaves the ray parameters undefined.
65  GfRay() {
66  }
67 
68  /// This constructor takes a starting point and a direction.
69  GfRay(const GfVec3d &startPoint, const GfVec3d &direction) {
70  SetPointAndDirection(startPoint, direction);
71  }
72 
73  /// Sets the ray by specifying a starting point and a direction.
74  GF_API
75  void SetPointAndDirection(const GfVec3d &startPoint,
76  const GfVec3d &direction);
77 
78  /// Sets the ray by specifying a starting point and an ending point.
79  GF_API
80  void SetEnds(const GfVec3d &startPoint, const GfVec3d &endPoint);
81 
82  /// Returns the starting point of the segment.
83  const GfVec3d & GetStartPoint() const {
84  return _startPoint;
85  }
86 
87  /// Returns the direction vector of the segment. This is not guaranteed to
88  /// be unit length.
89  const GfVec3d & GetDirection() const {
90  return _direction;
91  }
92 
93  /// Returns the point that is \p distance units from the starting point
94  /// along the direction vector, expressed in parametic distance.
95  GfVec3d GetPoint(double distance) const {
96  return _startPoint + distance * _direction;
97  }
98 
99  /// Transforms the ray by the given matrix.
100  GF_API
101  GfRay & Transform(const GfMatrix4d &matrix);
102 
103  /// Returns the point on the ray that is closest to \p point. If \p
104  /// rayDistance is not \c NULL, it will be set to the parametric distance
105  /// along the ray of the closest point.
106  GF_API
107  GfVec3d FindClosestPoint(const GfVec3d &point,
108  double *rayDistance = NULL) const;
109 
110  /// Component-wise equality test. The starting points, directions, and
111  /// lengths must match exactly for rays to be considered equal.
112  bool operator ==(const GfRay &r) const {
113  return (_startPoint == r._startPoint &&
114  _direction == r._direction);
115  }
116 
117  /// Component-wise inequality test. The starting points, directions, and
118  /// lengths must match exactly for rays to be considered equal.
119  bool operator !=(const GfRay &r) const {
120  return ! (*this == r);
121  }
122 
123  /// \name Intersection methods.
124  ///
125  /// The methods in this group intersect the ray with a geometric entity.
126  ///
127  ///@{
128 
129  /// Intersects the ray with the triangle formed by points \p p0, \p p1,
130  /// and \p p2, returning \c true if it hits. If there is an intersection,
131  /// it also returns the parametric distance to the intersection point in
132  /// \p distance, the barycentric coordinates of the intersection point in
133  /// \p barycentricCoords and the front-facing flag in \p frontFacing. The
134  /// barycentric coordinates are defined with respect to the three vertices
135  /// taken in order. The front-facing flag is \c true if the intersection
136  /// hit the side of the triangle that is formed when the vertices are
137  /// ordered counter-clockwise (right-hand rule). If any of the return
138  /// pointers are \c NULL, the corresponding values are not returned.
139  ///
140  /// If the distance to the intersection is greater than \p maxDist, then
141  /// the method will return false.
142  ///
143  /// Barycentric coordinates are defined to sum to 1 and satisfy this
144  /// relationsip:
145  /// \code
146  /// intersectionPoint = (barycentricCoords[0] * p0 +
147  /// barycentricCoords[1] * p1 +
148  /// barycentricCoords[2] * p2);
149  /// \endcode
150  GF_API
151  bool Intersect(const GfVec3d &p0,
152  const GfVec3d &p1,
153  const GfVec3d &p2,
154  double *distance = NULL,
155  GfVec3d *barycentricCoords = NULL,
156  bool *frontFacing = NULL,
157  double maxDist = std::numeric_limits<double>::infinity())
158  const;
159 
160  /// Intersects the ray with a plane, returning \c true if the ray is not
161  /// parallel to the plane and the intersection is within the ray bounds.
162  /// If there is an intersection, it also returns the parametric distance
163  /// to the intersection point in \p distance and the front-facing flag in
164  /// \p frontFacing, if they are not \c NULL. The front-facing flag is \c
165  /// true if the intersection is on the side of the plane in which its
166  /// normal points.
167  GF_API
168  bool Intersect(const GfPlane &plane, double *distance = NULL,
169  bool *frontFacing = NULL) const;
170 
171  /// Intersects the ray with an axis-aligned box, returning \c true if the
172  /// ray intersects it at all within bounds. If there is an intersection,
173  /// this also returns the parametric distances to the two intersection
174  /// points in \p enterDistance and \p exitDistance.
175  GF_API
176  bool Intersect(const GfRange3d &box,
177  double *enterDistance = NULL,
178  double *exitDistance = NULL) const;
179 
180  /// Intersects the ray with a sphere, returning \c true if the ray
181  /// intersects it at all within bounds. If there is an intersection,
182  /// returns the parametric distance to the two intersection points in \p
183  /// enterDistance and \p exitDistance.
184  GF_API
185  bool Intersect(const GfVec3d &center, double radius,
186  double *enterDistance = NULL,
187  double *exitDistance = NULL ) const;
188 
189  /// Intersects the ray with an infinite cylinder, with axis \p axis,
190  /// centered at the \p origin, with radius \p radius.
191  ///
192  /// Returns \c true if the ray intersects it at all within bounds. If
193  /// there is an intersection, returns the parametric distance to the two
194  /// intersection points in \p enterDistance and \p exitDistance.
195  ///
196  /// Note this method does not validate whether the radius is valid.
197  GF_API
198  bool Intersect(const GfVec3d &origin,
199  const GfVec3d &axis,
200  const double radius,
201  double *enterDistance = NULL,
202  double *exitDistance = NULL) const;
203 
204  /// Intersects the ray with an infinite non-double cone, centered at \p
205  /// origin, with axis \p axis, radius \p radius and apex at \p height.
206  ///
207  /// Returns \c true if the ray intersects it at all within bounds. If
208  /// there is an intersection, returns the parametric distance to the two
209  /// intersection points in \p enterDistance and \p exitDistance.
210  ///
211  /// Note this method does not validate whether the radius are height are
212  /// valid.
213  GF_API
214  bool Intersect(const GfVec3d &origin,
215  const GfVec3d &axis,
216  const double radius,
217  const double height,
218  double *enterDistance = NULL,
219  double *exitDistance = NULL) const;
220  ///@}
221 
222  private:
223  GF_API
224  friend bool GfFindClosestPoints( const GfRay &, const GfLine &,
225  GfVec3d *, GfVec3d *,
226  double *, double * );
227  GF_API
228  friend bool GfFindClosestPoints( const GfRay &, const GfLineSeg &,
229  GfVec3d *, GfVec3d *,
230  double *, double * );
231 
232  /// Solves the quadratic equation returning the solutions, if defined, in
233  /// \p enterDistance and \p exitDistance, where \p enterDistance is less
234  /// than or equal to \p exitDistance.
235  bool _SolveQuadratic(const double a,
236  const double b,
237  const double c,
238  double *enterDistance = NULL,
239  double *exitDistance = NULL) const;
240 
241  /// The starting point of the ray.
242  GfVec3d _startPoint;
243  /// The direction vector.
244  GfVec3d _direction;
245 };
246 
247 /// Computes the closest points between a ray and a line. The two points are
248 /// returned in \p rayPoint and \p linePoint. The parametric distance of each
249 /// point on the lines is returned in \p rayDistance and \p lineDistance.
250 ///
251 /// This returns \c false if the lines were close enough to parallel that no
252 /// points could be computed; in this case, the other return values are
253 /// undefined.
254 GF_API
255 bool GfFindClosestPoints( const GfRay &ray, const GfLine &line,
256  GfVec3d *rayPoint = nullptr,
257  GfVec3d *linePoint = nullptr,
258  double *rayDistance = nullptr,
259  double *lineDistance = nullptr );
260 
261 /// Computes the closest points between a ray and a line segment. The two
262 /// points are returned in \p rayPoint and \p segPoint. The parametric
263 /// distance of each point is returned in \p rayDistance and \p segDistance.
264 ///
265 /// This returns \c false if the lines were close enough to parallel that no
266 /// points could be computed; in this case, the other return values are
267 /// undefined.
268 GF_API
269 bool GfFindClosestPoints( const GfRay &ray, const GfLineSeg &seg,
270  GfVec3d *rayPoint = nullptr,
271  GfVec3d *segPoint = nullptr,
272  double *rayDistance = nullptr,
273  double *segDistance = nullptr );
274 
275 /// Output a GfRay using the format [(x y z) >> (x y z)].
276 /// \ingroup group_gf_DebuggingOutput
277 GF_API std::ostream& operator<<(std::ostream&, const GfRay&);
278 
280 
281 #endif // GF_RAY_H
IMF_EXPORT IMATH_NAMESPACE::V3f direction(const IMATH_NAMESPACE::Box2i &dataWindow, const IMATH_NAMESPACE::V2f &pixelPosition)
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
Definition: glew.h:1252
const GfVec3d & GetStartPoint() const
Returns the starting point of the segment.
Definition: ray.h:83
bool operator!=(const GfRay &r) const
Definition: ray.h:119
GfRay()
The default constructor leaves the ray parameters undefined.
Definition: ray.h:65
Definition: plane.h:52
const GfVec3d & GetDirection() const
Definition: ray.h:89
GfVec3d GetPoint(double distance) const
Definition: ray.h:95
const GLfloat * c
Definition: glew.h:16296
GLsizei GLsizei GLfloat distance
Definition: glew.h:13640
Definition: line.h:49
GF_API void SetPointAndDirection(const GfVec3d &startPoint, const GfVec3d &direction)
Sets the ray by specifying a starting point and a direction.
GF_API bool Intersect(const GfVec3d &p0, const GfVec3d &p1, const GfVec3d &p2, double *distance=NULL, GfVec3d *barycentricCoords=NULL, bool *frontFacing=NULL, double maxDist=std::numeric_limits< double >::infinity()) const
GF_API void SetEnds(const GfVec3d &startPoint, const GfVec3d &endPoint)
Sets the ray by specifying a starting point and an ending point.
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1245
bool operator==(const GfRay &r) const
Definition: ray.h:112
GLdouble GLdouble GLdouble r
Definition: glew.h:1406
Definition: vec3d.h:63
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:83
GF_API GfVec3d FindClosestPoint(const GfVec3d &point, double *rayDistance=NULL) const
Definition: ray.h:60
GF_API bool GfFindClosestPoints(const GfRay &ray, const GfLine &line, GfVec3d *rayPoint=nullptr, GfVec3d *linePoint=nullptr, double *rayDistance=nullptr, double *lineDistance=nullptr)
GF_API friend bool GfFindClosestPoints(const GfRay &, const GfLine &, GfVec3d *, GfVec3d *, double *, double *)
GF_API std::ostream & operator<<(std::ostream &, const GfRay &)
GLuint GLenum matrix
Definition: glew.h:14742
GF_API GfRay & Transform(const GfMatrix4d &matrix)
Transforms the ray by the given matrix.
GfRay(const GfVec3d &startPoint, const GfVec3d &direction)
This constructor takes a starting point and a direction.
Definition: ray.h:69
#define GF_API
Definition: api.h:40