UEdGraphNode* FMaterialGraphSchemaAction_NewFunctionCall::PerformAction(class UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, bool bSelectNewNode/* = true*/)
{
	const FScopedTransaction Transaction(NSLOCTEXT("UnrealEd", "MaterialEditorNewFunctionCall", "Material Editor: New Function Call"));

	UMaterialExpressionMaterialFunctionCall* FunctionNode = CastChecked<UMaterialExpressionMaterialFunctionCall>(
																FMaterialEditorUtilities::CreateNewMaterialExpression(
																	ParentGraph, UMaterialExpressionMaterialFunctionCall::StaticClass(), Location, bSelectNewNode, /*bAutoAssignResource*/false));

	if (!FunctionNode->MaterialFunction)
	{
		UMaterialFunction* MaterialFunction = LoadObject<UMaterialFunction>(NULL, *FunctionPath, NULL, 0, NULL);
		UMaterialGraph* MaterialGraph = CastChecked<UMaterialGraph>(ParentGraph);
		if(FunctionNode->SetMaterialFunction(MaterialGraph->MaterialFunction, NULL, MaterialFunction))
		{
			FMaterialEditorUtilities::UpdateSearchResults(ParentGraph);
			FunctionNode->GraphNode->AutowireNewNode(FromPin);
			return FunctionNode->GraphNode;
		}
		else
		{
			FMaterialEditorUtilities::AddToSelection(ParentGraph, FunctionNode);
			FMaterialEditorUtilities::DeleteSelectedNodes(ParentGraph);
		}
	}

	return NULL;
}
void T3DMaterialParser::ImportMaterialExpressionFlipBookSample(UMaterialExpressionTextureSample * Expression, FRequirement &TextureRequirement)
{
	UMaterialExpressionMaterialFunctionCall * MEFunction = ConstructObject<UMaterialExpressionMaterialFunctionCall>(UMaterialExpressionMaterialFunctionCall::StaticClass(), Material);
	UMaterialExpressionConstant * MECRows = ConstructObject<UMaterialExpressionConstant>(UMaterialExpressionConstant::StaticClass(), Material);
	UMaterialExpressionConstant * MECCols = ConstructObject<UMaterialExpressionConstant>(UMaterialExpressionConstant::StaticClass(), Material);
	MEFunction->MaterialExpressionEditorY = Expression->MaterialExpressionEditorY;
	MECRows->MaterialExpressionEditorY = MEFunction->MaterialExpressionEditorY;
	MECCols->MaterialExpressionEditorY = MECRows->MaterialExpressionEditorY + 64;

	MEFunction->MaterialExpressionEditorX = Expression->MaterialExpressionEditorX - 304;
	MECRows->MaterialExpressionEditorX = MEFunction->MaterialExpressionEditorX - 80;
	MECCols->MaterialExpressionEditorX = MECRows->MaterialExpressionEditorX;

	MECRows->bCollapsed = true;
	MECCols->bCollapsed = true;

	MEFunction->SetMaterialFunction(NULL, NULL, LoadObject<UMaterialFunction>(NULL, TEXT("/Engine/Functions/Engine_MaterialFunctions02/Texturing/FlipBook.FlipBook")));

	MEFunction->FunctionInputs[1].Input.Expression = MECRows;
	MEFunction->FunctionInputs[2].Input.Expression = MECCols;

	if (Expression->Coordinates.Expression)
	{
		MEFunction->FunctionInputs[4].Input.Expression = Expression->Coordinates.Expression;
	}

	FString ExportFolder;
	FString FileName = TextureRequirement.Name + TEXT(".T3D");
	LevelParser->ExportPackage(TextureRequirement.Package, T3DLevelParser::EExportType::Texture2DInfo, ExportFolder);
	if (FFileHelper::LoadFileToString(Line, *(ExportFolder / FileName)))
	{
		FString Value;
		if (GetOneValueAfter(TEXT("HorizontalImages="), Value))
		{
			MECCols->R = FCString::Atof(*Value);
		}
		if (GetOneValueAfter(TEXT("VerticalImages="), Value))
		{
			MECRows->R = FCString::Atof(*Value);
		}
	}

	Expression->Coordinates.OutputIndex = 2;
	Expression->Coordinates.Expression = MEFunction;

	Material->Expressions.Add(MECRows);
	Material->Expressions.Add(MECCols);
	Material->Expressions.Add(MEFunction);
}
void UMaterialGraphSchema::DroppedAssetsOnGraph(const TArray<class FAssetData>& Assets, const FVector2D& GraphPosition, UEdGraph* Graph) const
{
	UMaterialGraph* MaterialGraph = CastChecked<UMaterialGraph>(Graph);
	const int32 LocOffsetBetweenNodes = 32;

	FVector2D ExpressionPosition = GraphPosition;

	for (int32 AssetIdx = 0; AssetIdx < Assets.Num(); ++AssetIdx)
	{
		bool bAddedNode = false;
		UObject* Asset = Assets[AssetIdx].GetAsset();
		UClass* MaterialExpressionClass = Cast<UClass>(Asset);
		UMaterialFunction* Func = Cast<UMaterialFunction>(Asset);
		UTexture* Tex = Cast<UTexture>(Asset);
		UMaterialParameterCollection* ParameterCollection = Cast<UMaterialParameterCollection>(Asset);
		
		if (MaterialExpressionClass && MaterialExpressionClass->IsChildOf(UMaterialExpression::StaticClass()))
		{
			FMaterialEditorUtilities::CreateNewMaterialExpression(Graph, MaterialExpressionClass, ExpressionPosition, true, true);
			bAddedNode = true;
		}
		else if ( Func )
		{
			UMaterialExpressionMaterialFunctionCall* FunctionNode = CastChecked<UMaterialExpressionMaterialFunctionCall>(
				FMaterialEditorUtilities::CreateNewMaterialExpression(Graph, UMaterialExpressionMaterialFunctionCall::StaticClass(), ExpressionPosition, true, false));

			if (!FunctionNode->MaterialFunction)
			{
				if(FunctionNode->SetMaterialFunction(MaterialGraph->MaterialFunction, NULL, Func))
				{
					FMaterialEditorUtilities::UpdateSearchResults(Graph);
				}
				else
				{
					FMaterialEditorUtilities::AddToSelection(Graph, FunctionNode);
					FMaterialEditorUtilities::DeleteSelectedNodes(Graph);

					continue;
				}
			}

			bAddedNode = true;
		}
		else if ( Tex )
		{
			UMaterialExpressionTextureSample* TextureSampleNode = CastChecked<UMaterialExpressionTextureSample>(
				FMaterialEditorUtilities::CreateNewMaterialExpression(Graph, UMaterialExpressionTextureSample::StaticClass(), ExpressionPosition, true, true) );
			TextureSampleNode->Texture = Tex;
			TextureSampleNode->AutoSetSampleType();

			FMaterialEditorUtilities::ForceRefreshExpressionPreviews(Graph);

			bAddedNode = true;
		}
		else if ( ParameterCollection )
		{
			UMaterialExpressionCollectionParameter* CollectionParameterNode = CastChecked<UMaterialExpressionCollectionParameter>(
				FMaterialEditorUtilities::CreateNewMaterialExpression(Graph, UMaterialExpressionCollectionParameter::StaticClass(), ExpressionPosition, true, true) );
			CollectionParameterNode->Collection = ParameterCollection;

			FMaterialEditorUtilities::ForceRefreshExpressionPreviews(Graph);

			bAddedNode = true;
		}

		if ( bAddedNode )
		{
			ExpressionPosition.X += LocOffsetBetweenNodes;
			ExpressionPosition.Y += LocOffsetBetweenNodes;
		}
	}
}