4
5
9#include "Containers/Array.h"
10#include "Containers/ArrayView.h"
11#include "Containers/ContainerAllocationPolicies.h"
16#include "HAL/PlatformMisc.h"
17#include "Logging/LogCategory.h"
18#include "Logging/LogMacros.h"
20#include "Math/BoxSphereBounds.h"
21#include "Math/MathFwd.h"
22#include "Math/UnrealMathSSE.h"
23#include "Math/UnrealMathUtility.h"
24#include "Math/Vector.h"
25#include "Math/Vector4.h"
26#include "Math/VectorRegister.h"
27#include "Misc/AssertionMacros.h"
28#include "Templates/EnableIf.h"
29#include "Templates/Models.h"
30#include "Templates/UnrealTemplate.h"
31#include "Templates/UnrealTypeTraits.h"
32#include "Trace/Detail/Channel.h"
35#define FOREACH_OCTREE_CHILD_NODE(ChildRef)
36 for(FOctreeChildNodeRef ChildRef(0
);!ChildRef.IsNULL();ChildRef.Advance())
41class FBoxCenterAndExtent
44 using FReal = FVector4::FReal;
50 FBoxCenterAndExtent() {}
53 FBoxCenterAndExtent(
const FVector& InCenter,
const FVector& InExtent)
59 FBoxCenterAndExtent(
const FBox& Box)
62 Box.GetCenterAndExtents(C,E);
63 Center = FVector4(C, 0);
64 Extent = FVector4(E, 0);
68 template<
typename TExtent>
69 explicit FBoxCenterAndExtent(
const UE::Math::TBoxSphereBounds<FReal, TExtent>& BoxSphere)
71 Center = BoxSphere.Origin;
72 Extent = FVector(BoxSphere.BoxExtent);
73 Center.W = Extent.W = 0;
77 explicit FBoxCenterAndExtent(
const float PositionRadius[4])
79 Center = FVector4(PositionRadius[0],PositionRadius[1],PositionRadius[2], 0);
80 Extent = FVector4(PositionRadius[3],PositionRadius[3],PositionRadius[3], 0);
86 return FBox(Center - Extent,Center + Extent);
90
91
92
93
94 friend FORCEINLINE bool Intersect(
const FBoxCenterAndExtent& A,
const FBoxCenterAndExtent& B)
97 const VectorRegister CenterDifference = VectorAbs(VectorSubtract(VectorLoadAligned(&A.Center),VectorLoadAligned(&B.Center)));
100 const VectorRegister CompositeExtent = VectorAdd(VectorLoadAligned(&A.Extent),VectorLoadAligned(&B.Extent));
104 return VectorAnyGreaterThan(CenterDifference,CompositeExtent) ==
false;
107
108
109
110
111 template<
typename TExtent>
112 friend FORCEINLINE bool Intersect(
const UE::Math::TBoxSphereBounds<FReal, TExtent>& A,
const FBoxCenterAndExtent& B)
115 const VectorRegister CenterDifference = VectorAbs(VectorSubtract(VectorLoadFloat3_W0(&A.Origin),VectorLoadAligned(&B.Center)));
118 const VectorRegister CompositeExtent = VectorAdd(VectorLoadFloat3_W0(&A.BoxExtent),VectorLoadAligned(&B.Extent));
122 return VectorAnyGreaterThan(CenterDifference,CompositeExtent) ==
false;
125
126
127
128
129
130 friend FORCEINLINE bool Intersect(
const float A[4],
const FBoxCenterAndExtent& B)
133 const VectorRegister CenterDifference = VectorAbs(VectorSubtract(VectorLoadFloat3_W0(A),VectorLoadAligned(&B.Center)));
136 const VectorRegister CompositeExtent = VectorAdd(VectorSet_W0(VectorLoadFloat1(A+3)),VectorLoadAligned(&B.Extent));
140 return VectorAnyGreaterThan(CenterDifference,CompositeExtent) ==
false;
156 Index = int8(InX << 0) | int8(InY << 1) | int8(InZ << 2);
185 return (
Index >> 0) & 1;
190 return (
Index >> 1) & 1;
195 return (
Index >> 2) & 1;
242 PositiveChildBits = ChildRef
.Index;
243 NegativeChildBits = ~ChildRef
.Index;
291 const FReal TightChildExtent = Bounds.Extent.X * 0.5f;
292 const FReal LooseChildExtent = TightChildExtent * (1.0f + 1.0f / (FReal)LoosenessDenominator);
294 ChildExtent = LooseChildExtent;
295 ChildCenterOffset = Bounds.Extent.X - LooseChildExtent;
305 const FReal TightChildExtent = Bounds.Extent.X * 0.5f;
306 const FReal LooseChildExtent = TightChildExtent * (1.0f + 1.0f / (FReal)LoosenessDenominator);
308 ChildExtent = LooseChildExtent;
309 ChildCenterOffset = Bounds.Extent.X - LooseChildExtent;
315 union MaskType { VectorRegister4Float v; VectorRegister4Int i;
318 : v(MakeVectorRegister(0.0f, 0.0f, 0.0f, 0.0f))
327 return VectorSelect(Mask.v, VectorSetFloat1(ChildCenterOffset), VectorSetFloat1(-ChildCenterOffset));
336 VectorStoreAligned(VectorMultiply(ZeroW, VectorSetFloat1(ChildExtent)), &(LocalBounds.Extent.X));
345 VectorStoreAligned(VectorMultiply(ZeroW, VectorSetFloat1(ChildExtent)), &(ChildContext->Bounds.Extent.X));
347 const FReal TightChildExtent = ChildExtent * 0.5f;
348 const FReal LooseChildExtent = TightChildExtent * (1.0f + 1.0f / (FReal)LoosenessDenominator);
349 ChildContext->ChildExtent = LooseChildExtent;
350 ChildContext->ChildCenterOffset = ChildExtent - LooseChildExtent;
359 VectorStoreAligned(VectorMultiply(ZeroW, VectorSetFloat1(ChildExtent)), &(LocalBounds.Extent.X));
363
364
365
366
370
371
372
373
374
381template<
typename ElementType,
typename OctreeSemantics>
384 using ElementArrayType =
TArray<ElementType,
typename OctreeSemantics::ElementAllocator>;
386 using FNodeIndex = uint32;
422 void Push(FNodeIndex NodeIndex)
609 template<
typename PredicateFunc,
typename IterateFunc>
630 template<
typename IterateFunc>
658 template<
typename IterateFunc>
687 template<
typename IterateFunc>
727
728
729
730 template<
typename IterateAllElementsFunc>
743
744
745
746
747 template<
typename PredicateFunc,
typename IterateFunc>
754
755
756
757
758 template<
typename PredicateFunc,
typename IterateFunc>
771
772
773
774
775 template<
typename IterateBoundsFunc>
782
783
784
785
786 template<
typename IterateBoundsFunc>
794
795
796
797
798 template<
typename IterateBoundsFunc>
806
807
808
817
818
819
879
880
904
905
906
913
914
915
993
994
995
996
997
998 void ApplyOffset(
const FVector& InOffset,
bool bGlobalOctree =
false)
1022 TOctree2(
const FVector& InOrigin,FVector::FReal InExtent)
1043 template<
typename Semantics>
1049 template <
typename Semantics>
1054 template <
typename Semantics>
1069template<
typename ElementType,
typename OctreeSemantics>
1393
1394
1395
1396
1403
1404
1405
1599
1600
1601
1602
1603
1672
1682 typename TTypeTraits<ElementType>::ConstInitType Element,
1683 const FNode& InNode,
1767 TEXT(
"Failed to find an octree node for an element with bounds (%f,%f,%f) +/- (%f,%f,%f)!"),
1780 template<
typename Semantics>
1782 ->
decltype(Semantics::SetElementId(OctreeInstance, Element, Id));
1786 template <
typename Semantics>
1791 template <
typename Semantics>
1805template<
typename ElementType,
typename OctreeSemantics>
1809 TOctree(
const FVector& InOrigin, FVector::FReal InExtent) : TOctree_DEPRECATED<ElementType, OctreeSemantics>(InOrigin, InExtent)
1813 TOctree() : TOctree_DEPRECATED<ElementType, OctreeSemantics>()
1818#include "Math/GenericOctree.inl"
#define UE_DEPRECATED(Version, Message)
#define FOREACH_OCTREE_CHILD_NODE(ChildRef)
#define VectorIntCompareEQ(A, B)
#define VectorIntAnd(A, B)
#define VectorIntLoad1(Ptr)
FORCEINLINE VectorRegister4Float MakeVectorRegister(uint32 X, uint32 Y, uint32 Z, uint32 W)
FORCEINLINE VectorRegister4Float MakeVectorRegister(float X, float Y, float Z, float W)
FORCEINLINE void Advance()
FOctreeChildNodeRef(int8 InX, int8 InY, int8 InZ)
FORCEINLINE bool IsNULL() const
FOctreeChildNodeRef(int8 InIndex=0)
FORCEINLINE void SetNULL()
FORCEINLINE int32 Z() const
FORCEINLINE int32 X() const
FORCEINLINE int32 Y() const
FOctreeChildNodeSubset(FOctreeChildNodeRef ChildRef)
bool Contains(FOctreeChildNodeRef ChildRef) const
FOctreeNodeContext(const FBoxCenterAndExtent &InBounds, uint32 InInCullBits, uint32 InOutCullBits)
FOctreeNodeContext GetChildContext(FOctreeChildNodeRef ChildRef) const
FOctreeNodeContext(uint32 InInCullBits, uint32 InOutCullBits)
FOctreeNodeContext GetChildContext(FOctreeChildNodeRef ChildRef, uint32 InInCullBits, uint32 InOutCullBits) const
FOctreeChildNodeSubset GetIntersectingChildren(const FBoxCenterAndExtent &BoundingBox) const
FOctreeNodeContext(const FBoxCenterAndExtent &InBounds)
void GetChildContext(FOctreeChildNodeRef ChildRef, FOctreeNodeContext *ChildContext) const
VectorRegister GetChildOffsetVec(int i) const
FBoxCenterAndExtent Bounds
FOctreeChildNodeRef GetContainingChild(const FBoxCenterAndExtent &BoundingBox) const
void Push(FNodeIndex NodeIndex)
FBoxCenterAndExtent GetRootBounds() const
TArray< FNodeIndex > FreeList
void FindNearbyElements(const FVector &Position, const IterateBoundsFunc &Func) const
void FindElementsWithBoundsTest(const FBoxCenterAndExtent &BoxBounds, const IterateBoundsFunc &Func) const
void SetElementId(const ElementType &Element, FOctreeElementId2 Id)
TOctree2(const FVector &InOrigin, FVector::FReal InExtent)
void CollapseNodesInternal(FNodeIndex CurrentNodeIndex, ElementArrayType &CollapsedNodeElements)
void FindNearbyElementsInternal(FNodeIndex CurrentNodeIndex, const FOctreeNodeContext &NodeContext, const FBoxCenterAndExtent &BoxBounds, const IterateFunc &Func) const
ElementType & GetElementById(FOctreeElementId2 ElementId)
void AddElement(typename TCallTraits< ElementType >::ConstReference Element)
void RemoveElement(FOctreeElementId2 ElementId)
bool IsValidElementId(FOctreeElementId2 ElementId) const
void AddElementInternal(FNodeIndex CurrentNodeIndex, const FOctreeNodeContext &NodeContext, const FBoxCenterAndExtent &ElementBounds, typename TCallTraits< ElementType >::ConstReference Element, ElementArrayType &TempElementStorage)
const ElementType & GetElementById(FOctreeElementId2 ElementId) const
void FindAllElements(const IterateAllElementsFunc &Func) const
FNodeIndex AllocateEightNodes()
SIZE_T GetSizeBytes() const
FReal GetNodeLevelExtent(int32 Level) const
void FindFirstElementWithBoundsTestInternal(FNodeIndex CurrentNodeIndex, const FOctreeNodeContext &NodeContext, const FBoxCenterAndExtent &BoxBounds, const IterateFunc &Func, bool &ContinueTraversal) const
void FreeEightNodes(FNodeIndex Index)
TArray< FNode > TreeNodes
FOctreeNodeContext RootNodeContext
TArray< ElementArrayType, TAlignedHeapAllocator< alignof(ElementArrayType)> > TreeElements
void FindElementsWithPredicate(const PredicateFunc &Predicate, const IterateFunc &Func) const
int32 GetNumNodes() const
void FindNodesWithPredicate(const PredicateFunc &Predicate, const IterateFunc &Func) const
void FindNodesWithPredicateInternal(FNodeIndex ParentNodeIndex, FNodeIndex CurrentNodeIndex, const FOctreeNodeContext &NodeContext, const PredicateFunc &Predicate, const IterateFunc &Func) const
FVector::FReal MinLeafExtent
void FindElementsWithBoundsTestInternal(FNodeIndex CurrentNodeIndex, const FOctreeNodeContext &NodeContext, const FBoxCenterAndExtent &BoxBounds, const IterateFunc &Func) const
void FindFirstElementWithBoundsTest(const FBoxCenterAndExtent &BoxBounds, const IterateBoundsFunc &Func) const
TEnableIf<!TModels< COctreeSemanticsV2, Semantics >::Value >::Type SetOctreeSemanticsElementId(const ElementType &Element, FOctreeElementId2 Id)
void ApplyOffset(const FVector &InOffset, bool bGlobalOctree=false)
TArray< FNodeIndex > ParentLinks
TArrayView< const ElementType > GetElementsForNode(FNodeIndex NodeIndex) const
ElementArrayType Elements
uint32 InclusiveNumElements
FORCEINLINE const ElementArrayType & GetElements() const
FNode(const FNode *InParent)
FORCEINLINE int32 GetInclusiveElementCount() const
FORCEINLINE bool IsLeaf() const
FORCEINLINE int32 GetElementCount() const
FORCEINLINE ElementConstIt GetElementIt() const
FORCEINLINE bool HasChild(FOctreeChildNodeRef ChildRef) const
void ApplyOffset(const FVector &InOffset)
FORCEINLINE FNode * GetChild(FOctreeChildNodeRef ChildRef) const
FNodeReference(const FNode *InNode, const FOctreeNodeContext &InContext)
FOctreeNodeContext Context
void AdvanceToNextIntersectingElement()
const ElementType & GetCurrentElement() const
bool HasPendingElements() const
TConstElementBoxIterator(const TOctree_DEPRECATED &Tree, const FBoxCenterAndExtent &InBoundingBox)
TConstIterator< StackAllocator > NodeIt
FBoxCenterAndExtent IteratorBounds
TArray< FNodeReference, StackAllocator > NodeStack
const FOctreeNodeContext & GetCurrentContext() const
TConstIterator(const TOctree_DEPRECATED &Tree)
TConstIterator(const FNode &Node, const FOctreeNodeContext &Context)
FNodeReference CurrentNode
void PushChild(FOctreeChildNodeRef ChildRef)
void PushChild(FOctreeChildNodeRef ChildRef, const FOctreeNodeContext &Context)
const FNode & GetCurrentNode() const
bool HasPendingNodes() const
void PushChild(FOctreeChildNodeRef ChildRef, uint32 FullyInsideView, uint32 FullyOutsideView)
TOctree_DEPRECATED(const FVector &InOrigin, FReal InExtent)
ElementType & GetElementById(FOctreeElementId ElementId)
FReal GetNodeLevelExtent(int32 Level) const
void SetOctreeMemoryUsage(TOctree_DEPRECATED< ElementType, OctreeSemantics > *Octree, int32 NewSize)
SIZE_T GetSizeBytes() const
FBoxCenterAndExtent GetRootBounds() const
const ElementType & GetElementById(FOctreeElementId ElementId) const
void RemoveElement(FOctreeElementId ElementId)
void ApplyOffset(const FVector &InOffset, bool bGlobalOctree)
bool IsValidElementId(FOctreeElementId ElementId) const
ElementArrayType::TConstIterator ElementConstIt
TArray< ElementType, typename OctreeSemantics::ElementAllocator > ElementArrayType
void SetElementId(const ElementType &Element, FOctreeElementId Id)
void AddElementToNode(typename TTypeTraits< ElementType >::ConstInitType Element, const FNode &InNode, const FOctreeNodeContext &InContext)
TEnableIf<!TModels< COctreeSemanticsV2, Semantics >::Value >::Type SetOctreeSemanticsElementId(const ElementType &Element, FOctreeElementId Id)
TInlineAllocator< 7 *(14 - 1)+8 > DefaultStackAllocator
FOctreeNodeContext RootNodeContext
void AddElement(typename TTypeTraits< ElementType >::ConstInitType Element)
auto Requires(typename Semantics::FOctree &OctreeInstance, const ElementType &Element, FOctreeElementId2 Id) -> decltype(Semantics::SetElementId(OctreeInstance, Element, Id))
uint32 InclusiveNumElements
auto Requires(typename Semantics::FOctree &OctreeInstance, const ElementType &Element, FOctreeElementId Id) -> decltype(Semantics::SetElementId(OctreeInstance, Element, Id))