There are not a lot of ressources for now on the topic. Here I’ll give an overview of what makes a PCG node and I will go deeper in posts about each specific part
It have two part, for both edit time features and runtime features. PCGSettings is used to define the exposed part of your node, from the inputs outputs definitions to the settings.
Settings contains Node centric runtime informations:
Settings handles the visual part of the node in the graph for edition:
This is the interface that you have to implement for the element part of the node. Where the execution logic lies.
It also allows to set a few flags about the execution context:
The execution code is done in the ExecuteInternal
It handles the Input and Output data of your node and keeps track of the execution phase of the node and it’s dependencies
It contains the parameters overrides (when you link a node entry for a specific node setting)
You can create a derived class from PCGContext if you need to handle thigs like Asynchronous loading, temporary storing of data, following substeps,…
There is ONE PCGContext by element, all communication between contexts is done through the Output/Input data and overrides that are in the FPCGDataCollection
You can get all the content of the input data through the InputData PCGDataCollection.
It can contain a few different type of data:
One important thing to know id the Input data is not to be changed. Any change is done on the copy of the data or any new data that we would affect to OutData.
Can be either the source PCGSetting content : Data set at edit time that is node specific
Or the data set at runtime from the graph execution of previous nodes and that overrides the content of PCGSettings
//Get input settings of the PCGAddTag Node as example
const UPCGAddTagSettings* Settings = Context->GetInputSettings<UPCGAddTagSettings>();
Contains non spatialized data (one value by attribute) data
TArray<FPCGTaggedData> Sources = Context->InputData.GetAllParams();
for (const FPCGTaggedData& Source : Sources)
{
const UPCGParamData* SourceData = Cast<const UPCGParamData>(Source.Data);
//Do whatever you want to do whith the ParamData
}
Spatial Data in the form of a metadata where attributes are set and a point array with each point base informations (properties). Attributes can be custom defined and changed along the life of the data through the graph.
const TArray<FPCGTaggedData> Inputs = Context->InputData.GetAllSpatialInputs();
You can get the PointData that are available in your Input. Depending on your needs and node input you can have more than one PointData
const UPCGData* InputData = Inputs[0].Data;
In a UPCGData that contains points for our example we can iterate on those points to do any process that we need.
const UPCGPointData* InputPointData = Cast<UPCGPointData>(InputData);
//Don't forget the usual null and validity checks
const TArray<FPCGPoint>& Points = InputPointData ->GetPoints();
Thoses FPCGPoint does’nt contains your attributes but only points porperties. If you need thoses they are in the Metadata of your UPCGData !
Metadata lives in the UPCGData alongside the other informations like the points if you are using a Spatial data
Any attribute you add to your dataset is store in the Metadata
Attributes are linked to the data of your Points or other data trhough EntryKey You can’t just ask the attribute of point “I” by asking for the attribute of Key “I”, you need to get the Key from your point “I” to get access to the corresponding attribute value.
To carry on Metadata from the inputs of your nodes to the outputs you need to Initialise your output Metadata using the Input Metadata
You can merge the Metadata from different Input to get an output that will give you access to both.
It is possible to manipulate directly the Metadata or to use accessors thought the PCGAttributeAccessorHelpers.
What do you think?