UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
AABBTreeDirtyGridUtils.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "Chaos/AABB.h"
5#include "Chaos/Defines.h"
6#include "ChaosLog.h"
7#include <limits>
8
9namespace Chaos
10{
11
13 {
15 Intermediate = (Intermediate ^ (Intermediate << 8)) & 0x00ff00ff;
16 Intermediate = (Intermediate ^ (Intermediate << 4)) & 0x0f0f0f0f;
17 Intermediate = (Intermediate ^ (Intermediate << 2)) & 0x33333333;
18 Intermediate = (Intermediate ^ (Intermediate << 1)) & 0x55555555;
19 return Intermediate;
20 }
21
23 {
24 FReal CellIndex = Coordinate * DirtyElementGridCellSizeInv;
25 // Bias values just enough to remove floating point integer inconsistencies
26 // Assume maximum of 1ULP error in DirtyElementGridCellSizeInv
27 FReal FloatingPointMaxCellIndexError = FMath::Abs(CellIndex) * std::numeric_limits<FReal>::epsilon();
29 }
30
35
37 {
38 // Requirement: Hash should change for adjacent cells
39 int64 X = GetDirtyCellIndexFromWorldCoordinate(Xcoordinate,DirtyElementGridCellSizeInv);
40 int64 Y = GetDirtyCellIndexFromWorldCoordinate(Ycoordinate,DirtyElementGridCellSizeInv);
41
42 return HashCell(X, Y);
43 }
44
45 template <typename T>
47 {
48 const int64 CellStartX = GetDirtyCellIndexFromWorldCoordinate(AABB.Min().X, DirtyElementGridCellSizeInv);
49 const int64 CellStartY = GetDirtyCellIndexFromWorldCoordinate(AABB.Min().Y, DirtyElementGridCellSizeInv);
50
51 const int64 CellEndX = GetDirtyCellIndexFromWorldCoordinate(AABB.Max().X, DirtyElementGridCellSizeInv);
52 const int64 CellEndY = GetDirtyCellIndexFromWorldCoordinate(AABB.Max().Y, DirtyElementGridCellSizeInv);
53
55 {
56 const uint64 XsampleCount = (CellEndX - CellStartX) + 1;
57 const uint64 YsampleCount = (CellEndY - CellStartY) + 1;
61 {
62 return false;
63 }
64 }
65 return true;
66 }
67
68 template <typename T, typename FunctionType>
69 FORCEINLINE_DEBUGGABLE bool DoForOverlappedCells(const TAABB<T, 3>& AABB, FReal DirtyElementGridCellSize, FReal DirtyElementGridCellSizeInv, FunctionType Function)
70 {
71 int64 CellStartX = GetDirtyCellIndexFromWorldCoordinate(AABB.Min().X, DirtyElementGridCellSizeInv);
72 int64 CellStartY = GetDirtyCellIndexFromWorldCoordinate(AABB.Min().Y, DirtyElementGridCellSizeInv);
73
74 int64 CellEndX = GetDirtyCellIndexFromWorldCoordinate(AABB.Max().X, DirtyElementGridCellSizeInv);
75 int64 CellEndY = GetDirtyCellIndexFromWorldCoordinate(AABB.Max().Y, DirtyElementGridCellSizeInv);
76
77 for (int64 X = CellStartX; X <= CellEndX; X++)
78 {
79 for (int64 Y = CellStartY; Y <= CellEndY; Y++)
80 {
81 if (!Function(HashCell(X, Y)))
82 {
83 return false; // early out requested by the lambda
84 }
85 }
86 }
87 return true;
88 }
89
90 // Only execute function for new Cells not covered in old (Set difference: {Cells spanned by AABB} - { Cells spanned by AABBExclude})
91 template <typename T, typename FunctionType>
92 FORCEINLINE_DEBUGGABLE bool DoForOverlappedCellsExclude(const TAABB<T, 3>& AABB, const TAABB<T, 3>& AABBExclude, FReal DirtyElementGridCellSize, FReal DirtyElementGridCellSizeInv, FunctionType Function)
93 {
94
95 int64 NewCellStartX = GetDirtyCellIndexFromWorldCoordinate((FReal)AABB.Min().X, DirtyElementGridCellSizeInv);
96 int64 NewCellStartY = GetDirtyCellIndexFromWorldCoordinate((FReal)AABB.Min().Y, DirtyElementGridCellSizeInv);
97
98 int64 NewCellEndX = GetDirtyCellIndexFromWorldCoordinate((FReal)AABB.Max().X, DirtyElementGridCellSizeInv);
99 int64 NewCellEndY = GetDirtyCellIndexFromWorldCoordinate((FReal)AABB.Max().Y, DirtyElementGridCellSizeInv);
100
101 int64 OldCellStartX = GetDirtyCellIndexFromWorldCoordinate((FReal)AABBExclude.Min().X, DirtyElementGridCellSizeInv);
102 int64 OldCellStartY = GetDirtyCellIndexFromWorldCoordinate((FReal)AABBExclude.Min().Y, DirtyElementGridCellSizeInv);
103
104 int64 OldCellEndX = GetDirtyCellIndexFromWorldCoordinate((FReal)AABBExclude.Max().X, DirtyElementGridCellSizeInv);
105 int64 OldCellEndY = GetDirtyCellIndexFromWorldCoordinate((FReal)AABBExclude.Max().Y, DirtyElementGridCellSizeInv);
106
107 // Early out here
112 {
113 return true;
114 }
115
116 for (int64 X = NewCellStartX; X <= NewCellEndX; X++)
117 {
118 for (int64 Y = NewCellStartY; Y <= NewCellEndY; Y++)
119 {
121 {
122 if (!Function(HashCell(X, Y)))
123 {
124 return false; // early out requested by the lambda
125 }
126 }
127 }
128 }
129 return true;
130 }
131
133 {
134 int32 TestIndex = (EndIndex + StartIndex) / 2;
135 int32 TestValue = Array[TestIndex];
136 if (TestValue == FindValue)
137 {
138 return TestIndex;
139 }
140
141 if (StartIndex == EndIndex)
142 {
143 return INDEX_NONE;
144 }
145
146 if (TestValue < FindValue)
147 {
148 // tail-recursion
149 return FindInSortedArray(Array, FindValue, TestIndex + 1, EndIndex);
150 }
151
152 if (StartIndex == TestIndex)
153 {
154 return INDEX_NONE;
155 }
156
157 // tail-recursion
158 return FindInSortedArray(Array, FindValue, StartIndex, TestIndex - 1);
159 }
160
162 {
163 int32 TestIndex = (EndIndex + StartIndex) / 2;
164 int32 TestValue = Array[TestIndex];
165 if (TestValue == FindValue)
166 {
167 return INDEX_NONE; // Already in array
168 }
169
170 if (StartIndex == EndIndex)
171 {
172 return FindValue > TestValue ? StartIndex + 1 : StartIndex;
173 }
174
175 if (TestValue < FindValue)
176 {
177 // tail-recursion
178 return FindInsertIndexIntoSortedArray(Array, FindValue, TestIndex + 1, EndIndex);
179 }
180
181 if (StartIndex == TestIndex)
182 {
183 return TestIndex;
184 }
185
186 // tail-recursion
187 return FindInsertIndexIntoSortedArray(Array, FindValue, StartIndex, TestIndex - 1);
188 }
189
190 // Prerequisites: The array must be sorted from StartIndex to StartIndex + Count -1, and must have one element past StartIndex + Count -1 allocated
191 // returns false if the value was already in the array and therefore not added again
193 {
194 // We must keep everything sorted
195 if (Count > 0)
196 {
197 int32 EndIndex = StartIndex + Count - 1;
198 int32 InsertIndex = FindInsertIndexIntoSortedArray(Array, Value, StartIndex, EndIndex);
199 //ensure(InsertIndex != INDEX_NONE) // Just for debugging
200 if (InsertIndex != INDEX_NONE)
201 {
202 for (int32 Index = EndIndex + 1; Index > InsertIndex; Index--)
203 {
204 Array[Index] = Array[Index - 1];
205 }
206 Array[InsertIndex] = Value;
207 }
208 else
209 {
210 return false;
211 }
212 }
213 else
214 {
215 Array[StartIndex] = Value;
216 }
217 return true;
218 }
219
220 // Prerequisites: The array must be sorted from StartIndex to EndIndex.
221 // The extra element won't be deallocated
222 // returns true if the element has been found and successfully deleted
224 {
225 if (ensure(Count > 0))
226 {
227 int32 EndIndex = StartIndex + Count - 1;
228 int32 DeleteIndex = FindInSortedArray(Array, Value, StartIndex, EndIndex);
229 if (DeleteIndex != INDEX_NONE)
230 {
231 for (int32 Index = DeleteIndex; Index < EndIndex; Index++)
232 {
233 Array[Index] = Array[Index + 1];
234 }
235 return true;
236 }
237 }
238 return false;
239 }
240
241 FORCEINLINE_DEBUGGABLE bool TooManySweepQueryCells(const TVec3<FReal>& QueryHalfExtents, const FVec3& StartPoint, const FVec3& Dir, FReal Length, FReal DirtyElementGridCellSizeInv, int32 DirtyElementMaxGridCellQueryCount)
242 {
244 {
245 return true;
246 }
247
249 ((uint64)(QueryHalfExtents.X * 2 * DirtyElementGridCellSizeInv) + 2) * ((uint64)(QueryHalfExtents.Y * 2 * DirtyElementGridCellSizeInv) + 2) +
250 ((uint64)(FMath::Max(QueryHalfExtents.X, QueryHalfExtents.Y) * 2 * DirtyElementGridCellSizeInv) + 2) * ((uint64)(Length * DirtyElementGridCellSizeInv) + 2);
251
252 return EstimatedNumberOfCells > (uint64)DirtyElementMaxGridCellQueryCount;
253 }
254
255
256 // This function should be called with a dominant x direction only!
257 // Todo: Refactor: Use TVectors consistently
258 template <typename FunctionType>
259 FORCEINLINE_DEBUGGABLE void DoForSweepIntersectCellsImp(const FReal QueryHalfExtentsX, const FReal QueryHalfExtentsY, const FReal StartPointX, const FReal StartPointY, const FReal RayX, const FReal RayY, FReal DirtyElementGridCellSize, FReal DirtyElementGridCellSizeInv, FunctionType InFunction)
260 {
261 // Use 2 paths (Line0 and Line1) that traces the shape of the swept AABB and fill between them
262 // Example of one of the cases (XDirectionDominant, Fill Up):
263 // Line0
264 // #############
265 // #
266 // #
267 // Line0 #
268 // # #
269 // # #
270 // # # ----> Dx
271 // # ^ #
272 // # | # Line1
273 // Fill #
274 // | #
275 // #
276 // #############
277 // Line1 ^TurningPointForLine1
278
279
280 // The Reference Cell's origin is used for the local coordinates origin
283 const TVector<FReal, 2> LocalCoordinatesOrigin{ (FReal)ReferenceCellIndexX * DirtyElementGridCellSize, (FReal)ReferenceCellIndexY * DirtyElementGridCellSize};
286
287 FReal DeltaX = RayX;
288 FReal DeltaY = RayY;
289
290 FReal AbsDx = FMath::Abs(DeltaX);
291 FReal AbsDy = FMath::Abs(DeltaY);
292
295
298 FReal DtDy = 0; // DeltaTime over DeltaX
299 FReal DtDx = 0;
300
301 if (DxTooSmall)
302 {
303 // This is just the overlap case (no casting along a ray)
304 DeltaCelIndexX = 1;
305 DeltaCelIndexY = 1;
306 }
307 else
308 {
309 DeltaCelIndexX = DeltaX >= 0 ? 1 : -1;
310 DeltaCelIndexY = DeltaY >= 0 ? 1 : -1;
311 }
312
313 // Use parametric description of the lines here (t is the parameter and is positive along the ray)
314 // x = Dx/Dt*t + x0
315 // y = Dy/Dt*t + x0
317 DtDy = DyTooSmall ? 1 : (FReal)DeltaCelIndexX * DeltaX / DeltaY;
318
319 // Calculate all the bounds we need
324 int64 TurningPointForLine1; // This is where we need to change direction for line 2
326
327 // Line0 current position
330
331 // Line1 current position
334
337
340
343
344 // Because of floating point math precision there's case where we can get LastCellIndexY to be smaller than CurrentCellIndexY0 when the ray is stright down
345 // that would cause the while loop to go on forever as it relies on an strict equality
346 // we then need to adjust the value of LastCellIndexY accordingly
347 if (DxTooSmall)
348 {
350 }
351
352 bool Done = false;
353 while (!Done)
354 {
355 // Advance Line 0 crossing a horizontal border here (angle is 45 degrees or less)
356
358 {
359 FReal CrossingVerticleCellBorderT = std::numeric_limits<FReal>::max();
360 FReal CrossingHorizontalCellBorderT = std::numeric_limits<FReal>::max();
361 CrossingVerticleCellBorderT = DtDx * ((FReal)(CurrentCellIndexX0 - ReferenceCellIndexX + (DeltaCelIndexX > 0 ? 1 : 0)) * DirtyElementGridCellSize - X0);
362 CrossingHorizontalCellBorderT = DtDy * ((FReal)(CurrentCellIndexY0 - ReferenceCellIndexY + (DeltaCelIndexY > 0 ? 1 : 0)) * DirtyElementGridCellSize - Y0);
364 {
365 X0 += CrossingHorizontalCellBorderT * (1 / DtDx); // DtDx is always 1 or -1
366 Y0 += CrossingHorizontalCellBorderT * (1 / DtDy); // Abs(DtDy) >= 1
368 }
369 }
370
372 {
373 InFunction((FReal)CurrentCellIndexX0 * DirtyElementGridCellSize, (FReal)CurrentFillCellIndexY * DirtyElementGridCellSize);
374 }
375
376 // Advance line 0 crossing vertical cell borders
377 {
379 {
380 FReal CrossingVerticleCellBorderT = std::numeric_limits<FReal>::max();
381 CrossingVerticleCellBorderT = DtDx * ((FReal)(CurrentCellIndexX0 - ReferenceCellIndexX + (DeltaCelIndexX > 0 ? 1 : 0)) * DirtyElementGridCellSize - X0);
384 }
385 else
386 {
387 X0 += DirtyElementGridCellSize * (FReal)DeltaCelIndexX;
388 }
389 }
390
391 // Advance line 1
393 {
395 {
396 X1 += DirtyElementGridCellSize * (FReal)DeltaCelIndexX;
397 }
398 else
399 {
401 {
402 // Put Line position exactly at the turning point
404 }
405
406 FReal CrossingVerticleCellBorderT = std::numeric_limits<FReal>::max();
407 FReal CrossingHorizontalCellBorderT = std::numeric_limits<FReal>::max();
408 if (!DxTooSmall)
409 {
410 CrossingVerticleCellBorderT = DtDx * ((FReal)(CurrentCellIndexX1 - ReferenceCellIndexX + (DeltaCelIndexX > 0 ? 1 : 0)) * DirtyElementGridCellSize - X1);
411 }
412
413 if (!DyTooSmall)
414 {
415 CrossingHorizontalCellBorderT = DtDy * ((FReal)(CurrentCellIndexY1 - ReferenceCellIndexY + (DeltaCelIndexY > 0 ? 1 : 0)) * DirtyElementGridCellSize - Y1);
416 }
417
419 {
421 }
422
423 if (!DxTooSmall)
424 {
425 X1 += CrossingVerticleCellBorderT * (1 / DtDx);
426 }
427
428 if (!DyTooSmall)
429 {
430 Y1 += CrossingVerticleCellBorderT * (1 / DtDy);
431 }
432 }
434 }
435
438 }
439 }
440
441 template <typename FunctionType>
442 void DoForSweepIntersectCells(const FVec3 QueryHalfExtents, const FVec3& StartPoint, const FVec3& Dir, FReal Length, FReal DirtyElementGridCellSize, FReal DirtyElementGridCellSizeInv, FunctionType InFunction)
443 {
444 FReal AbsDx = FMath::Abs(Dir.X * Length);
445 FReal AbsDy = FMath::Abs(Dir.Y * Length);
446
448
449 // if the ray is mostly vertical then we can default to an simple overlap
451 {
452 // no need to account for the ray length as we only collect 2 dimensional cell coordinates and the ray is already proven to be vertical
453 const FAABB3 QueryBounds(StartPoint- QueryHalfExtents, StartPoint + QueryHalfExtents);
454
455 const int64 CellStartX = GetDirtyCellIndexFromWorldCoordinate(QueryBounds.Min().X, DirtyElementGridCellSizeInv);
456 const int64 CellStartY = GetDirtyCellIndexFromWorldCoordinate(QueryBounds.Min().Y, DirtyElementGridCellSizeInv);
457 const int64 CellEndX = GetDirtyCellIndexFromWorldCoordinate(QueryBounds.Max().X, DirtyElementGridCellSizeInv);
458 const int64 CellEndY = GetDirtyCellIndexFromWorldCoordinate(QueryBounds.Max().Y, DirtyElementGridCellSizeInv);
459
460 for (int64 X = CellStartX; X <= CellEndX; X++)
461 {
462 for (int64 Y = CellStartY; Y <= CellEndY; Y++)
463 {
464 InFunction((FReal)X * DirtyElementGridCellSize, (FReal)Y * DirtyElementGridCellSize);
465 }
466 }
467 }
468 else
469 {
471 {
472 DoForSweepIntersectCellsImp(QueryHalfExtents.X, QueryHalfExtents.Y, StartPoint.X, StartPoint.Y, Dir.X * Length, Dir.Y * Length, DirtyElementGridCellSize, DirtyElementGridCellSizeInv, InFunction);
473 }
474 else
475 {
476 // Swap Y and X
477 DoForSweepIntersectCellsImp(QueryHalfExtents.Y, QueryHalfExtents.X, StartPoint.Y, StartPoint.X, Dir.Y * Length, Dir.X * Length, DirtyElementGridCellSize, DirtyElementGridCellSizeInv, [&](auto X, auto Y) {InFunction(Y, X); });
478 }
479 }
480
481 }
482
483 FORCEINLINE_DEBUGGABLE bool TooManyRaycastQueryCells(const FVec3& StartPoint, const FVec3& Dir, const FReal Length, FReal DirtyElementGridCellSizeInv, int32 DirtyElementMaxGridCellQueryCount)
484 {
485 if(Length > (FReal)TNumericLimits<uint64>::Max() || DirtyElementGridCellSizeInv == 0)
486 {
487 return true;
488 }
489
490 FVec3 EndPoint = StartPoint + Length * Dir;
491
492 const FReal ElementAbsLimit = (FReal)TNumericLimits<int64>::Max() / DirtyElementGridCellSizeInv;
493 if(StartPoint.GetAbsMax() >= ElementAbsLimit || EndPoint.GetAbsMax() >= ElementAbsLimit)
494 {
495 return true;
496 }
497
498 int64 FirstCellIndexX = GetDirtyCellIndexFromWorldCoordinate(StartPoint.X, DirtyElementGridCellSizeInv);
499 int64 FirstCellIndexY = GetDirtyCellIndexFromWorldCoordinate(StartPoint.Y, DirtyElementGridCellSizeInv);
500
501 int64 LastCellIndexX = GetDirtyCellIndexFromWorldCoordinate(EndPoint.X, DirtyElementGridCellSizeInv);
502 int64 LastCellIndexY = GetDirtyCellIndexFromWorldCoordinate(EndPoint.Y, DirtyElementGridCellSizeInv);
503
504 // This will be equal to the Manhattan distance
506
507 if (CellCount > (uint64)DirtyElementMaxGridCellQueryCount)
508 {
509 return true;
510 }
511
512 return false;
513 }
514
515 template <typename FunctionType>
516 FORCEINLINE_DEBUGGABLE void DoForRaycastIntersectCells(const FVec3& StartPoint, const FVec3& Dir, FReal Length, FReal DirtyElementGridCellSize, FReal DirtyElementGridCellSizeInv, FunctionType InFunction)
517 {
518 const int64 FirstCellIndexX = GetDirtyCellIndexFromWorldCoordinate(StartPoint.X, DirtyElementGridCellSizeInv);
519 const int64 FirstCellIndexY = GetDirtyCellIndexFromWorldCoordinate(StartPoint.Y, DirtyElementGridCellSizeInv);
520
523
524 // Note: local coordinates are relative to the StartPoint cell origin
525 const FVec3 LocalCoordinatesOrigin{ (FReal)CurrentCellIndexX * DirtyElementGridCellSize, (FReal)CurrentCellIndexY * DirtyElementGridCellSize, StartPoint.Z};
526
527 const FVec3 StartPointLocal = StartPoint - LocalCoordinatesOrigin;
528
529 const FVec3 EndPointLocal = StartPointLocal + Length * Dir; // Local coordinates are relative to the start point
530 const FVec3 EndPoint = LocalCoordinatesOrigin + EndPointLocal;
531 int64 LastCellIndexX = GetDirtyCellIndexFromWorldCoordinate(EndPoint.X, DirtyElementGridCellSizeInv);
532 int64 LastCellIndexY = GetDirtyCellIndexFromWorldCoordinate(EndPoint.Y, DirtyElementGridCellSizeInv);
533
534 FReal DeltaX = EndPointLocal.X - StartPointLocal.X;
535 FReal DeltaY = EndPointLocal.Y - StartPointLocal.Y;
536
537 FReal AbsDx = FMath::Abs(DeltaX);
538 FReal AbsDy = FMath::Abs(DeltaY);
539
542
543 if (DxTooSmall && DyTooSmall)
544 {
545 InFunction(HashCoordinates(StartPoint.X, StartPoint.Y, DirtyElementGridCellSizeInv));
546 return;
547 }
548
549 int DeltaCelIndexX = DeltaX >= 0 ? 1 : -1;
550 int DeltaCelIndexY = DeltaY >= 0 ? 1 : -1;
551
552 FReal DtDy = 0; // DeltaTime over DeltaX
553 FReal DtDx = 0;
554
556 // Use parametric description of line here (t is the parameter and is positive along the ray)
557 // x = Dx/Dt*t + x0
558 // y = Dy/Dt*t + x0
560 {
562 DtDy = DyTooSmall ? 1 : (FReal)DeltaCelIndexX * DeltaX / DeltaY;
563 }
564 else
565 {
566 DtDx = DxTooSmall ? 1 : (FReal)DeltaCelIndexY * DeltaY / DeltaX;
568 }
569
570 // These are local coordinates
573
574 bool Done = false;
575 while (!Done)
576 {
578 FReal CrossingVerticleCellBorderT = std::numeric_limits<FReal>::max();
579 FReal CrossingHorizontalCellBorderT = std::numeric_limits<FReal>::max();
580 if (!DxTooSmall)
581 {
582 CrossingVerticleCellBorderT = DtDx * ((FReal)(CurrentCellIndexX - FirstCellIndexX + (DeltaCelIndexX > 0 ? 1 : 0)) * DirtyElementGridCellSize - X);
583 }
584
585 if (!DyTooSmall)
586 {
587 CrossingHorizontalCellBorderT = DtDy * ((FReal)(CurrentCellIndexY - FirstCellIndexY + (DeltaCelIndexY > 0 ? 1 : 0)) * DirtyElementGridCellSize - Y);
588 }
589
592 {
595 }
596 else
597 {
600 }
601
602 if (!DxTooSmall)
603 {
604 X += SmallestT * (1 / DtDx);
605 }
606
607 if (!DyTooSmall)
608 {
609 Y += SmallestT * (1 / DtDy);
610 }
611
613 {
614 Done = true;
615 }
616 }
617 }
618}
#define ensure( InExpression)
Definition AssertionMacros.h:464
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define FORCEINLINE_DEBUGGABLE
Definition CoreMiscDefines.h:74
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition AABB.h:37
FORCEINLINE const TVector< T, d > & Max() const
Definition AABB.h:596
FORCEINLINE const TVector< T, d > & Min() const
Definition AABB.h:595
Definition Vector.h:1000
Definition Array.h:670
Definition SkeletalMeshComponent.h:307
FORCEINLINE_DEBUGGABLE bool TooManyRaycastQueryCells(const FVec3 &StartPoint, const FVec3 &Dir, const FReal Length, FReal DirtyElementGridCellSizeInv, int32 DirtyElementMaxGridCellQueryCount)
Definition AABBTreeDirtyGridUtils.h:483
FORCEINLINE_DEBUGGABLE int32 HashCell(int64 XCell, int64 YCell)
Definition AABBTreeDirtyGridUtils.h:31
FORCEINLINE_DEBUGGABLE bool DoForOverlappedCells(const TAABB< T, 3 > &AABB, FReal DirtyElementGridCellSize, FReal DirtyElementGridCellSizeInv, FunctionType Function)
Definition AABBTreeDirtyGridUtils.h:69
FORCEINLINE_DEBUGGABLE void DoForSweepIntersectCellsImp(const FReal QueryHalfExtentsX, const FReal QueryHalfExtentsY, const FReal StartPointX, const FReal StartPointY, const FReal RayX, const FReal RayY, FReal DirtyElementGridCellSize, FReal DirtyElementGridCellSizeInv, FunctionType InFunction)
Definition AABBTreeDirtyGridUtils.h:259
FORCEINLINE_DEBUGGABLE int64 GetDirtyCellIndexFromWorldCoordinate(FReal Coordinate, FReal DirtyElementGridCellSizeInv)
Definition AABBTreeDirtyGridUtils.h:22
@ Y
Definition SimulationModuleBase.h:153
@ X
Definition SimulationModuleBase.h:152
FORCEINLINE_DEBUGGABLE int32 FindInSortedArray(const TArray< int32 > &Array, int32 FindValue, int32 StartIndex, int32 EndIndex)
Definition AABBTreeDirtyGridUtils.h:132
FRealDouble FReal
Definition Real.h:22
FORCEINLINE_DEBUGGABLE bool DeleteValueFromSortedSubArray(TArray< int32 > &Array, int32 Value, int32 StartIndex, int32 Count)
Definition AABBTreeDirtyGridUtils.h:223
FORCEINLINE_DEBUGGABLE void DoForRaycastIntersectCells(const FVec3 &StartPoint, const FVec3 &Dir, FReal Length, FReal DirtyElementGridCellSize, FReal DirtyElementGridCellSizeInv, FunctionType InFunction)
Definition AABBTreeDirtyGridUtils.h:516
FORCEINLINE_DEBUGGABLE int32 FindInsertIndexIntoSortedArray(const TArray< int32 > &Array, int32 FindValue, int32 StartIndex, int32 EndIndex)
Definition AABBTreeDirtyGridUtils.h:161
FORCEINLINE_DEBUGGABLE bool TooManySweepQueryCells(const TVec3< FReal > &QueryHalfExtents, const FVec3 &StartPoint, const FVec3 &Dir, FReal Length, FReal DirtyElementGridCellSizeInv, int32 DirtyElementMaxGridCellQueryCount)
Definition AABBTreeDirtyGridUtils.h:241
FORCEINLINE_DEBUGGABLE int32 HashCoordinates(FReal Xcoordinate, FReal Ycoordinate, FReal DirtyElementGridCellSizeInv)
Definition AABBTreeDirtyGridUtils.h:36
FORCEINLINE_DEBUGGABLE bool TooManyOverlapQueryCells(const TAABB< T, 3 > &AABB, FReal DirtyElementGridCellSizeInv, int32 MaximumOverlap)
Definition AABBTreeDirtyGridUtils.h:46
FORCEINLINE_DEBUGGABLE bool InsertValueIntoSortedSubArray(TArray< int32 > &Array, int32 Value, int32 StartIndex, int32 Count)
Definition AABBTreeDirtyGridUtils.h:192
FORCEINLINE_DEBUGGABLE bool DoForOverlappedCellsExclude(const TAABB< T, 3 > &AABB, const TAABB< T, 3 > &AABBExclude, FReal DirtyElementGridCellSize, FReal DirtyElementGridCellSizeInv, FunctionType Function)
Definition AABBTreeDirtyGridUtils.h:92
FORCEINLINE_DEBUGGABLE uint32 InterleaveWithZeros(uint16 input)
Definition AABBTreeDirtyGridUtils.h:12
void DoForSweepIntersectCells(const FVec3 QueryHalfExtents, const FVec3 &StartPoint, const FVec3 &Dir, FReal Length, FReal DirtyElementGridCellSize, FReal DirtyElementGridCellSizeInv, FunctionType InFunction)
Definition AABBTreeDirtyGridUtils.h:442
U16 Index
Definition radfft.cpp:71
static UE_FORCEINLINE_HINT float Floor(float F)
Definition UnrealMathUtility.h:525
Definition NumericLimits.h:41