Skip to content

Commit 3f7f511

Browse files
committed
Add: async version of Build Kdtree and radius search
1 parent 396a164 commit 3f7f511

File tree

11 files changed

+528
-339
lines changed

11 files changed

+528
-339
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#include "Kismet/BlueprintAsyncActionBase.h"
2+
3+
#include "KdtreeBPLibrary.h"
4+
#include "AsyncKdtreeBPLibrary.h"
5+
#include "../Private/KdtreeInternal.h"
6+
7+
8+
struct FBuildKdtreeTaskParams
9+
{
10+
FKdtree* Tree;
11+
TArray<FVector> Data;
12+
};
13+
14+
class FBuildKdtreeTask : public FNonAbandonableTask
15+
{
16+
public:
17+
FBuildKdtreeTask(const FBuildKdtreeTaskParams& InParams) : Params(InParams)
18+
{
19+
}
20+
21+
void DoWork()
22+
{
23+
KdtreeInternal::BuildKdtree(&Params.Tree->Internal, Params.Data);
24+
}
25+
26+
FORCEINLINE TStatId GetStatId() const
27+
{
28+
RETURN_QUICK_DECLARE_CYCLE_STAT(FBuildKdtreeTask, STATGROUP_ThreadPoolAsyncTasks);
29+
}
30+
private:
31+
FBuildKdtreeTaskParams Params;
32+
};
33+
34+
35+
class FBuildKdtreeAction : public FPendingLatentAction
36+
{
37+
public:
38+
FLatentActionInfo LatentInfo;
39+
FAsyncTask<FBuildKdtreeTask>* Task;
40+
41+
FBuildKdtreeAction(const FLatentActionInfo& InLatentInfo,
42+
FKdtree* Tree, const TArray<FVector>& Data)
43+
: LatentInfo(InLatentInfo), Task(nullptr)
44+
{
45+
FBuildKdtreeTaskParams Params;
46+
Params.Tree = Tree;
47+
Params.Data = Data;
48+
Task = new FAsyncTask<FBuildKdtreeTask>(Params);
49+
Task->StartBackgroundTask();
50+
}
51+
52+
void UpdateOperation(FLatentResponse& Response) override
53+
{
54+
Response.FinishAndTriggerIf(Task->IsDone(), LatentInfo.ExecutionFunction, LatentInfo.Linkage,
55+
LatentInfo.CallbackTarget);
56+
}
57+
};
58+
59+
60+
UAsyncKdtreeBPLibrary::UAsyncKdtreeBPLibrary(const FObjectInitializer& ObjectInitializer)
61+
: Super(ObjectInitializer)
62+
{
63+
}
64+
65+
void UAsyncKdtreeBPLibrary::BuildKdtreeAsync(const UObject* WorldContextObject,
66+
FKdtree& Tree, const TArray<FVector>& Data,
67+
FLatentActionInfo LatentInfo)
68+
{
69+
if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
70+
{
71+
FLatentActionManager& LatentManager = World->GetLatentActionManager();
72+
if (LatentManager.FindExistingAction<FBuildKdtreeAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == nullptr)
73+
{
74+
FBuildKdtreeAction* NewAction = new FBuildKdtreeAction(LatentInfo, &Tree, Data);
75+
LatentManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, NewAction);
76+
}
77+
}
78+
}
79+
80+
struct FCollectFromKdtreeTaskParams
81+
{
82+
const FKdtree* Tree;
83+
FVector Center;
84+
float Radius;
85+
TArray<int>* Indices;
86+
TArray<FVector>* Data;
87+
};
88+
89+
class FCollectFromKdtreeTask : public FNonAbandonableTask
90+
{
91+
public:
92+
FCollectFromKdtreeTask(const FCollectFromKdtreeTaskParams& InParams) : Params(InParams)
93+
{
94+
}
95+
96+
void DoWork()
97+
{
98+
KdtreeInternal::CollectFromKdtree(Params.Tree->Internal, Params.Center,
99+
Params.Radius, Params.Indices);
100+
for (int Index = 0; Index < Params.Indices->Num(); ++Index)
101+
{
102+
Params.Data->Add(Params.Tree->Internal.Data[Index]);
103+
}
104+
}
105+
106+
FORCEINLINE TStatId GetStatId() const
107+
{
108+
RETURN_QUICK_DECLARE_CYCLE_STAT(FCollectFromKdtreeTask, STATGROUP_ThreadPoolAsyncTasks);
109+
}
110+
private:
111+
FCollectFromKdtreeTaskParams Params;
112+
};
113+
114+
class FCollectFromKdtreeAction : public FPendingLatentAction
115+
{
116+
public:
117+
FLatentActionInfo LatentInfo;
118+
FAsyncTask<FCollectFromKdtreeTask>* Task;
119+
120+
FCollectFromKdtreeAction(const FLatentActionInfo& InLatentInfo,
121+
const FKdtree* Tree, const FVector Center, float Radius,
122+
TArray<int>* Indices, TArray<FVector>* Data)
123+
: LatentInfo(InLatentInfo), Task(nullptr)
124+
{
125+
FCollectFromKdtreeTaskParams Params;
126+
Params.Tree = Tree;
127+
Params.Center = Center;
128+
Params.Radius = Radius;
129+
Params.Indices = Indices;
130+
Params.Data = Data;
131+
Task = new FAsyncTask<FCollectFromKdtreeTask>(Params);
132+
Task->StartBackgroundTask();
133+
}
134+
135+
void UpdateOperation(FLatentResponse& Response) override
136+
{
137+
Response.FinishAndTriggerIf(Task->IsDone(), LatentInfo.ExecutionFunction, LatentInfo.Linkage,
138+
LatentInfo.CallbackTarget);
139+
}
140+
};
141+
142+
143+
void UAsyncKdtreeBPLibrary::CollectFromKdtreeAsync(const UObject* WorldContextObject,
144+
const FKdtree& Tree, const FVector Center, float Radius,
145+
TArray<int>& Indices, TArray<FVector>& Data,
146+
FLatentActionInfo LatentInfo)
147+
{
148+
if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
149+
{
150+
FLatentActionManager& LatentManager = World->GetLatentActionManager();
151+
if (LatentManager.FindExistingAction<FCollectFromKdtreeAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == nullptr)
152+
{
153+
FCollectFromKdtreeAction* NewAction = new FCollectFromKdtreeAction(LatentInfo, &Tree, Center, Radius, &Indices, &Data);
154+
LatentManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, NewAction);
155+
}
156+
}
157+
}

0 commit comments

Comments
 (0)