UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
GridIndexing3.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3// Port of geometry3Sharp GridIndexing3
4
5#pragma once
6
7#include "VectorTypes.h"
8#include "HAL/Platform.h" // int32
9#include "IntVectorTypes.h"
10#include "BoxTypes.h"
11
12namespace UE
13{
14namespace Geometry
15{
16
17using namespace UE::Math;
18
22template<typename RealType>
24{
26 RealType CellSize;
27
28 TScaleGridIndexer3() : CellSize((RealType)1)
29 {
30 }
31
33 {
34 // Note a very small cell size is likely to overflow the integer grid coordinates
36 }
37
39 inline FVector3i ToGrid(const TVector<RealType>& P) const
40 {
41 return FVector3i(
45 }
46
52};
55
64template<typename RealType>
66{
68 RealType CellSize;
69
71 {
72 }
73
75 {
76 // Note a very small cell size could overflow division by cell size
78 }
79
84 inline FVector3i ToGrid(const TVector<RealType>& P) const
85 {
86 // The conversion below always goes through double. It could be done in RealType, but that is actually messy
87 // and error-prone because for floats, we would not want to do the WraparoundDistance addition below, as it
88 // loses precision unnecessarily for small negative numbers. So we would have to do more work to get the
89 // same kind of single-direction rounding and wraparound behavior, and it is not worth the bother (note if
90 // you do choose to switch: WraparoundDistance initialization would need to change too, using std::nextafter
91 // if we happen to round up)
92
93 static const double WraparoundDistance = static_cast<double>(TNumericLimits<uint32>::Max()) + 1;
94 auto GetInt = [](RealType Real) -> int32
95 {
96 double ModResult = FMath::Fmod(static_cast<double>(Real), WraparoundDistance);
98 uint32 Truncated = static_cast<uint32>(ModResult);
99
100 // Seems that even with 2's complement being required in C++20, static_cast might theoretically still be
101 // undefined outside representable range (?), hence the reinterpret here
102 return reinterpret_cast<int32&>(Truncated);
103 };
104
105 return FVector3i(
106 GetInt(P.X / CellSize),
107 GetInt(P.Y / CellSize),
108 GetInt(P.Z / CellSize));
109 }
110
116 TFunctionRef<bool(const FVector3i& Index)> ShouldContinue) const
117 {
118 FVector3i IntMin = ToGrid(RealMin);
120
121 // Technically signed int overflow is undefined, so we use unsigned int to overflow safely.
122 // Overflow is also the reason we have to use != for the comparison.
123 for (uint32 zi = static_cast<uint32>(IntMin.Z); zi != static_cast<uint32>(ExclusiveIntMax.Z); ++zi)
124 {
125 for (uint32 yi = static_cast<uint32>(IntMin.Y); yi != static_cast<uint32>(ExclusiveIntMax.Y); ++yi)
126 {
127 for (uint32 xi = static_cast<uint32>(IntMin.X); xi != static_cast<uint32>(ExclusiveIntMax.X); ++xi)
128 {
129 // Seems that even with 2's complement being required in C++20, static_cast might theoretically still be
130 // undefined outside representable range (?), hence the reinterpret here
131 if (!ShouldContinue(FVector3i(reinterpret_cast<int32&>(xi), reinterpret_cast<int32&>(yi), reinterpret_cast<int32&>(zi))))
132 {
133 return;
134 }
135 }
136 }
137 }
138 }
139};
140
143
147template<typename RealType>
149{
151 RealType CellSize;
154
156 : CellSize((RealType)1), Origin(TVector<RealType>::Zero())
157 {
158 }
159
160 TShiftGridIndexer3(const TVector<RealType>& origin, RealType cellSize)
161 : CellSize(cellSize), Origin(origin)
162 {
164 }
165
167 inline FVector3i ToGrid(const TVector<RealType>& point) const
168 {
169 return FVector3i(
170 (int)TMathUtil<RealType>::Floor((point.X - Origin.X) / CellSize),
171 (int)TMathUtil<RealType>::Floor((point.Y - Origin.Y) / CellSize),
172 (int)TMathUtil<RealType>::Floor((point.Z - Origin.Z) / CellSize));
173 }
174
177 {
178 return TVector<RealType>(
179 ((RealType)gridpoint.X * CellSize) + Origin.X,
180 ((RealType)gridpoint.Y * CellSize) + Origin.Y,
181 ((RealType)gridpoint.Z * CellSize) + Origin.Z);
182 }
183
186 {
187 return TVector<RealType>(
188 ((RealType)RealGridPoint.X * CellSize) + Origin.X,
189 ((RealType)RealGridPoint.Y * CellSize) + Origin.Y,
190 ((RealType)RealGridPoint.Z * CellSize) + Origin.Z);
191 }
192};
195
196
197template<typename RealType>
199{
200 using TShiftGridIndexer3<RealType>::CellSize;
201 using TShiftGridIndexer3<RealType>::Origin;
202
204
206 : TShiftGridIndexer3<RealType>(Bounds.Min, CellSize),
207 BoundsMax(Bounds.Max)
208 {}
209
211 {
212 const RealType InvCellSize = 1.0 / CellSize;
213 const TVector<RealType> Extents = BoundsMax - Origin;
214 return CeilInt(Extents * InvCellSize);
215 }
216
218 {
219 return FVector3i{ (int)TMathUtil<RealType>::Ceil(V[0]),
220 (int)TMathUtil<RealType>::Ceil(V[1]),
221 (int)TMathUtil<RealType>::Ceil(V[2]) };
222 }
223
224};
225
228
229} // end namespace UE::Geometry
230} // end namespace UE
#define ensure( InExpression)
Definition AssertionMacros.h:464
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition AssetRegistryState.h:50
Definition MathUtil.h:150
TWrapAroundGridIndexer3< float > FWrapAroundGridIndexer3f
Definition GridIndexing3.h:141
TShiftGridIndexer3< float > FShiftGridIndexer3f
Definition GridIndexing3.h:193
TBoundsGridIndexer3< float > FBoundsGridIndexer3f
Definition GridIndexing3.h:226
TWrapAroundGridIndexer3< double > FWrapAroundGridIndexer3d
Definition GridIndexing3.h:142
TScaleGridIndexer3< float > FScaleGridIndexer3f
Definition GridIndexing3.h:53
TScaleGridIndexer3< double > FScaleGridIndexer3d
Definition GridIndexing3.h:54
TShiftGridIndexer3< double > FShiftGridIndexer3d
Definition GridIndexing3.h:194
TBoundsGridIndexer3< double > FBoundsGridIndexer3d
Definition GridIndexing3.h:227
Definition Sphere.cpp:10
Definition AdvancedWidgetsModule.cpp:13
U16 Index
Definition radfft.cpp:71
Definition NumericLimits.h:41
Definition IntVectorTypes.h:252
static FVector3i One()
Definition IntVectorTypes.h:330
Definition BoxTypes.h:247
Definition GridIndexing3.h:199
TBoundsGridIndexer3(const TAxisAlignedBox3< RealType > &Bounds, RealType CellSize)
Definition GridIndexing3.h:205
TVector< RealType > BoundsMax
Definition GridIndexing3.h:203
FVector3i GridResolution() const
Definition GridIndexing3.h:210
static FVector3i CeilInt(const TVector< RealType > &V)
Definition GridIndexing3.h:217
Definition GridIndexing3.h:24
TScaleGridIndexer3()
Definition GridIndexing3.h:28
TScaleGridIndexer3(RealType CellSize)
Definition GridIndexing3.h:32
RealType CellSize
Definition GridIndexing3.h:26
FVector3i ToGrid(const TVector< RealType > &P) const
Definition GridIndexing3.h:39
TVector< RealType > FromGrid(const FVector3i &GridPoint) const
Definition GridIndexing3.h:48
Definition GridIndexing3.h:149
TVector< RealType > Origin
Definition GridIndexing3.h:153
RealType CellSize
Definition GridIndexing3.h:151
TShiftGridIndexer3()
Definition GridIndexing3.h:155
TVector< RealType > FromGrid(const TVector< RealType > &RealGridPoint) const
Definition GridIndexing3.h:185
TVector< RealType > FromGrid(const FVector3i &gridpoint) const
Definition GridIndexing3.h:176
FVector3i ToGrid(const TVector< RealType > &point) const
Definition GridIndexing3.h:167
TShiftGridIndexer3(const TVector< RealType > &origin, RealType cellSize)
Definition GridIndexing3.h:160
Definition GridIndexing3.h:66
RealType CellSize
Definition GridIndexing3.h:68
TWrapAroundGridIndexer3()
Definition GridIndexing3.h:70
FVector3i ToGrid(const TVector< RealType > &P) const
Definition GridIndexing3.h:84
void IterateAcrossBounds(const TVector< RealType > &RealMin, const TVector< RealType > &RealMax, TFunctionRef< bool(const FVector3i &Index)> ShouldContinue) const
Definition GridIndexing3.h:115
TWrapAroundGridIndexer3(RealType CellSize)
Definition GridIndexing3.h:74
Definition Vector.h:51
T Z
Definition Vector.h:68
T Y
Definition Vector.h:65
T X
Definition Vector.h:62