Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
Box2D.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Array.h"
6#include "Containers/UnrealString.h"
7#include "CoreTypes.h"
8#include "Math/UnrealMathUtility.h"
9#include "Math/Vector2D.h"
10#include "Misc/AssertionMacros.h"
11#include "Misc/LargeWorldCoordinates.h"
12#include "Misc/LargeWorldCoordinatesSerializer.h"
13#include "Serialization/Archive.h"
14#include "Templates/IsUECoreType.h"
15#include "Templates/UnrealTypeTraits.h"
16#include "UObject/NameTypes.h"
17#include "UObject/UnrealNames.h"
18
19template <typename T> struct TIsPODType;
20
21/**
22 * Implements a rectangular 2D Box.
23 */
24namespace UE {
25namespace Math {
26
27template<typename T>
28struct TBox2
29{
30public:
31 using FReal = T;
32
33 /** Holds the box's minimum point. */
34 TVector2<T> Min;
35
36 /** Holds the box's maximum point. */
37 TVector2<T> Max;
38
39 /** Holds a flag indicating whether this box is valid. */
41
42public:
43
44 /** Default constructor (no initialization). */
45 TBox2<T>() { }
46
47 /**
48 * Creates and initializes a new box.
49 *
50 * The box extents are initialized to zero and the box is marked as invalid.
51 *
52 * @param EForceInit Force Init Enum.
53 */
54 explicit TBox2<T>( EForceInit )
55 {
56 Init();
57 }
58
59 /**
60 * Creates and initializes a new box from the specified parameters.
61 *
62 * @param InMin The box's minimum point.
63 * @param InMax The box's maximum point.
64 */
65 TBox2<T>( const TVector2<T>& InMin, const TVector2<T>& InMax )
66 : Min(InMin)
67 , Max(InMax)
68 , bIsValid(true)
69 { }
70
71 /**
72 * Creates and initializes a new box from the given set of points.
73 *
74 * @param Points Array of Points to create for the bounding volume.
75 * @param Count The number of points.
76 */
77 TBox2<T>( const TVector2<T>* Points, const int32 Count );
78
79 /**
80 * Creates and initializes a new box from an array of points.
81 *
82 * @param Points Array of Points to create for the bounding volume.
83 */
84 TBox2<T>( const TArray<TVector2<T>>& Points );
85
86public:
87
88 /**
89 * Compares two boxes for equality.
90 *
91 * @param Other The other box to compare with.
92 * @return true if the boxes are equal, false otherwise.
93 */
94 bool operator==( const TBox2<T>& Other ) const
95 {
96 return (Min == Other.Min) && (Max == Other.Max);
97 }
98
99 /**
100 * Compares two boxes for inequality.
101 *
102 * @param Other The other box to compare with.
103 * @return true if the boxes are not equal, false otherwise.
104 */
105 bool operator!=( const TBox2<T>& Other ) const
106 {
107 return !(*this == Other);
108 }
109
110 /**
111 * Checks for equality with error-tolerant comparison.
112 *
113 * @param Other The box to compare.
114 * @param Tolerance Error tolerance.
115 * @return true if the boxes are equal within specified tolerance, otherwise false.
116 */
117 bool Equals( const TBox2<T>& Other, T Tolerance = UE_KINDA_SMALL_NUMBER ) const
118 {
119 return Min.Equals(Other.Min, Tolerance) && Max.Equals(Other.Max, Tolerance);
120 }
121
122 /**
123 * Adds to this bounding box to include a given point.
124 *
125 * @param Other The point to increase the bounding volume to.
126 * @return Reference to this bounding box after resizing to include the other point.
127 */
128 FORCEINLINE TBox2<T>& operator+=( const TVector2<T> &Other );
129
130 /**
131 * Gets the result of addition to this bounding volume.
132 *
133 * @param Other The other point to add to this.
134 * @return A new bounding volume.
135 */
136 TBox2<T> operator+( const TVector2<T>& Other ) const
137 {
138 return TBox2<T>(*this) += Other;
139 }
140
141 /**
142 * Adds to this bounding box to include a new bounding volume.
143 *
144 * @param Other The bounding volume to increase the bounding volume to.
145 * @return Reference to this bounding volume after resizing to include the other bounding volume.
146 */
147 FORCEINLINE TBox2<T>& operator+=( const TBox2<T>& Other );
148
149 /**
150 * Gets the result of addition to this bounding volume.
151 *
152 * @param Other The other volume to add to this.
153 * @return A new bounding volume.
154 */
155 TBox2<T> operator+( const TBox2<T>& Other ) const
156 {
157 return TBox2<T>(*this) += Other;
158 }
159
160 /**
161 * Gets reference to the min or max of this bounding volume.
162 *
163 * @param Index The index into points of the bounding volume.
164 * @return A reference to a point of the bounding volume.
165 */
166 TVector2<T>& operator[]( int32 Index )
167 {
168 check((Index >= 0) && (Index < 2));
169
170 if (Index == 0)
171 {
172 return Min;
173 }
174
175 return Max;
176 }
177
178public:
179
180 /**
181 * Calculates the distance of a point to this box.
182 *
183 * @param Point The point.
184 * @return The distance.
185 */
186 FORCEINLINE T ComputeSquaredDistanceToPoint( const TVector2<T>& Point ) const
187 {
188 // Accumulates the distance as we iterate axis
189 T DistSquared = 0.f;
190
191 if (Point.X < Min.X)
192 {
193 DistSquared += FMath::Square(Point.X - Min.X);
194 }
195 else if (Point.X > Max.X)
196 {
197 DistSquared += FMath::Square(Point.X - Max.X);
198 }
199
200 if (Point.Y < Min.Y)
201 {
202 DistSquared += FMath::Square(Point.Y - Min.Y);
203 }
204 else if (Point.Y > Max.Y)
205 {
206 DistSquared += FMath::Square(Point.Y - Max.Y);
207 }
208
209 return (T)DistSquared;
210 }
211
212 /**
213 * Increase the bounding box volume.
214 *
215 * @param W The size to increase volume by.
216 * @return A new bounding box increased in size.
217 */
218 TBox2<T> ExpandBy( const T W ) const
219 {
220 return TBox2<T>(Min - TVector2<T>(W, W), Max + TVector2<T>(W, W));
221 }
222
223 /**
224 * Returns a box of increased size.
225 *
226 * @param V The size to increase the volume by.
227 * @return A new bounding box.
228 */
229 TBox2<T> ExpandBy(const TVector2<T>& V) const
230 {
231 return TBox2<T>(Min - V, Max + V);
232 }
233
234 /**
235 * Gets the box area.
236 *
237 * @return Box area.
238 * @see GetCenter, GetCenterAndExtents, GetExtent, GetSize
239 */
240 T GetArea() const
241 {
242 return (Max.X - Min.X) * (Max.Y - Min.Y);
243 }
244
245 /**
246 * Gets the box's center point.
247 *
248 * @return Th center point.
249 * @see GetArea, GetCenterAndExtents, GetExtent, GetSize
250 */
251 TVector2<T> GetCenter() const
252 {
253 return TVector2<T>((Min + Max) * 0.5f);
254 }
255
256 /**
257 * Get the center and extents
258 *
259 * @param center[out] reference to center point
260 * @param Extents[out] reference to the extent around the center
261 * @see GetArea, GetCenter, GetExtent, GetSize
262 */
263 void GetCenterAndExtents( TVector2<T> & center, TVector2<T> & Extents ) const
264 {
265 Extents = GetExtent();
266 center = Min + Extents;
267 }
268
269 /**
270 * Calculates the closest point on or inside the box to a given point in space.
271 *
272 * @param Point The point in space.
273 *
274 * @return The closest point on or inside the box.
275 */
276 FORCEINLINE TVector2<T> GetClosestPointTo( const TVector2<T>& Point ) const;
277
278 /**
279 * Gets the box extents around the center.
280 *
281 * @return Box extents.
282 * @see GetArea, GetCenter, GetCenterAndExtents, GetSize
283 */
284 TVector2<T> GetExtent() const
285 {
286 return 0.5f * TVector2<T>(Max - Min);
287 }
288
289
290 /**
291 * Gets the box size.
292 *
293 * @return Box size.
294 * @see GetArea, GetCenter, GetCenterAndExtents, GetExtent
295 */
296 TVector2<T> GetSize() const
297 {
298 return TVector2<T>(Max - Min);
299 }
300
301 /**
302 * Set the initial values of the bounding box to Zero.
303 */
304 void Init()
305 {
306 Min = Max = TVector2<T>::ZeroVector;
307 bIsValid = false;
308 }
309
310 /**
311 * Returns the overlap box of two boxes
312 *
313 * @param Other The bounding box to test overlap
314 * @return the overlap box. Result will be invalid if they don't overlap
315 */
316 TBox2<T> Overlap( const TBox2<T>& Other ) const;
317
318 /**
319 * Checks whether the given box intersects this box.
320 *
321 * @param other bounding box to test intersection
322 * @return true if boxes intersect, false otherwise.
323 */
324 FORCEINLINE bool Intersect( const TBox2<T> & other ) const;
325
326 /**
327 * Checks whether the given point is inside this box.
328 *
329 * @param Point The point to test.
330 * @return true if the point is inside this box, otherwise false.
331 */
332 bool IsInside( const TVector2<T> & TestPoint ) const
333 {
334 return ((TestPoint.X > Min.X) && (TestPoint.X < Max.X) && (TestPoint.Y > Min.Y) && (TestPoint.Y < Max.Y));
335 }
336
337 /**
338 * Checks whether the given point is inside or on this box.
339 *
340 * @param Point The point to test.
341 * @return true if point is inside or on this box, otherwise false.
342 * @see IsInside
343 */
344 bool IsInsideOrOn( const TVector2<T>& TestPoint ) const
345 {
346 return ((TestPoint.X >= Min.X) && (TestPoint.X <= Max.X) && (TestPoint.Y >= Min.Y) && (TestPoint.Y <= Max.Y));
347 }
348
349 /**
350 * Checks whether the given box is fully encapsulated by this box.
351 *
352 * @param Other The box to test for encapsulation within the bounding volume.
353 * @return true if box is inside this volume, false otherwise.
354 */
355 bool IsInside( const TBox2<T>& Other ) const
356 {
357 return (IsInside(Other.Min) && IsInside(Other.Max));
358 }
359
360 /**
361 * Shift bounding box position.
362 *
363 * @param The offset vector to shift by.
364 * @return A new shifted bounding box.
365 */
366 TBox2<T> ShiftBy( const TVector2<T>& Offset ) const
367 {
368 return TBox2<T>(Min + Offset, Max + Offset);
369 }
370
371 /**
372 * Returns a box with its center moved to the new destination.
373 *
374 * @param Destination The destination point to move center of box to.
375 * @return A new bounding box.
376 */
377 TBox2<T> MoveTo(const TVector2<T>& Destination) const
378 {
379 const TVector2<T> Offset = Destination - GetCenter();
380 return TBox2<T>(Min + Offset, Max + Offset);
381 }
382
383 /**
384 * Get a textual representation of this box.
385 *
386 * @return A string describing the box.
387 */
388 FString ToString() const;
389
390public:
391
392 /**
393 * Serializes the bounding box.
394 *
395 * @param Ar The archive to serialize into.
396 * @param Box The box to serialize.
397 *
398 * @return Reference to the Archive after serialization.
399 */
400 friend FArchive& operator<<( FArchive& Ar, TBox2<T>& Box )
401 {
402 return Ar << Box.Min << Box.Max << Box.bIsValid;
403 }
404
405 // Note: TBox2 is usually written via binary serialization. This function exists for SerializeFromMismatchedTag conversion usage.
407 {
408 Ar << Min << Max;
409 // Can't do Ar << bIsValid as that performs legacy UBOOL (uint32) serialization.
410 uint8 bValid = bIsValid;
411 Ar.Serialize(&bValid, sizeof(uint8));
412 bIsValid = !!bValid;
413 return true;
414 }
415
416 bool SerializeFromMismatchedTag(FName StructTag, FArchive& Ar);
417
418 // Conversion from other type.
419 template<typename FArg, TEMPLATE_REQUIRES(!std::is_same_v<T, FArg>)>
420 explicit TBox2(const TBox2<FArg>& From) : Min((TVector2<T>)From.Min), Max((TVector2<T>)From.Max), bIsValid(From.bIsValid) {}
421};
422
423
424/* TBox2 inline functions
425 *****************************************************************************/
426
427template<typename T>
428TBox2<T>::TBox2(const TVector2<T>* Points, const int32 Count)
429 : Min(0.f, 0.f)
430 , Max(0.f, 0.f)
431 , bIsValid(false)
432{
433 for (int32 PointItr = 0; PointItr < Count; PointItr++)
434 {
435 *this += Points[PointItr];
436 }
437}
438
439template<typename T>
440TBox2<T>::TBox2(const TArray<TVector2<T>>& Points)
441 : Min(0.f, 0.f)
442 , Max(0.f, 0.f)
443 , bIsValid(false)
444{
445 for(const TVector2<T>& EachPoint : Points)
446 {
447 *this += EachPoint;
448 }
449}
450
451
452template<typename T>
453FORCEINLINE TBox2<T>& TBox2<T>::operator+=( const TVector2<T> &Other )
454{
455 if (bIsValid)
456 {
457 Min.X = FMath::Min(Min.X, Other.X);
458 Min.Y = FMath::Min(Min.Y, Other.Y);
459
460 Max.X = FMath::Max(Max.X, Other.X);
461 Max.Y = FMath::Max(Max.Y, Other.Y);
462
463 }
464 else
465 {
466 Min = Max = Other;
467 bIsValid = true;
468 }
469
470 return *this;
471}
472
473template<typename T>
474FORCEINLINE TBox2<T>& TBox2<T>::operator+=( const TBox2<T>& Other )
475{
476 if (bIsValid && Other.bIsValid)
477 {
478 Min.X = FMath::Min(Min.X, Other.Min.X);
479 Min.Y = FMath::Min(Min.Y, Other.Min.Y);
480
481 Max.X = FMath::Max(Max.X, Other.Max.X);
482 Max.Y = FMath::Max(Max.Y, Other.Max.Y);
483 }
484 else if (Other.bIsValid)
485 {
486 *this = Other;
487 }
488
489 return *this;
490}
491
492template<typename T>
493FORCEINLINE TVector2<T> TBox2<T>::GetClosestPointTo( const TVector2<T>& Point ) const
494{
495 // start by considering the point inside the box
497
498 // now clamp to inside box if it's outside
499 if (Point.X < Min.X)
500 {
502 }
503 else if (Point.X > Max.X)
504 {
506 }
507
508 // now clamp to inside box if it's outside
509 if (Point.Y < Min.Y)
510 {
512 }
513 else if (Point.Y > Max.Y)
514 {
516 }
517
518 return ClosestPoint;
519}
520
521template<typename T>
522TBox2<T> TBox2<T>::Overlap(const TBox2<T>& Other) const
523{
524 if (Intersect(Other) == false)
525 {
526 static TBox2<T> EmptyBox(ForceInit);
527 return EmptyBox;
528 }
529
530 // otherwise they overlap
531 // so find overlapping box
533
536
539
540 return TBox2<T>(MinVector, MaxVector);
541}
542
543template<typename T>
544FORCEINLINE bool TBox2<T>::Intersect( const TBox2<T> & Other ) const
545{
546 if ((Min.X > Other.Max.X) || (Other.Min.X > Max.X))
547 {
548 return false;
549 }
550
551 if ((Min.Y > Other.Max.Y) || (Other.Min.Y > Max.Y))
552 {
553 return false;
554 }
555
556 return true;
557}
558
559template<typename T>
560FORCEINLINE FString TBox2<T>::ToString() const
561{
562 return FString::Printf(TEXT("bIsValid=%s, Min=(%s), Max=(%s)"), bIsValid ? TEXT("true") : TEXT("false"), *Min.ToString(), *Max.ToString());
563}
564
565} // namespace Math
566} // namespace UE
567
568UE_DECLARE_LWC_TYPE(Box2,, FBox2D);
569
570//template<> struct TCanBulkSerialize<FBox2f> { enum { Value = true }; };
571template<> struct TIsPODType<FBox2f> { enum { Value = true }; };
572template<> struct TIsUECoreVariant<FBox2f> { enum { Value = true }; };
573
574//template<> struct TCanBulkSerialize<FBox2d> { enum { Value = false }; }; // LWC_TODO: This can be done (via versioning) once LWC is fixed to on.
575template<> struct TIsPODType<FBox2d> { enum { Value = true }; };
576template<> struct TIsUECoreVariant<FBox2d> { enum { Value = true }; };
577
578
579template<>
580inline bool FBox2f::SerializeFromMismatchedTag(FName StructTag, FArchive& Ar)
581{
582 return UE_SERIALIZE_VARIANT_FROM_MISMATCHED_TAG(Ar, Box2D, Box2f, Box2d);
583}
584
585template<>
586inline bool FBox2d::SerializeFromMismatchedTag(FName StructTag, FArchive& Ar)
587{
588 return UE_SERIALIZE_VARIANT_FROM_MISMATCHED_TAG(Ar, Box2D, Box2d, Box2f);
589}
#define check(expr)
EForceInit
#define UE_DECLARE_LWC_TYPE(...)
#define UE_SERIALIZE_VARIANT_FROM_MISMATCHED_TAG(AR_OR_SLOT, ALIAS, TYPE, ALT_TYPE)
#define TEXT(x)
Definition Platform.h:1108
#define FORCEINLINE
Definition Platform.h:644
#define UE_KINDA_SMALL_NUMBER
#define TEMPLATE_REQUIRES(...)
Definition Vector.h:40
Definition json.hpp:4518
TBox2< T > ExpandBy(const TVector2< T > &V) const
Definition Box2D.h:229
TBox2< T > MoveTo(const TVector2< T > &Destination) const
Definition Box2D.h:377
TBox2< T > operator+(const TBox2< T > &Other) const
Definition Box2D.h:155
bool operator==(const TBox2< T > &Other) const
Definition Box2D.h:94
TBox2< T > ShiftBy(const TVector2< T > &Offset) const
Definition Box2D.h:366
FString ToString() const
Definition Box2D.h:560
bool IsInside(const TBox2< T > &Other) const
Definition Box2D.h:355
TBox2(const TBox2< FArg > &From)
Definition Box2D.h:420
FORCEINLINE bool Intersect(const TBox2< T > &other) const
Definition Box2D.h:544
TVector2< T > & operator[](int32 Index)
Definition Box2D.h:166
TBox2< T > operator+(const TVector2< T > &Other) const
Definition Box2D.h:136
void Init()
Definition Box2D.h:304
T GetArea() const
Definition Box2D.h:240
TBox2< T > Overlap(const TBox2< T > &Other) const
Definition Box2D.h:522
bool IsInsideOrOn(const TVector2< T > &TestPoint) const
Definition Box2D.h:344
bool operator!=(const TBox2< T > &Other) const
Definition Box2D.h:105
TVector2< T > Max
Definition Box2D.h:37
bool bIsValid
Definition Box2D.h:40
bool Equals(const TBox2< T > &Other, T Tolerance=UE_KINDA_SMALL_NUMBER) const
Definition Box2D.h:117
TBox2< T > ExpandBy(const T W) const
Definition Box2D.h:218
FORCEINLINE TBox2< T > & operator+=(const TVector2< T > &Other)
Definition Box2D.h:453
bool Serialize(FArchive &Ar)
Definition Box2D.h:406
FORCEINLINE TBox2< T > & operator+=(const TBox2< T > &Other)
Definition Box2D.h:474
FORCEINLINE TVector2< T > GetClosestPointTo(const TVector2< T > &Point) const
Definition Box2D.h:493
bool SerializeFromMismatchedTag(FName StructTag, FArchive &Ar)
Definition Box2D.h:580
TVector2< T > GetSize() const
Definition Box2D.h:296
TVector2< T > GetExtent() const
Definition Box2D.h:284
FORCEINLINE T ComputeSquaredDistanceToPoint(const TVector2< T > &Point) const
Definition Box2D.h:186
bool IsInside(const TVector2< T > &TestPoint) const
Definition Box2D.h:332
TVector2< T > Min
Definition Box2D.h:34
TVector2< T > GetCenter() const
Definition Box2D.h:251
void GetCenterAndExtents(TVector2< T > &center, TVector2< T > &Extents) const
Definition Box2D.h:263