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();
	}
}
Exemplo n.º 4
0
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();
	}
}