void FLODUtilities::SimplifySkeletalMeshLOD( USkeletalMesh* SkeletalMesh, const FSkeletalMeshOptimizationSettings& InSetting, int32 DesiredLOD, bool bReregisterComponent /*= true*/ ) { IMeshUtilities& MeshUtilities = FModuleManager::Get().LoadModuleChecked<IMeshUtilities>("MeshUtilities"); IMeshReduction* MeshReduction = MeshUtilities.GetMeshReductionInterface(); check (MeshReduction && MeshReduction->IsSupported()); { FFormatNamedArguments Args; Args.Add(TEXT("DesiredLOD"), DesiredLOD); Args.Add(TEXT("SkeletalMeshName"), FText::FromString(SkeletalMesh->GetName())); const FText StatusUpdate = FText::Format(NSLOCTEXT("UnrealEd", "MeshSimp_GeneratingLOD_F", "Generating LOD{DesiredLOD} for {SkeletalMeshName}..."), Args); GWarn->BeginSlowTask(StatusUpdate, true); } bool bRecalcLOD = ( !SkeletalMesh->LODInfo.IsValidIndex(DesiredLOD) ); if (MeshReduction->ReduceSkeletalMesh(SkeletalMesh, DesiredLOD, InSetting, bRecalcLOD, bReregisterComponent)) { check(SkeletalMesh->LODInfo.Num() >= 2); SkeletalMesh->MarkPackageDirty(); #if WITH_APEX_CLOTHING ApexClothingUtils::ReImportClothingSectionsFromClothingAsset(SkeletalMesh); #endif// #if WITH_APEX_CLOTHING } else { // Simplification failed! Warn the user. FFormatNamedArguments Args; Args.Add(TEXT("SkeletalMeshName"), FText::FromString(SkeletalMesh->GetName())); const FText Message = FText::Format(NSLOCTEXT("UnrealEd", "MeshSimp_GenerateLODFailed_F", "An error occurred while simplifying the geometry for mesh '{SkeletalMeshName}'. Consider adjusting simplification parameters and re-simplifying the mesh."), Args); FMessageDialog::Open(EAppMsgType::Ok, Message); } GWarn->EndSlowTask(); }
void FLODUtilities::SimplifySkeletalMesh( FSkeletalMeshUpdateContext& UpdateContext, TArray<FSkeletalMeshOptimizationSettings> &InSettings, bool bForceRegenerate ) { USkeletalMesh* SkeletalMesh = UpdateContext.SkeletalMesh; IMeshUtilities& MeshUtilities = FModuleManager::Get().LoadModuleChecked<IMeshUtilities>("MeshUtilities"); IMeshReduction* MeshReduction = MeshUtilities.GetMeshReductionInterface(); if ( MeshReduction && MeshReduction->IsSupported() && SkeletalMesh ) { // Simplify each LOD for (int32 SettingIndex = 0; SettingIndex < InSettings.Num(); ++SettingIndex) { uint32 DesiredLOD = SettingIndex + 1; // check whether reduction settings are same or not if (!bForceRegenerate && SkeletalMesh->LODInfo.IsValidIndex(DesiredLOD) && SkeletalMesh->LODInfo[DesiredLOD].ReductionSettings == InSettings[SettingIndex]) { continue; } SimplifySkeletalMeshLOD( SkeletalMesh, InSettings[SettingIndex], DesiredLOD ); } //Notify calling system of change UpdateContext.OnLODChanged.ExecuteIfBound(); } }
void FLODUtilities::SimplifySkeletalMeshLOD(FSkeletalMeshUpdateContext& UpdateContext, const FSkeletalMeshOptimizationSettings& Setting, int32 DesiredLOD, bool bReregisterComponent /*= true*/) { USkeletalMesh* SkeletalMesh = UpdateContext.SkeletalMesh; IMeshUtilities& MeshUtilities = FModuleManager::Get().LoadModuleChecked<IMeshUtilities>("MeshUtilities"); IMeshReduction* MeshReduction = MeshUtilities.GetMeshReductionInterface(); if (MeshReduction && MeshReduction->IsSupported() && SkeletalMesh) { SimplifySkeletalMeshLOD(SkeletalMesh, Setting, DesiredLOD, bReregisterComponent); //Notify calling system of change UpdateContext.OnLODChanged.ExecuteIfBound(); } }
void FLODUtilities::SimplifySkeletalMesh(FSkeletalMeshUpdateContext& UpdateContext, TArray<FSkeletalMeshOptimizationSettings> &InSettings, TArray<FSimplygonRemeshingSettings> &InRemeshingSettings, bool bForceRegenerate) { USkeletalMesh* SkeletalMesh = UpdateContext.SkeletalMesh; IMeshUtilities& MeshUtilities = FModuleManager::Get().LoadModuleChecked<IMeshUtilities>("MeshUtilities"); IMeshReduction* MeshReduction = MeshUtilities.GetMeshReductionInterface(); if ( MeshReduction && MeshReduction->IsSupported() && SkeletalMesh ) { // Simplify each LOD //@third party code BEGIN SIMPLYGON bool MeshBuilt[MAX_SKELETAL_MESH_LODS]; FMemory::Memzero(MeshBuilt); //@third party code END SIMPLYGON for (int32 SettingIndex = 0; SettingIndex < InSettings.Num(); ++SettingIndex) { uint32 DesiredLOD = SettingIndex + 1; // check whether reduction settings are same or not //@third party code BEGIN SIMPLYGON check(InSettings.Num() == InRemeshingSettings.Num()); if (!bForceRegenerate && SkeletalMesh->LODInfo.IsValidIndex(DesiredLOD)) { const FSkeletalMeshOptimizationSettings& NewReductionSettings = InSettings[SettingIndex]; const FSimplygonRemeshingSettings& NewRemeshingSettings = InRemeshingSettings[SettingIndex]; bool IsReduction = !NewRemeshingSettings.bActive; // check bForceBuild property, reset it immediately bool bForceBuildThisLOD = NewReductionSettings.bForceRebuild; InSettings[SettingIndex].bForceRebuild = false; if (IsReduction) { const FSkeletalMeshOptimizationSettings& CurrentReductionSettings = SkeletalMesh->LODInfo[DesiredLOD].ReductionSettings; int32 ParentLOD = NewReductionSettings.BaseLODModel; if (CurrentReductionSettings == NewReductionSettings && CurrentReductionSettings.MaterialLODSettings == NewReductionSettings.MaterialLODSettings && !MeshBuilt[ParentLOD] && !bForceBuildThisLOD) { continue; } } else { const FSimplygonRemeshingSettings& CurrentRemeshingSettings = SkeletalMesh->LODInfo[DesiredLOD].RemeshingSettings; if (CurrentRemeshingSettings == NewRemeshingSettings && CurrentRemeshingSettings.MaterialLODSettings == NewRemeshingSettings.MaterialLODSettings && !bForceBuildThisLOD) { continue; } } } MeshBuilt[DesiredLOD] = true; //@third party code END SIMPLYGON SimplifySkeletalMeshLOD(SkeletalMesh, InSettings[SettingIndex], InRemeshingSettings[SettingIndex], DesiredLOD); } //Notify calling system of change UpdateContext.OnLODChanged.ExecuteIfBound(); } }