UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Plane.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2// Copyright Epic Games, Inc. All Rights Reserved.
3
4#pragma once
5
6#include "CoreTypes.h"
7#include "Math/MathFwd.h" // IWYU pragma: export
9#include "Math/Vector.h"
10#include "Math/Vector4.h"
13
14#ifdef _MSC_VER
15#pragma warning (push)
16// Ensure template functions don't generate shadowing warnings against global variables at the point of instantiation.
17#pragma warning (disable : 4459)
18#endif
19
27namespace UE
28{
29namespace Math
30{
31
32template<typename T>
33struct alignas(16) TPlane
34 : public TVector<T>
35{
36public:
37 using FReal = T;
38 using TVector<T>::X;
39 using TVector<T>::Y;
40 using TVector<T>::Z;
41
43 T W;
44
45
46
47#if ENABLE_NAN_DIAGNOSTIC
48 inline void DiagnosticCheckNaN() const
49 {
50 if (TVector<T>::ContainsNaN() || !FMath::IsFinite(W))
51 {
52 logOrEnsureNanError(TEXT("FPlane contains NaN: %s W=%3.3f"), *TVector<T>::ToString(), W);
53 *const_cast<TPlane<T>*>(static_cast<const TPlane<T>*>(this)) = TPlane<T>(ForceInitToZero);
54 }
55 }
56#else
58#endif
59
60public:
61
63 [[nodiscard]] TPlane() = default;
64
71
80 [[nodiscard]] inline TPlane(T InX, T InY, T InZ, T InW);
81
89
97
106
113
114 // Functions.
115
122
129
136
137
145
152 bool Normalize(T Tolerance = UE_SMALL_NUMBER);
153
160
167 [[nodiscard]] TPlane<T> TransformBy(const TMatrix<T>& M) const;
168
180
188
195 [[nodiscard]] bool operator==(const TPlane<T>& V) const;
196
203 [[nodiscard]] bool operator!=(const TPlane<T>& V) const;
204
212 [[nodiscard]] bool Equals(const TPlane<T>& V, T Tolerance = UE_KINDA_SMALL_NUMBER) const;
213
221
229
237
245
253
261
269
277
285
293
301
303 {
304 //if (Ar.UEVer() >= VER_UE4_ADDED_NATIVE_SERIALIZATION_FOR_IMMUTABLE_STRUCTURES)
305 {
306 Ar << (TPlane<T>&)*this;
307 return true;
308 }
309 //return false;
310 }
311
313 {
314 if constexpr (std::is_same_v<T, float>)
315 {
316 return UE_SERIALIZE_VARIANT_FROM_MISMATCHED_TAG(Ar, Plane, Plane4f, Plane4d);
317 }
318 else if constexpr (std::is_same_v<T, double>)
319 {
320 return UE_SERIALIZE_VARIANT_FROM_MISMATCHED_TAG(Ar, Plane, Plane4d, Plane4f);
321 }
322 else
323 {
324 static_assert(sizeof(T) == 0, "Unimplemented");
325 return false;
326 }
327 }
328
334 bool NetSerialize(FArchive& Ar, class UPackageMap*, bool& bOutSuccess)
335 {
336 if (Ar.IsLoading())
337 {
338 int16 iX, iY, iZ, iW;
339 Ar << iX << iY << iZ << iW;
340 *this = TPlane<T>(iX, iY, iZ, iW);
341 }
342 else
343 {
344 int16 iX((int16)FMath::RoundToInt(X));
345 int16 iY((int16)FMath::RoundToInt(Y));
346 int16 iZ((int16)FMath::RoundToInt(Z));
347 int16 iW((int16)FMath::RoundToInt(W));
348 Ar << iX << iY << iZ << iW;
349 }
350 bOutSuccess = true;
351 return true;
352 }
353
354 // Conversion to other type.
355 template<typename FArg UE_REQUIRES(!std::is_same_v<T, FArg>)>
356 explicit TPlane(const TPlane<FArg>& From)
357 : TPlane<T>((T)From.X, (T)From.Y, (T)From.Z, (T)From.W)
358 {
359 }
360};
361
362
371{
372 Ar << (TVector<float>&)P << P.W;
373 P.DiagnosticCheckNaN();
374 return Ar;
375}
376
385{
386 Ar << (TVector<double>&)P;
387
389 {
390 Ar << P.W;
391 }
392 else
393 {
394 checkf(Ar.IsLoading(), TEXT("float -> double conversion applied outside of load!"));
395 // Stored as floats, so serialize float and copy.
396 float SW;
397 Ar << SW;
398 P.W = SW;
399 }
400
401 P.DiagnosticCheckNaN();
402 return Ar;
403}
404
405
406/* TPlane inline functions
407 *****************************************************************************/
408
409template<typename T>
411 : TVector<T>(V)
412 , W(V.W)
413{}
414
415
416template<typename T>
417inline TPlane<T>::TPlane(T InX, T InY, T InZ, T InW)
418 : TVector<T>(InX, InY, InZ)
419 , W(InW)
420{
422}
423
424
425template<typename T>
431
432template<typename T>
439
440
441template<typename T>
443 : TVector<T>(((B - A) ^ (C - A)).GetSafeNormal())
444{
445 W = A | (TVector<T>)(*this);
447}
448
449
450template<typename T>
454
455template<typename T>
457{
458 return !this->IsNearlyZero();
459}
460
461template<typename T>
463{
464 return *this;
465}
466
467template<typename T>
469{
470 return GetNormal() * W;
471}
472
473template<typename T>
475{
476 return X * P.X + Y * P.Y + Z * P.Z - W;
477}
478
479template<typename T>
480inline bool TPlane<T>::Normalize(T Tolerance)
481{
482 const T SquareSum = X * X + Y * Y + Z * Z;
483 if (SquareSum > Tolerance)
484 {
485 const T Scale = FMath::InvSqrt(SquareSum);
486 X *= Scale; Y *= Scale; Z *= Scale; W *= Scale;
487 return true;
488 }
489 return false;
490}
491
492template<typename T>
494{
495 return TPlane<T>(-X, -Y, -Z, -W);
496}
497
498template<typename T>
500{
501 return TPlane<T>(GetOrigin() + V, GetNormal());
502}
503
504template<typename T>
506{
507 return (X == V.X) && (Y == V.Y) && (Z == V.Z) && (W == V.W);
508}
509
510
511template<typename T>
513{
514 return (X != V.X) || (Y != V.Y) || (Z != V.Z) || (W != V.W);
515}
516
517
518template<typename T>
519UE_FORCEINLINE_HINT bool TPlane<T>::Equals(const TPlane<T>& V, T Tolerance) const
520{
521 return (FMath::Abs(X - V.X) < Tolerance) && (FMath::Abs(Y - V.Y) < Tolerance) && (FMath::Abs(Z - V.Z) < Tolerance) && (FMath::Abs(W - V.W) < Tolerance);
522}
523
524
525template<typename T>
527{
528 return X * V.X + Y * V.Y + Z * V.Z + W * V.W;
529}
530
531
532template<typename T>
534{
535 return TPlane<T>(X + V.X, Y + V.Y, Z + V.Z, W + V.W);
536}
537
538
539template<typename T>
541{
542 return TPlane<T>(X - V.X, Y - V.Y, Z - V.Z, W - V.W);
543}
544
545
546template<typename T>
548{
549 const T RScale = 1 / Scale;
550 return TPlane<T>(X * RScale, Y * RScale, Z * RScale, W * RScale);
551}
552
553
554template<typename T>
559
560
561template<typename T>
563{
564 return TPlane<T>(X * V.X, Y * V.Y, Z * V.Z, W * V.W);
565}
566
567
568template<typename T>
570{
571 X += V.X; Y += V.Y; Z += V.Z; W += V.W;
572 return *this;
573}
574
575
576template<typename T>
578{
579 X -= V.X; Y -= V.Y; Z -= V.Z; W -= V.W;
580 return *this;
581}
582
583
584template<typename T>
586{
587 X *= Scale; Y *= Scale; Z *= Scale; W *= Scale;
588 return *this;
589}
590
591
592template<typename T>
594{
595 X *= V.X; Y *= V.Y; Z *= V.Z; W *= V.W;
596 return *this;
597}
598
599
600template<typename T>
602{
603 const T RV = 1 / V;
604 X *= RV; Y *= RV; Z *= RV; W *= RV;
605 return *this;
606}
607
608
609/* TVector inline functions
610 *****************************************************************************/
611
612template<typename T>
614{
615 return *this - Plane * (2.f * Plane.PlaneDot(*this));
616}
617
618template<typename T>
620{
621 //Find the distance of X from the plane
622 //Add the distance back along the normal from the point
623 return Point - Plane.PlaneDot(Point) * Plane;
624}
625
626template<typename T>
628{
629 //Compute the plane normal from ABC
630 TPlane<T> Plane(A, B, C);
631
632 //Find the distance of X from the plane
633 //Add the distance back along the normal from the point
634 return Point - Plane.PlaneDot(Point) * Plane;
635}
636
637} // namespace UE::Math
638} // namespace UE
639
640
641/* FMath inline functions
642 *****************************************************************************/
643
644template<typename T>
646{
647 using TVector = UE::Math::TVector<T>;
648 const TVector PlaneNormal = TVector(Plane.X, Plane.Y, Plane.Z);
649 const TVector PlaneOrigin = PlaneNormal * Plane.W;
650
651 const T Distance = TVector::DotProduct((PlaneOrigin - RayOrigin), PlaneNormal) / TVector::DotProduct(RayDirection, PlaneNormal);
652 return RayOrigin + RayDirection * Distance;
653}
654
655template<typename T>
657{
658 using TVector = UE::Math::TVector<T>;
659 const TVector PlaneNormal = TVector(Plane.X, Plane.Y, Plane.Z);
660 const TVector PlaneOrigin = PlaneNormal * Plane.W;
661
662 return TVector::DotProduct((PlaneOrigin - RayOrigin), PlaneNormal) / TVector::DotProduct(RayDirection, PlaneNormal);
663}
664
665template<typename T>
667(
668 const UE::Math::TVector<T>& Point1,
669 const UE::Math::TVector<T>& Point2,
671)
672{
673 return
674 Point1
675 + (Point2 - Point1)
676 * ((Plane.W - (Point1 | Plane)) / ((Point2 - Point1) | Plane));
677}
678
679template<typename T>
681{
682 // Compute determinant, the triple product P1|(P2^P3)==(P1^P2)|P3.
683 const T Det = (P1 ^ P2) | P3;
684 if (Square(Det) < Square(0.001f))
685 {
686 // Degenerate.
688 return 0;
689 }
690 else
691 {
692 // Compute the intersection point, guaranteed valid if determinant is nonzero.
693 I = (P1.W * (P2 ^ P3) + P2.W * (P3 ^ P1) + P3.W * (P1 ^ P2)) / Det;
694 }
695 return 1;
696}
697
698template<typename T>
700{
701 // Compute line direction, perpendicular to both plane normals.
702 D = P1 ^ P2;
703 const T DD = D.SizeSquared();
704 if (DD < Square(0.001f))
705 {
706 // Parallel or nearly parallel planes.
708 return 0;
709 }
710 else
711 {
712 // Compute intersection.
713 I = (P1.W * (P2 ^ D) + P2.W * (D ^ P1)) / DD;
714 D.Normalize();
715 return 1;
716 }
717}
718
719
721template<> struct TIsPODType<FPlane4f> { enum { Value = true }; };
722template<> struct TIsUECoreVariant<FPlane4f> { enum { Value = true }; };
723
724template<> struct TIsPODType<FPlane4d> { enum { Value = true }; };
725template<> struct TIsUECoreVariant<FPlane4d> { enum { Value = true }; };
726
727
728#ifdef _MSC_VER
729#pragma warning (pop)
730#endif
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
EForceInit
Definition CoreMiscDefines.h:154
@ ForceInitToZero
Definition CoreMiscDefines.h:156
@ ForceInit
Definition CoreMiscDefines.h:155
FPlatformTypes::int16 int16
A 16-bit signed integer.
Definition Platform.h:1123
#define TEXT(x)
Definition Platform.h:1272
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define X(Name, Desc)
Definition FormatStringSan.h:47
#define UE_SERIALIZE_VARIANT_FROM_MISMATCHED_TAG(AR_OR_SLOT, ALIAS, TYPE, ALT_TYPE)
Definition LargeWorldCoordinatesSerializer.h:9
#define UE_DECLARE_LWC_TYPE(...)
Definition LargeWorldCoordinates.h:27
#define logOrEnsureNanError(_FormatString_,...)
Definition LogMacros.h:436
#define Square(a, x, y)
Definition Predicates.inl:251
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
Definition Archive.h:1208
UE_FORCEINLINE_HINT bool IsLoading() const
Definition Archive.h:236
UE_FORCEINLINE_HINT FPackageFileVersion UEVer() const
Definition Archive.h:204
Definition NameTypes.h:617
Definition CoreNet.h:191
FArchive & operator<<(FArchive &Ar, TBoxSphereBounds< float, float > &Bounds)
Definition BoxSphereBounds.h:396
Definition AdvancedWidgetsModule.cpp:13
static UE::Math::TVector< FReal > LinePlaneIntersection(const UE::Math::TVector< FReal > &Point1, const UE::Math::TVector< FReal > &Point2, const UE::Math::TVector< FReal > &PlaneOrigin, const UE::Math::TVector< FReal > &PlaneNormal)
static FReal RayPlaneIntersectionParam(const UE::Math::TVector< FReal > &RayOrigin, const UE::Math::TVector< FReal > &RayDirection, const UE::Math::TPlane< FReal > &Plane)
static bool IntersectPlanes2(UE::Math::TVector< FReal > &I, UE::Math::TVector< FReal > &D, const UE::Math::TPlane< FReal > &P1, const UE::Math::TPlane< FReal > &P2)
static bool IntersectPlanes3(UE::Math::TVector< FReal > &I, const UE::Math::TPlane< FReal > &P1, const UE::Math::TPlane< FReal > &P2, const UE::Math::TPlane< FReal > &P3)
static UE::Math::TVector< FReal > RayPlaneIntersection(const UE::Math::TVector< FReal > &RayOrigin, const UE::Math::TVector< FReal > &RayDirection, const UE::Math::TPlane< FReal > &Plane)
Definition IsPODType.h:12
@ Value
Definition IsPODType.h:13
Definition IsUECoreType.h:19
@ Value
Definition IsUECoreType.h:20
Definition Matrix.h:43
Definition Plane.h:35
TPlane(T InX, T InY, T InZ, T InW)
Definition Plane.h:417
TPlane< T > operator-(const TPlane< T > &V) const
Definition Plane.h:540
TPlane< T > operator*(const TPlane< T > &V) const
Definition Plane.h:562
UE_FORCEINLINE_HINT TPlane(const TVector4< T > &V)
Definition Plane.h:410
bool SerializeFromMismatchedTag(FName StructTag, FArchive &Ar)
Definition Plane.h:312
T FReal
Definition Plane.h:37
bool operator==(const TPlane< T > &V) const
Definition Plane.h:505
TPlane< T > operator+=(const TPlane< T > &V)
Definition Plane.h:569
UE_FORCEINLINE_HINT void DiagnosticCheckNaN() const
Definition Plane.h:57
bool Serialize(FArchive &Ar)
Definition Plane.h:302
TPlane(TVector< T > A, TVector< T > B, TVector< T > C)
Definition Plane.h:442
bool Normalize(T Tolerance=UE_SMALL_NUMBER)
Definition Plane.h:480
TPlane< T > operator*(T Scale) const
Definition Plane.h:555
TPlane(TVector< T > InBase, const TVector< T > &InNormal)
Definition Plane.h:433
UE_FORCEINLINE_HINT TPlane(EForceInit)
Definition Plane.h:451
TPlane< T > Flip() const
Definition Plane.h:493
TPlane< T > TransformByUsingAdjointT(const TMatrix< T > &M, T DetM, const TMatrix< T > &TA) const
Definition Matrix.inl:923
bool operator!=(const TPlane< T > &V) const
Definition Plane.h:512
UE_FORCEINLINE_HINT T operator|(const TPlane< T > &V) const
Definition Plane.h:526
TPlane< T > operator/=(T V)
Definition Plane.h:601
TPlane< T > operator+(const TPlane< T > &V) const
Definition Plane.h:533
TPlane(const TPlane< FArg > &From)
Definition Plane.h:356
UE_FORCEINLINE_HINT const TVector< T > & GetNormal() const
Definition Plane.h:462
UE_FORCEINLINE_HINT TVector< T > GetOrigin() const
Definition Plane.h:468
TPlane< T > operator/(T Scale) const
Definition Plane.h:547
TPlane< T > operator-=(const TPlane< T > &V)
Definition Plane.h:577
TPlane(TVector< T > InNormal, T InW)
Definition Plane.h:426
TPlane< T > TransformBy(const TMatrix< T > &M) const
Definition Matrix.inl:915
TPlane()=default
T W
Definition Plane.h:43
bool NetSerialize(FArchive &Ar, class UPackageMap *, bool &bOutSuccess)
Definition Plane.h:334
UE_FORCEINLINE_HINT T PlaneDot(const TVector< T > &P) const
Definition Plane.h:474
TPlane< T > operator*=(T Scale)
Definition Plane.h:585
UE_FORCEINLINE_HINT bool IsValid() const
Definition Plane.h:456
TPlane< T > operator*=(const TPlane< T > &V)
Definition Plane.h:593
TPlane< T > TranslateBy(const TVector< T > &V) const
Definition Plane.h:499
bool Equals(const TPlane< T > &V, T Tolerance=UE_KINDA_SMALL_NUMBER) const
Definition Plane.h:519
Definition Vector4.h:30
Definition Vector.h:51
T Z
Definition Vector.h:68
T Y
Definition Vector.h:65
TVector< T > MirrorByPlane(const TPlane< T > &Plane) const
Definition Plane.h:613
bool Normalize(T Tolerance=UE_SMALL_NUMBER)
Definition Vector.h:1767
T X
Definition Vector.h:62
UE_FORCEINLINE_HINT TVector< T > operator-() const
Definition Vector.h:1614
static TVector< T > PointPlaneProject(const TVector< T > &Point, const TPlane< T > &Plane)
Definition Plane.h:619
T SizeSquared() const
Definition Vector.h:1728