Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Nebukam committed Oct 18, 2024
1 parent 3bcbf32 commit 89b8384
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ void FPCGExPrimitiveComponentDescriptor::InitFrom(const UPrimitiveComponent* Com
LDMaxDrawDistance = SourceComponent->LDMaxDrawDistance;
CachedMaxDrawDistance = SourceComponent->CachedMaxDrawDistance;
IndirectLightingCacheQuality = SourceComponent->IndirectLightingCacheQuality;
#if PCGEX_ENGINE_VERSION < 505
LightmapType = SourceComponent->LightmapType;
#else
LightmapType = SourceComponent->GetLightmapType();
#endif
HLODBatchingPolicy = SourceComponent->HLODBatchingPolicy;
bEnableAutoLODGeneration = SourceComponent->bEnableAutoLODGeneration;
bNeverDistanceCull = SourceComponent->bNeverDistanceCull;
Expand Down Expand Up @@ -98,7 +102,11 @@ void FPCGExPrimitiveComponentDescriptor::InitComponent(UPrimitiveComponent* InCo
TargetComponent->LDMaxDrawDistance = LDMaxDrawDistance;
TargetComponent->CachedMaxDrawDistance = CachedMaxDrawDistance;
TargetComponent->IndirectLightingCacheQuality = IndirectLightingCacheQuality;
#if PCGEX_ENGINE_VERSION < 505
TargetComponent->LightmapType = LightmapType;
#else
TargetComponent->SetLightmapType(LightmapType);
#endif
TargetComponent->HLODBatchingPolicy = HLODBatchingPolicy;
TargetComponent->bEnableAutoLODGeneration = bEnableAutoLODGeneration;
TargetComponent->bNeverDistanceCull = bNeverDistanceCull;
Expand Down
80 changes: 49 additions & 31 deletions Source/PCGExtendedToolkit/Private/Graph/PCGExBuildCustomGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,32 @@
#define LOCTEXT_NAMESPACE "PCGExBuildCustomGraphElement"
#define PCGEX_NAMESPACE BuildCustomGraph

void UPCGExCustomGraphBuilder::InitializeWithContext_Implementation(const FPCGContext& InContext)
void UPCGExCustomGraphBuilder::InitializeWithContext_Implementation(const FPCGContext& InContext, bool& OutSuccess)
{
OutSuccess = false;
}

void UPCGExCustomGraphBuilder::BuildGraph_Implementation(const FPCGContext& InContext, const int32 InGraphIndex)
void UPCGExCustomGraphSettings::AddEdge(const int32 InStartIndex, const int32 InEndIndex)
{
if (InStartIndex < 0 || InEndIndex < 0 || InStartIndex > MaxIndex || InEndIndex > MaxIndex) { return; }
UniqueEdges.Add(PCGEx::H64U(InStartIndex, InEndIndex));
}

void UPCGExCustomGraphBuilder::AddEdge(int32 InGraphIndex, int32 InStartIndex, int32 InEndIndex)
UPCGExCustomGraphSettings* UPCGExCustomGraphBuilder::CreateGraphSettings(TSubclassOf<UPCGExCustomGraphSettings> SettingsClass, int32 InMaxNumNodes)
{
const int32 MaxIndex = GraphSettings[InGraphIndex].MaxNumNodes - 1;
if (InStartIndex < 0 || InEndIndex < 0 || InStartIndex > MaxIndex || InEndIndex > MaxIndex) { return; }
TObjectPtr<UPCGExCustomGraphSettings> NewSettings = Context->ManagedObjects->New<UPCGExCustomGraphSettings>(GetTransientPackage(), SettingsClass);
NewSettings->Index = GraphSettings.Add(NewSettings);
NewSettings->MaxNumNodes = InMaxNumNodes;
NewSettings->MaxIndex = InMaxNumNodes - 1; // Might need to update prior to processing
return NewSettings;
}

GraphSettings[InGraphIndex].UniqueEdges.Add(PCGEx::H64U(InStartIndex, InEndIndex));
void UPCGExCustomGraphBuilder::BuildGraph_Implementation(const FPCGContext& InContext, UPCGExCustomGraphSettings* InCustomGraphSettings, bool& OutSuccess)
{
OutSuccess = false;
}

void UPCGExCustomGraphBuilder::UpdateNodePoint_Implementation(const int32 InGraphIndex, const int32 InNodeIndex, const FPCGPoint& InPoint, FPCGPoint& OutPoint)
void UPCGExCustomGraphBuilder::UpdateNodePoint_Implementation(const UPCGExCustomGraphSettings* InCustomGraphSettings, const int32 InNodeIndex, const FPCGPoint& InPoint, FPCGPoint& OutPoint)
{
OutPoint = InPoint;
}
Expand Down Expand Up @@ -104,7 +113,14 @@ bool FPCGExBuildCustomGraphElement::ExecuteInternal(FPCGContext* InContext) cons
}

// Init builder now that we have resolved actor references.
Context->Builder->InitializeWithContext(*Context);

bool bSuccessfulInit = false;
Context->Builder->InitializeWithContext(*Context, bSuccessfulInit);
if (!bSuccessfulInit)
{
PCGE_LOG(Error, GraphAndLog, FTEXT("Builder returned failed initialization."));
return true;
}

// Prepare graph builders
if (Context->Builder->GraphSettings.IsEmpty())
Expand All @@ -115,42 +131,39 @@ bool FPCGExBuildCustomGraphElement::ExecuteInternal(FPCGContext* InContext) cons

Context->SetAsyncState(PCGExGraph::State_WritingClusters);

const int32 NumGraphs = Context->Builder->GraphSettings.Num();

Context->GraphBuilders = MakeShared<TArray<TSharedPtr<PCGExGraph::FGraphBuilder>>>();
Context->GraphBuilders->Init(nullptr, NumGraphs);

for (int i = 0; i < NumGraphs; i++)
for (UPCGExCustomGraphSettings* GraphSettings : Context->Builder->GraphSettings)
{
if (Context->Builder->GraphSettings[i].MaxNumNodes < 2)
if (GraphSettings->MaxNumNodes < 2)
{
if (!Settings->bMuteUnprocessedSettingsWarning)
{
PCGE_LOG(Warning, GraphAndLog, FTEXT("A graph builder settings has less than 2 max nodes and won't be processed."));
}
continue;
}

TSharedPtr<PCGExData::FPointIO> NodeIO = Context->MainPoints->Emplace_GetRef();
NodeIO->IOIndex = i;
Context->GetAsyncManager()->Start<PCGExBuildCustomGraph::FBuildGraph>(i, NodeIO);
NodeIO->IOIndex = GraphSettings->Index;
GraphSettings->MaxIndex = GraphSettings->MaxNumNodes - 1;
Context->GetAsyncManager()->Start<PCGExBuildCustomGraph::FBuildGraph>(GraphSettings->Index, NodeIO, GraphSettings);
}

return false;
}

