You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
743 lines
27 KiB
C++
743 lines
27 KiB
C++
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "UnrealEd.h"
|
|
#include "Editor/MaterialEditor/Public/MaterialEditorModule.h"
|
|
#include "ComponentRecreateRenderStateContext.h"
|
|
#include "Materials/MaterialInstanceConstant.h"
|
|
|
|
/**
|
|
* Class for rendering the material on the preview mesh in the Material Editor
|
|
*/
|
|
class FPreviewMaterial : public FMaterialResource, public FMaterialRenderProxy
|
|
{
|
|
public:
|
|
FPreviewMaterial()
|
|
: FMaterialResource()
|
|
{
|
|
}
|
|
|
|
~FPreviewMaterial()
|
|
{
|
|
BeginReleaseResource(this);
|
|
FlushRenderingCommands();
|
|
}
|
|
|
|
/**
|
|
* Should the shader for this material with the given platform, shader type and vertex
|
|
* factory type combination be compiled
|
|
*
|
|
* @param Platform The platform currently being compiled for
|
|
* @param ShaderType Which shader is being compiled
|
|
* @param VertexFactory Which vertex factory is being compiled (can be NULL)
|
|
*
|
|
* @return true if the shader should be compiled
|
|
*/
|
|
virtual bool ShouldCache(EShaderPlatform Platform, const FShaderType* ShaderType, const FVertexFactoryType* VertexFactoryType) const
|
|
{
|
|
// only generate the needed shaders (which should be very restrictive for fast recompiling during editing)
|
|
// @todo: Add a FindShaderType by fname or something
|
|
|
|
if( Material->IsUIMaterial() )
|
|
{
|
|
if (FCString::Stristr(ShaderType->GetName(), TEXT("TSlateMaterialShaderPS")))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
{
|
|
bool bEditorStatsMaterial = Material->bIsMaterialEditorStatsMaterial;
|
|
|
|
// Always allow HitProxy shaders.
|
|
if (FCString::Stristr(ShaderType->GetName(), TEXT("HitProxy")))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// we only need local vertex factory for the preview static mesh
|
|
if (VertexFactoryType != FindVertexFactoryType(FName(TEXT("FLocalVertexFactory"), FNAME_Find)))
|
|
{
|
|
//cache for gpu skinned vertex factory if the material allows it
|
|
//this way we can have a preview skeletal mesh
|
|
if (bEditorStatsMaterial ||
|
|
!IsUsedWithSkeletalMesh() ||
|
|
(VertexFactoryType != FindVertexFactoryType(FName(TEXT("TGPUSkinVertexFactoryfalse"), FNAME_Find)) &&
|
|
VertexFactoryType != FindVertexFactoryType(FName(TEXT("TGPUSkinVertexFactorytrue"), FNAME_Find))))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (bEditorStatsMaterial)
|
|
{
|
|
TArray<FString> ShaderTypeNames;
|
|
TArray<FString> ShaderTypeDescriptions;
|
|
GetRepresentativeShaderTypesAndDescriptions(ShaderTypeNames, ShaderTypeDescriptions);
|
|
|
|
//Only allow shaders that are used in the stats.
|
|
return ShaderTypeNames.Find(ShaderType->GetName()) != INDEX_NONE;
|
|
}
|
|
|
|
// look for any of the needed type
|
|
bool bShaderTypeMatches = false;
|
|
|
|
// For FMaterialResource::GetRepresentativeInstructionCounts
|
|
if (FCString::Stristr(ShaderType->GetName(), TEXT("BasePassPSTDistanceFieldShadowsAndLightMapPolicyHQ")))
|
|
{
|
|
bShaderTypeMatches = true;
|
|
}
|
|
else if (FCString::Stristr(ShaderType->GetName(), TEXT("BasePassPSFNoLightMapPolicy")))
|
|
{
|
|
bShaderTypeMatches = true;
|
|
}
|
|
else if (FCString::Stristr(ShaderType->GetName(), TEXT("CachedPointIndirectLightingPolicy")))
|
|
{
|
|
bShaderTypeMatches = true;
|
|
}
|
|
else if (FCString::Stristr(ShaderType->GetName(), TEXT("BasePassPSFSelfShadowedTranslucencyPolicy")))
|
|
{
|
|
bShaderTypeMatches = true;
|
|
}
|
|
// Pick tessellation shader based on material settings
|
|
else if(FCString::Stristr(ShaderType->GetName(), TEXT("BasePassVSFNoLightMapPolicy")) ||
|
|
FCString::Stristr(ShaderType->GetName(), TEXT("BasePassHSFNoLightMapPolicy")) ||
|
|
FCString::Stristr(ShaderType->GetName(), TEXT("BasePassDSFNoLightMapPolicy")))
|
|
{
|
|
bShaderTypeMatches = true;
|
|
}
|
|
else if (FCString::Stristr(ShaderType->GetName(), TEXT("DepthOnly")))
|
|
{
|
|
bShaderTypeMatches = true;
|
|
}
|
|
else if (FCString::Stristr(ShaderType->GetName(), TEXT("ShadowDepth")))
|
|
{
|
|
bShaderTypeMatches = true;
|
|
}
|
|
else if (FCString::Stristr(ShaderType->GetName(), TEXT("TDistortion")))
|
|
{
|
|
bShaderTypeMatches = true;
|
|
}
|
|
else if (FCString::Stristr(ShaderType->GetName(), TEXT("TBasePassForForwardShading")))
|
|
{
|
|
bShaderTypeMatches = true;
|
|
}
|
|
|
|
return bShaderTypeMatches;
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Should shaders compiled for this material be saved to disk?
|
|
*/
|
|
virtual bool IsPersistent() const { return false; }
|
|
|
|
// FMaterialRenderProxy interface
|
|
virtual const FMaterial* GetMaterial(ERHIFeatureLevel::Type FeatureLevel) const
|
|
{
|
|
if(GetRenderingThreadShaderMap())
|
|
{
|
|
return this;
|
|
}
|
|
else
|
|
{
|
|
return UMaterial::GetDefaultMaterial(MD_Surface)->GetRenderProxy(false)->GetMaterial(FeatureLevel);
|
|
}
|
|
}
|
|
|
|
virtual bool GetVectorValue(const FName ParameterName, FLinearColor* OutValue, const FMaterialRenderContext& Context) const
|
|
{
|
|
return Material->GetRenderProxy(0)->GetVectorValue(ParameterName, OutValue, Context);
|
|
}
|
|
|
|
virtual bool GetScalarValue(const FName ParameterName, float* OutValue, const FMaterialRenderContext& Context) const
|
|
{
|
|
return Material->GetRenderProxy(0)->GetScalarValue(ParameterName, OutValue, Context);
|
|
}
|
|
|
|
virtual bool GetTextureValue(const FName ParameterName,const UTexture** OutValue, const FMaterialRenderContext& Context) const
|
|
{
|
|
return Material->GetRenderProxy(0)->GetTextureValue(ParameterName,OutValue,Context);
|
|
}
|
|
};
|
|
|
|
/** Implementation of Preview Material functions*/
|
|
UPreviewMaterial::UPreviewMaterial(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
}
|
|
|
|
FMaterialResource* UPreviewMaterial::AllocateResource()
|
|
{
|
|
return new FPreviewMaterial();
|
|
}
|
|
|
|
UMaterialEditorInstanceConstant::UMaterialEditorInstanceConstant(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
}
|
|
|
|
void UMaterialEditorInstanceConstant::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
|
{
|
|
if (SourceInstance)
|
|
{
|
|
UProperty* PropertyThatChanged = PropertyChangedEvent.Property;
|
|
|
|
FNavigationLockContext NavUpdateLock(ENavigationLockReason::MaterialUpdate);
|
|
|
|
if(PropertyThatChanged && PropertyThatChanged->GetName()==TEXT("Parent") )
|
|
{
|
|
UpdateSourceInstanceParent();
|
|
|
|
FGlobalComponentRecreateRenderStateContext RecreateComponentsRenderState;
|
|
// Fully update static parameters before recreating render state for all components
|
|
SetSourceInstance(SourceInstance);
|
|
}
|
|
|
|
CopyToSourceInstance();
|
|
|
|
// Tell our source instance to update itself so the preview updates.
|
|
SourceInstance->PostEditChangeProperty(PropertyChangedEvent);
|
|
}
|
|
}
|
|
|
|
void UMaterialEditorInstanceConstant::AssignParameterToGroup(UMaterial* ParentMaterial, UDEditorParameterValue * ParameterValue)
|
|
{
|
|
check(ParentMaterial);
|
|
check(ParameterValue);
|
|
|
|
FName ParameterGroupName;
|
|
ParentMaterial->GetGroupName(ParameterValue->ParameterName, ParameterGroupName);
|
|
|
|
if (ParameterGroupName == TEXT("") || ParameterGroupName == TEXT("None"))
|
|
{
|
|
if (bUseOldStyleMICEditorGroups == true)
|
|
{
|
|
if (Cast<UDEditorVectorParameterValue>( ParameterValue))
|
|
{
|
|
ParameterGroupName = TEXT("Vector Parameter Values");
|
|
}
|
|
else if (Cast<UDEditorTextureParameterValue>( ParameterValue))
|
|
{
|
|
ParameterGroupName = TEXT("Texture Parameter Values");
|
|
}
|
|
else if (Cast<UDEditorScalarParameterValue>( ParameterValue))
|
|
{
|
|
ParameterGroupName = TEXT("Scalar Parameter Values");
|
|
}
|
|
else if (Cast<UDEditorStaticSwitchParameterValue>( ParameterValue))
|
|
{
|
|
ParameterGroupName = TEXT("Static Switch Parameter Values");
|
|
}
|
|
else if (Cast<UDEditorStaticComponentMaskParameterValue>( ParameterValue))
|
|
{
|
|
ParameterGroupName = TEXT("Static Component Mask Parameter Values");
|
|
}
|
|
else if (Cast<UDEditorFontParameterValue>( ParameterValue))
|
|
{
|
|
ParameterGroupName = TEXT("Font Parameter Values");
|
|
}
|
|
else
|
|
{
|
|
ParameterGroupName = TEXT("None");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ParameterGroupName = TEXT("None");
|
|
}
|
|
|
|
}
|
|
|
|
FEditorParameterGroup& CurrentGroup = GetParameterGroup(ParameterGroupName);
|
|
ParameterValue->SetFlags( RF_Transactional );
|
|
CurrentGroup.Parameters.Add(ParameterValue);
|
|
}
|
|
|
|
FEditorParameterGroup& UMaterialEditorInstanceConstant::GetParameterGroup(FName& ParameterGroup)
|
|
{
|
|
if (ParameterGroup == TEXT(""))
|
|
{
|
|
ParameterGroup = TEXT("None");
|
|
}
|
|
for (int32 i = 0; i < ParameterGroups.Num(); i ++)
|
|
{
|
|
FEditorParameterGroup& Group= ParameterGroups[i];
|
|
if (Group.GroupName == ParameterGroup)
|
|
{
|
|
return Group;
|
|
}
|
|
}
|
|
int32 ind = ParameterGroups.AddZeroed(1);
|
|
FEditorParameterGroup& Group= ParameterGroups[ind];
|
|
Group.GroupName = ParameterGroup;
|
|
return Group;
|
|
}
|
|
|
|
void UMaterialEditorInstanceConstant::RegenerateArrays()
|
|
{
|
|
VisibleExpressions.Empty();
|
|
ParameterGroups.Empty();
|
|
if(Parent)
|
|
{
|
|
// Only operate on base materials
|
|
UMaterial* ParentMaterial = Parent->GetMaterial();
|
|
SourceInstance->UpdateParameterNames(); // Update any parameter names that may have changed.
|
|
|
|
// Loop through all types of parameters for this material and add them to the parameter arrays.
|
|
TArray<FName> ParameterNames;
|
|
TArray<FGuid> Guids;
|
|
ParentMaterial->GetAllVectorParameterNames(ParameterNames, Guids);
|
|
|
|
// Vector Parameters.
|
|
|
|
for(int32 ParameterIdx=0; ParameterIdx<ParameterNames.Num(); ParameterIdx++)
|
|
{
|
|
UDEditorVectorParameterValue & ParameterValue = *(NewObject<UDEditorVectorParameterValue>());
|
|
FName ParameterName = ParameterNames[ParameterIdx];
|
|
FLinearColor Value;
|
|
|
|
ParameterValue.bOverride = false;
|
|
ParameterValue.ParameterName = ParameterName;
|
|
ParameterValue.ExpressionId = Guids[ParameterIdx];
|
|
|
|
if(SourceInstance->GetVectorParameterValue(ParameterName, Value))
|
|
{
|
|
ParameterValue.ParameterValue = Value;
|
|
}
|
|
|
|
// @todo: This is kind of slow, maybe store these in a map for lookup?
|
|
// See if this keyname exists in the source instance.
|
|
for(int32 VectorParameterIdx=0; VectorParameterIdx<SourceInstance->VectorParameterValues.Num(); VectorParameterIdx++)
|
|
{
|
|
FVectorParameterValue& SourceParam = SourceInstance->VectorParameterValues[VectorParameterIdx];
|
|
if(ParameterName==SourceParam.ParameterName)
|
|
{
|
|
ParameterValue.bOverride = true;
|
|
ParameterValue.ParameterValue = SourceParam.ParameterValue;
|
|
}
|
|
}
|
|
AssignParameterToGroup(ParentMaterial, Cast<UDEditorParameterValue>(&ParameterValue));
|
|
}
|
|
// Scalar Parameters.
|
|
ParentMaterial->GetAllScalarParameterNames(ParameterNames, Guids);
|
|
for (int32 ParameterIdx=0; ParameterIdx<ParameterNames.Num(); ParameterIdx++)
|
|
{
|
|
UDEditorScalarParameterValue& ParameterValue = *(NewObject<UDEditorScalarParameterValue>());
|
|
FName ParameterName = ParameterNames[ParameterIdx];
|
|
float Value;
|
|
|
|
ParameterValue.bOverride = false;
|
|
ParameterValue.ParameterName = ParameterName;
|
|
ParameterValue.ExpressionId = Guids[ParameterIdx];
|
|
|
|
if (SourceInstance->GetScalarParameterValue(ParameterName, Value))
|
|
{
|
|
ParentMaterial->GetScalarParameterSliderMinMax(ParameterName, ParameterValue.SliderMin, ParameterValue.SliderMax);
|
|
ParameterValue.ParameterValue = Value;
|
|
}
|
|
|
|
// @todo: This is kind of slow, maybe store these in a map for lookup?
|
|
// See if this keyname exists in the source instance.
|
|
for(int32 ScalarParameterIdx=0; ScalarParameterIdx<SourceInstance->ScalarParameterValues.Num(); ScalarParameterIdx++)
|
|
{
|
|
FScalarParameterValue& SourceParam = SourceInstance->ScalarParameterValues[ScalarParameterIdx];
|
|
if(ParameterName==SourceParam.ParameterName)
|
|
{
|
|
ParameterValue.bOverride = true;
|
|
ParameterValue.ParameterValue = SourceParam.ParameterValue;
|
|
}
|
|
}
|
|
AssignParameterToGroup(ParentMaterial, Cast<UDEditorParameterValue>(&ParameterValue));
|
|
}
|
|
|
|
// Texture Parameters.
|
|
ParentMaterial->GetAllTextureParameterNames(ParameterNames, Guids);
|
|
for(int32 ParameterIdx=0; ParameterIdx<ParameterNames.Num(); ParameterIdx++)
|
|
{
|
|
UDEditorTextureParameterValue& ParameterValue = *(NewObject<UDEditorTextureParameterValue>());
|
|
FName ParameterName = ParameterNames[ParameterIdx];
|
|
UTexture* Value;
|
|
|
|
ParameterValue.bOverride = false;
|
|
ParameterValue.ParameterName = ParameterName;
|
|
ParameterValue.ExpressionId = Guids[ParameterIdx];
|
|
|
|
if(SourceInstance->GetTextureParameterValue(ParameterName, Value))
|
|
{
|
|
ParameterValue.ParameterValue = Value;
|
|
}
|
|
|
|
|
|
// @todo: This is kind of slow, maybe store these in a map for lookup?
|
|
// See if this keyname exists in the source instance.
|
|
for(int32 TextureParameterIdx=0; TextureParameterIdx<SourceInstance->TextureParameterValues.Num(); TextureParameterIdx++)
|
|
{
|
|
FTextureParameterValue& SourceParam = SourceInstance->TextureParameterValues[TextureParameterIdx];
|
|
if(ParameterName==SourceParam.ParameterName)
|
|
{
|
|
ParameterValue.bOverride = true;
|
|
ParameterValue.ParameterValue = SourceParam.ParameterValue;
|
|
}
|
|
}
|
|
AssignParameterToGroup(ParentMaterial, Cast<UDEditorParameterValue>(&ParameterValue));
|
|
}
|
|
|
|
// Font Parameters.
|
|
ParentMaterial->GetAllFontParameterNames(ParameterNames, Guids);
|
|
for(int32 ParameterIdx=0; ParameterIdx<ParameterNames.Num(); ParameterIdx++)
|
|
{
|
|
UDEditorFontParameterValue& ParameterValue = *(NewObject<UDEditorFontParameterValue>());
|
|
FName ParameterName = ParameterNames[ParameterIdx];
|
|
UFont* FontValue;
|
|
int32 FontPage;
|
|
|
|
ParameterValue.bOverride = false;
|
|
ParameterValue.ParameterName = ParameterName;
|
|
ParameterValue.ExpressionId = Guids[ParameterIdx];
|
|
|
|
if(SourceInstance->GetFontParameterValue(ParameterName, FontValue,FontPage))
|
|
{
|
|
ParameterValue.ParameterValue.FontValue = FontValue;
|
|
ParameterValue.ParameterValue.FontPage = FontPage;
|
|
}
|
|
|
|
|
|
// @todo: This is kind of slow, maybe store these in a map for lookup?
|
|
// See if this keyname exists in the source instance.
|
|
for(int32 FontParameterIdx=0; FontParameterIdx<SourceInstance->FontParameterValues.Num(); FontParameterIdx++)
|
|
{
|
|
FFontParameterValue& SourceParam = SourceInstance->FontParameterValues[FontParameterIdx];
|
|
if(ParameterName==SourceParam.ParameterName)
|
|
{
|
|
ParameterValue.bOverride = true;
|
|
ParameterValue.ParameterValue.FontValue = SourceParam.FontValue;
|
|
ParameterValue.ParameterValue.FontPage = SourceParam.FontPage;
|
|
}
|
|
}
|
|
AssignParameterToGroup(ParentMaterial, Cast<UDEditorParameterValue>(&ParameterValue));
|
|
}
|
|
|
|
// Get all static parameters from the source instance. This will handle inheriting parent values.
|
|
FStaticParameterSet SourceStaticParameters;
|
|
SourceInstance->GetStaticParameterValues(SourceStaticParameters);
|
|
|
|
// Copy Static Switch Parameters
|
|
for(int32 ParameterIdx=0; ParameterIdx<SourceStaticParameters.StaticSwitchParameters.Num(); ParameterIdx++)
|
|
{
|
|
FStaticSwitchParameter StaticSwitchParameterValue = FStaticSwitchParameter(SourceStaticParameters.StaticSwitchParameters[ParameterIdx]);
|
|
UDEditorStaticSwitchParameterValue& ParameterValue = *(NewObject<UDEditorStaticSwitchParameterValue>());
|
|
ParameterValue.ParameterValue =StaticSwitchParameterValue.Value;
|
|
ParameterValue.bOverride =StaticSwitchParameterValue.bOverride;
|
|
ParameterValue.ParameterName =StaticSwitchParameterValue.ParameterName;
|
|
ParameterValue.ExpressionId= StaticSwitchParameterValue.ExpressionGUID;
|
|
|
|
AssignParameterToGroup(ParentMaterial, Cast<UDEditorParameterValue>(&ParameterValue));
|
|
}
|
|
|
|
// Copy Static Component Mask Parameters
|
|
|
|
for(int32 ParameterIdx=0; ParameterIdx<SourceStaticParameters.StaticComponentMaskParameters.Num(); ParameterIdx++)
|
|
{
|
|
FStaticComponentMaskParameter StaticComponentMaskParameterValue = FStaticComponentMaskParameter(SourceStaticParameters.StaticComponentMaskParameters[ParameterIdx]);
|
|
UDEditorStaticComponentMaskParameterValue& ParameterValue = *(NewObject<UDEditorStaticComponentMaskParameterValue>());
|
|
ParameterValue.ParameterValue.R = StaticComponentMaskParameterValue.R;
|
|
ParameterValue.ParameterValue.G = StaticComponentMaskParameterValue.G;
|
|
ParameterValue.ParameterValue.B = StaticComponentMaskParameterValue.B;
|
|
ParameterValue.ParameterValue.A = StaticComponentMaskParameterValue.A;
|
|
ParameterValue.bOverride =StaticComponentMaskParameterValue.bOverride;
|
|
ParameterValue.ParameterName =StaticComponentMaskParameterValue.ParameterName;
|
|
ParameterValue.ExpressionId= StaticComponentMaskParameterValue.ExpressionGUID;
|
|
|
|
AssignParameterToGroup(ParentMaterial, Cast<UDEditorParameterValue>(&ParameterValue));
|
|
}
|
|
|
|
IMaterialEditorModule* MaterialEditorModule = &FModuleManager::LoadModuleChecked<IMaterialEditorModule>( "MaterialEditor" );
|
|
MaterialEditorModule->GetVisibleMaterialParameters(ParentMaterial, SourceInstance, VisibleExpressions);
|
|
}
|
|
// sort contents of groups
|
|
for(int32 ParameterIdx=0; ParameterIdx<ParameterGroups.Num(); ParameterIdx++)
|
|
{
|
|
FEditorParameterGroup & ParamGroup = ParameterGroups[ParameterIdx];
|
|
struct FCompareUDEditorParameterValueByParameterName
|
|
{
|
|
FORCEINLINE bool operator()(const UDEditorParameterValue& A, const UDEditorParameterValue& B) const
|
|
{
|
|
FString AName = A.ParameterName.ToString().ToLower();
|
|
FString BName = B.ParameterName.ToString().ToLower();
|
|
return AName < BName;
|
|
}
|
|
};
|
|
ParamGroup.Parameters.Sort( FCompareUDEditorParameterValueByParameterName() );
|
|
}
|
|
|
|
// sort groups itself pushing defaults to end
|
|
struct FCompareFEditorParameterGroupByName
|
|
{
|
|
FORCEINLINE bool operator()(const FEditorParameterGroup& A, const FEditorParameterGroup& B) const
|
|
{
|
|
FString AName = A.GroupName.ToString().ToLower();
|
|
FString BName = B.GroupName.ToString().ToLower();
|
|
if (AName == TEXT("none"))
|
|
{
|
|
return false;
|
|
}
|
|
if (BName == TEXT("none"))
|
|
{
|
|
return false;
|
|
}
|
|
return AName < BName;
|
|
}
|
|
};
|
|
ParameterGroups.Sort( FCompareFEditorParameterGroupByName() );
|
|
TArray<struct FEditorParameterGroup> ParameterDefaultGroups;
|
|
for(int32 ParameterIdx=0; ParameterIdx<ParameterGroups.Num(); ParameterIdx++)
|
|
{
|
|
FEditorParameterGroup & ParamGroup = ParameterGroups[ParameterIdx];
|
|
if (bUseOldStyleMICEditorGroups == false)
|
|
{
|
|
if (ParamGroup.GroupName == TEXT("None"))
|
|
{
|
|
ParameterDefaultGroups.Add(ParamGroup);
|
|
ParameterGroups.RemoveAt(ParameterIdx);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (ParamGroup.GroupName == TEXT("Vector Parameter Values") ||
|
|
ParamGroup.GroupName == TEXT("Scalar Parameter Values") ||
|
|
ParamGroup.GroupName == TEXT("Texture Parameter Values") ||
|
|
ParamGroup.GroupName == TEXT("Static Switch Parameter Values") ||
|
|
ParamGroup.GroupName == TEXT("Static Component Mask Parameter Values") ||
|
|
ParamGroup.GroupName == TEXT("Font Parameter Values"))
|
|
{
|
|
ParameterDefaultGroups.Add(ParamGroup);
|
|
ParameterGroups.RemoveAt(ParameterIdx);
|
|
}
|
|
|
|
}
|
|
}
|
|
if (ParameterDefaultGroups.Num() >0)
|
|
{
|
|
ParameterGroups.Append(ParameterDefaultGroups);
|
|
}
|
|
|
|
}
|
|
|
|
void UMaterialEditorInstanceConstant::CopyToSourceInstance()
|
|
{
|
|
if(SourceInstance->IsTemplate(RF_ClassDefaultObject) == false )
|
|
{
|
|
SourceInstance->MarkPackageDirty();
|
|
SourceInstance->ClearParameterValuesEditorOnly();
|
|
|
|
// Scalar Parameters
|
|
for(int32 GroupIdx=0; GroupIdx<ParameterGroups.Num(); GroupIdx++)
|
|
{
|
|
FEditorParameterGroup & Group = ParameterGroups[GroupIdx];
|
|
for(int32 ParameterIdx=0; ParameterIdx<Group.Parameters.Num(); ParameterIdx++)
|
|
{
|
|
if (Group.Parameters[ParameterIdx] == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
UDEditorScalarParameterValue * ScalarParameterValue = Cast<UDEditorScalarParameterValue>(Group.Parameters[ParameterIdx]);
|
|
if (ScalarParameterValue)
|
|
{
|
|
if(ScalarParameterValue->bOverride)
|
|
{
|
|
SourceInstance->SetScalarParameterValueEditorOnly(ScalarParameterValue->ParameterName, ScalarParameterValue->ParameterValue);
|
|
continue;
|
|
}
|
|
}
|
|
UDEditorFontParameterValue * FontParameterValue = Cast<UDEditorFontParameterValue>(Group.Parameters[ParameterIdx]);
|
|
if (FontParameterValue)
|
|
{
|
|
if(FontParameterValue->bOverride)
|
|
{
|
|
SourceInstance->SetFontParameterValueEditorOnly(FontParameterValue->ParameterName, FontParameterValue->ParameterValue.FontValue, FontParameterValue->ParameterValue.FontPage);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
UDEditorTextureParameterValue * TextureParameterValue = Cast<UDEditorTextureParameterValue>(Group.Parameters[ParameterIdx]);
|
|
if (TextureParameterValue)
|
|
{
|
|
if(TextureParameterValue->bOverride)
|
|
{
|
|
SourceInstance->SetTextureParameterValueEditorOnly(TextureParameterValue->ParameterName, TextureParameterValue->ParameterValue);
|
|
continue;
|
|
}
|
|
}
|
|
UDEditorVectorParameterValue * VectorParameterValue = Cast<UDEditorVectorParameterValue>(Group.Parameters[ParameterIdx]);
|
|
if (VectorParameterValue)
|
|
{
|
|
if(VectorParameterValue->bOverride)
|
|
{
|
|
SourceInstance->SetVectorParameterValueEditorOnly(VectorParameterValue->ParameterName, VectorParameterValue->ParameterValue);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//Check for changes to see if we need to force a recompile
|
|
bool bForceRecompile = false;
|
|
if (SourceInstance->BasePropertyOverrides != BasePropertyOverrides)
|
|
{
|
|
bForceRecompile = true;
|
|
SourceInstance->BasePropertyOverrides = BasePropertyOverrides;
|
|
}
|
|
|
|
FStaticParameterSet NewStaticParameters;
|
|
BuildStaticParametersForSourceInstance(NewStaticParameters);
|
|
SourceInstance->UpdateStaticPermutation(NewStaticParameters,bForceRecompile);
|
|
|
|
// Copy phys material back to source instance
|
|
SourceInstance->PhysMaterial = PhysMaterial;
|
|
|
|
// Copy the Lightmass settings...
|
|
SourceInstance->SetOverrideCastShadowAsMasked(LightmassSettings.CastShadowAsMasked.bOverride);
|
|
SourceInstance->SetCastShadowAsMasked(LightmassSettings.CastShadowAsMasked.ParameterValue);
|
|
SourceInstance->SetOverrideEmissiveBoost(LightmassSettings.EmissiveBoost.bOverride);
|
|
SourceInstance->SetEmissiveBoost(LightmassSettings.EmissiveBoost.ParameterValue);
|
|
SourceInstance->SetOverrideDiffuseBoost(LightmassSettings.DiffuseBoost.bOverride);
|
|
SourceInstance->SetDiffuseBoost(LightmassSettings.DiffuseBoost.ParameterValue);
|
|
SourceInstance->SetOverrideExportResolutionScale(LightmassSettings.ExportResolutionScale.bOverride);
|
|
SourceInstance->SetExportResolutionScale(LightmassSettings.ExportResolutionScale.ParameterValue);
|
|
SourceInstance->SetOverrideDistanceFieldPenumbraScale(LightmassSettings.DistanceFieldPenumbraScale.bOverride);
|
|
SourceInstance->SetDistanceFieldPenumbraScale(LightmassSettings.DistanceFieldPenumbraScale.ParameterValue);
|
|
|
|
// Copy Refraction bias setting
|
|
SourceInstance->SetScalarParameterValueEditorOnly(TEXT("RefractionDepthBias"), RefractionDepthBias);
|
|
|
|
SourceInstance->bOverrideSubsurfaceProfile = bOverrideSubsurfaceProfile;
|
|
SourceInstance->SubsurfaceProfile = SubsurfaceProfile;
|
|
|
|
// Update object references and parameter names.
|
|
SourceInstance->UpdateParameterNames();
|
|
VisibleExpressions.Empty();
|
|
|
|
// force refresh of visibility of properties
|
|
if( Parent )
|
|
{
|
|
UMaterial* ParentMaterial = Parent->GetMaterial();
|
|
IMaterialEditorModule* MaterialEditorModule = &FModuleManager::LoadModuleChecked<IMaterialEditorModule>( "MaterialEditor" );
|
|
MaterialEditorModule->GetVisibleMaterialParameters(ParentMaterial, SourceInstance, VisibleExpressions);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UMaterialEditorInstanceConstant::BuildStaticParametersForSourceInstance(FStaticParameterSet& OutStaticParameters)
|
|
{
|
|
for(int32 GroupIdx=0; GroupIdx<ParameterGroups.Num(); GroupIdx++)
|
|
{
|
|
FEditorParameterGroup& Group = ParameterGroups[GroupIdx];
|
|
|
|
for(int32 ParameterIdx=0; ParameterIdx<Group.Parameters.Num(); ParameterIdx++)
|
|
{
|
|
if (Group.Parameters[ParameterIdx] == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
// static switch
|
|
|
|
UDEditorStaticSwitchParameterValue* StaticSwitchParameterValue = Cast<UDEditorStaticSwitchParameterValue>(Group.Parameters[ParameterIdx]);
|
|
if (StaticSwitchParameterValue)
|
|
{
|
|
bool SwitchValue = StaticSwitchParameterValue->ParameterValue;
|
|
FGuid ExpressionIdValue = StaticSwitchParameterValue->ExpressionId;
|
|
|
|
if (StaticSwitchParameterValue->bOverride)
|
|
{
|
|
FStaticSwitchParameter * NewParameter =
|
|
new(OutStaticParameters.StaticSwitchParameters) FStaticSwitchParameter(StaticSwitchParameterValue->ParameterName, SwitchValue, StaticSwitchParameterValue->bOverride, ExpressionIdValue);
|
|
}
|
|
}
|
|
|
|
// static component mask
|
|
|
|
UDEditorStaticComponentMaskParameterValue* StaticComponentMaskParameterValue = Cast<UDEditorStaticComponentMaskParameterValue>(Group.Parameters[ParameterIdx]);
|
|
if (StaticComponentMaskParameterValue)
|
|
{
|
|
bool MaskR = StaticComponentMaskParameterValue->ParameterValue.R;
|
|
bool MaskG = StaticComponentMaskParameterValue->ParameterValue.G;
|
|
bool MaskB = StaticComponentMaskParameterValue->ParameterValue.B;
|
|
bool MaskA = StaticComponentMaskParameterValue->ParameterValue.A;
|
|
FGuid ExpressionIdValue = StaticComponentMaskParameterValue->ExpressionId;
|
|
|
|
if (StaticComponentMaskParameterValue->bOverride)
|
|
{
|
|
FStaticComponentMaskParameter* NewParameter = new(OutStaticParameters.StaticComponentMaskParameters)
|
|
FStaticComponentMaskParameter(StaticComponentMaskParameterValue->ParameterName, MaskR, MaskG, MaskB, MaskA, StaticComponentMaskParameterValue->bOverride, ExpressionIdValue);\
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void UMaterialEditorInstanceConstant::SetSourceInstance(UMaterialInstanceConstant* MaterialInterface)
|
|
{
|
|
check(MaterialInterface);
|
|
SourceInstance = MaterialInterface;
|
|
Parent = SourceInstance->Parent;
|
|
PhysMaterial = SourceInstance->PhysMaterial;
|
|
|
|
BasePropertyOverrides = SourceInstance->BasePropertyOverrides;
|
|
|
|
// Copy the Lightmass settings...
|
|
LightmassSettings.CastShadowAsMasked.bOverride = SourceInstance->GetOverrideCastShadowAsMasked();
|
|
LightmassSettings.CastShadowAsMasked.ParameterValue = SourceInstance->GetCastShadowAsMasked();
|
|
LightmassSettings.EmissiveBoost.bOverride = SourceInstance->GetOverrideEmissiveBoost();
|
|
LightmassSettings.EmissiveBoost.ParameterValue = SourceInstance->GetEmissiveBoost();
|
|
LightmassSettings.DiffuseBoost.bOverride = SourceInstance->GetOverrideDiffuseBoost();
|
|
LightmassSettings.DiffuseBoost.ParameterValue = SourceInstance->GetDiffuseBoost();
|
|
LightmassSettings.ExportResolutionScale.bOverride = SourceInstance->GetOverrideExportResolutionScale();
|
|
LightmassSettings.ExportResolutionScale.ParameterValue = SourceInstance->GetExportResolutionScale();
|
|
LightmassSettings.DistanceFieldPenumbraScale.bOverride = SourceInstance->GetOverrideDistanceFieldPenumbraScale();
|
|
LightmassSettings.DistanceFieldPenumbraScale.ParameterValue = SourceInstance->GetDistanceFieldPenumbraScale();
|
|
|
|
//Copy refraction settings
|
|
SourceInstance->GetRefractionSettings(RefractionDepthBias);
|
|
|
|
bOverrideSubsurfaceProfile = SourceInstance->bOverrideSubsurfaceProfile;
|
|
SubsurfaceProfile = SourceInstance->SubsurfaceProfile;
|
|
|
|
RegenerateArrays();
|
|
|
|
//propagate changes to the base material so the instance will be updated if it has a static permutation resource
|
|
FStaticParameterSet NewStaticParameters;
|
|
BuildStaticParametersForSourceInstance(NewStaticParameters);
|
|
SourceInstance->UpdateStaticPermutation(NewStaticParameters);
|
|
}
|
|
|
|
void UMaterialEditorInstanceConstant::UpdateSourceInstanceParent()
|
|
{
|
|
// If the parent was changed to the source instance, set it to NULL
|
|
if( Parent == SourceInstance )
|
|
{
|
|
Parent = NULL;
|
|
}
|
|
|
|
SourceInstance->SetParentEditorOnly( Parent );
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
void UMaterialEditorInstanceConstant::PostEditUndo()
|
|
{
|
|
UpdateSourceInstanceParent();
|
|
|
|
Super::PostEditUndo();
|
|
}
|
|
#endif
|
|
|
|
UMaterialEditorMeshComponent::UMaterialEditorMeshComponent(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
}
|