Files
UnrealEngineUWP/Engine/Plugins/Experimental/MeshModelingToolset/Source/ModelingComponents/Private/AssetUtils/MeshDescriptionUtil.cpp
Richard TalbotWatkin 51d4cb3f66 Fully deprecated old MeshDescription APIs.
Prepared direct attribute access for deprecation, preferring use of APIs to access static mesh attributes.
Fixed recently merged Enterprise code to comply with new APIs.
Changed all tools to use triangle-centric iteration where possible.
Added new MeshAttributeArray APIs for querying attribute flags, and added a new Mandatory flag.
Various bug fixes.
#rb Alexis.Matte

[CL 13873755 by Richard TalbotWatkin in ue5-main branch]
2020-07-16 08:23:15 -04:00

109 lines
4.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "AssetUtils/MeshDescriptionUtil.h"
#include "Engine/StaticMesh.h"
#include "Engine/Classes/Components/StaticMeshComponent.h"
#include "StaticMeshAttributes.h"
#include "StaticMeshOperations.h"
void UE::MeshDescription::InitializeAutoGeneratedAttributes(FMeshDescription& Mesh, const FMeshBuildSettings* BuildSettings)
{
check(BuildSettings);
// if the build settings don't indicate calculated normals/tangents, we will assume they are good
if (BuildSettings->bRecomputeNormals || BuildSettings->bRecomputeTangents)
{
// check if any are invalid
bool bHasInvalidNormals, bHasInvalidTangents;
FStaticMeshOperations::AreNormalsAndTangentsValid(Mesh, bHasInvalidNormals, bHasInvalidTangents);
// if neither are invalid we are not going to recompute
if (bHasInvalidNormals || bHasInvalidTangents)
{
FStaticMeshAttributes Attributes(Mesh);
if (!Attributes.GetTriangleNormals().IsValid() || !Attributes.GetTriangleTangents().IsValid())
{
// If these attributes don't exist, create them and compute their values for each triangle
FStaticMeshOperations::ComputeTriangleTangentsAndNormals(Mesh);
}
EComputeNTBsFlags ComputeNTBsOptions = EComputeNTBsFlags::BlendOverlappingNormals;
ComputeNTBsOptions |= BuildSettings->bRecomputeNormals ? EComputeNTBsFlags::Normals : EComputeNTBsFlags::None;
ComputeNTBsOptions |= BuildSettings->bRecomputeTangents ? EComputeNTBsFlags::Tangents : EComputeNTBsFlags::None;
ComputeNTBsOptions |= BuildSettings->bUseMikkTSpace ? EComputeNTBsFlags::UseMikkTSpace : EComputeNTBsFlags::None;
ComputeNTBsOptions |= BuildSettings->bComputeWeightedNormals ? EComputeNTBsFlags::WeightedNTBs : EComputeNTBsFlags::None;
ComputeNTBsOptions |= BuildSettings->bRemoveDegenerates ? EComputeNTBsFlags::IgnoreDegenerateTriangles : EComputeNTBsFlags::None;
FStaticMeshOperations::ComputeTangentsAndNormals(Mesh, ComputeNTBsOptions);
}
}
}
void UE::MeshDescription::InitializeAutoGeneratedAttributes(FMeshDescription& Mesh, UStaticMesh* StaticMesh, int32 SourceLOD)
{
#if WITH_EDITOR
if (ensureMsgf(SourceLOD < StaticMesh->GetNumSourceModels(), TEXT("InitializeMeshDescription requested LOD index greater than num available in UStaticMesh")))
{
const FStaticMeshSourceModel& SourceModel = StaticMesh->GetSourceModel(SourceLOD);
InitializeAutoGeneratedAttributes(Mesh, &SourceModel.BuildSettings);
}
#else
ensureMsgf(false, TEXT("InitializeMeshDescription requires Editor-only SourceModel field of UStaticMesh"));
#endif
}
void UE::MeshDescription::InitializeAutoGeneratedAttributes(FMeshDescription& Mesh, UActorComponent* StaticMeshComponent, int32 SourceLOD)
{
#if WITH_EDITOR
if (ensure(Cast<UStaticMeshComponent>(StaticMeshComponent) != nullptr))
{
UStaticMesh* StaticMesh = Cast<UStaticMeshComponent>(StaticMeshComponent)->GetStaticMesh();
if (ensure(StaticMesh != nullptr))
{
InitializeAutoGeneratedAttributes(Mesh, StaticMesh, SourceLOD);
}
}
#else
ensureMsgf(false, TEXT("InitializeMeshDescription requires Editor-only SourceModel field of UStaticMesh"));
#endif
}
void UE::MeshDescription::ConfigureBuildSettings(UStaticMesh* StaticMesh, int32 SourceLOD, FStaticMeshBuildSettingChange NewSettings)
{
#if WITH_EDITOR
if (ensureMsgf(SourceLOD < StaticMesh->GetNumSourceModels(), TEXT("ConfigureBuildSettings requested LOD index greater than num available in UStaticMesh")))
{
FStaticMeshSourceModel& SourceModel = StaticMesh->GetSourceModel(SourceLOD);
if (NewSettings.AutoGeneratedNormals != EBuildSettingBoolChange::NoChange)
{
SourceModel.BuildSettings.bRecomputeNormals =
(NewSettings.AutoGeneratedNormals == EBuildSettingBoolChange::Disable) ? false : true;
}
if (NewSettings.AutoGeneratedTangents != EBuildSettingBoolChange::NoChange)
{
SourceModel.BuildSettings.bRecomputeTangents =
(NewSettings.AutoGeneratedTangents == EBuildSettingBoolChange::Disable) ? false : true;
}
if (NewSettings.UseMikkTSpaceTangents != EBuildSettingBoolChange::NoChange)
{
SourceModel.BuildSettings.bUseMikkTSpace =
(NewSettings.UseMikkTSpaceTangents == EBuildSettingBoolChange::Disable) ? false : true;
}
}
#else
// just ignore?
#endif
}