PCGEX_ON_ASYNC_STATE_READY(PCGExGraph::State_WritingClusters)
{
for (const TSharedPtr<PCGExGraph::FGraphBuilder> GraphBuilder : *Context->GraphBuilders)
for (UPCGExCustomGraphSettings* GraphSettings : Context->Builder->GraphSettings)
{
if (!GraphBuilder) { continue; }
if (GraphBuilder->bCompiledSuccessfully)
if (!GraphSettings->GraphBuilder) { continue; }
if (GraphSettings->GraphBuilder->bCompiledSuccessfully)
{
GraphBuilder->StageEdgesOutputs();
GraphSettings->GraphBuilder->StageEdgesOutputs();
}
else
{
// Invalidate node IO
GraphBuilder->NodeDataFacade->Source->InitializeOutput(Context, PCGExData::EInit::NoOutput);
GraphSettings->GraphBuilder->NodeDataFacade->Source->InitializeOutput(Context, PCGExData::EInit::NoOutput);
}
}

Expand All @@ -168,19 +181,23 @@ namespace PCGExBuildCustomGraph
FPCGExBuildCustomGraphContext* Context = AsyncManager->GetContext<FPCGExBuildCustomGraphContext>();
PCGEX_SETTINGS(BuildCustomGraph)

const int32 GraphIndex = PointIO->IOIndex;
UPCGExCustomGraphBuilder* Builder = Context->Builder;

const FPCGExCustomGraphSettings& GraphSettings = Context->Builder->GraphSettings[GraphIndex];
PointIO->GetOut()->GetMutablePoints().SetNum(GraphSettings.MaxNumNodes);
PointIO->GetOut()->GetMutablePoints().SetNum(GraphSettings->MaxNumNodes);

TSharedPtr<PCGExData::FFacade> NodeDataFacade = MakeShared<PCGExData::FFacade>(PointIO.ToSharedRef());
const TSharedPtr<PCGExGraph::FGraphBuilder> GraphBuilder = MakeShared<PCGExGraph::FGraphBuilder>(NodeDataFacade.ToSharedRef(), &Settings->GraphBuilderDetails);
GraphSettings->GraphBuilder = GraphBuilder;

(*Context->GraphBuilders)[GraphIndex] = GraphBuilder;
bool bSuccessfulBuild = false;
Builder->BuildGraph(*Context, GraphSettings, bSuccessfulBuild);
if (!bSuccessfulBuild)
{
GraphSettings->GraphBuilder->bCompiledSuccessfully = false;
return false;
}

Builder->BuildGraph(*Context, GraphIndex);
GraphBuilder->Graph->InsertEdges(GraphSettings.UniqueEdges, -1);
GraphBuilder->Graph->InsertEdges(GraphSettings->UniqueEdges, -1);

PCGEX_ASYNC_GROUP_CHKD(AsyncManager, InitNodesGroup)

Expand All @@ -195,7 +212,8 @@ namespace PCGExBuildCustomGraph
GBuilder->CompileAsync(AsyncManager, true);
};

