// Copyright Epic Games, Inc. All Rights Reserved. #include "HierarchicalSimplificationCustomizations.h" #include "Modules/ModuleManager.h" #include "GameFramework/WorldSettings.h" #include "IDetailChildrenBuilder.h" #include "DetailWidgetRow.h" #include "IDetailGroup.h" #include "IDetailPropertyRow.h" #include "MeshUtilities.h" #include "IMeshReductionManagerModule.h" #define LOCTEXT_NAMESPACE "HierarchicalSimplificationCustomizations" TSharedRef FHierarchicalSimplificationCustomizations::MakeInstance() { return MakeShareable( new FHierarchicalSimplificationCustomizations ); } void FHierarchicalSimplificationCustomizations::CustomizeHeader(TSharedRef StructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) { FFormatOrderedArguments Args; Args.Add(StructPropertyHandle->GetPropertyDisplayName()); FText Name = FText::Format(LOCTEXT("HLODLevelName", "HLOD Level {0}"), Args); HeaderRow. NameContent() [ StructPropertyHandle->CreatePropertyNameWidget(Name) ] .ValueContent() [ StructPropertyHandle->CreatePropertyValueWidget(false) ]; } void FHierarchicalSimplificationCustomizations::CustomizeChildren( TSharedRef StructPropertyHandle, class IDetailChildrenBuilder& ChildBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils ) { // Retrieve structure's child properties uint32 NumChildren; StructPropertyHandle->GetNumChildren( NumChildren ); TMap > PropertyHandles; for( uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex ) { TSharedRef ChildHandle = StructPropertyHandle->GetChildHandle( ChildIndex ).ToSharedRef(); const FName PropertyName = ChildHandle->GetProperty()->GetFName(); PropertyHandles.Add(PropertyName, ChildHandle); } // Create two sub-settings groups for clean overview IDetailGroup& ClusterGroup = ChildBuilder.AddGroup(NAME_None, FText::FromString("Cluster generation settings")); IDetailGroup& MergeGroup = ChildBuilder.AddGroup(NAME_None, FText::FromString("Mesh generation settings")); // Retrieve special case properties SimplifyMeshPropertyHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FHierarchicalSimplification, bSimplifyMesh)); TSharedPtr< IPropertyHandle > ProxyMeshSettingPropertyHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FHierarchicalSimplification, ProxySetting)); TSharedPtr< IPropertyHandle > MergeMeshSettingPropertyHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FHierarchicalSimplification, MergeSetting)); TSharedPtr< IPropertyHandle > TransitionScreenSizePropertyHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FHierarchicalSimplification, TransitionScreenSize)); TSharedPtr< IPropertyHandle > OverrideDrawDistancePropertyHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FHierarchicalSimplification, OverrideDrawDistance)); TSharedPtr< IPropertyHandle > ReusePreviousLevelClustersPropertyHandle = PropertyHandles.FindChecked(GET_MEMBER_NAME_CHECKED(FHierarchicalSimplification, bReusePreviousLevelClusters)); for (auto Iter(PropertyHandles.CreateConstIterator()); Iter; ++Iter) { // Handle special property cases (done inside the loop to maintain order according to the struct if (Iter.Value() == SimplifyMeshPropertyHandle) { IDetailPropertyRow& SimplifyMeshRow = MergeGroup.AddPropertyRow(SimplifyMeshPropertyHandle.ToSharedRef()); AddResetToDefaultOverrides(SimplifyMeshRow); SimplifyMeshRow.Visibility(TAttribute(this, &FHierarchicalSimplificationCustomizations::IsSimplifyMeshVisible)); } else if (Iter.Value() == ProxyMeshSettingPropertyHandle) { IDetailPropertyRow& SettingsRow = MergeGroup.AddPropertyRow(Iter.Value().ToSharedRef()); AddResetToDefaultOverrides(SettingsRow); SettingsRow.Visibility(TAttribute(this, &FHierarchicalSimplificationCustomizations::IsProxyMeshSettingVisible)); } else if (Iter.Value() == MergeMeshSettingPropertyHandle) { IDetailPropertyRow& SettingsRow = MergeGroup.AddPropertyRow(Iter.Value().ToSharedRef()); AddResetToDefaultOverrides(SettingsRow); SettingsRow.Visibility(TAttribute(this, &FHierarchicalSimplificationCustomizations::IsMergeMeshSettingVisible)); } else if (Iter.Value() == TransitionScreenSizePropertyHandle) { IDetailPropertyRow& SettingsRow = MergeGroup.AddPropertyRow(Iter.Value().ToSharedRef()); AddResetToDefaultOverrides(SettingsRow); } else if (Iter.Value() == OverrideDrawDistancePropertyHandle) { IDetailPropertyRow& SettingsRow = MergeGroup.AddPropertyRow(Iter.Value().ToSharedRef()); AddResetToDefaultOverrides(SettingsRow); } else if (Iter.Value() == ReusePreviousLevelClustersPropertyHandle) { IDetailPropertyRow& SettingsRow = ClusterGroup.AddPropertyRow(Iter.Value().ToSharedRef()); AddResetToDefaultOverrides(SettingsRow); uint32 Index = StructPropertyHandle->GetIndexInArray(); // Hide the property for HLOD level 0 SettingsRow.Visibility(TAttribute::Create([Index]() { return (Index == INDEX_NONE || Index > 0) ? EVisibility::Visible : EVisibility::Collapsed; })); } else { IDetailPropertyRow& SettingsRow = ClusterGroup.AddPropertyRow(Iter.Value().ToSharedRef()); AddResetToDefaultOverrides(SettingsRow); } } } EVisibility FHierarchicalSimplificationCustomizations::IsSimplifyMeshVisible() const { // Determine whether or not there is a mesh merging interface available (SimplygonMeshReduction/SimplygonSwarm) IMeshReductionModule& ReductionModule = FModuleManager::Get().LoadModuleChecked("MeshReductionInterface"); if (ReductionModule.GetMeshMergingInterface() != nullptr) { return EVisibility::Visible; } return EVisibility::Hidden; } EVisibility FHierarchicalSimplificationCustomizations::IsProxyMeshSettingVisible() const { bool bSimplifyMesh; if (SimplifyMeshPropertyHandle->GetValue(bSimplifyMesh) == FPropertyAccess::Result::Success) { if (IsSimplifyMeshVisible() == EVisibility::Visible && bSimplifyMesh) { return EVisibility::Visible; } } return EVisibility::Hidden; } EVisibility FHierarchicalSimplificationCustomizations::IsMergeMeshSettingVisible() const { if(IsProxyMeshSettingVisible() == EVisibility::Hidden) { return EVisibility::Visible; } return EVisibility::Hidden; } #undef LOCTEXT_NAMESPACE