You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#preflight 6286aff4286cf1867a0ccf40 #rb Jonathan.Bard #ROBOMERGE-AUTHOR: luc.eygasier #ROBOMERGE-SOURCE: CL 20294036 via CL 20294043 via CL 20294053 via CL 20294056 #ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v948-20297126) [CL 20305112 by luc eygasier in ue5-main branch]
937 lines
39 KiB
C++
937 lines
39 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "LandscapeEditorObject.h"
|
|
#include "LandscapeDataAccess.h"
|
|
#include "Engine/Texture2D.h"
|
|
#include "HAL/FileManager.h"
|
|
#include "Modules/ModuleManager.h"
|
|
#include "UObject/ConstructorHelpers.h"
|
|
#include "LandscapeEditorModule.h"
|
|
#include "LandscapeRender.h"
|
|
#include "LandscapeSettings.h"
|
|
#include "LandscapeImportHelper.h"
|
|
#include "LandscapeMaterialInstanceConstant.h"
|
|
#include "Misc/ConfigCacheIni.h"
|
|
#include "EngineUtils.h"
|
|
#include "Misc/MessageDialog.h"
|
|
|
|
//#define LOCTEXT_NAMESPACE "LandscapeEditor"
|
|
|
|
ULandscapeEditorObject::ULandscapeEditorObject(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
|
|
// Tool Settings:
|
|
, ToolStrength(0.3f)
|
|
, bUseWeightTargetValue(false)
|
|
, WeightTargetValue(1.0f)
|
|
, MaximumValueRadius(10000.0f)
|
|
, bCombinedLayersOperation(true)
|
|
|
|
, FlattenMode(ELandscapeToolFlattenMode::Both)
|
|
, bUseSlopeFlatten(false)
|
|
, bPickValuePerApply(false)
|
|
, bUseFlattenTarget(false)
|
|
, FlattenTarget(0)
|
|
, bShowFlattenTargetPreview(true)
|
|
|
|
, TerraceInterval(1.0f)
|
|
, TerraceSmooth(0.0001f)
|
|
|
|
, RampWidth(2000)
|
|
, RampSideFalloff(0.4f)
|
|
|
|
, SmoothFilterKernelSize(4)
|
|
, bDetailSmooth(false)
|
|
, DetailScale(0.3f)
|
|
|
|
, ErodeThresh(64)
|
|
, ErodeSurfaceThickness(256)
|
|
, ErodeIterationNum(28)
|
|
, ErosionNoiseMode(ELandscapeToolErosionMode::Lower)
|
|
, ErosionNoiseScale(60.0f)
|
|
|
|
, RainAmount(128)
|
|
, SedimentCapacity(0.3f)
|
|
, HErodeIterationNum(75)
|
|
, RainDistMode(ELandscapeToolHydroErosionMode::Both)
|
|
, RainDistScale(60.0f)
|
|
, bHErosionDetailSmooth(true)
|
|
, HErosionDetailScale(0.01f)
|
|
|
|
, NoiseMode(ELandscapeToolNoiseMode::Both)
|
|
, NoiseScale(128.0f)
|
|
|
|
, bUseSelectedRegion(true)
|
|
, bUseNegativeMask(true)
|
|
|
|
, PasteMode(ELandscapeToolPasteMode::Both)
|
|
, bApplyToAllTargets(true)
|
|
, bSnapGizmo(false)
|
|
, bSmoothGizmoBrush(true)
|
|
|
|
, MirrorPoint(FVector::ZeroVector)
|
|
, MirrorOp(ELandscapeMirrorOperation::MinusXToPlusX)
|
|
|
|
, ResizeLandscape_QuadsPerSection(0)
|
|
, ResizeLandscape_SectionsPerComponent(0)
|
|
, ResizeLandscape_ComponentCount(0, 0)
|
|
, ResizeLandscape_ConvertMode(ELandscapeConvertMode::Expand)
|
|
|
|
, NewLandscape_Material(NULL)
|
|
, NewLandscape_QuadsPerSection(63)
|
|
, NewLandscape_SectionsPerComponent(1)
|
|
, NewLandscape_ComponentCount(8, 8)
|
|
, NewLandscape_Location(0, 0, 100)
|
|
, NewLandscape_Rotation(0, 0, 0)
|
|
, NewLandscape_Scale(100, 100, 100)
|
|
, ImportLandscape_Width(0)
|
|
, ImportLandscape_Height(0)
|
|
, ImportLandscape_AlphamapType(ELandscapeImportAlphamapType::Additive)
|
|
|
|
// Brush Settings:
|
|
, BrushRadius(2048.0f)
|
|
, BrushFalloff(0.5f)
|
|
, bUseClayBrush(false)
|
|
|
|
, AlphaBrushScale(0.5f)
|
|
, bAlphaBrushAutoRotate(true)
|
|
, AlphaBrushRotation(0.0f)
|
|
, AlphaBrushPanU(0.5f)
|
|
, AlphaBrushPanV(0.5f)
|
|
, bUseWorldSpacePatternBrush(false)
|
|
, WorldSpacePatternBrushSettings(FVector2D::ZeroVector, 0.0f, false, 3200)
|
|
, AlphaTexture(NULL)
|
|
, AlphaTextureChannel(EColorChannel::Red)
|
|
, AlphaTextureSizeX(1)
|
|
, AlphaTextureSizeY(1)
|
|
|
|
, BrushComponentSize(1)
|
|
, TargetDisplayOrder(ELandscapeLayerDisplayMode::Default)
|
|
, ShowUnusedLayers(true)
|
|
, CurrentLayerIndex(INDEX_NONE)
|
|
{
|
|
// Structure to hold one-time initialization
|
|
struct FConstructorStatics
|
|
{
|
|
ConstructorHelpers::FObjectFinder<UTexture2D> AlphaTexture;
|
|
|
|
FConstructorStatics()
|
|
: AlphaTexture(TEXT("/Engine/EditorLandscapeResources/DefaultAlphaTexture"))
|
|
{
|
|
}
|
|
};
|
|
static FConstructorStatics ConstructorStatics;
|
|
|
|
SetAlphaTexture(ConstructorStatics.AlphaTexture.Object, AlphaTextureChannel);
|
|
}
|
|
|
|
void ULandscapeEditorObject::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
|
{
|
|
Super::PostEditChangeProperty(PropertyChangedEvent);
|
|
|
|
SetbUseSelectedRegion(bUseSelectedRegion);
|
|
SetbUseNegativeMask(bUseNegativeMask);
|
|
SetPasteMode(PasteMode);
|
|
SetbSnapGizmo(bSnapGizmo);
|
|
|
|
if (PropertyChangedEvent.MemberProperty == nullptr ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, AlphaTexture) ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, AlphaTextureChannel))
|
|
{
|
|
SetAlphaTexture(AlphaTexture, AlphaTextureChannel);
|
|
}
|
|
|
|
|
|
if (PropertyChangedEvent.MemberProperty == nullptr ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, NewLandscape_QuadsPerSection) ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, NewLandscape_SectionsPerComponent) ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, NewLandscape_ComponentCount))
|
|
{
|
|
NewLandscape_ClampSize();
|
|
}
|
|
|
|
if (PropertyChangedEvent.MemberProperty == nullptr ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, ResizeLandscape_QuadsPerSection) ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, ResizeLandscape_SectionsPerComponent) ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, ResizeLandscape_ConvertMode))
|
|
{
|
|
UpdateComponentCount();
|
|
}
|
|
|
|
if (PropertyChangedEvent.MemberProperty == nullptr ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, NewLandscape_Material) ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, ImportLandscape_HeightmapFilename) ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, ImportLandscape_Layers))
|
|
{
|
|
// In Import/Export tool we need to refresh from the existing material
|
|
const bool bRefreshFromTarget = ParentMode && ParentMode->CurrentTool && ParentMode->CurrentTool->GetToolName() == FName(TEXT("ImportExport"));
|
|
RefreshImportLayersList(bRefreshFromTarget);
|
|
}
|
|
|
|
if (PropertyChangedEvent.MemberProperty == nullptr ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, PaintingRestriction))
|
|
{
|
|
UpdateComponentLayerAllowList();
|
|
}
|
|
|
|
if (PropertyChangedEvent.MemberProperty == nullptr ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, TargetDisplayOrder))
|
|
{
|
|
UpdateTargetLayerDisplayOrder();
|
|
}
|
|
|
|
if (PropertyChangedEvent.MemberProperty == nullptr ||
|
|
PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(ULandscapeEditorObject, ShowUnusedLayers))
|
|
{
|
|
UpdateShowUnusedLayers();
|
|
}
|
|
}
|
|
|
|
/** Load UI settings from ini file */
|
|
void ULandscapeEditorObject::Load()
|
|
{
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("ToolStrength"), ToolStrength, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("WeightTargetValue"), WeightTargetValue, GEditorPerProjectIni);
|
|
bool InbUseWeightTargetValue = bUseWeightTargetValue;
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bUseWeightTargetValue"), InbUseWeightTargetValue, GEditorPerProjectIni);
|
|
bUseWeightTargetValue = InbUseWeightTargetValue;
|
|
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("BrushRadius"), BrushRadius, GEditorPerProjectIni);
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("BrushComponentSize"), BrushComponentSize, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("BrushFalloff"), BrushFalloff, GEditorPerProjectIni);
|
|
bool InbUseClayBrush = bUseClayBrush;
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bUseClayBrush"), InbUseClayBrush, GEditorPerProjectIni);
|
|
bUseClayBrush = InbUseClayBrush;
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("AlphaBrushScale"), AlphaBrushScale, GEditorPerProjectIni);
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("AlphaBrushAutoRotate"), bAlphaBrushAutoRotate, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("AlphaBrushRotation"), AlphaBrushRotation, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("AlphaBrushPanU"), AlphaBrushPanU, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("AlphaBrushPanV"), AlphaBrushPanV, GEditorPerProjectIni);
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bUseWorldSpacePatternBrush"), bUseWorldSpacePatternBrush, GEditorPerProjectIni);
|
|
GConfig->GetVector2D(TEXT("LandscapeEdit"), TEXT("WorldSpacePatternBrushSettings.Origin"), WorldSpacePatternBrushSettings.Origin, GEditorPerProjectIni);
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("WorldSpacePatternBrushSettings.bCenterTextureOnOrigin"), WorldSpacePatternBrushSettings.bCenterTextureOnOrigin, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("WorldSpacePatternBrushSettings.RepeatSize"), WorldSpacePatternBrushSettings.RepeatSize, GEditorPerProjectIni);
|
|
FString AlphaTextureName = (AlphaTexture != NULL) ? AlphaTexture->GetPathName() : FString();
|
|
int32 InAlphaTextureChannel = AlphaTextureChannel;
|
|
GConfig->GetString(TEXT("LandscapeEdit"), TEXT("AlphaTextureName"), AlphaTextureName, GEditorPerProjectIni);
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("AlphaTextureChannel"), InAlphaTextureChannel, GEditorPerProjectIni);
|
|
AlphaTextureChannel = (EColorChannel::Type)InAlphaTextureChannel;
|
|
SetAlphaTexture(LoadObject<UTexture2D>(NULL, *AlphaTextureName, NULL, LOAD_NoWarn), AlphaTextureChannel);
|
|
|
|
int32 InFlattenMode = (int32)ELandscapeToolFlattenMode::Both;
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("FlattenMode"), InFlattenMode, GEditorPerProjectIni);
|
|
FlattenMode = (ELandscapeToolFlattenMode)InFlattenMode;
|
|
|
|
bool InbUseSlopeFlatten = bUseSlopeFlatten;
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bUseSlopeFlatten"), InbUseSlopeFlatten, GEditorPerProjectIni);
|
|
bUseSlopeFlatten = InbUseSlopeFlatten;
|
|
|
|
bool InbPickValuePerApply = bPickValuePerApply;
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bPickValuePerApply"), InbPickValuePerApply, GEditorPerProjectIni);
|
|
bPickValuePerApply = InbPickValuePerApply;
|
|
|
|
bool InbUseFlattenTarget = bUseFlattenTarget;
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bUseFlattenTarget"), InbUseFlattenTarget, GEditorPerProjectIni);
|
|
bUseFlattenTarget = InbUseFlattenTarget;
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("FlattenTarget"), FlattenTarget, GEditorPerProjectIni);
|
|
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("TerraceSmooth"), TerraceSmooth, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("TerraceInterval"), TerraceInterval, GEditorPerProjectIni);
|
|
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("RampWidth"), RampWidth, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("RampSideFalloff"), RampSideFalloff, GEditorPerProjectIni);
|
|
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bCombinedLayersOperation"), bCombinedLayersOperation, GEditorPerProjectIni);
|
|
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("ErodeThresh"), ErodeThresh, GEditorPerProjectIni);
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("ErodeIterationNum"), ErodeIterationNum, GEditorPerProjectIni);
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("ErodeSurfaceThickness"), ErodeSurfaceThickness, GEditorPerProjectIni);
|
|
int32 InErosionNoiseMode = (int32)ErosionNoiseMode;
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("ErosionNoiseMode"), InErosionNoiseMode, GEditorPerProjectIni);
|
|
ErosionNoiseMode = (ELandscapeToolErosionMode)InErosionNoiseMode;
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("ErosionNoiseScale"), ErosionNoiseScale, GEditorPerProjectIni);
|
|
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("RainAmount"), RainAmount, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("SedimentCapacity"), SedimentCapacity, GEditorPerProjectIni);
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("HErodeIterationNum"), HErodeIterationNum, GEditorPerProjectIni);
|
|
int32 InRainDistMode = (int32)RainDistMode;
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("RainDistNoiseMode"), InRainDistMode, GEditorPerProjectIni);
|
|
RainDistMode = (ELandscapeToolHydroErosionMode)InRainDistMode;
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("RainDistScale"), RainDistScale, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("HErosionDetailScale"), HErosionDetailScale, GEditorPerProjectIni);
|
|
bool InbHErosionDetailSmooth = bHErosionDetailSmooth;
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bHErosionDetailSmooth"), InbHErosionDetailSmooth, GEditorPerProjectIni);
|
|
bHErosionDetailSmooth = InbHErosionDetailSmooth;
|
|
|
|
int32 InNoiseMode = (int32)NoiseMode;
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("NoiseMode"), InNoiseMode, GEditorPerProjectIni);
|
|
NoiseMode = (ELandscapeToolNoiseMode)InNoiseMode;
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("NoiseScale"), NoiseScale, GEditorPerProjectIni);
|
|
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("SmoothFilterKernelSize"), SmoothFilterKernelSize, GEditorPerProjectIni);
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("DetailScale"), DetailScale, GEditorPerProjectIni);
|
|
bool InbDetailSmooth = bDetailSmooth;
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bDetailSmooth"), InbDetailSmooth, GEditorPerProjectIni);
|
|
bDetailSmooth = InbDetailSmooth;
|
|
|
|
GConfig->GetFloat(TEXT("LandscapeEdit"), TEXT("MaximumValueRadius"), MaximumValueRadius, GEditorPerProjectIni);
|
|
|
|
bool InbSmoothGizmoBrush = bSmoothGizmoBrush;
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bSmoothGizmoBrush"), InbSmoothGizmoBrush, GEditorPerProjectIni);
|
|
bSmoothGizmoBrush = InbSmoothGizmoBrush;
|
|
|
|
int32 InPasteMode = (int32)ELandscapeToolPasteMode::Both;
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("PasteMode"), InPasteMode, GEditorPerProjectIni);
|
|
//PasteMode = (ELandscapeToolPasteMode)InPasteMode;
|
|
SetPasteMode((ELandscapeToolPasteMode)InPasteMode);
|
|
|
|
int32 InMirrorOp = (int32)ELandscapeMirrorOperation::MinusXToPlusX;
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("MirrorOp"), InMirrorOp, GEditorPerProjectIni);
|
|
MirrorOp = (ELandscapeMirrorOperation)InMirrorOp;
|
|
|
|
int32 InConvertMode = (int32)ResizeLandscape_ConvertMode;
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("ConvertMode"), InConvertMode, GEditorPerProjectIni);
|
|
ResizeLandscape_ConvertMode = (ELandscapeConvertMode)InConvertMode;
|
|
|
|
// Region
|
|
//GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bUseSelectedRegion"), bUseSelectedRegion, GEditorPerProjectIni);
|
|
//GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bUseNegativeMask"), bUseNegativeMask, GEditorPerProjectIni);
|
|
bool InbApplyToAllTargets = bApplyToAllTargets;
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("bApplyToAllTargets"), InbApplyToAllTargets, GEditorPerProjectIni);
|
|
bApplyToAllTargets = InbApplyToAllTargets;
|
|
|
|
GConfig->GetBool(TEXT("LandscapeEdit"), TEXT("ShowUnusedLayers"), ShowUnusedLayers, GEditorPerProjectIni);
|
|
|
|
// Set EditRenderMode
|
|
SetbUseSelectedRegion(bUseSelectedRegion);
|
|
SetbUseNegativeMask(bUseNegativeMask);
|
|
|
|
// Gizmo History (not saved!)
|
|
GizmoHistories.Empty();
|
|
for (TActorIterator<ALandscapeGizmoActor> It(ParentMode->GetWorld()); It; ++It)
|
|
{
|
|
ALandscapeGizmoActor* Gizmo = *It;
|
|
if (!Gizmo->IsEditable())
|
|
{
|
|
new(GizmoHistories) FGizmoHistory(Gizmo);
|
|
}
|
|
}
|
|
|
|
FString NewLandscapeMaterialName;
|
|
|
|
// If NewLandscape_Material is not null, we will try to use it
|
|
if (!NewLandscape_Material.IsExplicitlyNull())
|
|
{
|
|
NewLandscapeMaterialName = NewLandscape_Material->GetPathName();
|
|
}
|
|
else
|
|
{
|
|
// If this project already has a saved NewLandscapeMaterialName, we use it
|
|
GConfig->GetString(TEXT("LandscapeEdit"), TEXT("NewLandscapeMaterialName"), NewLandscapeMaterialName, GEditorPerProjectIni);
|
|
|
|
if (NewLandscapeMaterialName.IsEmpty())
|
|
{
|
|
/* Project does not have a saved NewLandscapeMaterialNameand and NewLandscape_Material is not already assigned;
|
|
* we fallback to the DefaultLandscapeMaterial for the project, if set */
|
|
const ULandscapeSettings* Settings = GetDefault<ULandscapeSettings>();
|
|
TSoftObjectPtr<UMaterialInterface> DefaultMaterial = Settings->GetDefaultLandscapeMaterial();
|
|
|
|
if (!DefaultMaterial.IsNull())
|
|
{
|
|
NewLandscapeMaterialName = DefaultMaterial.ToString();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!NewLandscapeMaterialName.IsEmpty())
|
|
{
|
|
NewLandscape_Material = LoadObject<UMaterialInterface>(NULL, *NewLandscapeMaterialName, NULL, LOAD_NoWarn);
|
|
}
|
|
|
|
int32 AlphamapType = (uint8)ImportLandscape_AlphamapType;
|
|
GConfig->GetInt(TEXT("LandscapeEdit"), TEXT("ImportLandscape_AlphamapType"), AlphamapType, GEditorPerProjectIni);
|
|
ImportLandscape_AlphamapType = (ELandscapeImportAlphamapType)AlphamapType;
|
|
|
|
RefreshImportLayersList();
|
|
}
|
|
|
|
/** Save UI settings to ini file */
|
|
void ULandscapeEditorObject::Save()
|
|
{
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("ToolStrength"), ToolStrength, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("WeightTargetValue"), WeightTargetValue, GEditorPerProjectIni);
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bUseWeightTargetValue"), bUseWeightTargetValue, GEditorPerProjectIni);
|
|
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("BrushRadius"), BrushRadius, GEditorPerProjectIni);
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("BrushComponentSize"), BrushComponentSize, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("BrushFalloff"), BrushFalloff, GEditorPerProjectIni);
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bUseClayBrush"), bUseClayBrush, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("AlphaBrushScale"), AlphaBrushScale, GEditorPerProjectIni);
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("AlphaBrushAutoRotate"), bAlphaBrushAutoRotate, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("AlphaBrushRotation"), AlphaBrushRotation, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("AlphaBrushPanU"), AlphaBrushPanU, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("AlphaBrushPanV"), AlphaBrushPanV, GEditorPerProjectIni);
|
|
GConfig->SetVector2D(TEXT("LandscapeEdit"), TEXT("WorldSpacePatternBrushSettings.Origin"), WorldSpacePatternBrushSettings.Origin, GEditorPerProjectIni);
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("WorldSpacePatternBrushSettings.bCenterTextureOnOrigin"), WorldSpacePatternBrushSettings.bCenterTextureOnOrigin, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("WorldSpacePatternBrushSettings.RepeatSize"), WorldSpacePatternBrushSettings.RepeatSize, GEditorPerProjectIni);
|
|
const FString AlphaTextureName = (AlphaTexture != NULL) ? AlphaTexture->GetPathName() : FString();
|
|
GConfig->SetString(TEXT("LandscapeEdit"), TEXT("AlphaTextureName"), *AlphaTextureName, GEditorPerProjectIni);
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("AlphaTextureChannel"), (int32)AlphaTextureChannel, GEditorPerProjectIni);
|
|
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("FlattenMode"), (int32)FlattenMode, GEditorPerProjectIni);
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bUseSlopeFlatten"), bUseSlopeFlatten, GEditorPerProjectIni);
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bPickValuePerApply"), bPickValuePerApply, GEditorPerProjectIni);
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bUseFlattenTarget"), bUseFlattenTarget, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("FlattenTarget"), FlattenTarget, GEditorPerProjectIni);
|
|
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("TerraceSmooth"), TerraceSmooth, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("TerraceInterval"), TerraceInterval, GEditorPerProjectIni);
|
|
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("RampWidth"), RampWidth, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("RampSideFalloff"), RampSideFalloff, GEditorPerProjectIni);
|
|
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bCombinedLayersOperation"), bCombinedLayersOperation, GEditorPerProjectIni);
|
|
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("ErodeThresh"), ErodeThresh, GEditorPerProjectIni);
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("ErodeIterationNum"), ErodeIterationNum, GEditorPerProjectIni);
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("ErodeSurfaceThickness"), ErodeSurfaceThickness, GEditorPerProjectIni);
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("ErosionNoiseMode"), (int32)ErosionNoiseMode, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("ErosionNoiseScale"), ErosionNoiseScale, GEditorPerProjectIni);
|
|
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("RainAmount"), RainAmount, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("SedimentCapacity"), SedimentCapacity, GEditorPerProjectIni);
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("HErodeIterationNum"), ErodeIterationNum, GEditorPerProjectIni);
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("RainDistMode"), (int32)RainDistMode, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("RainDistScale"), RainDistScale, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("HErosionDetailScale"), HErosionDetailScale, GEditorPerProjectIni);
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bHErosionDetailSmooth"), bHErosionDetailSmooth, GEditorPerProjectIni);
|
|
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("NoiseMode"), (int32)NoiseMode, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("NoiseScale"), NoiseScale, GEditorPerProjectIni);
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("SmoothFilterKernelSize"), SmoothFilterKernelSize, GEditorPerProjectIni);
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("DetailScale"), DetailScale, GEditorPerProjectIni);
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bDetailSmooth"), bDetailSmooth, GEditorPerProjectIni);
|
|
|
|
GConfig->SetFloat(TEXT("LandscapeEdit"), TEXT("MaximumValueRadius"), MaximumValueRadius, GEditorPerProjectIni);
|
|
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bSmoothGizmoBrush"), bSmoothGizmoBrush, GEditorPerProjectIni);
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("PasteMode"), (int32)PasteMode, GEditorPerProjectIni);
|
|
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("MirrorOp"), (int32)MirrorOp, GEditorPerProjectIni);
|
|
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("ConvertMode"), (int32)ResizeLandscape_ConvertMode, GEditorPerProjectIni);
|
|
//GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bUseSelectedRegion"), bUseSelectedRegion, GEditorPerProjectIni);
|
|
//GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bUseNegativeMask"), bUseNegativeMask, GEditorPerProjectIni);
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("bApplyToAllTargets"), bApplyToAllTargets, GEditorPerProjectIni);
|
|
|
|
const FString NewLandscapeMaterialName = (NewLandscape_Material != NULL) ? NewLandscape_Material->GetPathName() : FString();
|
|
GConfig->SetString(TEXT("LandscapeEdit"), TEXT("NewLandscapeMaterialName"), *NewLandscapeMaterialName, GEditorPerProjectIni);
|
|
|
|
GConfig->SetInt(TEXT("LandscapeEdit"), TEXT("ImportLandscape_AlphamapType"), (uint8)ImportLandscape_AlphamapType, GEditorPerProjectIni);
|
|
|
|
GConfig->SetBool(TEXT("LandscapeEdit"), TEXT("ShowUnusedLayers"), ShowUnusedLayers, GEditorPerProjectIni);
|
|
}
|
|
|
|
// Region
|
|
void ULandscapeEditorObject::SetbUseSelectedRegion(bool InbUseSelectedRegion)
|
|
{
|
|
bUseSelectedRegion = InbUseSelectedRegion;
|
|
if (bUseSelectedRegion)
|
|
{
|
|
GLandscapeEditRenderMode |= ELandscapeEditRenderMode::Mask;
|
|
}
|
|
else
|
|
{
|
|
GLandscapeEditRenderMode &= ~(ELandscapeEditRenderMode::Mask);
|
|
}
|
|
}
|
|
void ULandscapeEditorObject::SetbUseNegativeMask(bool InbUseNegativeMask)
|
|
{
|
|
bUseNegativeMask = InbUseNegativeMask;
|
|
if (bUseNegativeMask)
|
|
{
|
|
GLandscapeEditRenderMode |= ELandscapeEditRenderMode::InvertedMask;
|
|
}
|
|
else
|
|
{
|
|
GLandscapeEditRenderMode &= ~(ELandscapeEditRenderMode::InvertedMask);
|
|
}
|
|
}
|
|
|
|
void ULandscapeEditorObject::SetPasteMode(ELandscapeToolPasteMode InPasteMode)
|
|
{
|
|
PasteMode = InPasteMode;
|
|
}
|
|
|
|
void ULandscapeEditorObject::SetbSnapGizmo(bool InbSnapGizmo)
|
|
{
|
|
bSnapGizmo = InbSnapGizmo;
|
|
|
|
if (ParentMode->CurrentGizmoActor.IsValid())
|
|
{
|
|
ParentMode->CurrentGizmoActor->bSnapToLandscapeGrid = bSnapGizmo;
|
|
}
|
|
|
|
if (bSnapGizmo)
|
|
{
|
|
if (ParentMode->CurrentGizmoActor.IsValid())
|
|
{
|
|
check(ParentMode->CurrentGizmoActor->TargetLandscapeInfo);
|
|
|
|
const FVector WidgetLocation = ParentMode->CurrentGizmoActor->GetActorLocation();
|
|
const FRotator WidgetRotation = ParentMode->CurrentGizmoActor->GetActorRotation();
|
|
|
|
const FVector SnappedWidgetLocation = ParentMode->CurrentGizmoActor->SnapToLandscapeGrid(WidgetLocation);
|
|
const FRotator SnappedWidgetRotation = ParentMode->CurrentGizmoActor->SnapToLandscapeGrid(WidgetRotation);
|
|
|
|
ParentMode->CurrentGizmoActor->SetActorLocation(SnappedWidgetLocation, false);
|
|
ParentMode->CurrentGizmoActor->SetActorRotation(SnappedWidgetRotation);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool ULandscapeEditorObject::SetAlphaTexture(UTexture2D* InTexture, EColorChannel::Type InTextureChannel)
|
|
{
|
|
bool Result = true;
|
|
|
|
TArray64<uint8> NewTextureData;
|
|
UTexture2D* NewAlphaTexture = InTexture;
|
|
|
|
// No texture or no source art, try to use the previous texture.
|
|
if (NewAlphaTexture == NULL || !NewAlphaTexture->Source.IsValid())
|
|
{
|
|
NewAlphaTexture = AlphaTexture;
|
|
Result = false;
|
|
}
|
|
|
|
if (NewAlphaTexture != NULL && NewAlphaTexture->Source.IsValid())
|
|
{
|
|
NewAlphaTexture->Source.GetMipData(NewTextureData, 0);
|
|
}
|
|
|
|
const bool bSourceDataIsG8 = NewAlphaTexture != NULL && NewAlphaTexture->Source.IsValid() && NewAlphaTexture->Source.GetFormat() == TSF_G8;
|
|
const int32 NumChannels = bSourceDataIsG8 ? 1 : 4;
|
|
|
|
// Load fallback if there's no texture or data
|
|
if (NewAlphaTexture == NULL || (NewTextureData.Num() != NumChannels * NewAlphaTexture->Source.GetSizeX() * NewAlphaTexture->Source.GetSizeY()))
|
|
{
|
|
NewAlphaTexture = GetClass()->GetDefaultObject<ULandscapeEditorObject>()->AlphaTexture;
|
|
if (NewAlphaTexture)
|
|
{
|
|
NewAlphaTexture->Source.GetMipData(NewTextureData, 0);
|
|
}
|
|
Result = false;
|
|
}
|
|
|
|
if (NewAlphaTexture)
|
|
{
|
|
AlphaTexture = NewAlphaTexture;
|
|
AlphaTextureSizeX = NewAlphaTexture->Source.GetSizeX();
|
|
AlphaTextureSizeY = NewAlphaTexture->Source.GetSizeY();
|
|
AlphaTextureChannel = NumChannels == 1 ? EColorChannel::Red : InTextureChannel;
|
|
AlphaTextureData.Empty(AlphaTextureSizeX * AlphaTextureSizeY);
|
|
|
|
if (NewTextureData.Num() != NumChannels * AlphaTextureSizeX * AlphaTextureSizeY)
|
|
{
|
|
// Don't crash if for some reason we couldn't load any source art
|
|
AlphaTextureData.AddZeroed(AlphaTextureSizeX * AlphaTextureSizeY);
|
|
}
|
|
else
|
|
{
|
|
uint8* SrcPtr;
|
|
switch (AlphaTextureChannel)
|
|
{
|
|
case 1:
|
|
SrcPtr = &((FColor*)NewTextureData.GetData())->G;
|
|
break;
|
|
case 2:
|
|
SrcPtr = &((FColor*)NewTextureData.GetData())->B;
|
|
break;
|
|
case 3:
|
|
SrcPtr = &((FColor*)NewTextureData.GetData())->A;
|
|
break;
|
|
default:
|
|
SrcPtr = &((FColor*)NewTextureData.GetData())->R;
|
|
break;
|
|
}
|
|
|
|
for (int32 i = 0; i < AlphaTextureSizeX * AlphaTextureSizeY; i++)
|
|
{
|
|
AlphaTextureData.Add(*SrcPtr);
|
|
SrcPtr += NumChannels;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
void ULandscapeEditorObject::ChooseBestComponentSizeForImport()
|
|
{
|
|
FLandscapeImportHelper::ChooseBestComponentSizeForImport(ImportLandscape_Width, ImportLandscape_Height, NewLandscape_QuadsPerSection, NewLandscape_SectionsPerComponent, NewLandscape_ComponentCount);
|
|
}
|
|
|
|
bool ULandscapeEditorObject::UseSingleFileImport() const
|
|
{
|
|
if (ParentMode)
|
|
{
|
|
return ParentMode->UseSingleFileImport();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void ULandscapeEditorObject::RefreshImports()
|
|
{
|
|
ClearImportLandscapeData();
|
|
HeightmapImportDescriptorIndex = 0;
|
|
HeightmapImportDescriptor.Reset();
|
|
ImportLandscape_Width = 0;
|
|
ImportLandscape_Height = 0;
|
|
|
|
ImportLandscape_HeightmapImportResult = ELandscapeImportResult::Success;
|
|
ImportLandscape_HeightmapErrorMessage = FText();
|
|
|
|
if (!ImportLandscape_HeightmapFilename.IsEmpty())
|
|
{
|
|
ImportLandscape_HeightmapImportResult =
|
|
FLandscapeImportHelper::GetHeightmapImportDescriptor(ImportLandscape_HeightmapFilename, UseSingleFileImport(), bFlipYAxis, HeightmapImportDescriptor, ImportLandscape_HeightmapErrorMessage);
|
|
if (ImportLandscape_HeightmapImportResult != ELandscapeImportResult::Error)
|
|
{
|
|
ImportLandscape_Width = HeightmapImportDescriptor.ImportResolutions[HeightmapImportDescriptorIndex].Width;
|
|
ImportLandscape_Height = HeightmapImportDescriptor.ImportResolutions[HeightmapImportDescriptorIndex].Height;
|
|
ChooseBestComponentSizeForImport();
|
|
ImportLandscapeData();
|
|
}
|
|
}
|
|
|
|
RefreshLayerImports();
|
|
}
|
|
|
|
void ULandscapeEditorObject::RefreshLayerImports()
|
|
{
|
|
// Make sure to reset import width and height if we don't have a Heightmap to import
|
|
if (ImportLandscape_HeightmapFilename.IsEmpty())
|
|
{
|
|
HeightmapImportDescriptorIndex = 0;
|
|
ImportLandscape_Width = 0;
|
|
ImportLandscape_Height = 0;
|
|
}
|
|
|
|
for (FLandscapeImportLayer& UIImportLayer : ImportLandscape_Layers)
|
|
{
|
|
RefreshLayerImport(UIImportLayer);
|
|
}
|
|
}
|
|
|
|
void ULandscapeEditorObject::RefreshLayerImport(FLandscapeImportLayer& ImportLayer)
|
|
{
|
|
ImportLayer.ErrorMessage = FText();
|
|
ImportLayer.ImportResult = ELandscapeImportResult::Success;
|
|
|
|
if (!ImportLayer.SourceFilePath.IsEmpty())
|
|
{
|
|
if (!ImportLayer.LayerInfo)
|
|
{
|
|
ImportLayer.ImportResult = ELandscapeImportResult::Error;
|
|
ImportLayer.ErrorMessage = NSLOCTEXT("LandscapeEditor.NewLandscape", "Import_LayerInfoNotSet", "Can't import a layer file without a layer info");
|
|
}
|
|
else
|
|
{
|
|
ImportLayer.ImportResult = FLandscapeImportHelper::GetWeightmapImportDescriptor(ImportLayer.SourceFilePath, UseSingleFileImport(), bFlipYAxis, ImportLayer.LayerName, ImportLayer.ImportDescriptor, ImportLayer.ErrorMessage);
|
|
if (ImportLayer.ImportResult != ELandscapeImportResult::Error)
|
|
{
|
|
if (ImportLandscape_Height != 0 || ImportLandscape_Width != 0)
|
|
{
|
|
// Use same import index as Heightmap
|
|
int32 FoundIndex = INDEX_NONE;
|
|
for (int32 Index = 0; Index < ImportLayer.ImportDescriptor.FileResolutions.Num(); ++Index)
|
|
{
|
|
if (ImportLayer.ImportDescriptor.ImportResolutions[Index] == HeightmapImportDescriptor.ImportResolutions[HeightmapImportDescriptorIndex])
|
|
{
|
|
FoundIndex = Index;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (FoundIndex == INDEX_NONE)
|
|
{
|
|
ImportLayer.ImportResult = ELandscapeImportResult::Error;
|
|
ImportLayer.ErrorMessage = NSLOCTEXT("LandscapeEditor.ImportLandscape", "Import_WeightHeightResolutionMismatch", "Weightmap import resolution isn't same as Heightmap resolution.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ULandscapeEditorObject::OnChangeImportLandscapeResolution(int32 DescriptorIndex)
|
|
{
|
|
check(DescriptorIndex >= 0 && DescriptorIndex < HeightmapImportDescriptor.ImportResolutions.Num());
|
|
HeightmapImportDescriptorIndex = DescriptorIndex;
|
|
ImportLandscape_Width = HeightmapImportDescriptor.ImportResolutions[HeightmapImportDescriptorIndex].Width;
|
|
ImportLandscape_Height = HeightmapImportDescriptor.ImportResolutions[HeightmapImportDescriptorIndex].Height;
|
|
ClearImportLandscapeData();
|
|
ImportLandscapeData();
|
|
ChooseBestComponentSizeForImport();
|
|
}
|
|
|
|
void ULandscapeEditorObject::ImportLandscapeData()
|
|
{
|
|
ImportLandscape_HeightmapImportResult = FLandscapeImportHelper::GetHeightmapImportData(HeightmapImportDescriptor, HeightmapImportDescriptorIndex, ImportLandscape_Data, ImportLandscape_HeightmapErrorMessage);
|
|
if (ImportLandscape_HeightmapImportResult == ELandscapeImportResult::Error)
|
|
{
|
|
ImportLandscape_Data.Empty();
|
|
}
|
|
}
|
|
|
|
ELandscapeImportResult ULandscapeEditorObject::CreateImportLayersInfo(TArray<FLandscapeImportLayerInfo>& OutImportLayerInfos)
|
|
{
|
|
const uint32 ImportSizeX = ImportLandscape_Width;
|
|
const uint32 ImportSizeY = ImportLandscape_Height;
|
|
|
|
if (ImportLandscape_HeightmapImportResult == ELandscapeImportResult::Error)
|
|
{
|
|
// Cancel import
|
|
return ELandscapeImportResult::Error;
|
|
}
|
|
|
|
OutImportLayerInfos.Reserve(ImportLandscape_Layers.Num());
|
|
|
|
// Fill in LayerInfos array and allocate data
|
|
for (FLandscapeImportLayer& UIImportLayer : ImportLandscape_Layers)
|
|
{
|
|
OutImportLayerInfos.Add((const FLandscapeImportLayer&)UIImportLayer); //slicing is fine here
|
|
FLandscapeImportLayerInfo& ImportLayer = OutImportLayerInfos.Last();
|
|
|
|
if (ImportLayer.LayerInfo != nullptr && !ImportLayer.SourceFilePath.IsEmpty())
|
|
{
|
|
UIImportLayer.ImportResult = FLandscapeImportHelper::GetWeightmapImportDescriptor(ImportLayer.SourceFilePath, UseSingleFileImport(), bFlipYAxis, ImportLayer.LayerName, UIImportLayer.ImportDescriptor, UIImportLayer.ErrorMessage);
|
|
if (UIImportLayer.ImportResult == ELandscapeImportResult::Error)
|
|
{
|
|
FMessageDialog::Open(EAppMsgType::Ok, UIImportLayer.ErrorMessage);
|
|
return ELandscapeImportResult::Error;
|
|
}
|
|
|
|
// Use same import index as Heightmap
|
|
int32 FoundIndex = INDEX_NONE;
|
|
for (int32 Index = 0; Index < UIImportLayer.ImportDescriptor.FileResolutions.Num(); ++Index)
|
|
{
|
|
if (UIImportLayer.ImportDescriptor.ImportResolutions[Index] == HeightmapImportDescriptor.ImportResolutions[HeightmapImportDescriptorIndex])
|
|
{
|
|
FoundIndex = Index;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (FoundIndex == INDEX_NONE)
|
|
{
|
|
UIImportLayer.ImportResult = ELandscapeImportResult::Error;
|
|
UIImportLayer.ErrorMessage = NSLOCTEXT("LandscapeEditor.NewLandscape", "Import_WeightHeightResolutionMismatch", "Weightmap import resolution isn't same as Heightmap resolution.");
|
|
FMessageDialog::Open(EAppMsgType::Ok, UIImportLayer.ErrorMessage);
|
|
return ELandscapeImportResult::Error;
|
|
}
|
|
|
|
UIImportLayer.ImportResult = FLandscapeImportHelper::GetWeightmapImportData(UIImportLayer.ImportDescriptor, FoundIndex, ImportLayer.LayerName, ImportLayer.LayerData, UIImportLayer.ErrorMessage);
|
|
if (UIImportLayer.ImportResult == ELandscapeImportResult::Error)
|
|
{
|
|
FMessageDialog::Open(EAppMsgType::Ok, UIImportLayer.ErrorMessage);
|
|
return ELandscapeImportResult::Error;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ELandscapeImportResult::Success;
|
|
}
|
|
|
|
ELandscapeImportResult ULandscapeEditorObject::CreateNewLayersInfo(TArray<FLandscapeImportLayerInfo>& OutNewLayerInfos)
|
|
{
|
|
const int32 QuadsPerComponent = NewLandscape_SectionsPerComponent * NewLandscape_QuadsPerSection;
|
|
const int32 SizeX = NewLandscape_ComponentCount.X * QuadsPerComponent + 1;
|
|
const int32 SizeY = NewLandscape_ComponentCount.Y * QuadsPerComponent + 1;
|
|
|
|
OutNewLayerInfos.Reset(ImportLandscape_Layers.Num());
|
|
|
|
// Fill in LayerInfos array and allocate data
|
|
for (const FLandscapeImportLayer& UIImportLayer : ImportLandscape_Layers)
|
|
{
|
|
FLandscapeImportLayerInfo ImportLayer = FLandscapeImportLayerInfo(UIImportLayer.LayerName);
|
|
ImportLayer.LayerInfo = UIImportLayer.LayerInfo;
|
|
ImportLayer.SourceFilePath = "";
|
|
ImportLayer.LayerData = TArray<uint8>();
|
|
OutNewLayerInfos.Add(MoveTemp(ImportLayer));
|
|
}
|
|
|
|
// Fill the first weight-blended layer to 100%
|
|
if (FLandscapeImportLayerInfo* FirstBlendedLayer = OutNewLayerInfos.FindByPredicate([](const FLandscapeImportLayerInfo& ImportLayer) { return ImportLayer.LayerInfo && !ImportLayer.LayerInfo->bNoWeightBlend; }))
|
|
{
|
|
const int32 DataSize = SizeX * SizeY;
|
|
FirstBlendedLayer->LayerData.AddUninitialized(DataSize);
|
|
|
|
uint8* ByteData = FirstBlendedLayer->LayerData.GetData();
|
|
FMemory::Memset(ByteData, 255, DataSize);
|
|
}
|
|
|
|
return ELandscapeImportResult::Success;
|
|
}
|
|
|
|
void ULandscapeEditorObject::InitializeDefaultHeightData(TArray<uint16>& OutData)
|
|
{
|
|
const int32 QuadsPerComponent = NewLandscape_SectionsPerComponent * NewLandscape_QuadsPerSection;
|
|
const int32 SizeX = NewLandscape_ComponentCount.X * QuadsPerComponent + 1;
|
|
const int32 SizeY = NewLandscape_ComponentCount.Y * QuadsPerComponent + 1;
|
|
const int32 TotalSize = SizeX * SizeY;
|
|
// Initialize heightmap data
|
|
OutData.Reset();
|
|
OutData.AddUninitialized(TotalSize);
|
|
|
|
TArray<uint16> StrideData;
|
|
StrideData.AddUninitialized(SizeX);
|
|
// Initialize blank heightmap data
|
|
for (int32 X = 0; X < SizeX; ++X)
|
|
{
|
|
StrideData[X] = LandscapeDataAccess::MidValue;
|
|
}
|
|
for (int32 Y = 0; Y < SizeY; ++Y)
|
|
{
|
|
FMemory::Memcpy(&OutData[Y * SizeX], StrideData.GetData(), sizeof(uint16) * SizeX);
|
|
}
|
|
}
|
|
|
|
void ULandscapeEditorObject::ExpandImportData(TArray<uint16>& OutHeightData, TArray<FLandscapeImportLayerInfo>& OutImportLayerInfos)
|
|
{
|
|
const TArray<uint16>& ImportData = GetImportLandscapeData();
|
|
if (ImportData.Num())
|
|
{
|
|
const int32 QuadsPerComponent = NewLandscape_SectionsPerComponent * NewLandscape_QuadsPerSection;
|
|
FLandscapeImportResolution RequiredResolution(NewLandscape_ComponentCount.X * QuadsPerComponent + 1, NewLandscape_ComponentCount.Y * QuadsPerComponent + 1);
|
|
FLandscapeImportResolution ImportResolution(ImportLandscape_Width, ImportLandscape_Height);
|
|
|
|
FLandscapeImportHelper::TransformHeightmapImportData(ImportData, OutHeightData, ImportResolution, RequiredResolution, ELandscapeImportTransformType::ExpandCentered);
|
|
|
|
for (int32 LayerIdx = 0; LayerIdx < OutImportLayerInfos.Num(); ++LayerIdx)
|
|
{
|
|
TArray<uint8>& OutImportLayerData = OutImportLayerInfos[LayerIdx].LayerData;
|
|
TArray<uint8> OutLayerData;
|
|
if (OutImportLayerData.Num())
|
|
{
|
|
FLandscapeImportHelper::TransformWeightmapImportData(OutImportLayerData, OutLayerData, ImportResolution, RequiredResolution, ELandscapeImportTransformType::ExpandCentered);
|
|
OutImportLayerData = MoveTemp(OutLayerData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ULandscapeEditorObject::RefreshImportLayersList(bool bRefreshFromTarget)
|
|
{
|
|
UTexture2D* ThumbnailWeightmap = nullptr;
|
|
UTexture2D* ThumbnailHeightmap = nullptr;
|
|
|
|
TArray<FName> LayerNames;
|
|
TArray<ULandscapeLayerInfoObject*> LayerInfoObjs;
|
|
UMaterialInterface* Material = nullptr;
|
|
if (bRefreshFromTarget)
|
|
{
|
|
LayerNames.Reset(ImportLandscape_Layers.Num());
|
|
LayerInfoObjs.Reset(ImportLandscape_Layers.Num());
|
|
Material = ParentMode->GetTargetLandscapeMaterial();
|
|
for (const TSharedRef<FLandscapeTargetListInfo>& TargetListInfo : ParentMode->GetTargetList())
|
|
{
|
|
if (TargetListInfo->TargetType != ELandscapeToolTargetType::Weightmap)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
LayerNames.Add(TargetListInfo->LayerName);
|
|
LayerInfoObjs.Add(TargetListInfo->LayerInfoObj.Get());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Material = NewLandscape_Material.Get();
|
|
LayerNames = ALandscapeProxy::GetLayersFromMaterial(Material);
|
|
}
|
|
|
|
const TArray<FLandscapeImportLayer> OldLayersList = MoveTemp(ImportLandscape_Layers);
|
|
ImportLandscape_Layers.Reset(LayerNames.Num());
|
|
|
|
for (int32 i = 0; i < LayerNames.Num(); i++)
|
|
{
|
|
const FName& LayerName = LayerNames[i];
|
|
|
|
bool bFound = false;
|
|
FLandscapeImportLayer NewImportLayer;
|
|
NewImportLayer.ImportResult = ELandscapeImportResult::Success;
|
|
NewImportLayer.ErrorMessage = FText();
|
|
|
|
for (int32 j = 0; j < OldLayersList.Num(); j++)
|
|
{
|
|
if (OldLayersList[j].LayerName == LayerName)
|
|
{
|
|
NewImportLayer = OldLayersList[j];
|
|
bFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bFound)
|
|
{
|
|
if (NewImportLayer.ThumbnailMIC->Parent != Material)
|
|
{
|
|
FMaterialUpdateContext Context;
|
|
NewImportLayer.ThumbnailMIC->SetParentEditorOnly(Material);
|
|
Context.AddMaterialInterface(NewImportLayer.ThumbnailMIC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!ThumbnailWeightmap)
|
|
{
|
|
ThumbnailWeightmap = LoadObject<UTexture2D>(NULL, TEXT("/Engine/EditorLandscapeResources/LandscapeThumbnailWeightmap.LandscapeThumbnailWeightmap"), NULL, LOAD_None, NULL);
|
|
}
|
|
|
|
if (!ThumbnailHeightmap)
|
|
{
|
|
ThumbnailHeightmap = LoadObject<UTexture2D>(NULL, TEXT("/Engine/EditorLandscapeResources/LandscapeThumbnailHeightmap.LandscapeThumbnailHeightmap"), NULL, LOAD_None, NULL);
|
|
}
|
|
|
|
NewImportLayer.LayerName = LayerName;
|
|
NewImportLayer.ThumbnailMIC = ALandscapeProxy::GetLayerThumbnailMIC(Material, LayerName, ThumbnailWeightmap, ThumbnailHeightmap, nullptr);
|
|
}
|
|
|
|
if (bRefreshFromTarget)
|
|
{
|
|
NewImportLayer.LayerInfo = LayerInfoObjs[i];
|
|
}
|
|
|
|
RefreshLayerImport(NewImportLayer);
|
|
|
|
ImportLandscape_Layers.Add(MoveTemp(NewImportLayer));
|
|
}
|
|
}
|
|
|
|
void ULandscapeEditorObject::UpdateComponentLayerAllowList()
|
|
{
|
|
if (ParentMode->CurrentToolTarget.LandscapeInfo.IsValid())
|
|
{
|
|
ParentMode->CurrentToolTarget.LandscapeInfo->UpdateComponentLayerAllowList();
|
|
}
|
|
}
|
|
|
|
void ULandscapeEditorObject::UpdateTargetLayerDisplayOrder()
|
|
{
|
|
if (ParentMode != nullptr)
|
|
{
|
|
ParentMode->UpdateTargetLayerDisplayOrder(TargetDisplayOrder);
|
|
}
|
|
}
|
|
|
|
void ULandscapeEditorObject::UpdateShowUnusedLayers()
|
|
{
|
|
if (ParentMode != nullptr)
|
|
{
|
|
ParentMode->UpdateShownLayerList();
|
|
}
|
|
}
|
|
|