InitNodesGroup->OnIterationRangeStartCallback = [WeakIO, Builder](const int32 StartIndex, const int32 Count, const int32 LoopIdx)
UPCGExCustomGraphSettings* CustomGraphSettings = GraphSettings;
InitNodesGroup->OnIterationRangeStartCallback = [WeakIO, Builder, CustomGraphSettings](const int32 StartIndex, const int32 Count, const int32 LoopIdx)
{
const TSharedPtr<PCGExData::FPointIO> IO = WeakIO.Pin();
if (!IO) { return; }
Expand All @@ -205,11 +223,11 @@ namespace PCGExBuildCustomGraph
for (int i = StartIndex; i < MaxIndex; i++)
{
FPCGPoint& Point = MutablePoints[i];
Builder->UpdateNodePoint(IO->IOIndex, i, Point, Point);
Builder->UpdateNodePoint(CustomGraphSettings, i, Point, Point);
}
};

InitNodesGroup->StartRangePrepareOnly(GraphSettings.MaxNumNodes, 256);
InitNodesGroup->StartRangePrepareOnly(GraphSettings->MaxNumNodes, 256);

return true;
}
Expand Down
86 changes: 52 additions & 34 deletions Source/PCGExtendedToolkit/Public/Graph/PCGExBuildCustomGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,34 @@ enum class EPCGExCustomGraphActorSourceMode : uint8
ActorReferences = 1 UMETA(DisplayName = "Actor References", ToolTip="Point data with an actor reference property."),
};

USTRUCT(BlueprintType)
struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExCustomGraphSettings
/**
*
*/
UCLASS(Blueprintable, BlueprintType, DisplayName = "[PCGEx] Custom Graph Settings")
class PCGEXTENDEDTOOLKIT_API UPCGExCustomGraphSettings : public UObject
{
GENERATED_BODY()

FPCGExCustomGraphSettings()
{
}

public:
/** Maximum number of node in the graph. The final number can be less, as isolated points will be pruned; but no edge endpoint' index should be greater that this number. */
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable))
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "PCGEx|Settings", meta = (ExposeOnSpawn = "true"))
int32 MaxNumNodes = 0;


/** Internal index of these settings. */
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "PCGEx|Settings")
int32 Index = 0;

TSet<uint64> UniqueEdges;
int32 MaxIndex = -1;
TSharedPtr<PCGExGraph::FGraphBuilder> GraphBuilder;

/**
* Create an edge between two nodes in an indexed graph.
* @param InStartIndex
* @param InEndIndex
*/
UFUNCTION(BlueprintCallable, Category = "PCGEx|Data")
void AddEdge(const int32 InStartIndex, const int32 InEndIndex);
};

/**
Expand All @@ -43,53 +57,56 @@ class /*PCGEXTENDEDTOOLKIT_API*/ UPCGExCustomGraphBuilder : public UPCGExOperati
public:
/**
* Main initialization function. Called once, and is responsible for populating graph builder settings.
* At least one setting is expected to be found in the GraphSettings array.
* At least one setting is expected to be found in the GraphSettings array. This is executed on the main thread.
* @param InContext - Context of the initialization
* @param OutSuccess
*/
UFUNCTION(BlueprintNativeEvent, Category = "PCGEx|Execution")
void InitializeWithContext(const FPCGContext& InContext);
void InitializeWithContext(const FPCGContext& InContext, bool& OutSuccess);

/**
* Main execution function. Called once per requested graphs.
* @param InContext - Context of the execution
* @param InGraphIndex
* Create an edge between two nodes in an indexed graph. This method is executed in a multi-threaded context
* @param SettingsClass
* @param InMaxNumNodes
*/
UFUNCTION(BlueprintNativeEvent, Category = "PCGEx|Execution")
void BuildGraph(const FPCGContext& InContext, const int32 InGraphIndex);
UFUNCTION(BlueprintCallable, Category = "PCGEx|Execution")
UPCGExCustomGraphSettings* CreateGraphSettings(TSubclassOf<UPCGExCustomGraphSettings> SettingsClass, int32 InMaxNumNodes);

