Hi Adam, happy new year to you, too!
Since it works now, for some reason, I am pretty happy with what I have. However, since it might interest other plugin developers, I'll share more code. Maybe you have some tipps about improvements or potentially dangerous stuff, too.
The idea is that the shader has a LINK
field where the user can link an object (which is also part of my plugin). The object can (but doesn't have to) provide a list of "custom outputs" that will be added to the shader's CYCLE
. In the screenshot below it's the "Difference Map".
When a rendering is started, the shader will request the according data from the linked object during InitRender()
. But that's not part of this thread
The shader's GetDDescription()
:
Bool TerrainOperatorShader::GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags)
{
iferr_scope_handler
{
GePrint(err.GetMessage());
return false;
};
if (!description->LoadDescription(node->GetType()))
return false;
flags |= DESCFLAGS_DESC::LOADED;
BaseDocument* doc = node->GetDocument();
const BaseContainer& dataRef = static_cast<BaseShader*>(node)->GetDataInstanceRef();
// Hide or show attributes, depending on shader mode
const Bool slopeMode = dataRef.GetInt32(XTERRAINOPERATORSHADER_DATA) == XTERRAINOPERATORSHADER_DATA_SLOPE;
TF4D::GUI::ShowDescription(node, description, XTERRAINOPERATORSHADER_SLOPE_DIRECTION_ENABLE, slopeMode);
TF4D::GUI::ShowDescription(node, description, XTERRAINOPERATORSHADER_SLOPE_DIRECTION, slopeMode);
// Get linked object
BaseObject *linkedObject = dataRef.GetObjectLink(XTERRAINOPERATORSHADER_OPERATORLINK, doc);
if (linkedObject)
{
// Get linked object's NodeData
TF4D::BaseTerrainOperatorData* linkedOperator = linkedObject->GetNodeData<TF4D::BaseTerrainOperatorData>();
// Get list of custom outputs (these are the elements to add to the CYCLE)
maxon::BaseArray<TF4D::GUI::CycleElementData> customOutputs;
if (linkedOperator->GetCustomOperatorOutputs(customOutputs))
{
if (!TF4D::GUI::AddCycleElements(node, description, XTERRAINOPERATORSHADER_DATA, customOutputs, true))
iferr_throw(maxon::UnexpectedError(MAXON_SOURCE_LOCATION, "Could not add LONG CYCLE elements!"_s));
}
}
return SUPER::GetDDescription(node, description, flags);
}
The linked object's NodeData
's GetCustomOperatorOutputs()
:
Bool ErosionOperator::GetCustomOperatorOutputs(maxon::BaseArray<TF4D::GUI::CycleElementData>& customOperatorOutputs) const
{
iferr_scope_handler
{
GePrint(err.GetMessage());
return false;
};
customOperatorOutputs.Reset();
// GetCustomOutputName() simply returns a maxon::String
customOperatorOutputs.Append(TF4D::GUI::CycleElementData(TF4D_CUSTOMOUTPUT_EROSION_DIFFERENCE, GetCustomOutputName(TF4D_CUSTOMOUTPUT_EROSION_DIFFERENCE))) iferr_return;
return true;
}
Cheers,
Frank
Ah, damn. Now I've spoiled that I'm working on erosion for Terraform4D