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
{
2019-10-04 13:11:45 -04:00
TRACE_CPUPROFILER_EVENT_SCOPE ( FMeshDescriptionHelper : : GetRenderMeshDescription ) ;
2017-09-25 13:46:28 -04:00
UStaticMesh * StaticMesh = Cast < UStaticMesh > ( Owner ) ;
check ( StaticMesh ) ;
2017-09-15 11:19:07 -04:00
2017-09-22 17:58:06 -04:00
float ComparisonThreshold = BuildSettings - > bRemoveDegenerates ? THRESH_POINTS_ARE_SAME : 0.0f ;
2018-04-16 17:40:43 -04:00
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 ) ;
2018-06-07 16:22:56 -04:00
//OutRenderMeshDescription->ComputePolygonTangentsAndNormals(BuildSettings->bRemoveDegenerates ? SMALL_NUMBER : 0.0f);
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 ) ;
TVertexInstanceAttributesRef < FVector > Normals = Attributes . GetVertexInstanceNormals ( ) ;
TVertexInstanceAttributesRef < FVector > Tangents = Attributes . GetVertexInstanceTangents ( ) ;
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 - > bRemoveDegenerates ? EComputeNTBsFlags : : IgnoreDegenerateTriangles : EComputeNTBsFlags : : None ;
ComputeNTBsOptions | = BuildSettings - > bComputeWeightedNormals ? EComputeNTBsFlags : : WeightedNTBs : EComputeNTBsFlags : : None ;
ComputeNTBsOptions | = BuildSettings - > bRecomputeNormals ? EComputeNTBsFlags : : Normals : EComputeNTBsFlags : : None ;
ComputeNTBsOptions | = BuildSettings - > bRecomputeTangents & & ! StaticMesh - > NaniteSettings . bEnabled ? EComputeNTBsFlags : : Tangents : EComputeNTBsFlags : : None ; // Nanite doesn't need tangents
ComputeNTBsOptions | = BuildSettings - > bUseMikkTSpace ? EComputeNTBsFlags : : UseMikkTSpace : 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
{
2020-07-16 08:23:15 -04:00
TVertexInstanceAttributesRef < FVector2D > 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
}