/**
* Create an edge between two nodes in an indexed graph.
* @param InGraphIndex
* @param InStartIndex
* @param InEndIndex
* Main execution function. Called once per requested graphs. This method is executed in a multi-threaded context, Graph Settings are safe but the custom builder wrapper itself isn't.
* @param InContext - Context of the execution
* @param InCustomGraphSettings
* @param OutSuccess
*/
UFUNCTION(BlueprintCallable, Category = "PCGEx|Execution")
void AddEdge(int32 InGraphIndex, int32 InStartIndex, int32 InEndIndex);
UFUNCTION(BlueprintNativeEvent, Category = "PCGEx|Execution")
void BuildGraph(const FPCGContext& InContext, UPCGExCustomGraphSettings* InCustomGraphSettings, bool& OutSuccess);

/**
* Update Node Point is called on each node point after BuildGraph has been called. This method is executed asynchronously, and in parallel.
* Update Node Point is called on each node point after BuildGraph has been, and edges added. This method is executed in a multi-threaded context.
* This is where point transform & properties should be set.
* @param InGraphIndex
* @param InCustomGraphSettings
* @param InNodeIndex
* @param InPoint
* @param OutPoint
*/
UFUNCTION(BlueprintNativeEvent, Category = "PCGEx|Execution")
void UpdateNodePoint(const int32 InGraphIndex, const int32 InNodeIndex, const FPCGPoint& InPoint, FPCGPoint& OutPoint);
void UpdateNodePoint(const UPCGExCustomGraphSettings* InCustomGraphSettings, const int32 InNodeIndex, const FPCGPoint& InPoint, FPCGPoint& OutPoint);

virtual void Cleanup() override
{
InputActors.Empty();

for (UPCGExCustomGraphSettings* GSettings : GraphSettings) { GSettings->GraphBuilder.Reset(); }

GraphSettings.Empty();
Super::Cleanup();
}

UPROPERTY(BlueprintReadOnly, Category = "PCGEx|Inputs")
TArray<TObjectPtr<AActor>> InputActors;

UPROPERTY(BlueprintReadWrite, Category = "PCGEx|Outputs")
TArray<FPCGExCustomGraphSettings> GraphSettings;


UPROPERTY(BlueprintReadOnly, Category = "PCGEx|Outputs")
TArray<TObjectPtr<UPCGExCustomGraphSettings>> GraphSettings;
};

/**
Expand Down Expand Up @@ -120,12 +137,12 @@ class /*PCGEXTENDEDTOOLKIT_API*/ UPCGExBuildCustomGraphSettings : public UPCGExP
//~End UPCGExPointsProcessorSettings

/** Actor fetching mode. These actors will be forwarded to the builder so it can fetch components and data from there during its initialization. */
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, InlineEditConditionToggle))
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable))
EPCGExCustomGraphActorSourceMode Mode = EPCGExCustomGraphActorSourceMode::Owner;

/** Actor reference */
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="Mode==EPCGExCustomGraphActorSourceMode::ActorReferences", EditConditionHides))
FName ActorReferenceAttribute;
FName ActorReferenceAttribute = FName(TEXT("ActorReference"));

/** Builder instance. */
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = Settings, Instanced, meta = (PCG_Overridable, NoResetToDefault, ShowOnlyInnerProperties))
Expand All @@ -134,7 +151,7 @@ class /*PCGEXTENDEDTOOLKIT_API*/ UPCGExBuildCustomGraphSettings : public UPCGExP
/** Graph & Edges output properties */
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings)
bool bMuteUnprocessedSettingsWarning = false;

/** Graph & Edges output properties */
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, DisplayName="Cluster Output Settings"))
FPCGExGraphBuilderDetails GraphBuilderDetails;
Expand All @@ -144,7 +161,6 @@ struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExBuildCustomGraphContext final : FPCGExPo
{
friend class FPCGExBuildCustomGraphElement;
UPCGExCustomGraphBuilder* Builder = nullptr;
TSharedPtr<TArray<TSharedPtr<PCGExGraph::FGraphBuilder>>> GraphBuilders;
};

class /*PCGEXTENDEDTOOLKIT_API*/ FPCGExBuildCustomGraphElement final : public FPCGExPointsProcessorElement
Expand All @@ -165,11 +181,13 @@ namespace PCGExBuildCustomGraph
class /*PCGEXTENDEDTOOLKIT_API*/ FBuildGraph final : public PCGExMT::FPCGExTask
{
public:
FBuildGraph(const TSharedPtr<PCGExData::FPointIO>& InPointIO) :
FPCGExTask(InPointIO)
FBuildGraph(const TSharedPtr<PCGExData::FPointIO>& InPointIO,
UPCGExCustomGraphSettings* InGraphSettings) :
FPCGExTask(InPointIO), GraphSettings(InGraphSettings)
{
}

UPCGExCustomGraphSettings* GraphSettings = nullptr;
virtual bool ExecuteTask(const TSharedPtr<PCGExMT::FTaskManager>& AsyncManager) override;
};
}

0 comments on commit 89b8384

Please sign in to comment.