1 /* Copyright 2011 Jukka Jyl�nki
2
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6
7        http://www.apache.org/licenses/LICENSE-2.0
8
9    Unless required by applicable law or agreed to in writing, software
10    distributed under the License is distributed on an "AS IS" BASIS,
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    See the License for the specific language governing permissions and
13    limitations under the License. */
14
15 /** @file Ray.h
16         @author Jukka Jyl�nki
17         @brief The Ray geometry object. */
18 #pragma once
19
20 #include "Math/MathFwd.h"
21 #include "Math/float3.h"
22
23 #ifdef MATH_OGRE_INTEROP
24 #include <OgreRay.h>
25 #endif
26
27 MATH_BEGIN_NAMESPACE
28
29 /// A ray in 3D space is a line that starts from an origin point and extends to infinity in one direction.
30 class Ray
31 {
32 public:
33         /// Specifies the origin of this ray.
34         float3 pos;
35
36         /// The normalized direction vector of this ray. [similarOverload: pos]
37         /** @note For proper functionality, this direction vector needs to always be normalized. If you set to this
38                 member manually, remember to make sure you only assign normalized direction vectors. */
39         float3 dir;
40
41         /// The default constructor does not initialize any members of this class.
42         /** This means that the values of the members pos and dir are undefined after creating a new Ray using this
43                 default constructor. Remember to assign to them before use.
44                 @see pos, dir. */
45         Ray() {}
46
47         /// Constructs a new ray by explicitly specifying the member variables.
48         /** @param pos The origin position of the ray.
49                 @param dir The direction of the ray. This vector must be normalized, this function will not normalize
50                         the vector for you (for performance reasons).
51                 @see pos, dir. */
52         Ray(const float3 &posconst float3 &dir);
53
54         /// Converts a Line to a Ray.
55         /** This conversion simply copies the members pos and dir over from the given Line to this Ray. 
56                 This means that the new Ray starts at the same position, but only extends to one direction in space,
57                 instead of two.
58                 @see class Line, ToLine(). */
59         explicit Ray(const Line &line);
60
61         /// Converts a LineSegment to a Ray.
62         /** This constructor sets pos = lineSegment.a, and dir = (lineSegment.b - lineSegment.a).Normalized().
63                 @see class LineSegment, ToLineSegment(). */
64         explicit Ray(const LineSegment &lineSegment);
65
66         /// Gets a point along the ray at the given distance.
67         /** Use this function to convert a 1D parametric point along the Ray to a 3D point in the linear space.
68                 @param distance The point to compute. GetPoint(0) will return pos. GetPoint(t) will return a point
69                         at distance |t| from pos. Passing in negative values is allowed, but in that case, the
70                         returned point does not actually lie on this Ray.
71                 @return pos + distance * dir.
72                 @see pos, dir. */
73         float3 GetPoint(float distance) const;
74
75         /// Applies a transformation to this ray, in-place.
76         /** See classes float3x3, float3x4, float4x4, Quat. */
77         void Transform(const float3x3 &transform);
78         void Transform(const float3x4 &transform);
79         void Transform(const float4x4 &transform);
80         void Transform(const Quat &transform);
81
82         /// Tests if the given object is fully contained on this ray.
83         /** @param distanceThreshold The magnitude of the epsilon test threshold to use. Since a Ray 
84                 is a 1D object in a 3D space, an epsilon threshold is used to allow errors caused by floating-point 
85                 inaccuracies.
86                 @return True if this ray contains the given object, up to the given distance threshold.
87                 @see class LineSegment, Distance(), ClosestPoint(), Intersects(). */
88         bool Contains(const float3 &point, float distanceThreshold = 1e-3f) const;
89         bool Contains(const LineSegment &lineSegment, float distanceThreshold = 1e-3f) const;
90
91         /// Tests if two rays are equal.
92         /** @return True if this and the given Ray represent the same set of points, up to the given epsilon. */
93         bool Equals(const Ray &otherRay, float epsilon = 1e-3f) const;
94
95         /// Computes the distance between this ray and the given object.
96         /** This function finds the nearest pair of points on this and the given object, and computes their distance.
97                 If the two objects intersect, or one object is contained inside the other, the returned distance is zero.
98                 @param d [out] If specified, receives the parametric distance along this ray that 
99                         specifies the closest point on this ray to the given object. The value returned here can be negative.
100                         This pointer may be null.
101                 @see Contains(), Intersects(), ClosestPoint(), GetPoint(). */
102         float Distance(const float3 &point, float *d) const;
103         float Distance(const float3 &point) const;
104
105         /** @param d2 [out] If specified, receives the parametric distance along the other line that specifies the 
106                 closest point on that line to this ray. The value returned here can be negative. This pointer may
107                 be null. */
108         float Distance(const Ray &other, float *d, float *d2 = 0) const;
109         float Distance(const Ray &other) const;
110         float Distance(const Line &other, float *d, float *d2 = 0) const;
111         float Distance(const Line &other) const;
112         float Distance(const LineSegment &other, float *d, float *d2 = 0) const;
113         float Distance(const LineSegment &other) const;
114         float Distance(const Sphere &sphere) const;
115         float Distance(const Capsule &capsule) const;
116
117         /// Computes the closest point on this ray to the given object.
118         /** If the other object intersects this ray, this function will return an arbitrary point inside
119                 the region of intersection.
120                 @param d [out] If specified, receives the parametric distance along this ray that 
121                         specifies the closest point on this ray to the given object. The value returned here can be negative.
122                         This pointer may be null.
123                 @see Contains(), Distance(), Intersects(), GetPoint(). */
124         float3 ClosestPoint(const float3 &targetPoint, float *d = 0) const;
125         /** @param d2 [out] If specified, receives the parametric distance along the other line that specifies the 
126                 closest point on that line to this ray. The value returned here can be negative. This pointer may
127                 be null. */
128         float3 ClosestPoint(const Ray &other, float *d = 0, float *d2 = 0) const;
129         float3 ClosestPoint(const Line &other, float *d = 0, float *d2 = 0) const;
130         float3 ClosestPoint(const LineSegment &other, float *d = 0, float *d2 = 0) const;
131
132         /// Tests whether this ray and the given object intersect.         
133         /** Both objects are treated as "solid", meaning that if one of the objects is fully contained inside 
134                 another, this function still returns true.
135                 @param d [out] If specified, this parameter will receive the parametric distance of 
136                         the intersection point along this object. Use the GetPoint(d) function
137                         to get the actual point of intersection. This pointer may be null.
138                 @param intersectionPoint [out] If specified, receives the actual point of intersection. This pointer
139                         may be null.
140                 @return True if an intersection occurs or one of the objects is contained inside the other, false otherwise.
141                 @see Contains(), Distance(), ClosestPoint(), GetPoint(). */
142         bool Intersects(const Triangle &triangle, float *d, float3 *intersectionPoint) const;
143         bool Intersects(const Triangle &triangle) const;
144         bool Intersects(const Plane &plane, float *d) const;
145         bool Intersects(const Plane &plane) const;
146         /** @param intersectionNormal [out] If specified, receives the surface normal of the other object at
147                 the point of intersection. This pointer may be null. */
148         bool Intersects(const Sphere &s, float3 *intersectionPoint, float3 *intersectionNormal, float *d) const;
149         bool Intersects(const Sphere &s) const;
150         /** @param dNear [out] If specified, receives the distance along this ray to where the ray enters
151                 the bounding box. This pointer may be null.
152                 @param dFar [out] If specified, receives the distance along this ray to where the ray exits
153                 the bounding box. This pointer may be null. */
154         bool Intersects(const AABB &aabb, float *dNear, float *dFar) const;
155         bool Intersects(const AABB &aabb) const;
156         bool Intersects(const OBB &obb, float *dNear, float *dFar) const;
157         bool Intersects(const OBB &obb) const;
158         bool Intersects(const Capsule &capsule) const;
159         bool Intersects(const Polygon &polygon) const;
160         bool Intersects(const Frustum &frustum) const;
161         bool Intersects(const Polyhedron &polyhedron) const;
162         /// Tests if this ray intersects the given disc.
163         /// @todo This signature will be moved to bool Intersects(const Disc &disc) const;
164         bool IntersectsDisc(const Circle &disc) const;
165
166         /// Converts this Ray to a Line.
167         /** The pos and dir members of the returned Line will be equal to this Ray. The only difference is
168                 that a Line extends to infinity in two directions, whereas the Ray spans only in the positive
169                 direction.
170                 @see dir, Ray::Ray, class Line, ToLineSegment(). */
171         Line ToLine() const;
172         /// Converts this Ray to a LineSegment.
173         /** @param d Specifies the position of the other endpoint along this Ray. This parameter may be negative,
174                 in which case the returned LineSegment does not lie inside this Ray.
175                 @return A LineSegment with point a at pos, and point b at pos + d * dir.
176                 @see pos, dir, Ray::Ray, class LineSegment, ToLine(). */
177         LineSegment ToLineSegment(float d) const;
178
179 #ifdef MATH_ENABLE_STL_SUPPORT
180         /// Returns a human-readable representation of this Ray.
181         /** The returned string specifies the position and direction of this Ray. */
182         std::string ToString() const;
183 #endif
184 #ifdef MATH_QT_INTEROP
185         operator QString() const return toString(); }
186         QString toString() const return QString::fromStdString(ToString()); }
187 #endif
188
189 #ifdef MATH_OGRE_INTEROP
190         Ray(const Ogre::Ray &other) { pos = other.getOrigin(); dir = other.getDirection(); }
191         operator Ogre::Ray() const return Ogre::Ray(posdir); }
192 #endif
193
194 };
195
196 Ray operator *(const float3x3 &transform, const Ray &ray);
197 Ray operator *(const float3x4 &transform, const Ray &ray);
198 Ray operator *(const float4x4 &transform, const Ray &ray);
199 Ray operator *(const Quat &transform, const Ray &ray);
200
201 MATH_END_NAMESPACE
202
203 #ifdef MATH_QT_INTEROP
204 Q_DECLARE_METATYPE(Ray)
205 Q_DECLARE_METATYPE(Ray*)
206 #endif

Go back to previous page