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 PXR_BASE_GF_RAY_H
25 #define PXR_BASE_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 GfBBox3d;
41 class GfLine;
42 class GfLineSeg;
43 class GfPlane;
44 class GfRange3d;
45 
46 /// \class GfRay
47 /// \ingroup group_gf_BasicGeometry
48 ///
49 /// Basic type: Ray used for intersection testing
50 ///
51 /// This class represents a three-dimensional ray in space, typically
52 /// used for intersection testing. It consists of an origin and a
53 /// direction.
54 ///
55 /// Note that by default a \c GfRay does not normalize its direction
56 /// vector to unit length.
57 ///
58 /// Note for ray intersections, the start point is included in the computations,
59 /// i.e., a distance of zero is defined to be intersecting.
60 ///
61 class GfRay {
62 
63  public:
64 
65  /// The default constructor leaves the ray parameters undefined.
66  GfRay() {
67  }
68 
69  /// This constructor takes a starting point and a direction.
70  GfRay(const GfVec3d &startPoint, const GfVec3d &direction) {
71  SetPointAndDirection(startPoint, direction);
72  }
73 
74  /// Sets the ray by specifying a starting point and a direction.
75  GF_API
76  void SetPointAndDirection(const GfVec3d &startPoint,
77  const GfVec3d &direction);
78 
79  /// Sets the ray by specifying a starting point and an ending point.
80  GF_API
81  void SetEnds(const GfVec3d &startPoint, const GfVec3d &endPoint);
82 
83  /// Returns the starting point of the segment.
84  const GfVec3d & GetStartPoint() const {
85  return _startPoint;
86  }
87 
88  /// Returns the direction vector of the segment. This is not guaranteed to
89  /// be unit length.
90  const GfVec3d & GetDirection() const {
91  return _direction;
92  }
93 
94  /// Returns the point that is \p distance units from the starting point
95  /// along the direction vector, expressed in parametic distance.
96  GfVec3d GetPoint(double distance) const {
97  return _startPoint + distance * _direction;
98  }
99 
100  /// Transforms the ray by the given matrix.
101  GF_API
102  GfRay & Transform(const GfMatrix4d &matrix);
103 
104  /// Returns the point on the ray that is closest to \p point. If \p
105  /// rayDistance is not \c NULL, it will be set to the parametric distance
106  /// along the ray of the closest point.
107  GF_API
108  GfVec3d FindClosestPoint(const GfVec3d &point,
109  double *rayDistance = NULL) const;
110 
111  /// Component-wise equality test. The starting points, directions, and
112  /// lengths must match exactly for rays to be considered equal.
113  bool operator ==(const GfRay &r) const {
114  return (_startPoint == r._startPoint &&
115  _direction == r._direction);
116  }
117 
118  /// Component-wise inequality test. The starting points, directions, and
119  /// lengths must match exactly for rays to be considered equal.
120  bool operator !=(const GfRay &r) const {
121  return ! (*this == r);
122  }
123 
124  /// \name Intersection methods.
125  ///
126  /// The methods in this group intersect the ray with a geometric entity.
127  ///
128  ///@{
129 
130  /// Intersects the ray with the triangle formed by points \p p0, \p p1,
131  /// and \p p2, returning \c true if it hits. If there is an intersection,
132  /// it also returns the parametric distance to the intersection point in
133  /// \p distance, the barycentric coordinates of the intersection point in
134  /// \p barycentricCoords and the front-facing flag in \p frontFacing. The
135  /// barycentric coordinates are defined with respect to the three vertices
136  /// taken in order. The front-facing flag is \c true if the intersection
137  /// hit the side of the triangle that is formed when the vertices are
138  /// ordered counter-clockwise (right-hand rule). If any of the return
139  /// pointers are \c NULL, the corresponding values are not returned.
140  ///
141  /// If the distance to the intersection is greater than \p maxDist, then
142  /// the method will return false.
143  ///
144  /// Barycentric coordinates are defined to sum to 1 and satisfy this
145  /// relationsip:
146  /// \code
147  /// intersectionPoint = (barycentricCoords[0] * p0 +
148  /// barycentricCoords[1] * p1 +
149  /// barycentricCoords[2] * p2);
150  /// \endcode
151  GF_API
152  bool Intersect(const GfVec3d &p0,
153  const GfVec3d &p1,
154  const GfVec3d &p2,
155  double *distance = NULL,
156  GfVec3d *barycentricCoords = NULL,
157  bool *frontFacing = NULL,
158  double maxDist = std::numeric_limits<double>::infinity())
159  const;
160 
161  /// Intersects the ray with a plane, returning \c true if the ray is not
162  /// parallel to the plane and the intersection is within the ray bounds.
163  /// If there is an intersection, it also returns the parametric distance
164  /// to the intersection point in \p distance and the front-facing flag in
165  /// \p frontFacing, if they are not \c NULL. The front-facing flag is \c
166  /// true if the intersection is on the side of the plane in which its
167  /// normal points.
168  GF_API
169  bool Intersect(const GfPlane &plane, double *distance = NULL,
170  bool *frontFacing = NULL) const;
171 
172  /// Intersects the ray with an axis-aligned box, returning \c true if the
173  /// ray intersects it at all within bounds. If there is an intersection,
174  /// this also returns the parametric distances to the two intersection
175  /// points in \p enterDistance and \p exitDistance.
176  GF_API
177  bool Intersect(const GfRange3d &box,
178  double *enterDistance = NULL,
179  double *exitDistance = NULL) const;
180 
181  /// Intersects the ray with an oriented box, returning \c true if the
182  /// ray intersects it at all within bounds. If there is an intersection,
183  /// this also returns the parametric distances to the two intersection
184  /// points in \p enterDistance and \p exitDistance.
185  GF_API
186  bool Intersect(const GfBBox3d &box,
187  double *enterDistance = NULL,
188  double *exitDistance = NULL) const;
189 
190  /// Intersects the ray with a sphere, returning \c true if the ray
191  /// intersects it at all within bounds. If there is an intersection,
192  /// returns the parametric distance to the two intersection points in \p
193  /// enterDistance and \p exitDistance.
194  GF_API
195  bool Intersect(const GfVec3d &center, double radius,
196  double *enterDistance = NULL,
197  double *exitDistance = NULL ) const;
198 
199  /// Intersects the ray with an infinite cylinder, with axis \p axis,
200  /// centered at the \p origin, with radius \p radius.
201  ///
202  /// Returns \c true if the ray intersects it at all within bounds. If
203  /// there is an intersection, returns the parametric distance to the two
204  /// intersection points in \p enterDistance and \p exitDistance.
205  ///
206  /// Note this method does not validate whether the radius is valid.
207  GF_API
208  bool Intersect(const GfVec3d &origin,
209  const GfVec3d &axis,
210  const double radius,
211  double *enterDistance = NULL,
212  double *exitDistance = NULL) const;
213 
214  /// Intersects the ray with an infinite non-double cone, centered at \p
215  /// origin, with axis \p axis, radius \p radius and apex at \p height.
216  ///
217  /// Returns \c true if the ray intersects it at all within bounds. If
218  /// there is an intersection, returns the parametric distance to the two
219  /// intersection points in \p enterDistance and \p exitDistance.
220  ///
221  /// Note this method does not validate whether the radius are height are
222  /// valid.
223  GF_API
224  bool Intersect(const GfVec3d &origin,
225  const GfVec3d &axis,
226  const double radius,
227  const double height,
228  double *enterDistance = NULL,
229  double *exitDistance = NULL) const;
230  ///@}
231 
232  private:
233  GF_API
234  friend bool GfFindClosestPoints( const GfRay &, const GfLine &,
235  GfVec3d *, GfVec3d *,
236  double *, double * );
237  GF_API
238  friend bool GfFindClosestPoints( const GfRay &, const GfLineSeg &,
239  GfVec3d *, GfVec3d *,
240  double *, double * );
241 
242  /// Solves the quadratic equation returning the solutions, if defined, in
243  /// \p enterDistance and \p exitDistance, where \p enterDistance is less
244  /// than or equal to \p exitDistance.
245  bool _SolveQuadratic(const double a,
246  const double b,
247  const double c,
248  double *enterDistance = NULL,
249  double *exitDistance = NULL) const;
250 
251  /// The starting point of the ray.
252  GfVec3d _startPoint;
253  /// The direction vector.
254  GfVec3d _direction;
255 };
256 
257 /// Computes the closest points between a ray and a line. The two points are
258 /// returned in \p rayPoint and \p linePoint. The parametric distance of each
259 /// point on the lines is returned in \p rayDistance and \p lineDistance.
260 ///
261 /// This returns \c false if the lines were close enough to parallel that no
262 /// points could be computed; in this case, the other return values are
263 /// undefined.
264 GF_API
265 bool GfFindClosestPoints( const GfRay &ray, const GfLine &line,
266  GfVec3d *rayPoint = nullptr,
267  GfVec3d *linePoint = nullptr,
268  double *rayDistance = nullptr,
269  double *lineDistance = nullptr );
270 
271 /// Computes the closest points between a ray and a line segment. The two
272 /// points are returned in \p rayPoint and \p segPoint. The parametric
273 /// distance of each point is returned in \p rayDistance and \p segDistance.
274 ///
275 /// This returns \c false if the lines were close enough to parallel that no
276 /// points could be computed; in this case, the other return values are
277 /// undefined.
278 GF_API
279 bool GfFindClosestPoints( const GfRay &ray, const GfLineSeg &seg,
280  GfVec3d *rayPoint = nullptr,
281  GfVec3d *segPoint = nullptr,
282  double *rayDistance = nullptr,
283  double *segDistance = nullptr );
284 
285 /// Output a GfRay using the format [(x y z) >> (x y z)].
286 /// \ingroup group_gf_DebuggingOutput
287 GF_API std::ostream& operator<<(std::ostream&, const GfRay&);
288 
290 
291 #endif // PXR_BASE_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: glcorearb.h:1222
const GfVec3d & GetStartPoint() const
Returns the starting point of the segment.
Definition: ray.h:84
bool operator!=(const GfRay &r) const
Definition: ray.h:120
GfRay()
The default constructor leaves the ray parameters undefined.
Definition: ray.h:66
Definition: plane.h:53
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
const GfVec3d & GetDirection() const
Definition: ray.h:90
GfVec3d GetPoint(double distance) const
Definition: ray.h:96
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.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
bool operator==(const GfRay &r) const
Definition: ray.h:113
Definition: vec3d.h:62
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
GF_API GfVec3d FindClosestPoint(const GfVec3d &point, double *rayDistance=NULL) const
Definition: ray.h:61
GLboolean r
Definition: glcorearb.h:1222
GF_API bool GfFindClosestPoints(const GfRay &ray, const GfLine &line, GfVec3d *rayPoint=nullptr, GfVec3d *linePoint=nullptr, double *rayDistance=nullptr, double *lineDistance=nullptr)
SIM_API const UT_StringHolder distance
GF_API friend bool GfFindClosestPoints(const GfRay &, const GfLine &, GfVec3d *, GfVec3d *, double *, double *)
GF_API std::ostream & operator<<(std::ostream &, const GfRay &)
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:70
#define GF_API
Definition: api.h:40