2019-12-26 15:32:37 -05:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
2017-09-15 11:19:07 -04:00
|
|
|
|
|
|
|
|
#include "MeshDescriptionHelper.h"
|
|
|
|
|
|
2020-01-23 16:28:59 -05:00
|
|
|
#include "BuildStatisticManager.h"
|
2017-09-15 11:19:07 -04:00
|
|
|
#include "CoreMinimal.h"
|
|
|
|
|
#include "CoreTypes.h"
|
|
|
|
|
#include "Engine/EngineTypes.h"
|
2017-09-25 13:46:28 -04:00
|
|
|
#include "Engine/StaticMesh.h"
|
2017-11-01 18:22:05 -04:00
|
|
|
#include "IMeshReductionInterfaces.h"
|
|
|
|
|
#include "IMeshReductionManagerModule.h"
|
2017-12-28 17:15:00 -05:00
|
|
|
#include "Materials/Material.h"
|
2018-03-07 09:10:20 -05:00
|
|
|
#include "Modules/ModuleManager.h"
|
2020-01-23 16:28:59 -05:00
|
|
|
#include "RawMesh.h"
|
|
|
|
|
#include "RenderUtils.h"
|
|
|
|
|
#include "StaticMeshAttributes.h"
|
|
|
|
|
#include "Serialization/MemoryWriter.h"
|
|
|
|
|
#include "Serialization/MemoryReader.h"
|
|
|
|
|
#include "StaticMeshOperations.h"
|
|
|
|
|
#include "UObject/Package.h"
|
|
|
|
|
#include "UObject/UObjectGlobals.h"
|
2017-09-22 17:58:06 -04:00
|
|
|
|
|
|
|
|
//Enable all check
|
|
|
|
|
//#define ENABLE_NTB_CHECK
|
|
|
|
|
|
2018-01-11 17:52:50 -05:00
|
|
|
DEFINE_LOG_CATEGORY(LogMeshDescriptionBuildStatistic);
|
|
|
|
|
|
2018-06-07 16:22:56 -04:00
|
|
|
FMeshDescriptionHelper::FMeshDescriptionHelper(FMeshBuildSettings* InBuildSettings)
|
|
|
|
|
: BuildSettings(InBuildSettings)
|
2017-09-15 11:19:07 -04:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-26 13:09:34 -04:00
|
|
|
void FMeshDescriptionHelper::SetupRenderMeshDescription(UObject* Owner, FMeshDescription& RenderMeshDescription)
|
2017-09-15 11:19:07 -04:00
|
|
|
{
|
2021-04-29 19:32:06 -04:00
|
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(FMeshDescriptionHelper::SetupRenderMeshDescription);
|
2019-10-04 13:11:45 -04:00
|
|
|
|
2017-09-25 13:46:28 -04:00
|
|
|
UStaticMesh* StaticMesh = Cast<UStaticMesh>(Owner);
|
|
|
|
|
check(StaticMesh);
|
2017-09-15 11:19:07 -04:00
|
|
|
|
2021-04-13 14:54:07 -04:00
|
|
|
const bool bNaniteBuildEnabled = StaticMesh->NaniteSettings.bEnabled;
|
|
|
|
|
float ComparisonThreshold = (BuildSettings->bRemoveDegenerates && !bNaniteBuildEnabled) ? THRESH_POINTS_ARE_SAME : 0.0f;
|
2018-04-16 17:40:43 -04:00
|
|
|
|
2021-10-12 21:21:22 -04:00
|
|
|
// Compact the mesh description prior to performing operations
|
|
|
|
|
if (RenderMeshDescription.Triangles().GetArraySize() != RenderMeshDescription.Triangles().Num() ||
|
|
|
|
|
RenderMeshDescription.Vertices().GetArraySize() != RenderMeshDescription.Vertices().Num())
|
|
|
|
|
{
|
|
|
|
|
FElementIDRemappings Remappings;
|
|
|
|
|
RenderMeshDescription.Compact(Remappings);
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-23 16:28:59 -05:00
|
|
|
//This function make sure the Polygon Normals Tangents Binormals are computed and also remove degenerated triangle from the render mesh description.
|
First pass of MeshDescription API and format refactor.
- Removed hardcoded element type arrays (Vertices, Edges, Triangles etc.). Mesh element types can now be arbitrarily added, with any number of channels.
- Mesh element containers have a much leaner format; instead of sparse arrays, they are now represented by a simple bitarray, determining whether an index is used or not. Consequently, mesh topology is now entirely described with the attribute system, e.g. edge start and end vertices, triangle vertices, etc.
- Support added for attributes of arbitrary dimensions, e.g. float[4] or int[2].
- Support added for attributes which index into another mesh element container.
- Added FMeshElementIndexer: this is an efficient container for maintaining backward references from one element type to another; for example, edges have an attribute specifying which vertices are at each end (an attribute of type FVertexID[2]). With an indexer, it is possible to look up which edges contain a given vertex, even though this is not explicitly stored. Indexers are designed to do minimal allocations and update lazily and in batch when necessary.
- Added support for preserving UV topology in static meshes. UVs are now a first-class element type which may be indexed directly from triangles.
- Added the facility to access the underlying array in an attribute array directly.
- Triangles now directly reference their vertex, edge and UV IDs. Vertex instances are to be deprecated.
- Changed various systems to be triangle-centric rather than polygon-centric, as this is faster. Triangles are presumed to be the elementary face type in a MeshDescription, even if polygons are still supported. The concept of polygons will be somewhat shifted to mean a group of triangles which should be treated collectively for editing purposes.
- Optimised normal/tangent generation and FBX import.
- Deprecated EditableMesh, MeshEditor and StaticMeshEditorExtension plugins - these are to be removed, but they still have certain hooks in place which need removing.
#rb
[CL 13568702 by Richard TalbotWatkin in ue5-main branch]
2020-05-28 10:56:57 -04:00
|
|
|
FStaticMeshOperations::ComputeTriangleTangentsAndNormals(RenderMeshDescription, ComparisonThreshold);
|
2017-09-22 17:58:06 -04:00
|
|
|
|
2019-10-23 06:44:22 -04:00
|
|
|
FVertexInstanceArray& VertexInstanceArray = RenderMeshDescription.VertexInstances();
|
2020-07-16 08:23:15 -04:00
|
|
|
|
|
|
|
|
FStaticMeshAttributes Attributes(RenderMeshDescription);
|
2021-05-05 15:07:25 -04:00
|
|
|
TVertexInstanceAttributesRef<FVector3f> Normals = Attributes.GetVertexInstanceNormals();
|
|
|
|
|
TVertexInstanceAttributesRef<FVector3f> Tangents = Attributes.GetVertexInstanceTangents();
|
2020-07-16 08:23:15 -04:00
|
|
|
TVertexInstanceAttributesRef<float> BinormalSigns = Attributes.GetVertexInstanceBinormalSigns();
|
2017-11-02 16:53:04 -04:00
|
|
|
|
2017-11-03 15:58:34 -04:00
|
|
|
// Find overlapping corners to accelerate adjacency.
|
2020-01-23 16:28:59 -05:00
|
|
|
FStaticMeshOperations::FindOverlappingCorners(OverlappingCorners, RenderMeshDescription, ComparisonThreshold);
|
2017-11-03 15:58:34 -04:00
|
|
|
|
2020-10-26 13:09:34 -04:00
|
|
|
// Static meshes always blend normals of overlapping corners.
|
|
|
|
|
EComputeNTBsFlags ComputeNTBsOptions = EComputeNTBsFlags::BlendOverlappingNormals;
|
|
|
|
|
ComputeNTBsOptions |= BuildSettings->bComputeWeightedNormals ? EComputeNTBsFlags::WeightedNTBs : EComputeNTBsFlags::None;
|
|
|
|
|
ComputeNTBsOptions |= BuildSettings->bRecomputeNormals ? EComputeNTBsFlags::Normals : EComputeNTBsFlags::None;
|
|
|
|
|
ComputeNTBsOptions |= BuildSettings->bUseMikkTSpace ? EComputeNTBsFlags::UseMikkTSpace : EComputeNTBsFlags::None;
|
|
|
|
|
|
2021-04-13 14:54:07 -04:00
|
|
|
// Set extra options for non-Nanite meshes
|
|
|
|
|
if (!bNaniteBuildEnabled)
|
|
|
|
|
{
|
|
|
|
|
ComputeNTBsOptions |= BuildSettings->bRemoveDegenerates ? EComputeNTBsFlags::IgnoreDegenerateTriangles : EComputeNTBsFlags::None;
|
|
|
|
|
ComputeNTBsOptions |= BuildSettings->bRecomputeTangents ? EComputeNTBsFlags::Tangents : EComputeNTBsFlags::None;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 15:58:34 -04:00
|
|
|
// Compute any missing normals or tangents.
|
2020-10-26 13:09:34 -04:00
|
|
|
FStaticMeshOperations::ComputeTangentsAndNormals(RenderMeshDescription, ComputeNTBsOptions);
|
2017-09-22 17:58:06 -04:00
|
|
|
|
2020-10-26 13:09:34 -04:00
|
|
|
if (BuildSettings->bGenerateLightmapUVs && VertexInstanceArray.Num() > 0)
|
2017-09-15 11:19:07 -04:00
|
|
|
{
|
2021-11-18 14:37:34 -05:00
|
|
|
TVertexInstanceAttributesRef<FVector2f> VertexInstanceUVs = Attributes.GetVertexInstanceUVs();
|
First pass of MeshDescription API and format refactor.
- Removed hardcoded element type arrays (Vertices, Edges, Triangles etc.). Mesh element types can now be arbitrarily added, with any number of channels.
- Mesh element containers have a much leaner format; instead of sparse arrays, they are now represented by a simple bitarray, determining whether an index is used or not. Consequently, mesh topology is now entirely described with the attribute system, e.g. edge start and end vertices, triangle vertices, etc.
- Support added for attributes of arbitrary dimensions, e.g. float[4] or int[2].
- Support added for attributes which index into another mesh element container.
- Added FMeshElementIndexer: this is an efficient container for maintaining backward references from one element type to another; for example, edges have an attribute specifying which vertices are at each end (an attribute of type FVertexID[2]). With an indexer, it is possible to look up which edges contain a given vertex, even though this is not explicitly stored. Indexers are designed to do minimal allocations and update lazily and in batch when necessary.
- Added support for preserving UV topology in static meshes. UVs are now a first-class element type which may be indexed directly from triangles.
- Added the facility to access the underlying array in an attribute array directly.
- Triangles now directly reference their vertex, edge and UV IDs. Vertex instances are to be deprecated.
- Changed various systems to be triangle-centric rather than polygon-centric, as this is faster. Triangles are presumed to be the elementary face type in a MeshDescription, even if polygons are still supported. The concept of polygons will be somewhat shifted to mean a group of triangles which should be treated collectively for editing purposes.
- Optimised normal/tangent generation and FBX import.
- Deprecated EditableMesh, MeshEditor and StaticMeshEditorExtension plugins - these are to be removed, but they still have certain hooks in place which need removing.
#rb
[CL 13568702 by Richard TalbotWatkin in ue5-main branch]
2020-05-28 10:56:57 -04:00
|
|
|
int32 NumIndices = VertexInstanceUVs.GetNumChannels();
|
2017-12-28 17:15:00 -05:00
|
|
|
//Verify the src light map channel
|
|
|
|
|
if (BuildSettings->SrcLightmapIndex >= NumIndices)
|
2017-09-22 17:58:06 -04:00
|
|
|
{
|
|
|
|
|
BuildSettings->SrcLightmapIndex = 0;
|
|
|
|
|
}
|
2017-12-28 17:15:00 -05:00
|
|
|
//Verify the destination light map channel
|
|
|
|
|
if (BuildSettings->DstLightmapIndex >= NumIndices)
|
|
|
|
|
{
|
|
|
|
|
//Make sure we do not add illegal UV Channel index
|
|
|
|
|
if (BuildSettings->DstLightmapIndex >= MAX_MESH_TEXTURE_COORDS_MD)
|
|
|
|
|
{
|
|
|
|
|
BuildSettings->DstLightmapIndex = MAX_MESH_TEXTURE_COORDS_MD - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Add some unused UVChannel to the mesh description for the lightmapUVs
|
First pass of MeshDescription API and format refactor.
- Removed hardcoded element type arrays (Vertices, Edges, Triangles etc.). Mesh element types can now be arbitrarily added, with any number of channels.
- Mesh element containers have a much leaner format; instead of sparse arrays, they are now represented by a simple bitarray, determining whether an index is used or not. Consequently, mesh topology is now entirely described with the attribute system, e.g. edge start and end vertices, triangle vertices, etc.
- Support added for attributes of arbitrary dimensions, e.g. float[4] or int[2].
- Support added for attributes which index into another mesh element container.
- Added FMeshElementIndexer: this is an efficient container for maintaining backward references from one element type to another; for example, edges have an attribute specifying which vertices are at each end (an attribute of type FVertexID[2]). With an indexer, it is possible to look up which edges contain a given vertex, even though this is not explicitly stored. Indexers are designed to do minimal allocations and update lazily and in batch when necessary.
- Added support for preserving UV topology in static meshes. UVs are now a first-class element type which may be indexed directly from triangles.
- Added the facility to access the underlying array in an attribute array directly.
- Triangles now directly reference their vertex, edge and UV IDs. Vertex instances are to be deprecated.
- Changed various systems to be triangle-centric rather than polygon-centric, as this is faster. Triangles are presumed to be the elementary face type in a MeshDescription, even if polygons are still supported. The concept of polygons will be somewhat shifted to mean a group of triangles which should be treated collectively for editing purposes.
- Optimised normal/tangent generation and FBX import.
- Deprecated EditableMesh, MeshEditor and StaticMeshEditorExtension plugins - these are to be removed, but they still have certain hooks in place which need removing.
#rb
[CL 13568702 by Richard TalbotWatkin in ue5-main branch]
2020-05-28 10:56:57 -04:00
|
|
|
VertexInstanceUVs.SetNumChannels(BuildSettings->DstLightmapIndex + 1);
|
2017-12-28 17:15:00 -05:00
|
|
|
BuildSettings->DstLightmapIndex = NumIndices;
|
|
|
|
|
}
|
2020-01-23 16:28:59 -05:00
|
|
|
FStaticMeshOperations::CreateLightMapUVLayout(RenderMeshDescription,
|
2018-02-22 11:20:51 -05:00
|
|
|
BuildSettings->SrcLightmapIndex,
|
|
|
|
|
BuildSettings->DstLightmapIndex,
|
|
|
|
|
BuildSettings->MinLightmapResolution,
|
2020-10-22 19:19:16 -04:00
|
|
|
(ELightmapUVVersion)StaticMesh->GetLightmapUVVersion(),
|
2018-02-22 11:20:51 -05:00
|
|
|
OverlappingCorners);
|
2017-09-15 11:19:07 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-31 05:49:40 -04:00
|
|
|
void FMeshDescriptionHelper::ReduceLOD(const FMeshDescription& BaseMesh, FMeshDescription& DestMesh, const FMeshReductionSettings& ReductionSettings, const FOverlappingCorners& InOverlappingCorners, float &OutMaxDeviation)
|
2017-11-01 18:22:05 -04:00
|
|
|
{
|
|
|
|
|
IMeshReductionManagerModule& MeshReductionModule = FModuleManager::Get().LoadModuleChecked<IMeshReductionManagerModule>("MeshReductionInterface");
|
|
|
|
|
IMeshReduction* MeshReduction = MeshReductionModule.GetStaticMeshReductionInterface();
|
|
|
|
|
|
2018-11-14 19:05:13 -05:00
|
|
|
|
|
|
|
|
if (!MeshReduction)
|
2017-11-01 18:22:05 -04:00
|
|
|
{
|
2018-11-14 19:05:13 -05:00
|
|
|
// no reduction possible
|
|
|
|
|
OutMaxDeviation = 0.f;
|
2017-11-01 18:22:05 -04:00
|
|
|
return;
|
|
|
|
|
}
|
2018-11-14 19:05:13 -05:00
|
|
|
|
2018-06-16 10:22:53 -04:00
|
|
|
OutMaxDeviation = ReductionSettings.MaxDeviation;
|
|
|
|
|
MeshReduction->ReduceMeshDescription(DestMesh, OutMaxDeviation, BaseMesh, InOverlappingCorners, ReductionSettings);
|
2017-11-01 18:22:05 -04:00
|
|
|
}
|
|
|
|
|
|
2018-06-07 16:22:56 -04:00
|
|
|
void FMeshDescriptionHelper::FindOverlappingCorners(const FMeshDescription& MeshDescription, float ComparisonThreshold)
|
2017-11-01 18:22:05 -04:00
|
|
|
{
|
2020-01-23 16:28:59 -05:00
|
|
|
FStaticMeshOperations::FindOverlappingCorners(OverlappingCorners, MeshDescription, ComparisonThreshold);
|
2017-11-01 18:22:05 -04:00
|
|
|
}
|
|
|
|
|
|