bool FMaterialEditorUtilities::HasCompatibleConnection(UClass* ExpressionClass, uint32 TestType, EEdGraphPinDirection TestDirection, bool bMaterialFunction)
{
	if (TestType != 0)
	{
		UMaterialExpression* DefaultExpression = CastChecked<UMaterialExpression>(ExpressionClass->GetDefaultObject());
		if (TestDirection == EGPD_Output)
		{
			int32 NumInputs = DefaultExpression->GetInputs().Num();
			for (int32 Index = 0; Index < NumInputs; ++Index)
			{
				uint32 InputType = DefaultExpression->GetInputType(Index);
				if (CanConnectMaterialValueTypes(InputType, TestType))
				{
					return true;
				}
			}
		}
		else
		{
			int32 NumOutputs = DefaultExpression->GetOutputs().Num();
			for (int32 Index = 0; Index < NumOutputs; ++Index)
			{
				uint32 OutputType = DefaultExpression->GetOutputType(Index);
				if (CanConnectMaterialValueTypes(TestType, OutputType))
				{
					return true;
				}
			}
		}
		
		if (bMaterialFunction)
		{
			// Specific test as Default object won't have texture input
			if (ExpressionClass == UMaterialExpressionTextureSample::StaticClass() && TestType & MCT_Texture && TestDirection == EGPD_Output)
			{
				return true;
			}
			// Always allow creation of new inputs as they can take any type
			else if (ExpressionClass == UMaterialExpressionFunctionInput::StaticClass())
			{
				return true;
			}
			// Allow creation of outputs for floats and material attributes
			else if (ExpressionClass == UMaterialExpressionFunctionOutput::StaticClass() && TestType & (MCT_Float|MCT_MaterialAttributes))
			{
				return true;
			}
		}
	}

	return false;
}
Пример #2
0
bool UMaterialGraphSchema::HasCompatibleConnection(const FAssetData& FunctionAssetData, uint32 TestType, EEdGraphPinDirection TestDirection) const
{
	if (TestType != 0)
	{
		const FString* CombinedInputTagValue = FunctionAssetData.TagsAndValues.Find(GET_MEMBER_NAME_CHECKED(UMaterialFunction, CombinedInputTypes));
		const FString* CombinedOutputTagValue = FunctionAssetData.TagsAndValues.Find(GET_MEMBER_NAME_CHECKED(UMaterialFunction, CombinedOutputTypes));
		uint32 CombinedInputTypes = CombinedInputTagValue ? FCString::Atoi(**CombinedInputTagValue) : 0;
		uint32 CombinedOutputTypes = CombinedOutputTagValue ? FCString::Atoi(**CombinedOutputTagValue) : 0;

		if (CombinedOutputTypes == 0)
		{
			// Need to load function to build combined output types
			UMaterialFunction* MaterialFunction = Cast<UMaterialFunction>(FunctionAssetData.GetAsset());
			if (MaterialFunction != nullptr)
			{
				CombinedInputTypes = MaterialFunction->CombinedInputTypes;
				CombinedOutputTypes = MaterialFunction->CombinedOutputTypes;
			}
		}

		if (TestDirection == EGPD_Output)
		{
			if (CanConnectMaterialValueTypes(CombinedInputTypes, TestType))
			{
				return true;
			}
		}
		else
		{
			if (CanConnectMaterialValueTypes(TestType, CombinedOutputTypes))
			{
				return true;
			}
		}
	}

	return false;
}
bool UMaterialGraphSchema::ArePinsCompatible(const UEdGraphPin* InputPin, const UEdGraphPin* OutputPin, FText& ResponseMessage) const
{
	UMaterialGraphNode_Base* InputNode = CastChecked<UMaterialGraphNode_Base>(InputPin->GetOwningNode());
	UMaterialGraphNode* OutputNode = CastChecked<UMaterialGraphNode>(OutputPin->GetOwningNode());
	uint32 InputType = InputNode->GetInputType(InputPin);
	uint32 OutputType = OutputNode->GetOutputType(OutputPin);

	bool bPinsCompatible = CanConnectMaterialValueTypes(InputType, OutputType);
	if (!bPinsCompatible)
	{
		TArray<FText> InputDescriptions;
		TArray<FText> OutputDescriptions;
		GetMaterialValueTypeDescriptions(InputType, InputDescriptions);
		GetMaterialValueTypeDescriptions(OutputType, OutputDescriptions);

		FString CombinedInputDescription;
		FString CombinedOutputDescription;
		for (int32 Index = 0; Index < InputDescriptions.Num(); ++Index)
		{
			if ( CombinedInputDescription.Len() > 0 )
			{
				CombinedInputDescription += TEXT(", ");
			}
			CombinedInputDescription += InputDescriptions[Index].ToString();
		}
		for (int32 Index = 0; Index < OutputDescriptions.Num(); ++Index)
		{
			if ( CombinedOutputDescription.Len() > 0 )
			{
				CombinedOutputDescription += TEXT(", ");
			}
			CombinedOutputDescription += OutputDescriptions[Index].ToString();
		}

		FFormatNamedArguments Args;
		Args.Add( TEXT("InputType"), FText::FromString(CombinedInputDescription) );
		Args.Add( TEXT("OutputType"), FText::FromString(CombinedOutputDescription) );
		ResponseMessage = FText::Format( LOCTEXT("IncompatibleDesc", "{OutputType} is not compatible with {InputType}"), Args );
	}

	return bPinsCompatible;
}