UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
BVTree.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "Math/Box.h"
7
19template<typename InElementType, typename InAllocator = FDefaultAllocator>
20struct TBVTree
21{
23
24 struct FElementBox : public FBox
25 {
26 // index to TBVTree.Elements
28
31
33 {}
34 };
35
37
42
47
48 // Recreate the tree based on the current content of Elements.
49 // Callers are expected to have filled the GetElements() array before calling this function.
51 {
52 Nodes.Reset();
53 NodeBoundingBoxes.Reset();
55 }
56
62
68
70 {
71 const int LimitIndex = Nodes.Num();
72 int NodeIndex = 0;
73
74 while (NodeIndex < LimitIndex)
75 {
76 const bool bOverlap = Box.Intersect(NodeBoundingBoxes[NodeIndex]);
77 const int16 ElementIndex = Nodes[NodeIndex];
78 const bool bLeafNode = (ElementIndex >= 0);
79
80 if (bLeafNode && bOverlap)
81 {
82 OutOverlappingElements.Add(Elements[ElementIndex]);
83 }
84
85 NodeIndex += (bOverlap || bLeafNode) ? 1 : -ElementIndex;
86 }
87 }
88
89 const TArray<int16, InAllocator>& GetNodes() const { return Nodes; }
90 const TArray<FBox, InAllocator>& GetBoundingBoxes() const { return NodeBoundingBoxes; }
91 const TArray<FElement>& GetElements() const { return Elements; }
92 TArray<FElement>& GetElements() { return Elements; }
93
94 bool IsEmpty() const { return Nodes.Num() == 0; }
95
96protected:
97 void Subdivide(TArray<FElementBox>& ElementBBoxes, const int StartIndex, const int LimitIndex, int& CurrentNode)
98 {
99 const int Count = LimitIndex - StartIndex;
100 const int ThisCurrentNode = CurrentNode;
101
102 int16& NodeIndex = Nodes[CurrentNode];
103 FBox& NodeBounds = NodeBoundingBoxes[CurrentNode++];
104
105 if (Count == 1)
106 {
107 // Leaf node
108 NodeBounds = ElementBBoxes[StartIndex];
109 NodeIndex = ElementBBoxes[StartIndex].ElementIndex;
110 }
111 else
112 {
113 // Needs splitting
116
117 const int NumChildNodes = Count * 2 - 1;
118
119 // A negative index means this is a non-leaf node, and the value is the number of nodes
120 // to skip to exit the current branch and jump to the next unvisited node during a search.
121 NodeIndex = -NumChildNodes;
122
123 const int Axis = GetLongestAxis(NodeBounds);
124
125 struct FAxisSort
126 {
127 const int Axis;
128 FAxisSort(const int InAxis) : Axis(InAxis) {}
129
130 bool operator()(const FElementBox& A, const FElementBox& B) const
131 {
132 return ((&A.Min.X)[Axis] < (&B.Min.X)[Axis]);
133 }
134 };
135
136 Algo::Sort(MakeArrayView(ElementBBoxes.GetData() + StartIndex, Count), FAxisSort(Axis));
137
138 const int SplitIndex = StartIndex + Count / 2;
139
140 // Left
141 Subdivide(ElementBBoxes, StartIndex, SplitIndex, CurrentNode);
142 // Right
144 }
145 }
146
147 void Reset()
148 {
149 Nodes.Reset();
150 NodeBoundingBoxes.Reset();
151 Elements.Reset();
152 }
153
155 {
156 Elements = InElements;
157
159 }
160
161
163 {
164 Elements = MoveTemp(InElements);
165
167 }
168
169 //assumes Elements has been set up
171 {
172 if (Elements.Num())
173 {
174 const int NodesCount = 2 * Elements.Num() - 1;
175 Nodes.AddUninitialized(NodesCount);
176 NodeBoundingBoxes.AddUninitialized(NodesCount);
177
180
181 int Index = 0;
182 for (const FElement& Element : Elements)
183 {
185 ElementBBoxes[Index].ElementIndex = Index;
186 ++Index;
187 }
188
189 int CurrentNode = 0;
190 Subdivide(ElementBBoxes, 0, Elements.Num(), CurrentNode);
191 }
192 }
193
194 static FBox CalcNodeBounds(const TArray<FElementBox>& ElementBBoxes, const int StartIndex, const int LimitIndex)
195 {
197 for (int Index = StartIndex; Index < LimitIndex; ++Index)
198 {
200 }
201 return Extends;
202 }
203
204 static int GetLongestAxis(const FBox& NodeBounds)
205 {
206 const float MaxX = NodeBounds.Max.X - NodeBounds.Min.X;
207 const float MaxY = NodeBounds.Max.Y - NodeBounds.Min.Y;
208 const float MaxZ = NodeBounds.Max.Z - NodeBounds.Min.Z;
209
210 return (MaxX > MaxY && MaxX > MaxZ)
211 ? 0
212 : ((MaxY > MaxZ) ? 1 : 2);
213 }
214
215 // you have to supply this yourself
216 static FBox CalcElementBounds(const FElement& /*Element*/);
217
218private:
219
221 TArray<FBox, InAllocator> NodeBoundingBoxes;
222 TArray<FElement> Elements;
223};
224
225// static FBox CalcElementBounds(const FElement& /*Element*/) const;
constexpr auto MakeArrayView(OtherRangeType &&Other)
Definition ArrayView.h:873
@ ForceInit
Definition CoreMiscDefines.h:155
FPlatformTypes::int16 int16
A 16-bit signed integer.
Definition Platform.h:1123
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
Definition Array.h:670
UE_FORCEINLINE_HINT SizeType AddUninitialized()
Definition Array.h:1664
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void Reset(SizeType NewSize=0)
Definition Array.h:2246
UE_REWRITE void Sort(RangeType &&Range)
Definition Sort.h:16
U16 Index
Definition radfft.cpp:71
Definition BVTree.h:25
int ElementIndex
Definition BVTree.h:27
FElementBox(const FBox &Box)
Definition BVTree.h:32
FElementBox()
Definition BVTree.h:29
Definition BVTree.h:21
static int GetLongestAxis(const FBox &NodeBounds)
Definition BVTree.h:204
void Subdivide(TArray< FElementBox > &ElementBBoxes, const int StartIndex, const int LimitIndex, int &CurrentNode)
Definition BVTree.h:97
void GetOverlapping(const FBox &Box, TArray< FElement > &OutOverlappingElements) const
Definition BVTree.h:69
bool IsEmpty() const
Definition BVTree.h:94
TBVTree(const TArray< FElement > &InElements)
Definition BVTree.h:38
void Create(TArray< FElement > &&InElements)
Definition BVTree.h:162
void Create(const TArray< FElement > &InElements)
Definition BVTree.h:154
void RecreateTree()
Definition BVTree.h:50
void RecreateTree(const TArray< FElement > &InElements)
Definition BVTree.h:57
static FBox CalcElementBounds(const FElement &)
TBVTree()
Definition BVTree.h:36
InElementType FElement
Definition BVTree.h:22
const TArray< FElement > & GetElements() const
Definition BVTree.h:91
void RecreateTree(TArray< FElement > &&InElements)
Definition BVTree.h:63
TArray< FElement > & GetElements()
Definition BVTree.h:92
const TArray< int16, InAllocator > & GetNodes() const
Definition BVTree.h:89
void CreateCommonInternal()
Definition BVTree.h:170
void Reset()
Definition BVTree.h:147
static FBox CalcNodeBounds(const TArray< FElementBox > &ElementBBoxes, const int StartIndex, const int LimitIndex)
Definition BVTree.h:194
TBVTree(TArray< FElement > &&InElements)
Definition BVTree.h:43
const TArray< FBox, InAllocator > & GetBoundingBoxes() const
Definition BVTree.h:90