UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
IntersectionUtil.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "VectorTypes.h"
6#include "BoxTypes.h"
7
8
9namespace UE
10{
11namespace Geometry
12{
13
18{
20 int numIntersections; // 0, 1, or 2
21 FInterval1d parameter; // t-values along ray
22};
23
24
25} // end namespace UE::Geometry
26} // end namespace UE
27
28
33{
34 using namespace UE::Math;
35 using namespace UE::Geometry;
36
37 template<typename RealType>
38 bool RayTriangleTest(const TVector<RealType>& RayOrigin, const TVector<RealType>& RayDirection, const TVector<RealType>& V0, const TVector<RealType>& V1, const TVector<RealType>& V2)
39 {
40 // same code as IntrRay3Triangle3, but can be called w/o constructing additional data structures
41
42 // Compute the offset origin, edges, and normal.
43 TVector<RealType> diff = RayOrigin - V0;
44 TVector<RealType> edge1 = V1 - V0;
45 TVector<RealType> edge2 = V2 - V0;
47
48 // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
49 // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
50 // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
51 // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
52 // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
53 RealType DdN = RayDirection.Dot(normal);
54 RealType sign;
56 {
57 sign = 1;
58 }
60 {
61 sign = -1;
62 DdN = -DdN;
63 }
64 else
65 {
66 // Ray and triangle are parallel, call it a "no intersection"
67 // even if the ray does intersect.
68 return false;
69 }
70
71 RealType DdQxE2 = sign * RayDirection.Dot(diff.Cross(edge2));
72 if (DdQxE2 >= 0)
73 {
74 RealType DdE1xQ = sign * RayDirection.Dot(edge1.Cross(diff));
75 if (DdE1xQ >= 0)
76 {
77 if (DdQxE2 + DdE1xQ <= DdN)
78 {
79 // Line intersects triangle, check if ray does.
80 RealType QdN = -sign * diff.Dot(normal);
81 if (QdN >= 0)
82 {
83 // Ray intersects triangle.
84 return true;
85 }
86 // else: t < 0, no intersection
87 }
88 // else: b1+b2 > 1, no intersection
89 }
90 // else: b2 < 0, no intersection
91 }
92 // else: b1 < 0, no intersection
93 return false;
94
95 }
96
97
98
103 template<typename RealType>
108 RealType SphereRadius)
109 {
110 // adapted from GeometricTools GTEngine
111 // https://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrLine3Sphere3.h
112
113 // The sphere is (X-C)^T*(X-C)-1 = 0 and the line is X = P+t*D.
114 // Substitute the line equation into the sphere equation to obtain a
115 // quadratic equation Q(t) = t^2 + 2*a1*t + a0 = 0, where a1 = D^T*(P-C),
116 // and a0 = (P-C)^T*(P-C)-1.
117
119 RealType a0 = diff.SquaredLength() - SphereRadius * SphereRadius;
120 RealType a1 = LineDirection.Dot(diff);
121
122 // Intersection occurs when Q(t) has real roots.
123 RealType discr = a1 * a1 - a0;
124 return (discr >= 0);
125 }
126
127
132 template<typename RealType>
137 RealType SphereRadius,
139 {
140 // adapted from GeometricTools GTEngine
141 // https://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrLine3Sphere3.h
142
143 // The sphere is (X-C)^T*(X-C)-1 = 0 and the line is X = P+t*D.
144 // Substitute the line equation into the sphere equation to obtain a
145 // quadratic equation Q(t) = t^2 + 2*a1*t + a0 = 0, where a1 = D^T*(P-C),
146 // and a0 = (P-C)^T*(P-C)-1.
148 RealType a0 = diff.SquaredLength() - SphereRadius * SphereRadius;
149 RealType a1 = LineDirection.Dot(diff);
150
151 // Intersection occurs when Q(t) has real roots.
152 RealType discr = a1 * a1 - a0;
153 if (discr > 0)
154 {
155 ResultOut.intersects = true;
156 ResultOut.numIntersections = 2;
157 RealType root = FMath::Sqrt(discr);
158 ResultOut.parameter.Min = -a1 - root;
159 ResultOut.parameter.Max = -a1 + root;
160 }
161 else if (discr < 0)
162 {
163 ResultOut.intersects = false;
164 ResultOut.numIntersections = 0;
165 }
166 else
167 {
168 ResultOut.intersects = true;
169 ResultOut.numIntersections = 1;
170 ResultOut.parameter.Min = -a1;
171 ResultOut.parameter.Max = -a1;
172 }
173 return ResultOut.intersects;
174 }
175
176 template<typename RealType>
181 RealType SphereRadius)
182 {
183 FLinearIntersection result;
185 return result;
186 }
187
188
189
193 template<typename RealType>
195 const TVector<RealType>& RayOrigin,
196 const TVector<RealType>& RayDirection,
198 RealType SphereRadius)
199 {
200 // adapted from GeometricTools GTEngine
201 // https://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Sphere3.h
202
203 // The sphere is (X-C)^T*(X-C)-1 = 0 and the line is X = P+t*D.
204 // Substitute the line equation into the sphere equation to obtain a
205 // quadratic equation Q(t) = t^2 + 2*a1*t + a0 = 0, where a1 = D^T*(P-C),
206 // and a0 = (P-C)^T*(P-C)-1.
207
208 TVector<RealType> diff = RayOrigin - SphereCenter;
209 RealType a0 = diff.SquaredLength() - SphereRadius * SphereRadius;
210 if (a0 <= 0)
211 {
212 return true; // P is inside the sphere.
213 }
214 // else: P is outside the sphere
215 RealType a1 = RayDirection.Dot(diff);
216 if (a1 >= 0)
217 {
218 return false;
219 }
220
221 // Intersection occurs when Q(t) has RealType roots.
222 RealType discr = a1 * a1 - a0;
223 return (discr >= 0);
224 }
225
226
231 template<typename RealType>
233 const TVector<RealType>& RayOrigin,
234 const TVector<RealType>& RayDirection,
236 RealType SphereRadius,
237 FLinearIntersection& Result)
238 {
239 // adapted from GeometricTools GTEngine
240 // https://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Sphere3.h
241
242 LineSphereIntersection(RayOrigin, RayDirection, SphereCenter, SphereRadius, Result);
243 if (Result.intersects)
244 {
245 // The line containing the ray intersects the sphere; the t-interval
246 // is [t0,t1]. The ray intersects the sphere as long as [t0,t1]
247 // overlaps the ray t-interval [0,+infinity).
248 if (Result.parameter.Max < 0)
249 {
250 Result.intersects = false;
251 Result.numIntersections = 0;
252 }
253 else if (Result.parameter.Min < 0)
254 {
255 Result.numIntersections--;
256 Result.parameter.Min = Result.parameter.Max;
257 }
258 }
259 return Result.intersects;
260 }
261
262 template<typename RealType>
264 const TVector<RealType>& RayOrigin,
265 const TVector<RealType>& RayDirection,
267 RealType SphereRadius)
268 {
269 FLinearIntersection result;
270 LineSphereIntersection(RayOrigin, RayDirection, SphereCenter, SphereRadius, result);
271 return result;
272 }
273
278 template <typename RealType>
280 const TVector<RealType>& RayOrigin,
281 const TVector<RealType>& RayDirection,
282 const TVector<RealType>& CircleCenter,
283 RealType CircleRadius,
285 FLinearIntersection& Result)
286 {
287
288 // if ray is parallel to circle, no hit
290 {
291 Result.intersects = false;
292 Result.numIntersections = 0;
293 return false;
294 }
295
296 TPlane<RealType> Plane(CircleCenter, CircleNormal);
297 RealType Param = FMath::RayPlaneIntersectionParam(RayOrigin, RayDirection, Plane);
298
299 if (Param < 0)
300 {
301 Result.intersects = false;
302 Result.numIntersections = 0;
303 return false;
304 }
305
306 TVector<RealType> HitPoint = RayOrigin + RayDirection * Param;
307 TVector<RealType> Offset = HitPoint - CircleCenter;
308 const RealType CircleRadiusSquared = CircleRadius * CircleRadius;
309
310 if (Offset.SizeSquared() <= CircleRadiusSquared)
311 {
312 Result.intersects = true;
313 Result.numIntersections = 1;
314 Result.parameter.Min = Result.parameter.Max = Param;
315 }
316 else
317 {
318 Result.intersects = false;
319 Result.numIntersections = 0;
320 }
321
322 return Result.intersects;
323 }
324};
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
uint32 Offset
Definition VulkanMemory.cpp:4033
Definition MathUtil.h:150
Definition IntersectionUtil.h:33
bool RayTriangleTest(const TVector< RealType > &RayOrigin, const TVector< RealType > &RayDirection, const TVector< RealType > &V0, const TVector< RealType > &V1, const TVector< RealType > &V2)
Definition IntersectionUtil.h:38
bool RaySphereTest(const TVector< RealType > &RayOrigin, const TVector< RealType > &RayDirection, const TVector< RealType > &SphereCenter, RealType SphereRadius)
Definition IntersectionUtil.h:194
bool LineSphereIntersection(const TVector< RealType > &LineOrigin, const TVector< RealType > &LineDirection, const TVector< RealType > &SphereCenter, RealType SphereRadius, FLinearIntersection &ResultOut)
Definition IntersectionUtil.h:133
bool RayCircleIntersection(const TVector< RealType > &RayOrigin, const TVector< RealType > &RayDirection, const TVector< RealType > &CircleCenter, RealType CircleRadius, const TVector< RealType > &CircleNormal, FLinearIntersection &Result)
Definition IntersectionUtil.h:279
bool LineSphereTest(const TVector< RealType > &LineOrigin, const TVector< RealType > &LineDirection, const TVector< RealType > &SphereCenter, RealType SphereRadius)
Definition IntersectionUtil.h:104
bool RaySphereIntersection(const TVector< RealType > &RayOrigin, const TVector< RealType > &RayDirection, const TVector< RealType > &SphereCenter, RealType SphereRadius, FLinearIntersection &Result)
Definition IntersectionUtil.h:232
Definition ParametricSurfaceData.h:18
Definition Sphere.cpp:10
Definition AdvancedWidgetsModule.cpp:13
static FReal RayPlaneIntersectionParam(const UE::Math::TVector< FReal > &RayOrigin, const UE::Math::TVector< FReal > &RayDirection, const UE::Math::TPlane< FReal > &Plane)
static UE_FORCEINLINE_HINT bool IsNearlyZero(float Value, float ErrorTolerance=UE_SMALL_NUMBER)
Definition UnrealMathUtility.h:407
Definition IntersectionUtil.h:18
bool intersects
Definition IntersectionUtil.h:19
int numIntersections
Definition IntersectionUtil.h:20
FInterval1d parameter
Definition IntersectionUtil.h:21
Definition Plane.h:35
Definition Vector.h:51
UE_FORCEINLINE_HINT TVector< T > Cross(const TVector< T > &V2) const
Definition Vector.h:1535
T SquaredLength() const
Definition Vector.h:1734
UE_FORCEINLINE_HINT T Dot(const TVector< T > &V) const
Definition Vector.h:1553