2019-12-26 14:45:42 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-10-01 20:41:42 -04:00
# include "StaticMeshOperations.h"
2020-01-23 16:28:59 -05:00
# include "StaticMeshAttributes.h"
# include "UVMapSettings.h"
# include "Async/ParallelFor.h"
# include "LayoutUV.h"
# include "MeshUtilitiesCommon.h"
# include "Misc/SecureHash.h"
# include "OverlappingCorners.h"
# include "RawMesh.h"
# if WITH_MIKKTSPACE
# include "mikktspace.h"
# endif //WITH_MIKKTSPACE
DEFINE_LOG_CATEGORY ( LogStaticMeshOperations ) ;
# define LOCTEXT_NAMESPACE "StaticMeshOperations"
2019-10-01 20:41:42 -04:00
static bool GetPolygonTangentsAndNormals ( FMeshDescription & MeshDescription ,
FPolygonID PolygonID ,
float ComparisonThreshold ,
2021-05-05 15:07:25 -04:00
TVertexAttributesConstRef < const FVector3f > VertexPositions ,
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesConstRef < const FVector2f > VertexUVs ,
2021-05-05 15:07:25 -04:00
TPolygonAttributesRef < FVector3f > PolygonNormals ,
TPolygonAttributesRef < FVector3f > PolygonTangents ,
TPolygonAttributesRef < FVector3f > PolygonBinormals ,
TPolygonAttributesRef < FVector3f > PolygonCenters )
2019-10-01 20:41:42 -04:00
{
bool bValidNTBs = true ;
2020-01-23 16:28:59 -05:00
// Calculate the tangent basis for the polygon, based on the average of all constituent triangles
2021-11-18 14:37:34 -05:00
FVector3f Normal ( FVector3f : : ZeroVector ) ;
FVector3f Tangent ( FVector3f : : ZeroVector ) ;
FVector3f Binormal ( FVector3f : : ZeroVector ) ;
FVector3f Center ( FVector3f : : ZeroVector ) ;
2020-01-23 16:28:59 -05:00
2019-10-01 20:41:42 -04:00
// Calculate the center of this polygon
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
TArray < FVertexInstanceID , TInlineAllocator < 4 > > VertexInstanceIDs = MeshDescription . GetPolygonVertexInstances < TInlineAllocator < 4 > > ( PolygonID ) ;
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID & VertexInstanceID : VertexInstanceIDs )
2019-10-01 20:41:42 -04:00
{
Center + = VertexPositions [ MeshDescription . GetVertexInstanceVertex ( VertexInstanceID ) ] ;
}
Center / = float ( VertexInstanceIDs . Num ( ) ) ;
2020-01-23 16:28:59 -05:00
float AdjustedComparisonThreshold = FMath : : Max ( ComparisonThreshold , MIN_flt ) ;
2022-01-06 16:44:09 +00:00
for ( const FTriangleID & TriangleID : MeshDescription . GetPolygonTriangles ( PolygonID ) )
2019-10-01 20:41:42 -04:00
{
TArrayView < const FVertexInstanceID > TriangleVertexInstances = MeshDescription . GetTriangleVertexInstances ( TriangleID ) ;
const FVertexID VertexID0 = MeshDescription . GetVertexInstanceVertex ( TriangleVertexInstances [ 0 ] ) ;
const FVertexID VertexID1 = MeshDescription . GetVertexInstanceVertex ( TriangleVertexInstances [ 1 ] ) ;
const FVertexID VertexID2 = MeshDescription . GetVertexInstanceVertex ( TriangleVertexInstances [ 2 ] ) ;
2021-11-18 14:37:34 -05:00
const FVector3f Position0 = VertexPositions [ VertexID0 ] ;
const FVector3f DPosition1 = VertexPositions [ VertexID1 ] - Position0 ;
const FVector3f DPosition2 = VertexPositions [ VertexID2 ] - Position0 ;
2019-10-01 20:41:42 -04:00
2021-11-18 14:37:34 -05:00
const FVector2f UV0 = VertexUVs [ TriangleVertexInstances [ 0 ] ] ;
const FVector2f DUV1 = VertexUVs [ TriangleVertexInstances [ 1 ] ] - UV0 ;
const FVector2f DUV2 = VertexUVs [ TriangleVertexInstances [ 2 ] ] - UV0 ;
2019-10-01 20:41:42 -04:00
// We have a left-handed coordinate system, but a counter-clockwise winding order
// Hence normal calculation has to take the triangle vectors cross product in reverse.
2021-11-18 14:37:34 -05:00
FVector3f TmpNormal = FVector3f : : CrossProduct ( DPosition2 , DPosition1 ) . GetSafeNormal ( AdjustedComparisonThreshold ) ;
2020-01-23 16:28:59 -05:00
if ( ! TmpNormal . IsNearlyZero ( ComparisonThreshold ) )
2019-10-01 20:41:42 -04:00
{
2021-11-18 14:37:34 -05:00
FMatrix44f ParameterToLocal (
2020-01-23 16:28:59 -05:00
DPosition1 ,
DPosition2 ,
Position0 ,
2021-11-18 14:37:34 -05:00
FVector3f : : ZeroVector
2020-01-23 16:28:59 -05:00
) ;
2019-10-01 20:41:42 -04:00
2021-11-18 14:37:34 -05:00
FMatrix44f ParameterToTexture (
FPlane4f ( DUV1 . X , DUV1 . Y , 0 , 0 ) ,
FPlane4f ( DUV2 . X , DUV2 . Y , 0 , 0 ) ,
FPlane4f ( UV0 . X , UV0 . Y , 1 , 0 ) ,
FPlane4f ( 0 , 0 , 0 , 1 )
2020-01-23 16:28:59 -05:00
) ;
// Use InverseSlow to catch singular matrices. Inverse can miss this sometimes.
2021-11-18 14:37:34 -05:00
const FMatrix44f TextureToLocal = ParameterToTexture . Inverse ( ) * ParameterToLocal ;
2020-01-23 16:28:59 -05:00
2021-11-18 14:37:34 -05:00
FVector3f TmpTangent = TextureToLocal . TransformVector ( FVector3f ( 1 , 0 , 0 ) ) . GetSafeNormal ( ) ;
FVector3f TmpBinormal = TextureToLocal . TransformVector ( FVector3f ( 0 , 1 , 0 ) ) . GetSafeNormal ( ) ;
FVector3f : : CreateOrthonormalBasis ( TmpTangent , TmpBinormal , TmpNormal ) ;
2020-01-23 16:28:59 -05:00
if ( TmpTangent . IsNearlyZero ( ) | | TmpTangent . ContainsNaN ( )
| | TmpBinormal . IsNearlyZero ( ) | | TmpBinormal . ContainsNaN ( ) )
{
2021-11-18 14:37:34 -05:00
TmpTangent = FVector3f : : ZeroVector ;
TmpBinormal = FVector3f : : ZeroVector ;
2020-01-23 16:28:59 -05:00
bValidNTBs = false ;
}
if ( TmpNormal . IsNearlyZero ( ) | | TmpNormal . ContainsNaN ( ) )
{
2021-11-18 14:37:34 -05:00
TmpNormal = FVector3f : : ZeroVector ;
2020-01-23 16:28:59 -05:00
bValidNTBs = false ;
}
Normal + = TmpNormal ;
Tangent + = TmpTangent ;
Binormal + = TmpBinormal ;
2019-10-01 20:41:42 -04:00
}
else
{
2020-01-23 16:28:59 -05:00
//This will force a recompute of the normals and tangents
2021-11-18 14:37:34 -05:00
Normal = FVector3f : : ZeroVector ;
Tangent = FVector3f : : ZeroVector ;
Binormal = FVector3f : : ZeroVector ;
2020-01-23 16:28:59 -05:00
2019-10-01 20:41:42 -04:00
// The polygon is degenerated
bValidNTBs = false ;
}
}
PolygonNormals [ PolygonID ] = Normal . GetSafeNormal ( ) ;
PolygonTangents [ PolygonID ] = Tangent . GetSafeNormal ( ) ;
PolygonBinormals [ PolygonID ] = Binormal . GetSafeNormal ( ) ;
PolygonCenters [ PolygonID ] = Center ;
return bValidNTBs ;
}
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
2019-11-06 18:17:34 -05:00
void FStaticMeshOperations : : ComputePolygonTangentsAndNormals ( FMeshDescription & MeshDescription , float ComparisonThreshold )
{
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
PRAGMA_DISABLE_DEPRECATION_WARNINGS
2020-09-24 00:43:27 -04:00
TRACE_CPUPROFILER_EVENT_SCOPE ( FStaticMeshOperations : : ComputePolygonTangentsAndNormals_Selection ) ;
2020-01-23 16:28:59 -05:00
2019-11-06 18:17:34 -05:00
FStaticMeshAttributes Attributes ( MeshDescription ) ;
Attributes . RegisterPolygonNormalAndTangentAttributes ( ) ;
2020-01-23 16:28:59 -05:00
TArray < FPolygonID > PolygonIDs ;
PolygonIDs . Reserve ( MeshDescription . Polygons ( ) . Num ( ) ) ;
2022-01-06 16:44:09 +00:00
for ( const FPolygonID Polygon : MeshDescription . Polygons ( ) . GetElementIDs ( ) )
2019-11-06 18:17:34 -05:00
{
2020-01-23 16:28:59 -05:00
PolygonIDs . Add ( Polygon ) ;
}
// Split work in batch to reduce call overhead
const int32 BatchSize = 8 * 1024 ;
const int32 BatchCount = 1 + PolygonIDs . Num ( ) / BatchSize ;
ParallelFor ( BatchCount ,
[ & PolygonIDs , & BatchSize , & ComparisonThreshold , & MeshDescription , & Attributes ] ( int32 BatchIndex )
2019-11-06 18:17:34 -05:00
{
2021-05-05 15:07:25 -04:00
TVertexAttributesConstRef < FVector3f > VertexPositions = Attributes . GetVertexPositions ( ) ;
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesConstRef < FVector2f > VertexUVs = Attributes . GetVertexInstanceUVs ( ) ;
2021-05-05 15:07:25 -04:00
TPolygonAttributesRef < FVector3f > PolygonNormals = Attributes . GetPolygonNormals ( ) ;
TPolygonAttributesRef < FVector3f > PolygonTangents = Attributes . GetPolygonTangents ( ) ;
TPolygonAttributesRef < FVector3f > PolygonBinormals = Attributes . GetPolygonBinormals ( ) ;
TPolygonAttributesRef < FVector3f > PolygonCenters = Attributes . GetPolygonCenters ( ) ;
2020-01-23 16:28:59 -05:00
FVertexInstanceArray & VertexInstanceArray = MeshDescription . VertexInstances ( ) ;
FVertexArray & VertexArray = MeshDescription . Vertices ( ) ;
FPolygonArray & PolygonArray = MeshDescription . Polygons ( ) ;
int32 Indice = BatchIndex * BatchSize ;
int32 LastIndice = FMath : : Min ( Indice + BatchSize , PolygonIDs . Num ( ) ) ;
for ( ; Indice < LastIndice ; + + Indice )
{
const FPolygonID PolygonID = PolygonIDs [ Indice ] ;
if ( ! PolygonNormals [ PolygonID ] . IsNearlyZero ( ) )
{
//By pass normal calculation if its already done
continue ;
}
GetPolygonTangentsAndNormals ( MeshDescription , PolygonID , ComparisonThreshold , VertexPositions , VertexUVs , PolygonNormals , PolygonTangents , PolygonBinormals , PolygonCenters ) ;
}
2019-11-06 18:17:34 -05:00
}
2020-01-23 16:28:59 -05:00
) ;
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
PRAGMA_ENABLE_DEPRECATION_WARNINGS
2019-10-01 20:41:42 -04:00
}
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
2021-11-18 14:37:34 -05:00
static TTuple < FVector3f , FVector3f , FVector3f > GetTriangleTangentsAndNormals ( float ComparisonThreshold , TArrayView < const FVector3f > VertexPositions , TArrayView < const FVector2D > VertexUVs )
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
{
float AdjustedComparisonThreshold = FMath : : Max ( ComparisonThreshold , MIN_flt ) ;
2021-11-18 14:37:34 -05:00
const FVector3f Position0 = VertexPositions [ 0 ] ;
const FVector3f DPosition1 = VertexPositions [ 1 ] - Position0 ;
const FVector3f DPosition2 = VertexPositions [ 2 ] - Position0 ;
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
2022-02-02 01:47:07 -05:00
const FVector2f UV0 = FVector2f ( VertexUVs [ 0 ] ) ;
const FVector2f DUV1 = FVector2f ( VertexUVs [ 1 ] ) - UV0 ;
const FVector2f DUV2 = FVector2f ( VertexUVs [ 2 ] ) - UV0 ;
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
// We have a left-handed coordinate system, but a counter-clockwise winding order
// Hence normal calculation has to take the triangle vectors cross product in reverse.
2021-11-18 14:37:34 -05:00
FVector3f Normal = FVector3f : : CrossProduct ( DPosition2 , DPosition1 ) . GetSafeNormal ( AdjustedComparisonThreshold ) ;
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
if ( ! Normal . IsNearlyZero ( ComparisonThreshold ) )
{
2021-11-18 14:37:34 -05:00
FMatrix44f ParameterToLocal (
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
DPosition1 ,
DPosition2 ,
Position0 ,
2021-11-18 14:37:34 -05:00
FVector3f : : ZeroVector
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
) ;
2021-11-18 14:37:34 -05:00
FMatrix44f ParameterToTexture (
FPlane4f ( DUV1 . X , DUV1 . Y , 0 , 0 ) ,
FPlane4f ( DUV2 . X , DUV2 . Y , 0 , 0 ) ,
FPlane4f ( UV0 . X , UV0 . Y , 1 , 0 ) ,
FPlane4f ( 0 , 0 , 0 , 1 )
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
) ;
// Use InverseSlow to catch singular matrices. Inverse can miss this sometimes.
2021-11-18 14:37:34 -05:00
const FMatrix44f TextureToLocal = ParameterToTexture . Inverse ( ) * ParameterToLocal ;
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
2021-11-18 14:37:34 -05:00
FVector3f Tangent = TextureToLocal . TransformVector ( FVector3f ( 1 , 0 , 0 ) ) . GetSafeNormal ( ) ;
FVector3f Binormal = TextureToLocal . TransformVector ( FVector3f ( 0 , 1 , 0 ) ) . GetSafeNormal ( ) ;
FVector3f : : CreateOrthonormalBasis ( Tangent , Binormal , Normal ) ;
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
if ( Tangent . IsNearlyZero ( ) | | Tangent . ContainsNaN ( )
| | Binormal . IsNearlyZero ( ) | | Binormal . ContainsNaN ( ) )
{
2021-11-18 14:37:34 -05:00
Tangent = FVector3f : : ZeroVector ;
Binormal = FVector3f : : ZeroVector ;
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
}
if ( Normal . IsNearlyZero ( ) | | Normal . ContainsNaN ( ) )
{
2021-11-18 14:37:34 -05:00
Normal = FVector3f : : ZeroVector ;
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
}
return MakeTuple ( Normal . GetSafeNormal ( ) , Tangent . GetSafeNormal ( ) , Binormal . GetSafeNormal ( ) ) ;
}
else
{
// This will force a recompute of the normals and tangents
2021-11-18 14:37:34 -05:00
return MakeTuple ( FVector3f : : ZeroVector , FVector3f : : ZeroVector , FVector3f : : ZeroVector ) ;
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
}
}
void FStaticMeshOperations : : ComputeTriangleTangentsAndNormals ( FMeshDescription & MeshDescription , float ComparisonThreshold )
{
2021-01-19 06:29:15 -04:00
TRACE_CPUPROFILER_EVENT_SCOPE ( FStaticMeshOperations : : ComputeTriangleTangentsAndNormals_Selection ) ;
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
FStaticMeshAttributes Attributes ( MeshDescription ) ;
Attributes . RegisterTriangleNormalAndTangentAttributes ( ) ;
// Check that the mesh description is compact
const int32 NumTriangles = MeshDescription . Triangles ( ) . Num ( ) ;
2021-03-02 15:34:39 -04:00
if ( MeshDescription . Triangles ( ) . GetArraySize ( ) ! = NumTriangles )
{
FElementIDRemappings Remappings ;
MeshDescription . Compact ( Remappings ) ;
}
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
// Split work in batch to reduce call overhead
const int32 BatchSize = 8 * 1024 ;
const int32 BatchCount = ( NumTriangles + BatchSize - 1 ) / BatchSize ;
2022-02-23 19:25:03 -05:00
ParallelFor ( TEXT ( " ComputeTriangleTangentsAndNormals.PF " ) , BatchCount , 1 ,
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
[ BatchSize , ComparisonThreshold , NumTriangles , & Attributes ] ( int32 BatchIndex )
{
2021-05-05 15:07:25 -04:00
TArrayView < const FVector3f > VertexPositions = Attributes . GetVertexPositions ( ) . GetRawArray ( ) ;
2021-11-18 14:37:34 -05:00
TArrayView < const FVector2f > VertexUVs = Attributes . GetVertexInstanceUVs ( ) . GetRawArray ( ) ;
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
TArrayView < const FVertexID > TriangleVertexIDs = Attributes . GetTriangleVertexIndices ( ) . GetRawArray ( ) ;
TArrayView < const FVertexInstanceID > TriangleVertexInstanceIDs = Attributes . GetTriangleVertexInstanceIndices ( ) . GetRawArray ( ) ;
2021-05-05 15:07:25 -04:00
TArrayView < FVector3f > TriangleNormals = Attributes . GetTriangleNormals ( ) . GetRawArray ( ) ;
TArrayView < FVector3f > TriangleTangents = Attributes . GetTriangleTangents ( ) . GetRawArray ( ) ;
TArrayView < FVector3f > TriangleBinormals = Attributes . GetTriangleBinormals ( ) . GetRawArray ( ) ;
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 StartIndex = BatchIndex * BatchSize ;
int32 TriIndex = StartIndex * 3 ;
int32 EndIndex = FMath : : Min ( StartIndex + BatchSize , NumTriangles ) ;
for ( ; StartIndex < EndIndex ; + + StartIndex , TriIndex + = 3 )
{
if ( ! TriangleNormals [ StartIndex ] . IsNearlyZero ( ) )
{
// Bypass normal calculation if it's already done
continue ;
}
2021-05-05 15:07:25 -04:00
FVector3f TriangleVertexPositions [ 3 ] =
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
{
VertexPositions [ TriangleVertexIDs [ TriIndex ] ] ,
VertexPositions [ TriangleVertexIDs [ TriIndex + 1 ] ] ,
VertexPositions [ TriangleVertexIDs [ TriIndex + 2 ] ]
} ;
FVector2D TriangleUVs [ 3 ] =
{
2022-02-02 01:47:07 -05:00
FVector2D ( VertexUVs [ TriangleVertexInstanceIDs [ TriIndex ] ] ) ,
FVector2D ( VertexUVs [ TriangleVertexInstanceIDs [ TriIndex + 1 ] ] ) ,
FVector2D ( VertexUVs [ TriangleVertexInstanceIDs [ TriIndex + 2 ] ] )
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
} ;
2021-05-05 15:07:25 -04:00
TTuple < FVector3f , FVector3f , FVector3f > Result = GetTriangleTangentsAndNormals ( ComparisonThreshold , TriangleVertexPositions , TriangleUVs ) ;
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
TriangleNormals [ StartIndex ] = Result . Get < 0 > ( ) ;
TriangleTangents [ StartIndex ] = Result . Get < 1 > ( ) ;
TriangleBinormals [ StartIndex ] = Result . Get < 2 > ( ) ;
}
}
) ;
}
2019-10-01 20:41:42 -04:00
void FStaticMeshOperations : : DetermineEdgeHardnessesFromVertexInstanceNormals ( FMeshDescription & MeshDescription , float Tolerance )
{
FStaticMeshAttributes Attributes ( MeshDescription ) ;
2021-05-05 15:07:25 -04:00
TVertexInstanceAttributesRef < const FVector3f > VertexNormals = Attributes . GetVertexInstanceNormals ( ) ;
2019-10-01 20:41:42 -04:00
TEdgeAttributesRef < bool > EdgeHardnesses = Attributes . GetEdgeHardnesses ( ) ;
// Holds unique vertex instance IDs for a given edge vertex
TArray < FVertexInstanceID > UniqueVertexInstanceIDs ;
for ( const FEdgeID EdgeID : MeshDescription . Edges ( ) . GetElementIDs ( ) )
{
// Get list of polygons connected to this edge
TArray < FPolygonID , TInlineAllocator < 2 > > ConnectedPolygonIDs = MeshDescription . GetEdgeConnectedPolygons < TInlineAllocator < 2 > > ( EdgeID ) ;
if ( ConnectedPolygonIDs . Num ( ) = = 0 )
{
// What does it mean if an edge has no connected polygons? For now we just skip it
continue ;
}
// Assume by default that the edge is soft - but as soon as any vertex instance belonging to a connected polygon
// has a distinct normal from the others (within the given tolerance), we mark it as hard.
// The exception is if an edge has exactly one connected polygon: in this case we automatically deem it a hard edge.
bool bEdgeIsHard = ( ConnectedPolygonIDs . Num ( ) = = 1 ) ;
// Examine vertices on each end of the edge, if we haven't yet identified it as 'hard'
for ( int32 VertexIndex = 0 ; ! bEdgeIsHard & & VertexIndex < 2 ; + + VertexIndex )
{
const FVertexID VertexID = MeshDescription . GetEdgeVertex ( EdgeID , VertexIndex ) ;
const int32 ReservedElements = 4 ;
UniqueVertexInstanceIDs . Reset ( ReservedElements ) ;
// Get a list of all vertex instances for this vertex which form part of any polygon connected to the edge
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID & VertexInstanceID : MeshDescription . GetVertexVertexInstanceIDs ( VertexID ) )
2019-10-01 20:41:42 -04:00
{
2022-01-06 16:44:09 +00:00
for ( const FPolygonID & PolygonID : MeshDescription . GetVertexInstanceConnectedPolygons < TInlineAllocator < 8 > > ( VertexInstanceID ) )
2019-10-01 20:41:42 -04:00
{
if ( ConnectedPolygonIDs . Contains ( PolygonID ) )
{
UniqueVertexInstanceIDs . AddUnique ( VertexInstanceID ) ;
break ;
}
}
}
check ( UniqueVertexInstanceIDs . Num ( ) > 0 ) ;
// First unique vertex instance is used as a reference against which the others are compared.
// (not a perfect approach: really the 'median' should be used as a reference)
2021-11-18 14:37:34 -05:00
const FVector3f ReferenceNormal = VertexNormals [ UniqueVertexInstanceIDs [ 0 ] ] ;
2019-10-01 20:41:42 -04:00
for ( int32 Index = 1 ; Index < UniqueVertexInstanceIDs . Num ( ) ; + + Index )
{
if ( ! VertexNormals [ UniqueVertexInstanceIDs [ Index ] ] . Equals ( ReferenceNormal , Tolerance ) )
{
bEdgeIsHard = true ;
break ;
}
}
}
EdgeHardnesses [ EdgeID ] = bEdgeIsHard ;
}
}
2020-01-23 16:28:59 -05:00
//////////////////
struct FVertexInfo
{
FVertexInfo ( )
{
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
TriangleID = INDEX_NONE ;
VertexInstanceID = INDEX_NONE ;
2022-02-02 01:47:07 -05:00
UVs = FVector2f ( 0.0f , 0.0f ) ;
2020-01-23 16:28:59 -05:00
}
FTriangleID TriangleID ;
FVertexInstanceID VertexInstanceID ;
2021-11-18 14:37:34 -05:00
FVector2f UVs ;
2020-01-23 16:28:59 -05:00
//Most of the time a edge has two triangles
TArray < FEdgeID , TInlineAllocator < 2 > > EdgeIDs ;
} ;
/** Helper struct for building acceleration structures. */
namespace MeshDescriptionOperationNamespace
{
struct FIndexAndZ
{
float Z ;
int32 Index ;
2021-05-05 15:07:25 -04:00
const FVector3f * OriginalVector ;
2020-01-23 16:28:59 -05:00
/** Default constructor. */
FIndexAndZ ( ) { }
/** Initialization constructor. */
2021-05-05 15:07:25 -04:00
FIndexAndZ ( int32 InIndex , const FVector3f & V )
2020-01-23 16:28:59 -05:00
{
Z = 0.30f * V . X + 0.33f * V . Y + 0.37f * V . Z ;
Index = InIndex ;
OriginalVector = & V ;
}
} ;
/** Sorting function for vertex Z/index pairs. */
struct FCompareIndexAndZ
{
FORCEINLINE bool operator ( ) ( const FIndexAndZ & A , const FIndexAndZ & B ) const { return A . Z < B . Z ; }
} ;
}
void FStaticMeshOperations : : ConvertHardEdgesToSmoothGroup ( const FMeshDescription & SourceMeshDescription , TArray < uint32 > & FaceSmoothingMasks )
{
TRACE_CPUPROFILER_EVENT_SCOPE ( FStaticMeshOperations : : ConvertHardEdgesToSmoothGroup ) ;
TMap < FPolygonID , uint32 > PolygonSmoothGroup ;
PolygonSmoothGroup . Reserve ( SourceMeshDescription . Polygons ( ) . GetArraySize ( ) ) ;
TArray < bool > ConsumedPolygons ;
ConsumedPolygons . AddZeroed ( SourceMeshDescription . Polygons ( ) . GetArraySize ( ) ) ;
TMap < FPolygonID , uint32 > PolygonAvoidances ;
TEdgeAttributesConstRef < bool > EdgeHardnesses = SourceMeshDescription . EdgeAttributes ( ) . GetAttributesRef < bool > ( MeshAttribute : : Edge : : IsHard ) ;
int32 TriangleCount = 0 ;
TArray < FPolygonID > SoftEdgeNeigbors ;
TArray < FEdgeID > PolygonEdges ;
TArray < FPolygonID > EdgeConnectedPolygons ;
TArray < FPolygonID > ConnectedPolygons ;
TArray < FPolygonID > LastConnectedPolygons ;
for ( const FPolygonID PolygonID : SourceMeshDescription . Polygons ( ) . GetElementIDs ( ) )
{
2020-07-16 08:23:15 -04:00
TriangleCount + = SourceMeshDescription . GetPolygonTriangles ( PolygonID ) . Num ( ) ;
2020-01-23 16:28:59 -05:00
if ( ConsumedPolygons [ PolygonID . GetValue ( ) ] )
{
continue ;
}
ConnectedPolygons . Reset ( ) ;
LastConnectedPolygons . Reset ( ) ;
ConnectedPolygons . Add ( PolygonID ) ;
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
LastConnectedPolygons . Add ( INDEX_NONE ) ;
2020-01-23 16:28:59 -05:00
while ( ConnectedPolygons . Num ( ) > 0 )
{
check ( LastConnectedPolygons . Num ( ) = = ConnectedPolygons . Num ( ) ) ;
FPolygonID LastPolygonID = LastConnectedPolygons . Pop ( false ) ;
FPolygonID CurrentPolygonID = ConnectedPolygons . Pop ( false ) ;
if ( ConsumedPolygons [ CurrentPolygonID . GetValue ( ) ] )
{
continue ;
}
SoftEdgeNeigbors . Reset ( ) ;
uint32 & SmoothGroup = PolygonSmoothGroup . FindOrAdd ( CurrentPolygonID ) ;
uint32 AvoidSmoothGroup = 0 ;
uint32 NeighborSmoothGroup = 0 ;
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
const uint32 LastSmoothGroupValue = ( LastPolygonID = = INDEX_NONE ) ? 0 : PolygonSmoothGroup [ LastPolygonID ] ;
2020-01-23 16:28:59 -05:00
PolygonEdges . Reset ( ) ;
SourceMeshDescription . GetPolygonPerimeterEdges ( CurrentPolygonID , PolygonEdges ) ;
for ( const FEdgeID & EdgeID : PolygonEdges )
{
bool bIsHardEdge = EdgeHardnesses [ EdgeID ] ;
EdgeConnectedPolygons . Reset ( ) ;
SourceMeshDescription . GetEdgeConnectedPolygons ( EdgeID , EdgeConnectedPolygons ) ;
for ( const FPolygonID & EdgePolygonID : EdgeConnectedPolygons )
{
if ( EdgePolygonID = = CurrentPolygonID )
{
continue ;
}
uint32 SmoothValue = 0 ;
if ( PolygonSmoothGroup . Contains ( EdgePolygonID ) )
{
SmoothValue = PolygonSmoothGroup [ EdgePolygonID ] ;
}
if ( bIsHardEdge ) //Hard Edge
{
AvoidSmoothGroup | = SmoothValue ;
}
else
{
NeighborSmoothGroup | = SmoothValue ;
//Put all none hard edge polygon in the next iteration
if ( ! ConsumedPolygons [ EdgePolygonID . GetValue ( ) ] )
{
ConnectedPolygons . Add ( EdgePolygonID ) ;
LastConnectedPolygons . Add ( CurrentPolygonID ) ;
}
else
{
SoftEdgeNeigbors . Add ( EdgePolygonID ) ;
}
}
}
}
if ( AvoidSmoothGroup ! = 0 )
{
PolygonAvoidances . FindOrAdd ( CurrentPolygonID ) = AvoidSmoothGroup ;
//find neighbor avoidance
for ( FPolygonID & NeighborID : SoftEdgeNeigbors )
{
if ( ! PolygonAvoidances . Contains ( NeighborID ) )
{
continue ;
}
AvoidSmoothGroup | = PolygonAvoidances [ NeighborID ] ;
}
uint32 NewSmoothGroup = 1 ;
while ( ( NewSmoothGroup & AvoidSmoothGroup ) ! = 0 & & NewSmoothGroup < MAX_uint32 )
{
//Shift the smooth group
NewSmoothGroup = NewSmoothGroup < < 1 ;
}
SmoothGroup = NewSmoothGroup ;
//Apply to all neighboard
for ( FPolygonID & NeighborID : SoftEdgeNeigbors )
{
PolygonSmoothGroup [ NeighborID ] | = NewSmoothGroup ;
}
}
else if ( NeighborSmoothGroup ! = 0 )
{
SmoothGroup | = LastSmoothGroupValue | NeighborSmoothGroup ;
}
else
{
SmoothGroup = 1 ;
}
ConsumedPolygons [ CurrentPolygonID . GetValue ( ) ] = true ;
}
}
//Set the smooth group in the FaceSmoothingMasks parameter
check ( FaceSmoothingMasks . Num ( ) = = TriangleCount ) ;
int32 TriangleIndex = 0 ;
for ( const FPolygonID PolygonID : SourceMeshDescription . Polygons ( ) . GetElementIDs ( ) )
{
2022-01-06 16:44:09 +00:00
const uint32 PolygonSmoothValue = PolygonSmoothGroup [ PolygonID ] ;
for ( int32 i = 0 , Num = SourceMeshDescription . GetPolygonTriangles ( PolygonID ) . Num ( ) ; i < Num ; + + i )
2020-01-23 16:28:59 -05:00
{
FaceSmoothingMasks [ TriangleIndex + + ] = PolygonSmoothValue ;
}
}
}
void FStaticMeshOperations : : ConvertSmoothGroupToHardEdges ( const TArray < uint32 > & FaceSmoothingMasks , FMeshDescription & DestinationMeshDescription )
{
TEdgeAttributesRef < bool > EdgeHardnesses = DestinationMeshDescription . EdgeAttributes ( ) . GetAttributesRef < bool > ( MeshAttribute : : Edge : : IsHard ) ;
TArray < bool > ConsumedPolygons ;
ConsumedPolygons . AddZeroed ( DestinationMeshDescription . Polygons ( ) . Num ( ) ) ;
for ( const FPolygonID PolygonID : DestinationMeshDescription . Polygons ( ) . GetElementIDs ( ) )
{
if ( ConsumedPolygons [ PolygonID . GetValue ( ) ] )
{
continue ;
}
TArray < FPolygonID > ConnectedPolygons ;
ConnectedPolygons . Add ( PolygonID ) ;
while ( ConnectedPolygons . Num ( ) > 0 )
{
FPolygonID CurrentPolygonID = ConnectedPolygons . Pop ( false ) ;
int32 CurrentPolygonIDValue = CurrentPolygonID . GetValue ( ) ;
check ( FaceSmoothingMasks . IsValidIndex ( CurrentPolygonIDValue ) ) ;
const uint32 ReferenceSmoothGroup = FaceSmoothingMasks [ CurrentPolygonIDValue ] ;
TArray < FEdgeID > PolygonEdges ;
DestinationMeshDescription . GetPolygonPerimeterEdges ( CurrentPolygonID , PolygonEdges ) ;
for ( const FEdgeID & EdgeID : PolygonEdges )
{
const bool bIsHardEdge = EdgeHardnesses [ EdgeID ] ;
if ( bIsHardEdge )
{
continue ;
}
const TArray < FPolygonID > & EdgeConnectedPolygons = DestinationMeshDescription . GetEdgeConnectedPolygons ( EdgeID ) ;
for ( const FPolygonID & EdgePolygonID : EdgeConnectedPolygons )
{
int32 EdgePolygonIDValue = EdgePolygonID . GetValue ( ) ;
if ( EdgePolygonID = = CurrentPolygonID | | ConsumedPolygons [ EdgePolygonIDValue ] )
{
continue ;
}
check ( FaceSmoothingMasks . IsValidIndex ( EdgePolygonIDValue ) ) ;
const uint32 TestSmoothGroup = FaceSmoothingMasks [ EdgePolygonIDValue ] ;
if ( ( TestSmoothGroup & ReferenceSmoothGroup ) = = 0 )
{
EdgeHardnesses [ EdgeID ] = true ;
break ;
}
else
{
ConnectedPolygons . Add ( EdgePolygonID ) ;
}
}
}
ConsumedPolygons [ CurrentPolygonID . GetValue ( ) ] = true ;
}
}
}
void FStaticMeshOperations : : ConvertToRawMesh ( const FMeshDescription & SourceMeshDescription , FRawMesh & DestinationRawMesh , const TMap < FName , int32 > & MaterialMap )
{
TRACE_CPUPROFILER_EVENT_SCOPE ( FStaticMeshOperations : : ConvertToRawMesh ) ;
DestinationRawMesh . Empty ( ) ;
//Gather all array data
2020-07-16 08:23:15 -04:00
FStaticMeshConstAttributes Attributes ( SourceMeshDescription ) ;
2021-05-05 15:07:25 -04:00
TVertexAttributesConstRef < FVector3f > VertexPositions = Attributes . GetVertexPositions ( ) ;
TVertexInstanceAttributesConstRef < FVector3f > VertexInstanceNormals = Attributes . GetVertexInstanceNormals ( ) ;
TVertexInstanceAttributesConstRef < FVector3f > VertexInstanceTangents = Attributes . GetVertexInstanceTangents ( ) ;
2020-07-16 08:23:15 -04:00
TVertexInstanceAttributesConstRef < float > VertexInstanceBinormalSigns = Attributes . GetVertexInstanceBinormalSigns ( ) ;
2021-09-22 10:01:48 -04:00
TVertexInstanceAttributesConstRef < FVector4f > VertexInstanceColors = Attributes . GetVertexInstanceColors ( ) ;
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesConstRef < FVector2f > VertexInstanceUVs = Attributes . GetVertexInstanceUVs ( ) ;
2020-07-16 08:23:15 -04:00
TPolygonGroupAttributesConstRef < FName > PolygonGroupMaterialSlotName = Attributes . GetPolygonGroupMaterialSlotNames ( ) ;
2020-01-23 16:28:59 -05:00
DestinationRawMesh . VertexPositions . AddZeroed ( SourceMeshDescription . Vertices ( ) . Num ( ) ) ;
TArray < int32 > RemapVerts ;
RemapVerts . AddZeroed ( SourceMeshDescription . Vertices ( ) . GetArraySize ( ) ) ;
int32 VertexIndex = 0 ;
2022-01-06 16:44:09 +00:00
for ( const FVertexID VertexID : SourceMeshDescription . Vertices ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
DestinationRawMesh . VertexPositions [ VertexIndex ] = VertexPositions [ VertexID ] ;
RemapVerts [ VertexID . GetValue ( ) ] = VertexIndex ;
+ + VertexIndex ;
}
int32 TriangleNumber = SourceMeshDescription . Triangles ( ) . Num ( ) ;
DestinationRawMesh . FaceMaterialIndices . AddZeroed ( TriangleNumber ) ;
DestinationRawMesh . FaceSmoothingMasks . AddZeroed ( TriangleNumber ) ;
bool bHasVertexColor = HasVertexColor ( SourceMeshDescription ) ;
int32 WedgeIndexNumber = TriangleNumber * 3 ;
if ( bHasVertexColor )
{
DestinationRawMesh . WedgeColors . AddZeroed ( WedgeIndexNumber ) ;
}
DestinationRawMesh . WedgeIndices . AddZeroed ( WedgeIndexNumber ) ;
DestinationRawMesh . WedgeTangentX . AddZeroed ( WedgeIndexNumber ) ;
DestinationRawMesh . WedgeTangentY . AddZeroed ( WedgeIndexNumber ) ;
DestinationRawMesh . WedgeTangentZ . AddZeroed ( WedgeIndexNumber ) ;
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 ExistingUVCount = VertexInstanceUVs . GetNumChannels ( ) ;
2020-01-23 16:28:59 -05:00
for ( int32 UVIndex = 0 ; UVIndex < ExistingUVCount ; + + UVIndex )
{
DestinationRawMesh . WedgeTexCoords [ UVIndex ] . AddZeroed ( WedgeIndexNumber ) ;
}
int32 TriangleIndex = 0 ;
int32 WedgeIndex = 0 ;
for ( const FPolygonID PolygonID : SourceMeshDescription . Polygons ( ) . GetElementIDs ( ) )
{
const FPolygonGroupID & PolygonGroupID = SourceMeshDescription . GetPolygonPolygonGroup ( PolygonID ) ;
int32 PolygonIDValue = PolygonID . GetValue ( ) ;
2020-07-16 08:23:15 -04:00
TArrayView < const FTriangleID > TriangleIDs = SourceMeshDescription . GetPolygonTriangles ( PolygonID ) ;
2022-01-06 16:44:09 +00:00
for ( const FTriangleID & TriangleID : TriangleIDs )
2020-01-23 16:28:59 -05:00
{
if ( MaterialMap . Num ( ) > 0 & & MaterialMap . Contains ( PolygonGroupMaterialSlotName [ PolygonGroupID ] ) )
{
DestinationRawMesh . FaceMaterialIndices [ TriangleIndex ] = MaterialMap [ PolygonGroupMaterialSlotName [ PolygonGroupID ] ] ;
}
else
{
DestinationRawMesh . FaceMaterialIndices [ TriangleIndex ] = PolygonGroupID . GetValue ( ) ;
}
DestinationRawMesh . FaceSmoothingMasks [ TriangleIndex ] = 0 ; //Conversion of soft/hard to smooth mask is done after the geometry is converted
for ( int32 Corner = 0 ; Corner < 3 ; + + Corner )
{
const FVertexInstanceID VertexInstanceID = SourceMeshDescription . GetTriangleVertexInstance ( TriangleID , Corner ) ;
if ( bHasVertexColor )
{
DestinationRawMesh . WedgeColors [ WedgeIndex ] = FLinearColor ( VertexInstanceColors [ VertexInstanceID ] ) . ToFColor ( true ) ;
}
DestinationRawMesh . WedgeIndices [ WedgeIndex ] = RemapVerts [ SourceMeshDescription . GetVertexInstanceVertex ( VertexInstanceID ) . GetValue ( ) ] ;
DestinationRawMesh . WedgeTangentX [ WedgeIndex ] = VertexInstanceTangents [ VertexInstanceID ] ;
2021-11-18 14:37:34 -05:00
DestinationRawMesh . WedgeTangentY [ WedgeIndex ] = FVector3f : : CrossProduct ( VertexInstanceNormals [ VertexInstanceID ] , VertexInstanceTangents [ VertexInstanceID ] ) . GetSafeNormal ( ) * VertexInstanceBinormalSigns [ VertexInstanceID ] ;
2020-01-23 16:28:59 -05:00
DestinationRawMesh . WedgeTangentZ [ WedgeIndex ] = VertexInstanceNormals [ VertexInstanceID ] ;
for ( int32 UVIndex = 0 ; UVIndex < ExistingUVCount ; + + UVIndex )
{
DestinationRawMesh . WedgeTexCoords [ UVIndex ] [ WedgeIndex ] = VertexInstanceUVs . Get ( VertexInstanceID , UVIndex ) ;
}
+ + WedgeIndex ;
}
+ + TriangleIndex ;
}
}
//Convert the smoothgroup
ConvertHardEdgesToSmoothGroup ( SourceMeshDescription , DestinationRawMesh . FaceSmoothingMasks ) ;
}
//We want to fill the FMeshDescription vertex position mesh attribute with the FRawMesh vertex position
//We will also weld the vertex position (old FRawMesh is not always welded) and construct a mapping array to match the FVertexID
2021-05-05 15:07:25 -04:00
void FillMeshDescriptionVertexPositionNoDuplicate ( const TArray < FVector3f > & RawMeshVertexPositions , FMeshDescription & DestinationMeshDescription , TArray < FVertexID > & RemapVertexPosition )
2020-01-23 16:28:59 -05:00
{
2021-05-05 15:07:25 -04:00
TVertexAttributesRef < FVector3f > VertexPositions = DestinationMeshDescription . GetVertexPositions ( ) ;
2020-01-23 16:28:59 -05:00
const int32 NumVertex = RawMeshVertexPositions . Num ( ) ;
TMap < int32 , int32 > TempRemapVertexPosition ;
TempRemapVertexPosition . Reserve ( NumVertex ) ;
// Create a list of vertex Z/index pairs
TArray < MeshDescriptionOperationNamespace : : FIndexAndZ > VertIndexAndZ ;
VertIndexAndZ . Reserve ( NumVertex ) ;
for ( int32 VertexIndex = 0 ; VertexIndex < NumVertex ; + + VertexIndex )
{
new ( VertIndexAndZ ) MeshDescriptionOperationNamespace : : FIndexAndZ ( VertexIndex , RawMeshVertexPositions [ VertexIndex ] ) ;
}
// Sort the vertices by z value
VertIndexAndZ . Sort ( MeshDescriptionOperationNamespace : : FCompareIndexAndZ ( ) ) ;
int32 VertexCount = 0 ;
// Search for duplicates, quickly!
for ( int32 i = 0 ; i < VertIndexAndZ . Num ( ) ; i + + )
{
int32 Index_i = VertIndexAndZ [ i ] . Index ;
if ( TempRemapVertexPosition . Contains ( Index_i ) )
{
continue ;
}
TempRemapVertexPosition . FindOrAdd ( Index_i ) = VertexCount ;
// only need to search forward, since we add pairs both ways
for ( int32 j = i + 1 ; j < VertIndexAndZ . Num ( ) ; j + + )
{
if ( FMath : : Abs ( VertIndexAndZ [ j ] . Z - VertIndexAndZ [ i ] . Z ) > SMALL_NUMBER )
break ; // can't be any more dups
2021-11-18 14:37:34 -05:00
const FVector3f & PositionA = * ( VertIndexAndZ [ i ] . OriginalVector ) ;
const FVector3f & PositionB = * ( VertIndexAndZ [ j ] . OriginalVector ) ;
2020-01-23 16:28:59 -05:00
if ( PositionA . Equals ( PositionB , SMALL_NUMBER ) )
{
TempRemapVertexPosition . FindOrAdd ( VertIndexAndZ [ j ] . Index ) = VertexCount ;
}
}
VertexCount + + ;
}
//Make sure the vertex are added in the same order to be lossless when converting the FRawMesh
//In case there is a duplicate even reordering it will not be lossless, but MeshDescription do not support
//bad data like duplicated vertex position.
RemapVertexPosition . AddUninitialized ( NumVertex ) ;
DestinationMeshDescription . ReserveNewVertices ( VertexCount ) ;
TArray < FVertexID > UniqueVertexDone ;
UniqueVertexDone . AddUninitialized ( VertexCount ) ;
for ( int32 VertexIndex = 0 ; VertexIndex < VertexCount ; + + VertexIndex )
{
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
UniqueVertexDone [ VertexIndex ] = INDEX_NONE ;
2020-01-23 16:28:59 -05:00
}
for ( int32 VertexIndex = 0 ; VertexIndex < NumVertex ; + + VertexIndex )
{
int32 RealIndex = TempRemapVertexPosition [ VertexIndex ] ;
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
if ( UniqueVertexDone [ RealIndex ] ! = INDEX_NONE )
2020-01-23 16:28:59 -05:00
{
RemapVertexPosition [ VertexIndex ] = UniqueVertexDone [ RealIndex ] ;
continue ;
}
FVertexID VertexID = DestinationMeshDescription . CreateVertex ( ) ;
UniqueVertexDone [ RealIndex ] = VertexID ;
VertexPositions [ VertexID ] = RawMeshVertexPositions [ VertexIndex ] ;
RemapVertexPosition [ VertexIndex ] = VertexID ;
}
}
//Discover degenerated triangle
bool IsTriangleDegenerated ( const FRawMesh & SourceRawMesh , const TArray < FVertexID > & RemapVertexPosition , const int32 VerticeIndexBase )
{
FVertexID VertexIDs [ 3 ] ;
for ( int32 Corner = 0 ; Corner < 3 ; + + Corner )
{
int32 VerticeIndex = VerticeIndexBase + Corner ;
VertexIDs [ Corner ] = RemapVertexPosition [ SourceRawMesh . WedgeIndices [ VerticeIndex ] ] ;
}
return ( VertexIDs [ 0 ] = = VertexIDs [ 1 ] | | VertexIDs [ 0 ] = = VertexIDs [ 2 ] | | VertexIDs [ 1 ] = = VertexIDs [ 2 ] ) ;
}
2020-02-19 06:00:18 -05:00
void FStaticMeshOperations : : ConvertFromRawMesh ( const FRawMesh & SourceRawMesh , FMeshDescription & DestinationMeshDescription , const TMap < int32 , FName > & MaterialMap , bool bSkipNormalsAndTangents )
2020-01-23 16:28:59 -05:00
{
DestinationMeshDescription . Empty ( ) ;
DestinationMeshDescription . ReserveNewVertexInstances ( SourceRawMesh . WedgeIndices . Num ( ) ) ;
DestinationMeshDescription . ReserveNewPolygons ( SourceRawMesh . WedgeIndices . Num ( ) / 3 ) ;
//Approximately 2.5 edges per polygons
DestinationMeshDescription . ReserveNewEdges ( SourceRawMesh . WedgeIndices . Num ( ) * 2.5f / 3 ) ;
//Gather all array data
2021-05-05 15:07:25 -04:00
TVertexInstanceAttributesRef < FVector3f > VertexInstanceNormals = DestinationMeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector3f > ( MeshAttribute : : VertexInstance : : Normal ) ;
TVertexInstanceAttributesRef < FVector3f > VertexInstanceTangents = DestinationMeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector3f > ( MeshAttribute : : VertexInstance : : Tangent ) ;
2020-01-23 16:28:59 -05:00
TVertexInstanceAttributesRef < float > VertexInstanceBinormalSigns = DestinationMeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < float > ( MeshAttribute : : VertexInstance : : BinormalSign ) ;
2021-09-22 10:01:48 -04:00
TVertexInstanceAttributesRef < FVector4f > VertexInstanceColors = DestinationMeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector4f > ( MeshAttribute : : VertexInstance : : Color ) ;
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesRef < FVector2f > VertexInstanceUVs = DestinationMeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector2f > ( MeshAttribute : : VertexInstance : : TextureCoordinate ) ;
2020-01-23 16:28:59 -05:00
TPolygonGroupAttributesRef < FName > PolygonGroupImportedMaterialSlotNames = DestinationMeshDescription . PolygonGroupAttributes ( ) . GetAttributesRef < FName > ( MeshAttribute : : PolygonGroup : : ImportedMaterialSlotName ) ;
int32 NumTexCoords = 0 ;
int32 MaxTexCoords = MAX_MESH_TEXTURE_COORDS ;
TArray < int32 > TextureCoordinnateRemapIndex ;
TextureCoordinnateRemapIndex . AddZeroed ( MaxTexCoords ) ;
for ( int32 TextureCoordinnateIndex = 0 ; TextureCoordinnateIndex < MaxTexCoords ; + + TextureCoordinnateIndex )
{
TextureCoordinnateRemapIndex [ TextureCoordinnateIndex ] = INDEX_NONE ;
if ( SourceRawMesh . WedgeTexCoords [ TextureCoordinnateIndex ] . Num ( ) = = SourceRawMesh . WedgeIndices . Num ( ) )
{
TextureCoordinnateRemapIndex [ TextureCoordinnateIndex ] = NumTexCoords ;
NumTexCoords + + ;
}
}
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 ( NumTexCoords ) ;
2020-01-23 16:28:59 -05:00
//Ensure we do not have any duplicate, We found all duplicated vertex and compact them and build a remap indice array to remap the wedgeindices
TArray < FVertexID > RemapVertexPosition ;
FillMeshDescriptionVertexPositionNoDuplicate ( SourceRawMesh . VertexPositions , DestinationMeshDescription , RemapVertexPosition ) ;
bool bHasColors = SourceRawMesh . WedgeColors . Num ( ) > 0 ;
bool bHasTangents = SourceRawMesh . WedgeTangentX . Num ( ) > 0 & & SourceRawMesh . WedgeTangentY . Num ( ) > 0 ;
bool bHasNormals = SourceRawMesh . WedgeTangentZ . Num ( ) > 0 ;
TArray < FPolygonGroupID > PolygonGroups ;
TMap < int32 , FPolygonGroupID > MaterialIndexToPolygonGroup ;
//Create the PolygonGroups
for ( int32 MaterialIndex : SourceRawMesh . FaceMaterialIndices )
{
if ( ! MaterialIndexToPolygonGroup . Contains ( MaterialIndex ) )
{
FPolygonGroupID PolygonGroupID ( MaterialIndex ) ;
DestinationMeshDescription . CreatePolygonGroupWithID ( PolygonGroupID ) ;
if ( MaterialMap . Contains ( MaterialIndex ) )
{
PolygonGroupImportedMaterialSlotNames [ PolygonGroupID ] = MaterialMap [ MaterialIndex ] ;
}
else
{
PolygonGroupImportedMaterialSlotNames [ PolygonGroupID ] = FName ( * FString : : Printf ( TEXT ( " MaterialSlot_%d " ) , MaterialIndex ) ) ;
}
PolygonGroups . Add ( PolygonGroupID ) ;
MaterialIndexToPolygonGroup . Add ( MaterialIndex , PolygonGroupID ) ;
}
}
//Triangles
int32 TriangleCount = SourceRawMesh . WedgeIndices . Num ( ) / 3 ;
2020-09-24 00:43:27 -04:00
// Reserve enough memory to avoid as much as possible reallocations
DestinationMeshDescription . ReserveNewVertexInstances ( SourceRawMesh . WedgeIndices . Num ( ) ) ;
DestinationMeshDescription . ReserveNewTriangles ( TriangleCount ) ;
DestinationMeshDescription . ReserveNewPolygons ( TriangleCount ) ;
DestinationMeshDescription . ReserveNewEdges ( TriangleCount * 2 ) ;
2020-01-23 16:28:59 -05:00
for ( int32 TriangleIndex = 0 ; TriangleIndex < TriangleCount ; + + TriangleIndex )
{
int32 VerticeIndexBase = TriangleIndex * 3 ;
//Check if the triangle is degenerated and skip the data if its the case
if ( IsTriangleDegenerated ( SourceRawMesh , RemapVertexPosition , VerticeIndexBase ) )
{
continue ;
}
//PolygonGroup
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
FPolygonGroupID PolygonGroupID = INDEX_NONE ;
2020-01-23 16:28:59 -05:00
FName PolygonGroupImportedMaterialSlotName = NAME_None ;
int32 MaterialIndex = SourceRawMesh . FaceMaterialIndices [ TriangleIndex ] ;
if ( MaterialIndexToPolygonGroup . Contains ( MaterialIndex ) )
{
PolygonGroupID = MaterialIndexToPolygonGroup [ MaterialIndex ] ;
}
else if ( MaterialMap . Num ( ) > 0 & & MaterialMap . Contains ( MaterialIndex ) )
{
PolygonGroupImportedMaterialSlotName = MaterialMap [ MaterialIndex ] ;
2022-01-06 16:44:09 +00:00
for ( const FPolygonGroupID SearchPolygonGroupID : DestinationMeshDescription . PolygonGroups ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
if ( PolygonGroupImportedMaterialSlotNames [ SearchPolygonGroupID ] = = PolygonGroupImportedMaterialSlotName )
{
PolygonGroupID = SearchPolygonGroupID ;
break ;
}
}
}
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
if ( PolygonGroupID = = INDEX_NONE )
2020-01-23 16:28:59 -05:00
{
PolygonGroupID = DestinationMeshDescription . CreatePolygonGroup ( ) ;
2021-04-28 01:58:36 -04:00
PolygonGroupImportedMaterialSlotNames [ PolygonGroupID ] = ( PolygonGroupImportedMaterialSlotName = = NAME_None ) ? FName ( * FString : : Printf ( TEXT ( " MaterialSlot_%d " ) , MaterialIndex ) ) : PolygonGroupImportedMaterialSlotName ;
2020-01-23 16:28:59 -05:00
PolygonGroups . Add ( PolygonGroupID ) ;
MaterialIndexToPolygonGroup . Add ( MaterialIndex , PolygonGroupID ) ;
}
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
FVertexInstanceID TriangleVertexInstanceIDs [ 3 ] ;
2020-01-23 16:28:59 -05:00
for ( int32 Corner = 0 ; Corner < 3 ; + + Corner )
{
int32 VerticeIndex = VerticeIndexBase + Corner ;
FVertexID VertexID = RemapVertexPosition [ SourceRawMesh . WedgeIndices [ VerticeIndex ] ] ;
FVertexInstanceID VertexInstanceID = DestinationMeshDescription . CreateVertexInstance ( VertexID ) ;
TriangleVertexInstanceIDs [ Corner ] = VertexInstanceID ;
2022-01-27 03:30:41 -05:00
VertexInstanceColors [ VertexInstanceID ] = bHasColors ? FVector4f ( FLinearColor : : FromSRGBColor ( SourceRawMesh . WedgeColors [ VerticeIndex ] ) ) : FVector4f ( FLinearColor : : White ) ;
2021-05-05 15:07:25 -04:00
VertexInstanceNormals [ VertexInstanceID ] = bHasNormals ? SourceRawMesh . WedgeTangentZ [ VerticeIndex ] : FVector3f ( ForceInitToZero ) ;
2020-01-23 16:28:59 -05:00
if ( bHasTangents )
{
VertexInstanceTangents [ VertexInstanceID ] = SourceRawMesh . WedgeTangentX [ VerticeIndex ] ;
2021-11-18 14:37:34 -05:00
VertexInstanceBinormalSigns [ VertexInstanceID ] = FMatrix44f ( SourceRawMesh . WedgeTangentX [ VerticeIndex ] . GetSafeNormal ( ) ,
2020-01-23 16:28:59 -05:00
SourceRawMesh . WedgeTangentY [ VerticeIndex ] . GetSafeNormal ( ) ,
SourceRawMesh . WedgeTangentZ [ VerticeIndex ] . GetSafeNormal ( ) ,
2021-11-18 14:37:34 -05:00
FVector3f : : ZeroVector ) . Determinant ( ) < 0 ? - 1.0f : + 1.0f ;
2020-01-23 16:28:59 -05:00
}
else
{
2021-11-18 14:37:34 -05:00
VertexInstanceTangents [ VertexInstanceID ] = FVector3f ( ForceInitToZero ) ;
2020-01-23 16:28:59 -05:00
VertexInstanceBinormalSigns [ VertexInstanceID ] = 0.0f ;
}
for ( int32 TextureCoordinnateIndex = 0 ; TextureCoordinnateIndex < NumTexCoords ; + + TextureCoordinnateIndex )
{
int32 TextureCoordIndex = TextureCoordinnateRemapIndex [ TextureCoordinnateIndex ] ;
if ( TextureCoordIndex = = INDEX_NONE )
{
continue ;
}
VertexInstanceUVs . Set ( VertexInstanceID , TextureCoordIndex , SourceRawMesh . WedgeTexCoords [ TextureCoordinnateIndex ] [ VerticeIndex ] ) ;
}
}
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
DestinationMeshDescription . CreateTriangle ( PolygonGroupID , TriangleVertexInstanceIDs ) ;
2020-01-23 16:28:59 -05:00
}
ConvertSmoothGroupToHardEdges ( SourceRawMesh . FaceSmoothingMasks , DestinationMeshDescription ) ;
//Create the missing normals and tangents, should we use Mikkt space for tangent???
2020-02-19 06:00:18 -05:00
if ( ! bSkipNormalsAndTangents & & ( ! bHasNormals | | ! bHasTangents ) )
2020-01-23 16:28:59 -05:00
{
//DestinationMeshDescription.ComputePolygonTangentsAndNormals(0.0f);
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
ComputeTriangleTangentsAndNormals ( DestinationMeshDescription , 0.0f ) ;
2020-01-23 16:28:59 -05:00
//Create the missing normals and recompute the tangents with MikkTSpace.
EComputeNTBsFlags ComputeNTBsOptions = EComputeNTBsFlags : : Tangents | EComputeNTBsFlags : : UseMikkTSpace | EComputeNTBsFlags : : BlendOverlappingNormals ;
ComputeTangentsAndNormals ( DestinationMeshDescription , ComputeNTBsOptions ) ;
}
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
DestinationMeshDescription . BuildIndexers ( ) ;
2020-01-23 16:28:59 -05:00
}
2021-02-16 13:49:10 -04:00
void FStaticMeshOperations : : AppendMeshDescriptions ( const TArray < const FMeshDescription * > & SourceMeshes , FMeshDescription & TargetMesh , FAppendSettings & AppendSettings )
2020-01-23 16:28:59 -05:00
{
2021-02-16 13:49:10 -04:00
TRACE_CPUPROFILER_EVENT_SCOPE_STR ( ( SourceMeshes . Num ( ) > 1 ? " FStaticMeshOperations::AppendMeshDescriptions " : " FStaticMeshOperations::AppendMeshDescription " ) ) ;
2020-01-23 16:28:59 -05:00
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
FStaticMeshAttributes TargetAttributes ( TargetMesh ) ;
2021-05-05 15:07:25 -04:00
TVertexAttributesRef < FVector3f > TargetVertexPositions = TargetAttributes . GetVertexPositions ( ) ;
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
TEdgeAttributesRef < bool > TargetEdgeHardnesses = TargetAttributes . GetEdgeHardnesses ( ) ;
TPolygonGroupAttributesRef < FName > TargetImportedMaterialSlotNames = TargetAttributes . GetPolygonGroupMaterialSlotNames ( ) ;
2021-05-05 15:07:25 -04:00
TVertexInstanceAttributesRef < FVector3f > TargetVertexInstanceNormals = TargetAttributes . GetVertexInstanceNormals ( ) ;
TVertexInstanceAttributesRef < FVector3f > TargetVertexInstanceTangents = TargetAttributes . GetVertexInstanceTangents ( ) ;
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
TVertexInstanceAttributesRef < float > TargetVertexInstanceBinormalSigns = TargetAttributes . GetVertexInstanceBinormalSigns ( ) ;
2021-09-22 10:01:48 -04:00
TVertexInstanceAttributesRef < FVector4f > TargetVertexInstanceColors = TargetAttributes . GetVertexInstanceColors ( ) ;
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesRef < FVector2f > TargetVertexInstanceUVs = TargetAttributes . GetVertexInstanceUVs ( ) ;
2020-01-23 16:28:59 -05:00
2021-02-16 13:49:10 -04:00
TargetMesh . SuspendVertexInstanceIndexing ( ) ;
TargetMesh . SuspendEdgeIndexing ( ) ;
TargetMesh . SuspendPolygonIndexing ( ) ;
TargetMesh . SuspendPolygonGroupIndexing ( ) ;
TargetMesh . SuspendUVIndexing ( ) ;
int32 NumVertices = 0 ;
int32 NumVertexInstances = 0 ;
int32 NumEdges = 0 ;
int32 NumTriangles = 0 ;
int32 MaxNumUVChannels = TargetVertexInstanceUVs . GetNumChannels ( ) ;
int32 MaxNumPolygonGroups = 0 ;
int32 MaxNumMeshVertices = 0 ;
int32 MaxNumEdges = 0 ;
int32 MaxNumVertexInstances = 0 ;
for ( const FMeshDescription * SourceMeshPtr : SourceMeshes )
{
const FMeshDescription & SourceMesh = * SourceMeshPtr ;
NumVertices + = SourceMesh . Vertices ( ) . Num ( ) ;
NumVertexInstances + = SourceMesh . VertexInstances ( ) . Num ( ) ;
NumEdges + = SourceMesh . Edges ( ) . Num ( ) ;
NumTriangles + = SourceMesh . Triangles ( ) . Num ( ) ;
FStaticMeshConstAttributes SourceAttributes ( SourceMesh ) ;
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesConstRef < FVector2f > SourceVertexInstanceUVs = SourceAttributes . GetVertexInstanceUVs ( ) ;
2021-02-16 13:49:10 -04:00
for ( int32 ChannelIdx = MaxNumUVChannels ; ChannelIdx < SourceVertexInstanceUVs . GetNumChannels ( ) ; + + ChannelIdx )
{
if ( AppendSettings . bMergeUVChannels [ ChannelIdx ] )
{
MaxNumUVChannels = ChannelIdx + 1 ;
}
}
MaxNumPolygonGroups = FMath : : Max ( MaxNumPolygonGroups , SourceMesh . PolygonGroups ( ) . Num ( ) ) ;
MaxNumMeshVertices = FMath : : Max ( MaxNumMeshVertices , SourceMesh . Vertices ( ) . Num ( ) ) ;
MaxNumEdges = FMath : : Max ( MaxNumEdges , SourceMesh . Edges ( ) . Num ( ) ) ;
MaxNumVertexInstances = FMath : : Max ( MaxNumVertexInstances , SourceMesh . VertexInstances ( ) . Num ( ) ) ;
}
2020-01-23 16:28:59 -05:00
//Copy into the target mesh
2021-02-16 13:49:10 -04:00
TargetMesh . ReserveNewVertices ( NumVertices ) ;
TargetMesh . ReserveNewVertexInstances ( NumVertexInstances ) ;
TargetMesh . ReserveNewEdges ( NumEdges ) ;
TargetMesh . ReserveNewTriangles ( NumTriangles ) ;
2020-01-23 16:28:59 -05:00
2021-02-16 13:49:10 -04:00
if ( MaxNumUVChannels > TargetVertexInstanceUVs . GetNumChannels ( ) )
2020-01-23 16:28:59 -05:00
{
2021-02-16 13:49:10 -04:00
TargetVertexInstanceUVs . SetNumChannels ( MaxNumUVChannels ) ;
2020-03-05 16:01:44 -05:00
}
2020-01-23 16:28:59 -05:00
PolygonGroupMap RemapPolygonGroup ;
2021-02-16 13:49:10 -04:00
TMap < FVertexID , FVertexID > SourceToTargetVertexID ;
SourceToTargetVertexID . Reserve ( MaxNumMeshVertices ) ;
TMap < FVertexInstanceID , FVertexInstanceID > SourceToTargetVertexInstanceID ;
SourceToTargetVertexInstanceID . Reserve ( MaxNumVertexInstances ) ;
for ( const FMeshDescription * SourceMeshPtr : SourceMeshes )
2020-01-23 16:28:59 -05:00
{
2021-02-16 13:49:10 -04:00
const FMeshDescription & SourceMesh = * SourceMeshPtr ;
RemapPolygonGroup . Empty ( MaxNumPolygonGroups ) ;
FStaticMeshConstAttributes SourceAttributes ( SourceMesh ) ;
2021-05-05 15:07:25 -04:00
TVertexAttributesConstRef < FVector3f > SourceVertexPositions = SourceAttributes . GetVertexPositions ( ) ;
2021-02-16 13:49:10 -04:00
TEdgeAttributesConstRef < bool > SourceEdgeHardnesses = SourceAttributes . GetEdgeHardnesses ( ) ;
TPolygonGroupAttributesConstRef < FName > SourceImportedMaterialSlotNames = SourceAttributes . GetPolygonGroupMaterialSlotNames ( ) ;
2021-05-05 15:07:25 -04:00
TVertexInstanceAttributesConstRef < FVector3f > SourceVertexInstanceNormals = SourceAttributes . GetVertexInstanceNormals ( ) ;
TVertexInstanceAttributesConstRef < FVector3f > SourceVertexInstanceTangents = SourceAttributes . GetVertexInstanceTangents ( ) ;
2021-02-16 13:49:10 -04:00
TVertexInstanceAttributesConstRef < float > SourceVertexInstanceBinormalSigns = SourceAttributes . GetVertexInstanceBinormalSigns ( ) ;
2021-09-22 10:01:48 -04:00
TVertexInstanceAttributesConstRef < FVector4f > SourceVertexInstanceColors = SourceAttributes . GetVertexInstanceColors ( ) ;
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesConstRef < FVector2f > SourceVertexInstanceUVs = SourceAttributes . GetVertexInstanceUVs ( ) ;
2021-02-16 13:49:10 -04:00
//PolygonGroups
if ( AppendSettings . PolygonGroupsDelegate . IsBound ( ) )
2020-01-23 16:28:59 -05:00
{
2021-02-16 13:49:10 -04:00
AppendSettings . PolygonGroupsDelegate . Execute ( SourceMesh , TargetMesh , RemapPolygonGroup ) ;
}
else
{
for ( FPolygonGroupID SourcePolygonGroupID : SourceMesh . PolygonGroups ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
2021-02-16 13:49:10 -04:00
FPolygonGroupID TargetMatchingID = INDEX_NONE ;
for ( FPolygonGroupID TargetPolygonGroupID : TargetMesh . PolygonGroups ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
2021-02-16 13:49:10 -04:00
if ( SourceImportedMaterialSlotNames [ SourcePolygonGroupID ] = = TargetImportedMaterialSlotNames [ TargetPolygonGroupID ] )
{
TargetMatchingID = TargetPolygonGroupID ;
break ;
}
2020-01-23 16:28:59 -05:00
}
2021-02-16 13:49:10 -04:00
if ( TargetMatchingID = = INDEX_NONE )
{
TargetMatchingID = TargetMesh . CreatePolygonGroup ( ) ;
TargetImportedMaterialSlotNames [ TargetMatchingID ] = SourceImportedMaterialSlotNames [ SourcePolygonGroupID ] ;
}
RemapPolygonGroup . Add ( SourcePolygonGroupID , TargetMatchingID ) ;
2020-01-23 16:28:59 -05:00
}
2021-02-16 13:49:10 -04:00
}
FPolygonGroupID SinglePolygonGroup = TargetMesh . PolygonGroups ( ) . Num ( ) = = 1 ? TargetMesh . PolygonGroups ( ) . GetFirstValidID ( ) : INDEX_NONE ;
//Vertices
for ( FVertexID SourceVertexID : SourceMesh . Vertices ( ) . GetElementIDs ( ) )
{
FVertexID TargetVertexID = TargetMesh . CreateVertex ( ) ;
2022-02-02 07:59:31 -05:00
TargetVertexPositions [ TargetVertexID ] = ( SourceVertexPositions [ SourceVertexID ] - FVector3f ( AppendSettings . MergedAssetPivot ) ) ; //LWC_TODO: Precision loss
2021-02-16 13:49:10 -04:00
SourceToTargetVertexID . Add ( SourceVertexID , TargetVertexID ) ;
}
// Transform vertices properties
if ( AppendSettings . MeshTransform )
{
const FTransform & Transform = AppendSettings . MeshTransform . GetValue ( ) ;
for ( const TPair < FVertexID , FVertexID > & VertexIDPair : SourceToTargetVertexID )
2020-01-23 16:28:59 -05:00
{
2021-05-05 15:07:25 -04:00
FVector3f & Position = TargetVertexPositions [ VertexIDPair . Value ] ;
2022-02-02 07:59:31 -05:00
Position = FVector3f ( Transform . TransformPosition ( FVector ( Position ) ) ) ; //LWC_TODO: Precision loss
2020-01-23 16:28:59 -05:00
}
}
2021-02-16 13:49:10 -04:00
//Edges
for ( const FEdgeID SourceEdgeID : SourceMesh . Edges ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
2021-02-16 13:49:10 -04:00
const FVertexID EdgeVertex0 = SourceMesh . GetEdgeVertex ( SourceEdgeID , 0 ) ;
const FVertexID EdgeVertex1 = SourceMesh . GetEdgeVertex ( SourceEdgeID , 1 ) ;
FEdgeID TargetEdgeID = TargetMesh . CreateEdge ( SourceToTargetVertexID [ EdgeVertex0 ] , SourceToTargetVertexID [ EdgeVertex1 ] ) ;
TargetEdgeHardnesses [ TargetEdgeID ] = SourceEdgeHardnesses [ SourceEdgeID ] ;
2020-01-23 16:28:59 -05:00
}
2021-02-16 13:49:10 -04:00
//VertexInstances
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID SourceVertexInstanceID : SourceMesh . VertexInstances ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
2021-02-16 13:49:10 -04:00
const FVertexID SourceVertexID = SourceMesh . GetVertexInstanceVertex ( SourceVertexInstanceID ) ;
FVertexInstanceID TargetVertexInstanceID = TargetMesh . CreateVertexInstance ( SourceToTargetVertexID [ SourceVertexID ] ) ;
TargetVertexInstanceNormals [ TargetVertexInstanceID ] = SourceVertexInstanceNormals [ SourceVertexInstanceID ] ;
TargetVertexInstanceTangents [ TargetVertexInstanceID ] = SourceVertexInstanceTangents [ SourceVertexInstanceID ] ;
TargetVertexInstanceBinormalSigns [ TargetVertexInstanceID ] = SourceVertexInstanceBinormalSigns [ SourceVertexInstanceID ] ;
if ( AppendSettings . bMergeVertexColor )
{
TargetVertexInstanceColors [ TargetVertexInstanceID ] = SourceVertexInstanceColors [ SourceVertexInstanceID ] ;
}
for ( int32 UVChannelIndex = 0 ; UVChannelIndex < MaxNumUVChannels & & UVChannelIndex < SourceVertexInstanceUVs . GetNumChannels ( ) ; + + UVChannelIndex )
{
TargetVertexInstanceUVs . Set ( TargetVertexInstanceID , UVChannelIndex , SourceVertexInstanceUVs . Get ( SourceVertexInstanceID , UVChannelIndex ) ) ;
}
SourceToTargetVertexInstanceID . Add ( SourceVertexInstanceID , TargetVertexInstanceID ) ;
2020-01-23 16:28:59 -05:00
}
2021-02-16 13:49:10 -04:00
// Transform vertex instances properties
if ( AppendSettings . MeshTransform )
2020-01-23 16:28:59 -05:00
{
2021-02-16 13:49:10 -04:00
const FTransform & Transform = AppendSettings . MeshTransform . GetValue ( ) ;
bool bFlipBinormal = Transform . GetDeterminant ( ) < 0 ;
float BinormalSignsFactor = bFlipBinormal ? - 1.f : 1.f ;
for ( const TPair < FVertexInstanceID , FVertexInstanceID > & VertexInstanceIDPair : SourceToTargetVertexInstanceID )
{
FVertexInstanceID InstanceID = VertexInstanceIDPair . Value ;
2021-05-05 15:07:25 -04:00
FVector3f & Normal = TargetVertexInstanceNormals [ InstanceID ] ;
2022-02-02 07:59:31 -05:00
Normal = FVector3f ( Transform . TransformVectorNoScale ( FVector ( Normal ) ) ) ;
2021-02-16 13:49:10 -04:00
2021-05-05 15:07:25 -04:00
FVector3f & Tangent = TargetVertexInstanceTangents [ InstanceID ] ;
2022-02-02 07:59:31 -05:00
Tangent = FVector3f ( Transform . TransformVectorNoScale ( FVector ( Tangent ) ) ) ;
2021-02-16 13:49:10 -04:00
TargetVertexInstanceBinormalSigns [ InstanceID ] * = BinormalSignsFactor ;
}
}
// Triangles
for ( const FTriangleID SourceTriangleID : SourceMesh . Triangles ( ) . GetElementIDs ( ) )
{
TArrayView < const FVertexInstanceID > TriangleVertexInstanceIDs = SourceMesh . GetTriangleVertexInstances ( SourceTriangleID ) ;
//Find the polygonGroupID
FPolygonGroupID TargetPolygonGroupID = SinglePolygonGroup ! = INDEX_NONE ? SinglePolygonGroup : RemapPolygonGroup [ SourceMesh . GetTrianglePolygonGroup ( SourceTriangleID ) ] ;
TArray < FVertexInstanceID , TInlineAllocator < 3 > > VertexInstanceIDs ;
VertexInstanceIDs . Reserve ( 3 ) ;
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID & VertexInstanceID : TriangleVertexInstanceIDs )
2021-02-16 13:49:10 -04:00
{
VertexInstanceIDs . Add ( SourceToTargetVertexInstanceID [ VertexInstanceID ] ) ;
}
// Insert a triangle into the mesh
TargetMesh . CreateTriangle ( TargetPolygonGroupID , VertexInstanceIDs ) ;
2020-01-23 16:28:59 -05:00
}
}
2021-02-16 13:49:10 -04:00
TargetMesh . ResumeVertexInstanceIndexing ( ) ;
TargetMesh . ResumeEdgeIndexing ( ) ;
TargetMesh . ResumePolygonIndexing ( ) ;
TargetMesh . ResumePolygonGroupIndexing ( ) ;
TargetMesh . ResumeUVIndexing ( ) ;
2020-01-23 16:28:59 -05:00
}
2021-02-16 13:49:10 -04:00
void FStaticMeshOperations : : AppendMeshDescription ( const FMeshDescription & SourceMesh , FMeshDescription & TargetMesh , FAppendSettings & AppendSettings )
{
AppendMeshDescriptions ( { & SourceMesh } , TargetMesh , AppendSettings ) ;
}
2020-01-23 16:28:59 -05:00
//////////////////////////////////////////////////////////////////////////
// Normals tangents and Bi-normals
void FStaticMeshOperations : : AreNormalsAndTangentsValid ( const FMeshDescription & MeshDescription , bool & bHasInvalidNormals , bool & bHasInvalidTangents )
{
bHasInvalidNormals = false ;
bHasInvalidTangents = false ;
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
FStaticMeshConstAttributes Attributes ( MeshDescription ) ;
2021-05-05 15:07:25 -04:00
TArrayView < const FVector3f > VertexInstanceNormals = Attributes . GetVertexInstanceNormals ( ) . GetRawArray ( ) ;
TArrayView < const FVector3f > VertexInstanceTangents = Attributes . GetVertexInstanceTangents ( ) . GetRawArray ( ) ;
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
for ( const FVertexInstanceID VertexInstanceID : MeshDescription . VertexInstances ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
bHasInvalidNormals | = ( VertexInstanceNormals [ VertexInstanceID ] . IsNearlyZero ( ) | | VertexInstanceNormals [ VertexInstanceID ] . ContainsNaN ( ) ) ;
bHasInvalidTangents | = ( VertexInstanceTangents [ VertexInstanceID ] . IsNearlyZero ( ) | | VertexInstanceTangents [ VertexInstanceID ] . ContainsNaN ( ) ) ;
if ( bHasInvalidNormals & & bHasInvalidTangents )
{
break ;
}
}
}
void ClearNormalsAndTangentsData ( FMeshDescription & MeshDescription , bool bClearNormals , bool bClearTangents )
{
2022-01-15 11:30:39 -05:00
if ( ! bClearNormals & & ! bClearTangents )
2020-01-23 16:28:59 -05:00
{
return ;
}
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
FStaticMeshAttributes Attributes ( MeshDescription ) ;
2021-05-05 15:07:25 -04:00
TArrayView < FVector3f > VertexInstanceNormals = Attributes . GetVertexInstanceNormals ( ) . GetRawArray ( ) ;
TArrayView < FVector3f > VertexInstanceTangents = Attributes . GetVertexInstanceTangents ( ) . GetRawArray ( ) ;
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
TArrayView < float > VertexInstanceBinormals = Attributes . GetVertexInstanceBinormalSigns ( ) . GetRawArray ( ) ;
2020-01-23 16:28:59 -05:00
//Zero out all value that need to be recompute
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
for ( const FVertexInstanceID VertexInstanceID : MeshDescription . VertexInstances ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
if ( bClearNormals )
{
2021-11-18 14:37:34 -05:00
VertexInstanceNormals [ VertexInstanceID ] = FVector3f : : ZeroVector ;
2020-01-23 16:28:59 -05:00
}
if ( bClearTangents )
{
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
// Dump the tangents
VertexInstanceBinormals [ VertexInstanceID ] = 0.0f ;
2021-11-18 14:37:34 -05:00
VertexInstanceTangents [ VertexInstanceID ] = FVector3f : : ZeroVector ;
2020-01-23 16:28:59 -05:00
}
}
}
2021-11-18 14:37:34 -05:00
struct FNTBGroupKeyFuncs : public TDefaultMapKeyFuncs < FVector2f , FVector3f , false >
2020-01-23 16:28:59 -05:00
{
//We need to sanitize the key here to make sure -0.0f fall on the same hash then 0.0f
static FORCEINLINE_DEBUGGABLE uint32 GetKeyHash ( KeyInitType Key )
{
2021-11-18 14:37:34 -05:00
FVector2f TmpKey ;
2020-01-23 16:28:59 -05:00
TmpKey . X = FMath : : IsNearlyZero ( Key . X ) ? 0.0f : Key . X ;
TmpKey . Y = FMath : : IsNearlyZero ( Key . Y ) ? 0.0f : Key . Y ;
return FCrc : : MemCrc32 ( & TmpKey , sizeof ( TmpKey ) ) ;
}
} ;
void FStaticMeshOperations : : RecomputeNormalsAndTangentsIfNeeded ( FMeshDescription & MeshDescription , EComputeNTBsFlags ComputeNTBsOptions )
{
if ( ! EnumHasAllFlags ( ComputeNTBsOptions , EComputeNTBsFlags : : Normals | EComputeNTBsFlags : : Tangents ) )
{
bool bRecomputeNormals = false ;
bool bRecomputeTangents = false ;
AreNormalsAndTangentsValid ( MeshDescription , bRecomputeNormals , bRecomputeTangents ) ;
ComputeNTBsOptions | = ( bRecomputeNormals ? EComputeNTBsFlags : : Normals : EComputeNTBsFlags : : None ) ;
ComputeNTBsOptions | = ( bRecomputeTangents ? EComputeNTBsFlags : : Tangents : EComputeNTBsFlags : : None ) ;
}
if ( EnumHasAnyFlags ( ComputeNTBsOptions , EComputeNTBsFlags : : Normals | EComputeNTBsFlags : : Tangents ) )
{
ComputeTangentsAndNormals ( MeshDescription , ComputeNTBsOptions ) ;
}
}
void FStaticMeshOperations : : ComputeTangentsAndNormals ( FMeshDescription & MeshDescription , EComputeNTBsFlags ComputeNTBsOptions )
{
TRACE_CPUPROFILER_EVENT_SCOPE ( FStaticMeshOperations : : ComputeTangentsAndNormals ) ;
//For each vertex compute the normals for every connected edges that are smooth between hard edges
// H A B
// \ || /
// G -- ** -- C
/ / / / | \
// F E D
//
// The double ** are the vertex, the double line are hard edges, the single line are soft edge.
// A and F are hard, all other edges are soft. The goal is to compute two average normals one from
// A to F and a second from F to A. Then we can set the vertex instance normals accordingly.
// First normal(A to F) = Normalize(A+B+C+D+E+F)
// Second normal(F to A) = Normalize(F+G+H+A)
// We found the connected edge using the triangle that share edges
// @todo: provide an option to weight each contributing polygon normal according to the size of
// the angle it makes with the vertex being calculated. This means that triangulated faces whose
// internal edge meets the vertex doesn't get undue extra weight.
struct FTriangleCornerData
{
FVertexInstanceID VertexInstanceID ;
float CornerAngle ;
} ;
struct FTriangleData
{
public :
//The area of the triangle
float Area ;
//Set the corner angle data for a FVertexInstanceID
void SetCornerAngleData ( FVertexInstanceID VertexInstanceID , float CornerAngle , int32 CornerIndex )
{
CornerAngleDatas [ CornerIndex ] . VertexInstanceID = VertexInstanceID ;
CornerAngleDatas [ CornerIndex ] . CornerAngle = CornerAngle ;
}
//Get the angle for the FVertexInstanceID
float GetCornerAngle ( FVertexInstanceID VertexInstanceID )
{
for ( int32 CornerIndex = 0 ; CornerIndex < 3 ; + + CornerIndex )
{
if ( CornerAngleDatas [ CornerIndex ] . VertexInstanceID = = VertexInstanceID )
{
return CornerAngleDatas [ CornerIndex ] . CornerAngle ;
}
}
//We should always found a valid VertexInstanceID
check ( false ) ;
return 0.0f ;
}
private :
//The data for each corner
FTriangleCornerData CornerAngleDatas [ 3 ] ;
} ;
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
#if 0
2020-01-23 16:28:59 -05:00
//Make sure the meshdescription is triangulate
if ( MeshDescription . Triangles ( ) . Num ( ) < MeshDescription . Polygons ( ) . Num ( ) )
{
//Triangulate the mesh, we compute the normals on triangle not on polygon.
MeshDescription . TriangulateMesh ( ) ;
}
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
# endif
2020-01-23 16:28:59 -05:00
2021-06-09 17:26:10 -04:00
if ( MeshDescription . Triangles ( ) . Num ( ) = = 0 )
{
return ;
}
2020-01-23 16:28:59 -05:00
const bool bForceComputeNormals = EnumHasAllFlags ( ComputeNTBsOptions , EComputeNTBsFlags : : Normals ) ;
const bool bForceComputeTangent = EnumHasAnyFlags ( ComputeNTBsOptions , EComputeNTBsFlags : : Normals | EComputeNTBsFlags : : Tangents ) ;
const bool bComputeTangentWithMikkTSpace = bForceComputeTangent & & EnumHasAllFlags ( ComputeNTBsOptions , EComputeNTBsFlags : : UseMikkTSpace ) ;
const bool bComputeWeightedNormals = EnumHasAllFlags ( ComputeNTBsOptions , EComputeNTBsFlags : : WeightedNTBs ) ;
//Clear any data we want to force-recompute since the following code actually look for any invalid data and recompute it.
ClearNormalsAndTangentsData ( MeshDescription , bForceComputeNormals , bForceComputeTangent ) ;
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
// Going to iterate over all triangles, so mandate that the triangle elements are compact, i.e. there are no holes
const int32 NumTriangles = MeshDescription . Triangles ( ) . Num ( ) ;
check ( MeshDescription . Triangles ( ) . GetArraySize ( ) = = NumTriangles ) ;
2020-07-16 08:23:15 -04:00
// Compute the weight (area and angle) for each triangles
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
TArray < FTriangleData > TriangleDatas ;
TriangleDatas . SetNum ( NumTriangles ) ;
2020-01-23 16:28:59 -05:00
if ( bComputeWeightedNormals )
{
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
FStaticMeshAttributes Attributes ( MeshDescription ) ;
2021-05-05 15:07:25 -04:00
TArrayView < const FVector3f > VertexPositions = Attributes . GetVertexPositions ( ) . GetRawArray ( ) ;
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
TArrayView < const FVertexID > TriVertexIDs = Attributes . GetTriangleVertexIndices ( ) . GetRawArray ( ) ;
TArrayView < const FVertexInstanceID > TriVertexInstanceIDs = Attributes . GetTriangleVertexInstanceIndices ( ) . GetRawArray ( ) ;
2020-01-23 16:28:59 -05:00
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
TriangleDatas . Reserve ( NumTriangles ) ;
for ( int32 Index = 0 , TriIndex = 0 ; Index < NumTriangles ; Index + + , TriIndex + = 3 )
2020-02-04 19:04:31 -05:00
{
2022-02-02 07:59:31 -05:00
const FVector PointA ( VertexPositions [ TriVertexIDs [ TriIndex + 0 ] ] ) ;
const FVector PointB ( VertexPositions [ TriVertexIDs [ TriIndex + 1 ] ] ) ;
const FVector PointC ( VertexPositions [ TriVertexIDs [ TriIndex + 2 ] ] ) ;
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
FTriangleData & TriangleData = TriangleDatas [ Index ] ;
2020-01-23 16:28:59 -05:00
TriangleData . Area = TriangleUtilities : : ComputeTriangleArea ( PointA , PointB , PointC ) ;
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
TriangleData . SetCornerAngleData ( TriVertexInstanceIDs [ TriIndex + 0 ] , TriangleUtilities : : ComputeTriangleCornerAngle ( PointA , PointB , PointC ) , 0 ) ;
TriangleData . SetCornerAngleData ( TriVertexInstanceIDs [ TriIndex + 1 ] , TriangleUtilities : : ComputeTriangleCornerAngle ( PointB , PointC , PointA ) , 1 ) ;
TriangleData . SetCornerAngleData ( TriVertexInstanceIDs [ TriIndex + 2 ] , TriangleUtilities : : ComputeTriangleCornerAngle ( PointC , PointA , PointB ) , 2 ) ;
2020-01-23 16:28:59 -05:00
}
}
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
// Ensure certain indexers are built in anticipation
MeshDescription . BuildVertexIndexers ( ) ;
MeshDescription . BuildEdgeIndexers ( ) ;
// Going to iterate over all vertices, so mandate that the vertex elements are compact, i.e. there are no holes
const int32 NumVertices = MeshDescription . Vertices ( ) . Num ( ) ;
check ( MeshDescription . Vertices ( ) . GetArraySize ( ) = = NumVertices ) ;
2020-01-23 16:28:59 -05:00
// Split work in batch to reduce call and allocation overhead
const int32 BatchSize = 128 * 1024 ;
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
const int32 BatchCount = ( NumVertices + BatchSize - 1 ) / BatchSize ;
2020-01-23 16:28:59 -05:00
//Iterate all vertex to compute normals for all vertex instance
2022-02-23 19:25:03 -05:00
ParallelFor ( TEXT ( " ComputeTangentsAndNormals.PF " ) , BatchCount , 1 ,
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
[ NumVertices , BatchSize , bComputeTangentWithMikkTSpace , bComputeWeightedNormals , & MeshDescription , & TriangleDatas ] ( int32 BatchIndex )
2020-02-04 19:04:31 -05:00
{
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
FStaticMeshAttributes Attributes ( MeshDescription ) ;
2020-01-23 16:28:59 -05:00
2021-11-18 14:37:34 -05:00
TArrayView < const FVector2f > VertexUVs = Attributes . GetVertexInstanceUVs ( ) . GetRawArray ( 0 ) ; // Use UV0
2021-05-05 15:07:25 -04:00
TArrayView < const FVector3f > TriangleNormals = Attributes . GetTriangleNormals ( ) . GetRawArray ( ) ;
TArrayView < const FVector3f > TriangleTangents = Attributes . GetTriangleTangents ( ) . GetRawArray ( ) ;
TArrayView < const FVector3f > TriangleBinormals = Attributes . GetTriangleBinormals ( ) . GetRawArray ( ) ;
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
TArrayView < const bool > EdgeHardnesses = Attributes . GetEdgeHardnesses ( ) . GetRawArray ( ) ;
2020-01-23 16:28:59 -05:00
2021-05-05 15:07:25 -04:00
TArrayView < FVector3f > VertexNormals = Attributes . GetVertexInstanceNormals ( ) . GetRawArray ( ) ;
TArrayView < FVector3f > VertexTangents = Attributes . GetVertexInstanceTangents ( ) . GetRawArray ( ) ;
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
TArrayView < float > VertexBinormalSigns = Attributes . GetVertexInstanceBinormalSigns ( ) . GetRawArray ( ) ;
check ( TriangleNormals . Num ( ) > 0 ) ;
check ( TriangleTangents . Num ( ) > 0 ) ;
check ( TriangleBinormals . Num ( ) > 0 ) ;
2020-01-23 16:28:59 -05:00
//Reuse containers between iterations to reduce allocations
2021-11-18 14:37:34 -05:00
TMap < FVector2f , FVector3f , FDefaultSetAllocator , FNTBGroupKeyFuncs > GroupTangent ;
TMap < FVector2f , FVector3f , FDefaultSetAllocator , FNTBGroupKeyFuncs > GroupBiNormal ;
2020-01-23 16:28:59 -05:00
TMap < FTriangleID , FVertexInfo > VertexInfoMap ;
TArray < TArray < FTriangleID , TInlineAllocator < 8 > > > Groups ;
TArray < FTriangleID > ConsumedTriangle ;
TArray < FTriangleID > PolygonQueue ;
TArray < FVertexInstanceID > VertexInstanceInGroup ;
VertexInfoMap . Reserve ( 20 ) ;
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 StartIndex = BatchIndex * BatchSize ;
int32 LastIndex = FMath : : Min ( StartIndex + BatchSize , NumVertices ) ;
for ( int32 Index = StartIndex ; Index < LastIndex ; + + Index )
2020-01-23 16:28:59 -05:00
{
VertexInfoMap . Reset ( ) ;
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
const FVertexID VertexID ( Index ) ;
2020-01-23 16:28:59 -05:00
bool bPointHasAllTangents = true ;
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
// Fill the VertexInfoMap
2022-01-06 16:44:09 +00:00
for ( const FEdgeID & EdgeID : MeshDescription . GetVertexConnectedEdgeIDs ( VertexID ) )
2020-01-23 16:28:59 -05:00
{
2022-01-06 16:44:09 +00:00
for ( const FTriangleID & TriangleID : MeshDescription . GetEdgeConnectedTriangleIDs ( EdgeID ) )
2020-01-23 16:28:59 -05:00
{
FVertexInfo & VertexInfo = VertexInfoMap . FindOrAdd ( TriangleID ) ;
int32 EdgeIndex = VertexInfo . EdgeIDs . AddUnique ( EdgeID ) ;
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
if ( VertexInfo . TriangleID = = INDEX_NONE )
2020-01-23 16:28:59 -05:00
{
VertexInfo . TriangleID = TriangleID ;
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID & VertexInstanceID : MeshDescription . GetTriangleVertexInstances ( TriangleID ) )
2020-01-23 16:28:59 -05:00
{
if ( MeshDescription . GetVertexInstanceVertex ( VertexInstanceID ) = = VertexID )
{
VertexInfo . VertexInstanceID = VertexInstanceID ;
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
VertexInfo . UVs = VertexUVs [ VertexInstanceID ] ; // UV0
2020-01-23 16:28:59 -05:00
bPointHasAllTangents & = ! VertexNormals [ VertexInstanceID ] . IsNearlyZero ( ) & & ! VertexTangents [ VertexInstanceID ] . IsNearlyZero ( ) ;
if ( bPointHasAllTangents )
{
2021-11-18 14:37:34 -05:00
FVector3f TangentX = VertexTangents [ VertexInstanceID ] . GetSafeNormal ( ) ;
FVector3f TangentZ = VertexNormals [ VertexInstanceID ] . GetSafeNormal ( ) ;
FVector3f TangentY = ( FVector3f : : CrossProduct ( TangentZ , TangentX ) . GetSafeNormal ( ) * VertexBinormalSigns [ VertexInstanceID ] ) . GetSafeNormal ( ) ;
2020-01-23 16:28:59 -05:00
if ( TangentX . ContainsNaN ( ) | | TangentX . IsNearlyZero ( SMALL_NUMBER ) | |
TangentY . ContainsNaN ( ) | | TangentY . IsNearlyZero ( SMALL_NUMBER ) | |
TangentZ . ContainsNaN ( ) | | TangentZ . IsNearlyZero ( SMALL_NUMBER ) )
{
bPointHasAllTangents = false ;
}
}
break ;
}
}
}
}
}
if ( bPointHasAllTangents )
{
continue ;
}
//Build all group by recursively traverse all polygon connected to the vertex
Groups . Reset ( ) ;
ConsumedTriangle . Reset ( ) ;
for ( auto Kvp : VertexInfoMap )
{
if ( ConsumedTriangle . Contains ( Kvp . Key ) )
{
continue ;
}
int32 CurrentGroupIndex = Groups . AddZeroed ( ) ;
TArray < FTriangleID , TInlineAllocator < 8 > > & CurrentGroup = Groups [ CurrentGroupIndex ] ;
PolygonQueue . Reset ( ) ;
PolygonQueue . Add ( Kvp . Key ) ; //Use a queue to avoid recursive function
while ( PolygonQueue . Num ( ) > 0 )
{
FTriangleID CurrentPolygonID = PolygonQueue . Pop ( false ) ;
FVertexInfo & CurrentVertexInfo = VertexInfoMap . FindOrAdd ( CurrentPolygonID ) ;
CurrentGroup . AddUnique ( CurrentVertexInfo . TriangleID ) ;
ConsumedTriangle . AddUnique ( CurrentVertexInfo . TriangleID ) ;
2022-01-06 16:44:09 +00:00
for ( const FEdgeID & EdgeID : CurrentVertexInfo . EdgeIDs )
2020-01-23 16:28:59 -05:00
{
if ( EdgeHardnesses [ EdgeID ] )
{
//End of the group
continue ;
}
2022-01-06 16:44:09 +00:00
for ( const FTriangleID & TriangleID : MeshDescription . GetEdgeConnectedTriangleIDs ( EdgeID ) )
2020-01-23 16:28:59 -05:00
{
if ( TriangleID = = CurrentVertexInfo . TriangleID )
{
continue ;
}
//Add this polygon to the group
FVertexInfo & OtherVertexInfo = VertexInfoMap . FindOrAdd ( TriangleID ) ;
//Do not repeat polygons
if ( ! ConsumedTriangle . Contains ( OtherVertexInfo . TriangleID ) )
{
PolygonQueue . Add ( TriangleID ) ;
}
}
}
}
}
for ( const TArray < FTriangleID , TInlineAllocator < 8 > > & Group : Groups )
{
//Compute tangents data
GroupTangent . Reset ( ) ;
GroupBiNormal . Reset ( ) ;
VertexInstanceInGroup . Reset ( ) ;
2021-11-18 14:37:34 -05:00
FVector3f GroupNormal ( FVector3f : : ZeroVector ) ;
2022-01-06 16:44:09 +00:00
for ( const FTriangleID & TriangleID : Group )
2020-01-23 16:28:59 -05:00
{
FVertexInfo & CurrentVertexInfo = VertexInfoMap . FindOrAdd ( TriangleID ) ;
float CornerWeight = 1.0f ;
if ( bComputeWeightedNormals )
{
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
FTriangleData & TriangleData = TriangleDatas [ TriangleID ] ;
2020-01-23 16:28:59 -05:00
CornerWeight = TriangleData . Area * TriangleData . GetCornerAngle ( CurrentVertexInfo . VertexInstanceID ) ;
}
2021-11-18 14:37:34 -05:00
const FVector3f TriNormal = CornerWeight * TriangleNormals [ TriangleID ] ;
const FVector3f TriTangent = CornerWeight * TriangleTangents [ TriangleID ] ;
const FVector3f TriBinormal = CornerWeight * TriangleBinormals [ TriangleID ] ;
2020-01-23 16:28:59 -05:00
VertexInstanceInGroup . Add ( VertexInfoMap [ TriangleID ] . VertexInstanceID ) ;
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
if ( ! TriNormal . IsNearlyZero ( SMALL_NUMBER ) & & ! TriNormal . ContainsNaN ( ) )
2020-01-23 16:28:59 -05:00
{
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
GroupNormal + = TriNormal ;
2020-01-23 16:28:59 -05:00
}
if ( ! bComputeTangentWithMikkTSpace )
{
2021-11-18 14:37:34 -05:00
const FVector2f & UVs = VertexInfoMap [ TriangleID ] . UVs ;
2020-01-23 16:28:59 -05:00
bool CreateGroup = ( ! GroupTangent . Contains ( UVs ) ) ;
2021-05-05 15:07:25 -04:00
FVector3f & GroupTangentValue = GroupTangent . FindOrAdd ( UVs ) ;
FVector3f & GroupBiNormalValue = GroupBiNormal . FindOrAdd ( UVs ) ;
2020-01-23 16:28:59 -05:00
if ( CreateGroup )
{
2021-11-18 14:37:34 -05:00
GroupTangentValue = FVector3f ( 0.0f ) ;
GroupBiNormalValue = FVector3f ( 0.0f ) ;
2020-01-23 16:28:59 -05:00
}
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
if ( ! TriTangent . IsNearlyZero ( SMALL_NUMBER ) & & ! TriTangent . ContainsNaN ( ) )
2020-01-23 16:28:59 -05:00
{
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
GroupTangentValue + = TriTangent ;
2020-01-23 16:28:59 -05:00
}
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
if ( ! TriBinormal . IsNearlyZero ( SMALL_NUMBER ) & & ! TriBinormal . ContainsNaN ( ) )
2020-01-23 16:28:59 -05:00
{
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
GroupBiNormalValue + = TriBinormal ;
2020-01-23 16:28:59 -05:00
}
}
}
//////////////////////////////////////////////////////////////////////////
//Apply the group to the Mesh
GroupNormal . Normalize ( ) ;
if ( ! bComputeTangentWithMikkTSpace )
{
for ( auto Kvp : GroupTangent )
{
Kvp . Value . Normalize ( ) ;
}
for ( auto Kvp : GroupBiNormal )
{
Kvp . Value . Normalize ( ) ;
}
}
//Apply the average NTB on all Vertex instance
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID & VertexInstanceID : VertexInstanceInGroup )
2020-01-23 16:28:59 -05:00
{
2021-11-18 14:37:34 -05:00
const FVector2f & VertexUV = VertexUVs [ VertexInstanceID ] ; // UV0
2020-01-23 16:28:59 -05:00
if ( VertexNormals [ VertexInstanceID ] . IsNearlyZero ( SMALL_NUMBER ) )
{
VertexNormals [ VertexInstanceID ] = GroupNormal ;
}
//If we are not computing the tangent with MikkTSpace, make sure the tangents are valid.
if ( ! bComputeTangentWithMikkTSpace )
{
//Avoid changing the original group value
2021-05-05 15:07:25 -04:00
FVector3f GroupTangentValue = GroupTangent [ VertexUV ] ;
FVector3f GroupBiNormalValue = GroupBiNormal [ VertexUV ] ;
2020-01-23 16:28:59 -05:00
if ( ! VertexTangents [ VertexInstanceID ] . IsNearlyZero ( SMALL_NUMBER ) )
{
GroupTangentValue = VertexTangents [ VertexInstanceID ] ;
}
2021-05-05 15:07:25 -04:00
FVector3f BiNormal ( 0.0f ) ;
2021-11-18 14:37:34 -05:00
const FVector3f & VertexNormal ( VertexNormals [ VertexInstanceID ] ) ;
2020-01-23 16:28:59 -05:00
if ( ! VertexNormal . IsNearlyZero ( SMALL_NUMBER ) & & ! VertexTangents [ VertexInstanceID ] . IsNearlyZero ( SMALL_NUMBER ) )
{
2021-05-05 15:07:25 -04:00
BiNormal = FVector3f : : CrossProduct ( VertexNormal , VertexTangents [ VertexInstanceID ] ) . GetSafeNormal ( ) * VertexBinormalSigns [ VertexInstanceID ] ;
2020-01-23 16:28:59 -05:00
}
if ( ! BiNormal . IsNearlyZero ( SMALL_NUMBER ) )
{
GroupBiNormalValue = BiNormal ;
}
// Gram-Schmidt orthogonalization
GroupBiNormalValue - = GroupTangentValue * ( GroupTangentValue | GroupBiNormalValue ) ;
GroupBiNormalValue . Normalize ( ) ;
GroupTangentValue - = VertexNormal * ( VertexNormal | GroupTangentValue ) ;
GroupTangentValue . Normalize ( ) ;
GroupBiNormalValue - = VertexNormal * ( VertexNormal | GroupBiNormalValue ) ;
GroupBiNormalValue . Normalize ( ) ;
//Set the value
VertexTangents [ VertexInstanceID ] = GroupTangentValue ;
//If the BiNormal is zero set the sign to 1.0f, inlining GetBasisDeterminantSign() to avoid depending on RenderCore.
2021-05-05 15:07:25 -04:00
VertexBinormalSigns [ VertexInstanceID ] = FMatrix44f ( GroupTangentValue , GroupBiNormalValue , VertexNormal , FVector3f : : ZeroVector ) . Determinant ( ) < 0 ? - 1.0f : + 1.0f ;
2020-01-23 16:28:59 -05:00
}
}
}
}
}
) ;
if ( bForceComputeTangent & & bComputeTangentWithMikkTSpace )
{
ComputeMikktTangents ( MeshDescription , EnumHasAnyFlags ( ComputeNTBsOptions , EComputeNTBsFlags : : IgnoreDegenerateTriangles ) ) ;
}
}
# if WITH_MIKKTSPACE
namespace MeshDescriptionMikktSpaceInterface
{
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
struct FMeshDescriptionCachedData
{
int32 NumTriangles ;
TArrayView < const FVertexID > TriangleVertexIDs ;
TArrayView < const FVertexInstanceID > TriangleVertexInstanceIDs ;
2021-05-05 15:07:25 -04:00
TArrayView < const FVector3f > VertexPositions ;
TArrayView < const FVector3f > VertexInstanceNormals ;
2021-11-18 14:37:34 -05:00
TArrayView < const FVector2f > VertexInstanceUVs ;
2021-05-05 15:07:25 -04:00
TArrayView < FVector3f > VertexInstanceTangents ;
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
TArrayView < float > VertexInstanceBinormalSigns ;
} ;
2020-01-23 16:28:59 -05:00
int MikkGetNumFaces ( const SMikkTSpaceContext * Context )
{
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
FMeshDescriptionCachedData * UserData = ( FMeshDescriptionCachedData * ) ( Context - > m_pUserData ) ;
return UserData - > NumTriangles ;
2020-01-23 16:28:59 -05:00
}
int MikkGetNumVertsOfFace ( const SMikkTSpaceContext * Context , const int FaceIdx )
{
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
FMeshDescriptionCachedData * UserData = ( FMeshDescriptionCachedData * ) ( Context - > m_pUserData ) ;
return 3 ;
2020-01-23 16:28:59 -05:00
}
void MikkGetPosition ( const SMikkTSpaceContext * Context , float Position [ 3 ] , const int FaceIdx , const int VertIdx )
{
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
FMeshDescriptionCachedData * UserData = ( FMeshDescriptionCachedData * ) ( Context - > m_pUserData ) ;
2021-05-05 15:07:25 -04:00
const FVector3f & VertexPosition = UserData - > VertexPositions [ UserData - > TriangleVertexIDs [ FaceIdx * 3 + VertIdx ] ] ;
2020-01-23 16:28:59 -05:00
Position [ 0 ] = VertexPosition . X ;
Position [ 1 ] = VertexPosition . Y ;
Position [ 2 ] = VertexPosition . Z ;
}
void MikkGetNormal ( const SMikkTSpaceContext * Context , float Normal [ 3 ] , const int FaceIdx , const int VertIdx )
{
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
FMeshDescriptionCachedData * UserData = ( FMeshDescriptionCachedData * ) ( Context - > m_pUserData ) ;
2021-05-05 15:07:25 -04:00
const FVector3f & VertexNormal = UserData - > VertexInstanceNormals [ UserData - > TriangleVertexInstanceIDs [ FaceIdx * 3 + VertIdx ] ] ;
2020-01-23 16:28:59 -05:00
Normal [ 0 ] = VertexNormal . X ;
Normal [ 1 ] = VertexNormal . Y ;
Normal [ 2 ] = VertexNormal . Z ;
}
void MikkSetTSpaceBasic ( const SMikkTSpaceContext * Context , const float Tangent [ 3 ] , const float BitangentSign , const int FaceIdx , const int VertIdx )
{
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
FMeshDescriptionCachedData * UserData = ( FMeshDescriptionCachedData * ) ( Context - > m_pUserData ) ;
const FVertexInstanceID VertexInstanceID = UserData - > TriangleVertexInstanceIDs [ FaceIdx * 3 + VertIdx ] ;
2021-11-18 14:37:34 -05:00
UserData - > VertexInstanceTangents [ VertexInstanceID ] = FVector3f ( Tangent [ 0 ] , Tangent [ 1 ] , Tangent [ 2 ] ) ;
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
UserData - > VertexInstanceBinormalSigns [ VertexInstanceID ] = - BitangentSign ;
2020-01-23 16:28:59 -05:00
}
void MikkGetTexCoord ( const SMikkTSpaceContext * Context , float UV [ 2 ] , const int FaceIdx , const int VertIdx )
{
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
FMeshDescriptionCachedData * UserData = ( FMeshDescriptionCachedData * ) ( Context - > m_pUserData ) ;
2021-11-18 14:37:34 -05:00
const FVector2f & TexCoord = UserData - > VertexInstanceUVs [ UserData - > TriangleVertexInstanceIDs [ FaceIdx * 3 + VertIdx ] ] ;
2020-01-23 16:28:59 -05:00
UV [ 0 ] = TexCoord . X ;
UV [ 1 ] = TexCoord . Y ;
}
}
# endif //#WITH_MIKKTSPACE
void FStaticMeshOperations : : ComputeMikktTangents ( FMeshDescription & MeshDescription , bool bIgnoreDegenerateTriangles )
{
# if WITH_MIKKTSPACE
TRACE_CPUPROFILER_EVENT_SCOPE ( FStaticMeshOperations : : ComputeMikktTangents ) ;
// The Mikkt interface does not handle properly polygon array with 'holes'
// Compact mesh description if this is the case
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
if ( MeshDescription . Triangles ( ) . Num ( ) ! = MeshDescription . Triangles ( ) . GetArraySize ( ) )
2020-01-23 16:28:59 -05:00
{
FElementIDRemappings Remappings ;
MeshDescription . Compact ( Remappings ) ;
}
2021-01-14 12:19:06 -04:00
int32 NumTriangles = MeshDescription . Triangles ( ) . Num ( ) ;
if ( NumTriangles = = 0 )
{
return ; // nothing to compute
}
2020-01-23 16:28:59 -05:00
// we can use mikktspace to calculate the tangents
SMikkTSpaceInterface MikkTInterface ;
MikkTInterface . m_getNormal = MeshDescriptionMikktSpaceInterface : : MikkGetNormal ;
MikkTInterface . m_getNumFaces = MeshDescriptionMikktSpaceInterface : : MikkGetNumFaces ;
MikkTInterface . m_getNumVerticesOfFace = MeshDescriptionMikktSpaceInterface : : MikkGetNumVertsOfFace ;
MikkTInterface . m_getPosition = MeshDescriptionMikktSpaceInterface : : MikkGetPosition ;
MikkTInterface . m_getTexCoord = MeshDescriptionMikktSpaceInterface : : MikkGetTexCoord ;
MikkTInterface . m_setTSpaceBasic = MeshDescriptionMikktSpaceInterface : : MikkSetTSpaceBasic ;
MikkTInterface . m_setTSpace = nullptr ;
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
MeshDescriptionMikktSpaceInterface : : FMeshDescriptionCachedData UserData ;
UserData . NumTriangles = MeshDescription . Triangles ( ) . Num ( ) ;
FStaticMeshAttributes Attributes ( MeshDescription ) ;
UserData . TriangleVertexIDs = Attributes . GetTriangleVertexIndices ( ) . GetRawArray ( ) ;
UserData . TriangleVertexInstanceIDs = Attributes . GetTriangleVertexInstanceIndices ( ) . GetRawArray ( ) ;
UserData . VertexPositions = Attributes . GetVertexPositions ( ) . GetRawArray ( ) ;
UserData . VertexInstanceUVs = Attributes . GetVertexInstanceUVs ( ) . GetRawArray ( 0 ) ;
UserData . VertexInstanceNormals = Attributes . GetVertexInstanceNormals ( ) . GetRawArray ( ) ;
UserData . VertexInstanceTangents = Attributes . GetVertexInstanceTangents ( ) . GetRawArray ( ) ;
UserData . VertexInstanceBinormalSigns = Attributes . GetVertexInstanceBinormalSigns ( ) . GetRawArray ( ) ;
2020-01-23 16:28:59 -05:00
SMikkTSpaceContext MikkTContext ;
MikkTContext . m_pInterface = & MikkTInterface ;
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
MikkTContext . m_pUserData = ( void * ) ( & UserData ) ;
2020-01-23 16:28:59 -05:00
MikkTContext . m_bIgnoreDegenerates = bIgnoreDegenerateTriangles ;
genTangSpaceDefault ( & MikkTContext ) ;
# else
ensureMsgf ( false , TEXT ( " MikkTSpace tangent generation is not supported on this platform. " ) ) ;
# endif //WITH_MIKKTSPACE
}
void FStaticMeshOperations : : FindOverlappingCorners ( FOverlappingCorners & OutOverlappingCorners , const FMeshDescription & MeshDescription , float ComparisonThreshold )
{
TRACE_CPUPROFILER_EVENT_SCOPE ( FStaticMeshOperations : : FindOverlappingCorners ) ;
// @todo: this should be shared with FOverlappingCorners
const FVertexInstanceArray & VertexInstanceArray = MeshDescription . VertexInstances ( ) ;
const FVertexArray & VertexArray = MeshDescription . Vertices ( ) ;
int32 NumWedges = 3 * MeshDescription . Triangles ( ) . Num ( ) ;
// Empty the old data and reserve space for new
OutOverlappingCorners . Init ( NumWedges ) ;
// Create a list of vertex Z/index pairs
TArray < MeshDescriptionOperationNamespace : : FIndexAndZ > VertIndexAndZ ;
VertIndexAndZ . Reserve ( NumWedges ) ;
2021-05-05 15:07:25 -04:00
TVertexAttributesConstRef < FVector3f > VertexPositions = MeshDescription . GetVertexPositions ( ) ;
2020-01-23 16:28:59 -05:00
int32 WedgeIndex = 0 ;
for ( const FPolygonID PolygonID : MeshDescription . Polygons ( ) . GetElementIDs ( ) )
{
2020-07-16 08:23:15 -04:00
TArrayView < const FTriangleID > TriangleIDs = MeshDescription . GetPolygonTriangles ( PolygonID ) ;
2022-01-06 16:44:09 +00:00
for ( const FTriangleID & TriangleID : TriangleIDs )
2020-01-23 16:28:59 -05:00
{
for ( int32 Corner = 0 ; Corner < 3 ; + + Corner )
{
const FVertexInstanceID VertexInstanceID = MeshDescription . GetTriangleVertexInstance ( TriangleID , Corner ) ;
new ( VertIndexAndZ ) MeshDescriptionOperationNamespace : : FIndexAndZ ( WedgeIndex , VertexPositions [ MeshDescription . GetVertexInstanceVertex ( VertexInstanceID ) ] ) ;
+ + WedgeIndex ;
}
}
}
// Sort the vertices by z value
VertIndexAndZ . Sort ( MeshDescriptionOperationNamespace : : FCompareIndexAndZ ( ) ) ;
// Search for duplicates, quickly!
for ( int32 i = 0 ; i < VertIndexAndZ . Num ( ) ; i + + )
{
// only need to search forward, since we add pairs both ways
for ( int32 j = i + 1 ; j < VertIndexAndZ . Num ( ) ; j + + )
{
if ( FMath : : Abs ( VertIndexAndZ [ j ] . Z - VertIndexAndZ [ i ] . Z ) > ComparisonThreshold )
break ; // can't be any more dups
2021-05-05 15:07:25 -04:00
const FVector3f & PositionA = * ( VertIndexAndZ [ i ] . OriginalVector ) ;
const FVector3f & PositionB = * ( VertIndexAndZ [ j ] . OriginalVector ) ;
2020-01-23 16:28:59 -05:00
if ( PositionA . Equals ( PositionB , ComparisonThreshold ) )
{
OutOverlappingCorners . Add ( VertIndexAndZ [ i ] . Index , VertIndexAndZ [ j ] . Index ) ;
OutOverlappingCorners . Add ( VertIndexAndZ [ j ] . Index , VertIndexAndZ [ i ] . Index ) ;
}
}
}
OutOverlappingCorners . FinishAdding ( ) ;
}
struct FLayoutUVMeshDescriptionView final : FLayoutUV : : IMeshView
{
FMeshDescription & MeshDescription ;
2021-05-05 15:07:25 -04:00
TVertexAttributesConstRef < FVector3f > Positions ;
TVertexInstanceAttributesConstRef < FVector3f > Normals ;
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesRef < FVector2f > TexCoords ;
2020-01-23 16:28:59 -05:00
const uint32 SrcChannel ;
const uint32 DstChannel ;
uint32 NumIndices = 0 ;
TArray < int32 > RemapVerts ;
2021-11-18 14:37:34 -05:00
TArray < FVector2f > FlattenedTexCoords ;
2020-01-23 16:28:59 -05:00
FLayoutUVMeshDescriptionView ( FMeshDescription & InMeshDescription , uint32 InSrcChannel , uint32 InDstChannel )
: MeshDescription ( InMeshDescription )
, SrcChannel ( InSrcChannel )
, DstChannel ( InDstChannel )
{
2020-07-16 08:23:15 -04:00
FStaticMeshAttributes Attributes ( InMeshDescription ) ;
Positions = Attributes . GetVertexPositions ( ) ;
Normals = Attributes . GetVertexInstanceNormals ( ) ;
TexCoords = Attributes . GetVertexInstanceUVs ( ) ;
2020-01-23 16:28:59 -05:00
uint32 NumTris = MeshDescription . Triangles ( ) . Num ( ) ;
NumIndices = NumTris * 3 ;
FlattenedTexCoords . SetNumUninitialized ( NumIndices ) ;
RemapVerts . SetNumUninitialized ( NumIndices ) ;
int32 WedgeIndex = 0 ;
for ( const FPolygonID PolygonID : MeshDescription . Polygons ( ) . GetElementIDs ( ) )
{
2020-07-16 08:23:15 -04:00
TArrayView < const FTriangleID > TriangleIDs = MeshDescription . GetPolygonTriangles ( PolygonID ) ;
2022-01-06 16:44:09 +00:00
for ( const FTriangleID & TriangleID : TriangleIDs )
2020-01-23 16:28:59 -05:00
{
for ( int32 Corner = 0 ; Corner < 3 ; + + Corner )
{
const FVertexInstanceID VertexInstanceID = MeshDescription . GetTriangleVertexInstance ( TriangleID , Corner ) ;
FlattenedTexCoords [ WedgeIndex ] = TexCoords . Get ( VertexInstanceID , SrcChannel ) ;
RemapVerts [ WedgeIndex ] = VertexInstanceID . GetValue ( ) ;
+ + WedgeIndex ;
}
}
}
}
uint32 GetNumIndices ( ) const override { return NumIndices ; }
2021-05-05 15:07:25 -04:00
FVector3f GetPosition ( uint32 Index ) const override
2020-01-23 16:28:59 -05:00
{
FVertexInstanceID VertexInstanceID ( RemapVerts [ Index ] ) ;
FVertexID VertexID = MeshDescription . GetVertexInstanceVertex ( VertexInstanceID ) ;
return Positions [ VertexID ] ;
}
2021-05-05 15:07:25 -04:00
FVector3f GetNormal ( uint32 Index ) const override
2020-01-23 16:28:59 -05:00
{
FVertexInstanceID VertexInstanceID ( RemapVerts [ Index ] ) ;
return Normals [ VertexInstanceID ] ;
}
2021-11-18 14:37:34 -05:00
FVector2f GetInputTexcoord ( uint32 Index ) const override
2020-01-23 16:28:59 -05:00
{
return FlattenedTexCoords [ Index ] ;
}
void InitOutputTexcoords ( uint32 Num ) override
{
// If current DstChannel is out of range of the number of UVs defined by the mesh description, change the index count accordingly
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
const uint32 NumUVs = TexCoords . GetNumChannels ( ) ;
2020-01-23 16:28:59 -05:00
if ( DstChannel > = NumUVs )
{
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
TexCoords . SetNumChannels ( DstChannel + 1 ) ;
2020-01-23 16:28:59 -05:00
ensure ( false ) ; // not expecting it to get here
}
}
2021-11-18 14:37:34 -05:00
void SetOutputTexcoord ( uint32 Index , const FVector2f & Value ) override
2020-01-23 16:28:59 -05:00
{
const FVertexInstanceID VertexInstanceID ( RemapVerts [ Index ] ) ;
TexCoords . Set ( VertexInstanceID , DstChannel , Value ) ;
}
} ;
int32 FStaticMeshOperations : : GetUVChartCount ( FMeshDescription & MeshDescription , int32 SrcLightmapIndex , ELightmapUVVersion LightmapUVVersion , const FOverlappingCorners & OverlappingCorners )
{
uint32 UnusedDstIndex = - 1 ;
FLayoutUVMeshDescriptionView MeshDescriptionView ( MeshDescription , SrcLightmapIndex , UnusedDstIndex ) ;
FLayoutUV Packer ( MeshDescriptionView ) ;
Packer . SetVersion ( LightmapUVVersion ) ;
return Packer . FindCharts ( OverlappingCorners ) ;
}
bool FStaticMeshOperations : : CreateLightMapUVLayout ( FMeshDescription & MeshDescription ,
int32 SrcLightmapIndex ,
int32 DstLightmapIndex ,
int32 MinLightmapResolution ,
ELightmapUVVersion LightmapUVVersion ,
const FOverlappingCorners & OverlappingCorners )
{
TRACE_CPUPROFILER_EVENT_SCOPE ( FStaticMeshOperations : : CreateLightMapUVLayout )
FLayoutUVMeshDescriptionView MeshDescriptionView ( MeshDescription , SrcLightmapIndex , DstLightmapIndex ) ;
FLayoutUV Packer ( MeshDescriptionView ) ;
Packer . SetVersion ( LightmapUVVersion ) ;
if ( LightmapUVVersion > = ELightmapUVVersion : : ForceLightmapPadding )
{
MinLightmapResolution - = 2 ;
}
Packer . FindCharts ( OverlappingCorners ) ;
bool bPackSuccess = Packer . FindBestPacking ( MinLightmapResolution ) ;
if ( bPackSuccess )
{
Packer . CommitPackedUVs ( ) ;
}
return bPackSuccess ;
}
2021-03-10 17:06:44 -04:00
// Mesh view that will expose only unique UVs if bMergeIdenticalMaterials is provided
struct FUniqueUVMeshDescriptionView final : FLayoutUV : : IMeshView
2020-01-23 16:28:59 -05:00
{
2021-03-10 17:06:44 -04:00
const FMeshDescription & MeshDescription ;
2020-01-23 16:28:59 -05:00
2021-05-05 15:07:25 -04:00
TVertexAttributesConstRef < FVector3f > Positions ;
TVertexInstanceAttributesConstRef < FVector3f > Normals ;
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesConstRef < FVector2f > TexCoords ;
2020-01-23 16:28:59 -05:00
2021-03-10 17:06:44 -04:00
uint32 NumIndices = 0 ;
TArray < int32 > RemapVerts ;
TMap < FVertexInstanceID , int32 > InstanceToIndex ;
TArray < FVertexInstanceID > UniqueVerts ;
2021-11-18 14:37:34 -05:00
TArray < FVector2f > OutputTexCoords ;
2021-03-10 17:06:44 -04:00
FUniqueUVMeshDescriptionView ( const FMeshDescription & InMeshDescription , bool bMergeIdenticalMaterials )
: MeshDescription ( InMeshDescription )
2020-01-23 16:28:59 -05:00
{
2021-03-10 17:06:44 -04:00
FStaticMeshConstAttributes Attributes ( MeshDescription ) ;
Positions = Attributes . GetVertexPositions ( ) ;
Normals = Attributes . GetVertexInstanceNormals ( ) ;
TexCoords = Attributes . GetVertexInstanceUVs ( ) ;
2021-09-22 10:01:48 -04:00
TVertexInstanceAttributesConstRef < FVector4f > VertexColors = Attributes . GetVertexInstanceColors ( ) ;
2021-03-10 17:06:44 -04:00
NumIndices = MeshDescription . VertexInstances ( ) . Num ( ) ;
OutputTexCoords . SetNumUninitialized ( NumIndices ) ;
UniqueVerts . Reserve ( NumIndices ) ;
TMap < uint32 , FTriangleID > UniqueTriangles ;
if ( bMergeIdenticalMaterials )
2020-01-23 16:28:59 -05:00
{
2021-03-10 17:06:44 -04:00
RemapVerts . Reserve ( NumIndices ) ;
UniqueTriangles . Reserve ( MeshDescription . Triangles ( ) . Num ( ) ) ;
2020-01-23 16:28:59 -05:00
}
2021-03-10 17:06:44 -04:00
auto HashAttribute = [ ] ( FVertexInstanceID InVertexInstanceID , auto InAttributeArrayRef , int32 & TriangleHash )
2021-01-27 10:10:54 -04:00
{
for ( int32 Channel = 0 ; Channel < InAttributeArrayRef . GetNumChannels ( ) ; + + Channel )
{
for ( const auto & Element : InAttributeArrayRef . GetArrayView ( InVertexInstanceID , Channel ) )
{
2021-03-10 17:06:44 -04:00
TriangleHash = HashCombine ( TriangleHash , GetTypeHash ( Element ) ) ;
2021-01-27 10:10:54 -04:00
}
}
} ;
2021-03-10 17:06:44 -04:00
for ( const FTriangleID TriangleID : MeshDescription . Triangles ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
2021-03-10 17:06:44 -04:00
const FPolygonGroupID RefPolygonGroupID = MeshDescription . GetTrianglePolygonGroup ( TriangleID ) ;
TArrayView < const FVertexInstanceID > VertexInstances = MeshDescription . GetTriangleVertexInstances ( TriangleID ) ;
2020-01-23 16:28:59 -05:00
2021-03-10 17:06:44 -04:00
bool bUnique = true ;
if ( bMergeIdenticalMaterials )
2020-01-23 16:28:59 -05:00
{
2021-03-10 17:06:44 -04:00
int32 TriangleHash = GetTypeHash ( RefPolygonGroupID ) ;
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID & VertexInstanceID : VertexInstances )
2020-01-23 16:28:59 -05:00
{
2021-03-10 17:06:44 -04:00
// Compute hash based on UVs & vertices colors
HashAttribute ( VertexInstanceID , TexCoords , TriangleHash ) ;
HashAttribute ( VertexInstanceID , VertexColors , TriangleHash ) ;
}
FTriangleID & UniqueTriangle = UniqueTriangles . FindOrAdd ( TriangleHash ) ;
if ( UniqueTriangle ! = INDEX_NONE )
{
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID & UniqueVertexInstance : MeshDescription . GetTriangleVertexInstances ( UniqueTriangle ) )
2021-03-10 17:06:44 -04:00
{
RemapVerts . Add ( InstanceToIndex [ UniqueVertexInstance ] ) ;
}
bUnique = false ;
}
else
{
UniqueTriangle = TriangleID ;
2020-01-23 16:28:59 -05:00
}
}
2021-03-10 17:06:44 -04:00
if ( bUnique )
2020-01-23 16:28:59 -05:00
{
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID & VertexInstanceID : VertexInstances )
2020-01-23 16:28:59 -05:00
{
2021-03-10 17:06:44 -04:00
if ( bMergeIdenticalMaterials )
{
InstanceToIndex . Emplace ( VertexInstanceID , UniqueVerts . Num ( ) ) ;
RemapVerts . Add ( UniqueVerts . Num ( ) ) ;
}
UniqueVerts . Add ( VertexInstanceID ) ;
2020-01-23 16:28:59 -05:00
}
}
}
}
2021-03-10 17:06:44 -04:00
uint32 GetNumIndices ( ) const override
{
return UniqueVerts . Num ( ) ;
}
2021-05-05 15:07:25 -04:00
FVector3f GetPosition ( uint32 Index ) const override
2021-03-10 17:06:44 -04:00
{
FVertexID VertexID = MeshDescription . GetVertexInstanceVertex ( UniqueVerts [ Index ] ) ;
return Positions [ VertexID ] ;
}
2021-05-05 15:07:25 -04:00
FVector3f GetNormal ( uint32 Index ) const override
2021-03-10 17:06:44 -04:00
{
return Normals [ UniqueVerts [ Index ] ] ;
}
2021-11-18 14:37:34 -05:00
FVector2f GetInputTexcoord ( uint32 Index ) const override
2021-03-10 17:06:44 -04:00
{
return TexCoords . Get ( UniqueVerts [ Index ] , 0 ) ;
}
void InitOutputTexcoords ( uint32 Num ) override
{
check ( Num = = UniqueVerts . Num ( ) ) ;
}
2021-11-18 14:37:34 -05:00
void SetOutputTexcoord ( uint32 Index , const FVector2f & Value ) override
2021-03-10 17:06:44 -04:00
{
OutputTexCoords [ Index ] = Value ;
}
2021-11-18 14:37:34 -05:00
TArray < FVector2f > RetrievePackedUVs ( )
2021-03-10 17:06:44 -04:00
{
if ( RemapVerts . IsEmpty ( ) )
{
return OutputTexCoords ;
}
2021-11-18 14:37:34 -05:00
TArray < FVector2f > Out ;
2021-03-10 17:06:44 -04:00
Out . Reserve ( NumIndices ) ;
for ( uint32 i = 0 ; i < NumIndices ; + + i )
{
Out . Add ( OutputTexCoords [ RemapVerts [ i ] ] ) ;
}
return Out ;
}
} ;
bool FStaticMeshOperations : : GenerateUniqueUVsForStaticMesh ( const FMeshDescription & MeshDescription , int32 TextureResolution , bool bMergeIdenticalMaterials , TArray < FVector2D > & OutTexCoords )
{
TRACE_CPUPROFILER_EVENT_SCOPE ( FStaticMeshOperations : : GenerateUniqueUVsForStaticMesh )
FUniqueUVMeshDescriptionView MeshDescriptionView ( MeshDescription , bMergeIdenticalMaterials ) ;
2020-01-23 16:28:59 -05:00
// Find overlapping corners for UV generator. Allow some threshold - this should not produce any error in a case if resulting
// mesh will not merge these vertices.
2021-03-10 17:06:44 -04:00
FOverlappingCorners OverlappingCorners ( MeshDescriptionView , THRESH_POINTS_ARE_SAME ) ;
2020-01-23 16:28:59 -05:00
// Generate new UVs
2021-03-10 17:06:44 -04:00
FLayoutUV Packer ( MeshDescriptionView ) ;
int32 NumCharts = Packer . FindCharts ( OverlappingCorners ) ;
2020-01-23 16:28:59 -05:00
bool bPackSuccess = Packer . FindBestPacking ( FMath : : Clamp ( TextureResolution / 4 , 32 , 512 ) ) ;
if ( bPackSuccess )
{
Packer . CommitPackedUVs ( ) ;
2021-11-18 14:37:34 -05:00
OutTexCoords = LWC : : ConvertArrayType < FVector2D > ( MeshDescriptionView . RetrievePackedUVs ( ) ) ; // LWC_TODO: Perf pessimization.
2020-01-23 16:28:59 -05:00
}
return bPackSuccess ;
}
bool FStaticMeshOperations : : AddUVChannel ( FMeshDescription & MeshDescription )
{
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesRef < FVector2f > VertexInstanceUVs = MeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector2f > ( MeshAttribute : : VertexInstance : : TextureCoordinate ) ;
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
if ( VertexInstanceUVs . GetNumChannels ( ) > = MAX_MESH_TEXTURE_COORDS )
2020-01-23 16:28:59 -05:00
{
UE_LOG ( LogStaticMeshOperations , Error , TEXT ( " AddUVChannel: Cannot add UV channel. Maximum number of UV channels reached (%d). " ) , MAX_MESH_TEXTURE_COORDS ) ;
return false ;
}
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 ( VertexInstanceUVs . GetNumChannels ( ) + 1 ) ;
2020-01-23 16:28:59 -05:00
return true ;
}
bool FStaticMeshOperations : : InsertUVChannel ( FMeshDescription & MeshDescription , int32 UVChannelIndex )
{
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesRef < FVector2f > VertexInstanceUVs = MeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector2f > ( MeshAttribute : : VertexInstance : : TextureCoordinate ) ;
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
if ( UVChannelIndex < 0 | | UVChannelIndex > VertexInstanceUVs . GetNumChannels ( ) )
2020-01-23 16:28:59 -05:00
{
UE_LOG ( LogStaticMeshOperations , Error , TEXT ( " InsertUVChannel: Cannot insert UV channel. Given UV channel index %d is out of bounds. " ) , UVChannelIndex ) ;
return false ;
}
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
if ( VertexInstanceUVs . GetNumChannels ( ) > = MAX_MESH_TEXTURE_COORDS )
2020-01-23 16:28:59 -05:00
{
UE_LOG ( LogStaticMeshOperations , Error , TEXT ( " InsertUVChannel: Cannot insert UV channel. Maximum number of UV channels reached (%d). " ) , MAX_MESH_TEXTURE_COORDS ) ;
return false ;
}
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 . InsertChannel ( UVChannelIndex ) ;
2020-01-23 16:28:59 -05:00
return true ;
}
bool FStaticMeshOperations : : RemoveUVChannel ( FMeshDescription & MeshDescription , int32 UVChannelIndex )
{
2021-11-18 14:37:34 -05:00
TVertexInstanceAttributesRef < FVector2f > VertexInstanceUVs = MeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector2f > ( MeshAttribute : : VertexInstance : : TextureCoordinate ) ;
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
if ( VertexInstanceUVs . GetNumChannels ( ) = = 1 )
2020-01-23 16:28:59 -05:00
{
UE_LOG ( LogStaticMeshOperations , Error , TEXT ( " RemoveUVChannel: Cannot remove UV channel. There must be at least one channel. " ) ) ;
return false ;
}
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
if ( UVChannelIndex < 0 | | UVChannelIndex > = VertexInstanceUVs . GetNumChannels ( ) )
2020-01-23 16:28:59 -05:00
{
UE_LOG ( LogStaticMeshOperations , Error , TEXT ( " RemoveUVChannel: Cannot remove UV channel. Given UV channel index %d is out of bounds. " ) , UVChannelIndex ) ;
return false ;
}
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 . RemoveChannel ( UVChannelIndex ) ;
2020-01-23 16:28:59 -05:00
return true ;
}
void FStaticMeshOperations : : GeneratePlanarUV ( const FMeshDescription & MeshDescription , const FUVMapParameters & Params , TMap < FVertexInstanceID , FVector2D > & OutTexCoords )
{
// Project along X-axis (left view), UV along Z Y axes
2022-02-02 07:59:31 -05:00
FVector U = FVector : : UpVector ;
FVector V = FVector : : RightVector ;
2020-01-23 16:28:59 -05:00
2021-05-05 15:07:25 -04:00
TMeshAttributesConstRef < FVertexID , FVector3f > VertexPositions = MeshDescription . GetVertexPositions ( ) ;
2020-01-23 16:28:59 -05:00
OutTexCoords . Reserve ( MeshDescription . VertexInstances ( ) . Num ( ) ) ;
2022-02-02 07:59:31 -05:00
FVector Size ( Params . Size * Params . Scale ) ;
FVector Offset = Params . Position - Size / 2.f ;
2020-01-23 16:28:59 -05:00
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID VertexInstanceID : MeshDescription . VertexInstances ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
const FVertexID VertexID = MeshDescription . GetVertexInstanceVertex ( VertexInstanceID ) ;
2022-02-02 07:59:31 -05:00
FVector Vertex ( VertexPositions [ VertexID ] ) ;
2020-01-23 16:28:59 -05:00
// Apply the gizmo transforms
Vertex = Params . Rotation . RotateVector ( Vertex ) ;
Vertex - = Offset ;
Vertex / = Size ;
2022-02-02 07:59:31 -05:00
float UCoord = FVector : : DotProduct ( Vertex , U ) * Params . UVTile . X ;
float VCoord = FVector : : DotProduct ( Vertex , V ) * Params . UVTile . Y ;
2020-01-23 16:28:59 -05:00
OutTexCoords . Add ( VertexInstanceID , FVector2D ( UCoord , VCoord ) ) ;
}
}
void FStaticMeshOperations : : GenerateCylindricalUV ( FMeshDescription & MeshDescription , const FUVMapParameters & Params , TMap < FVertexInstanceID , FVector2D > & OutTexCoords )
{
2022-02-02 07:59:31 -05:00
FVector3f Size ( Params . Size * Params . Scale ) ; //LWC_TODO: Precision loss
FVector3f Offset ( Params . Position ) ; //LWC_TODO: Precision loss
2020-01-23 16:28:59 -05:00
// Cylinder along X-axis, counterclockwise from -Y axis as seen from left view
2021-11-18 14:37:34 -05:00
FVector3f V = FVector3f : : ForwardVector ;
2020-01-23 16:28:59 -05:00
Offset . X - = Size . X / 2.f ;
2021-05-05 15:07:25 -04:00
TMeshAttributesConstRef < FVertexID , FVector3f > VertexPositions = MeshDescription . GetVertexPositions ( ) ;
2020-01-23 16:28:59 -05:00
OutTexCoords . Reserve ( MeshDescription . VertexInstances ( ) . Num ( ) ) ;
const float AngleOffset = PI ; // offset to get the same result as in 3dsmax
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID VertexInstanceID : MeshDescription . VertexInstances ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
const FVertexID VertexID = MeshDescription . GetVertexInstanceVertex ( VertexInstanceID ) ;
2021-11-18 14:37:34 -05:00
FVector3f Vertex = VertexPositions [ VertexID ] ;
2020-01-23 16:28:59 -05:00
// Apply the gizmo transforms
2022-02-02 07:59:31 -05:00
Vertex = FVector3f ( Params . Rotation . RotateVector ( FVector3d ( Vertex ) ) ) ;
2020-01-23 16:28:59 -05:00
Vertex - = Offset ;
Vertex / = Size ;
float Angle = FMath : : Atan2 ( Vertex . Z , Vertex . Y ) ;
Angle + = AngleOffset ;
Angle * = Params . UVTile . X ;
float UCoord = Angle / ( 2 * PI ) ;
2021-11-18 14:37:34 -05:00
float VCoord = FVector3f : : DotProduct ( Vertex , V ) * Params . UVTile . Y ;
2020-01-23 16:28:59 -05:00
OutTexCoords . Add ( VertexInstanceID , FVector2D ( UCoord , VCoord ) ) ;
}
// Fix the UV coordinates for triangles at the seam where the angle wraps around
2022-01-06 16:44:09 +00:00
for ( const FPolygonID PolygonID : MeshDescription . Polygons ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
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
TArray < FVertexInstanceID , TInlineAllocator < 4 > > VertexInstances = MeshDescription . GetPolygonVertexInstances < TInlineAllocator < 4 > > ( PolygonID ) ;
2020-01-23 16:28:59 -05:00
int32 NumInstances = VertexInstances . Num ( ) ;
if ( NumInstances > = 2 )
{
for ( int32 StartIndex = 0 ; StartIndex < NumInstances ; + + StartIndex )
{
int32 EndIndex = StartIndex + 1 ;
if ( EndIndex > = NumInstances )
{
EndIndex = EndIndex % NumInstances ;
}
const FVector2D & StartUV = OutTexCoords [ VertexInstances [ StartIndex ] ] ;
FVector2D & EndUV = OutTexCoords [ VertexInstances [ EndIndex ] ] ;
// TODO: Improve fix for UVTile other than 1
float Threshold = 0.5f / Params . UVTile . X ;
if ( FMath : : Abs ( EndUV . X - StartUV . X ) > Threshold )
{
// Fix the U coordinate to get the texture go counterclockwise
if ( EndUV . X > Threshold )
{
if ( EndUV . X > = 1.f )
{
EndUV . X - = 1.f ;
}
}
else
{
if ( EndUV . X < = 0 )
{
EndUV . X + = 1.f ;
}
}
}
}
}
}
}
void FStaticMeshOperations : : GenerateBoxUV ( const FMeshDescription & MeshDescription , const FUVMapParameters & Params , TMap < FVertexInstanceID , FVector2D > & OutTexCoords )
{
2022-02-02 07:59:31 -05:00
FVector3f Size ( Params . Size * Params . Scale ) ; //LWC_TODO: Precision loss
2021-11-18 14:37:34 -05:00
FVector3f HalfSize = Size / 2.0f ;
2020-01-23 16:28:59 -05:00
2021-05-05 15:07:25 -04:00
TMeshAttributesConstRef < FVertexID , FVector3f > VertexPositions = MeshDescription . GetVertexPositions ( ) ;
2020-01-23 16:28:59 -05:00
OutTexCoords . Reserve ( MeshDescription . VertexInstances ( ) . Num ( ) ) ;
// Setup the UVs such that the mapping is from top-left to bottom-right when viewed orthographically
2021-11-18 14:37:34 -05:00
TArray < TPair < FVector3f , FVector3f > > PlaneUVs ;
PlaneUVs . Add ( TPair < FVector3f , FVector3f > ( FVector3f : : ForwardVector , FVector3f : : RightVector ) ) ; // Top view
PlaneUVs . Add ( TPair < FVector3f , FVector3f > ( FVector3f : : BackwardVector , FVector3f : : RightVector ) ) ; // Bottom view
PlaneUVs . Add ( TPair < FVector3f , FVector3f > ( FVector3f : : ForwardVector , FVector3f : : DownVector ) ) ; // Right view
PlaneUVs . Add ( TPair < FVector3f , FVector3f > ( FVector3f : : BackwardVector , FVector3f : : DownVector ) ) ; // Left view
PlaneUVs . Add ( TPair < FVector3f , FVector3f > ( FVector3f : : LeftVector , FVector3f : : DownVector ) ) ; // Front view
PlaneUVs . Add ( TPair < FVector3f , FVector3f > ( FVector3f : : RightVector , FVector3f : : DownVector ) ) ; // Back view
2020-01-23 16:28:59 -05:00
2021-11-18 14:37:34 -05:00
TArray < FPlane4f > BoxPlanes ;
2022-02-02 07:59:31 -05:00
const FVector3f Center ( Params . Position ) ; //LWC_TODO: Precision loss
2020-01-23 16:28:59 -05:00
2021-11-18 14:37:34 -05:00
BoxPlanes . Add ( FPlane4f ( Center + FVector3f ( 0 , 0 , HalfSize . Z ) , FVector3f : : UpVector ) ) ; // Top plane
BoxPlanes . Add ( FPlane4f ( Center - FVector3f ( 0 , 0 , HalfSize . Z ) , FVector3f : : DownVector ) ) ; // Bottom plane
BoxPlanes . Add ( FPlane4f ( Center + FVector3f ( 0 , HalfSize . Y , 0 ) , FVector3f : : RightVector ) ) ; // Right plane
BoxPlanes . Add ( FPlane4f ( Center - FVector3f ( 0 , HalfSize . Y , 0 ) , FVector3f : : LeftVector ) ) ; // Left plane
BoxPlanes . Add ( FPlane4f ( Center + FVector3f ( HalfSize . X , 0 , 0 ) , FVector3f : : ForwardVector ) ) ; // Front plane
BoxPlanes . Add ( FPlane4f ( Center - FVector3f ( HalfSize . X , 0 , 0 ) , FVector3f : : BackwardVector ) ) ; // Back plane
2020-01-23 16:28:59 -05:00
// For each polygon, find the box plane that best matches the polygon normal
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
for ( const FTriangleID TriangleID : MeshDescription . Triangles ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
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
TArrayView < const FVertexID > Vertices = MeshDescription . GetTriangleVertices ( TriangleID ) ;
TArrayView < const FVertexInstanceID > VertexInstances = MeshDescription . GetTriangleVertexInstances ( TriangleID ) ;
2020-01-23 16:28:59 -05:00
2021-11-18 14:37:34 -05:00
FVector3f Vertex0 = VertexPositions [ Vertices [ 0 ] ] ;
FVector3f Vertex1 = VertexPositions [ Vertices [ 1 ] ] ;
FVector3f Vertex2 = VertexPositions [ Vertices [ 2 ] ] ;
2020-01-23 16:28:59 -05:00
2021-11-18 14:37:34 -05:00
FPlane4f PolygonPlane ( Vertex0 , Vertex2 , Vertex1 ) ;
2020-01-23 16:28:59 -05:00
// Find the box plane that is most aligned with the polygon plane
// TODO: Also take the distance between the planes into consideration
float MaxProj = 0.f ;
int32 BestPlaneIndex = 0 ;
for ( int32 Index = 0 ; Index < BoxPlanes . Num ( ) ; + + Index )
{
2021-11-18 14:37:34 -05:00
float Proj = FVector3f : : DotProduct ( BoxPlanes [ Index ] , PolygonPlane ) ;
2020-01-23 16:28:59 -05:00
if ( Proj > MaxProj )
{
MaxProj = Proj ;
BestPlaneIndex = Index ;
}
}
2021-11-18 14:37:34 -05:00
FVector3f U = PlaneUVs [ BestPlaneIndex ] . Key ;
FVector3f V = PlaneUVs [ BestPlaneIndex ] . Value ;
2022-02-02 07:59:31 -05:00
FVector3f Offset = FVector3f ( Params . Position ) - HalfSize * ( U + V ) ;
2020-01-23 16:28:59 -05:00
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID & VertexInstanceID : VertexInstances )
2020-01-23 16:28:59 -05:00
{
const FVertexID VertexID = MeshDescription . GetVertexInstanceVertex ( VertexInstanceID ) ;
2021-11-18 14:37:34 -05:00
FVector3f Vertex = VertexPositions [ VertexID ] ;
2020-01-23 16:28:59 -05:00
// Apply the gizmo transforms
2022-02-02 07:59:31 -05:00
Vertex = FVector3f ( Params . Rotation . RotateVector ( FVector3d ( Vertex ) ) ) ;
2020-01-23 16:28:59 -05:00
Vertex - = Offset ;
2021-01-21 16:22:06 -04:00
// Normalize coordinates
Vertex . X = FMath : : IsNearlyZero ( Size . X ) ? 0.0f : Vertex . X / Size . X ;
Vertex . Y = FMath : : IsNearlyZero ( Size . Y ) ? 0.0f : Vertex . Y / Size . Y ;
Vertex . Z = FMath : : IsNearlyZero ( Size . Z ) ? 0.0f : Vertex . Z / Size . Z ;
2020-01-23 16:28:59 -05:00
2021-11-18 14:37:34 -05:00
float UCoord = FVector3f : : DotProduct ( Vertex , U ) * Params . UVTile . X ;
float VCoord = FVector3f : : DotProduct ( Vertex , V ) * Params . UVTile . Y ;
2020-01-23 16:28:59 -05:00
OutTexCoords . Add ( VertexInstanceID , FVector2D ( UCoord , VCoord ) ) ;
}
}
}
void FStaticMeshOperations : : SwapPolygonPolygonGroup ( FMeshDescription & MeshDescription , int32 SectionIndex , int32 TriangleIndexStart , int32 TriangleIndexEnd , bool bRemoveEmptyPolygonGroup )
{
int32 TriangleIndex = 0 ;
TPolygonGroupAttributesRef < FName > PolygonGroupNames = MeshDescription . PolygonGroupAttributes ( ) . GetAttributesRef < FName > ( MeshAttribute : : PolygonGroup : : ImportedMaterialSlotName ) ;
FPolygonGroupID TargetPolygonGroupID ( SectionIndex ) ;
if ( ! bRemoveEmptyPolygonGroup )
{
while ( ! MeshDescription . PolygonGroups ( ) . IsValid ( TargetPolygonGroupID ) )
{
TargetPolygonGroupID = MeshDescription . CreatePolygonGroup ( ) ;
PolygonGroupNames [ TargetPolygonGroupID ] = FName ( * ( TEXT ( " SwapPolygonMaterialSlotName_ " ) + FString : : FromInt ( TargetPolygonGroupID . GetValue ( ) ) ) ) ;
TargetPolygonGroupID = FPolygonGroupID ( SectionIndex ) ;
}
}
else
{
//This will not follow the SectionIndex value if the value is greater then the number of section (do not use this when merging meshes)
if ( ! MeshDescription . PolygonGroups ( ) . IsValid ( TargetPolygonGroupID ) )
{
TargetPolygonGroupID = MeshDescription . CreatePolygonGroup ( ) ;
PolygonGroupNames [ TargetPolygonGroupID ] = FName ( * ( TEXT ( " SwapPolygonMaterialSlotName_ " ) + FString : : FromInt ( TargetPolygonGroupID . GetValue ( ) ) ) ) ;
}
}
for ( const FPolygonID PolygonID : MeshDescription . Polygons ( ) . GetElementIDs ( ) )
{
2020-07-16 08:23:15 -04:00
int32 TriangleCount = MeshDescription . GetPolygonTriangles ( PolygonID ) . Num ( ) ;
2020-01-23 16:28:59 -05:00
if ( TriangleIndex > = TriangleIndexStart & & TriangleIndex < TriangleIndexEnd )
{
check ( TriangleIndex + ( TriangleCount - 1 ) < TriangleIndexEnd ) ;
FPolygonGroupID OldpolygonGroupID = MeshDescription . GetPolygonPolygonGroup ( PolygonID ) ;
if ( OldpolygonGroupID ! = TargetPolygonGroupID )
{
MeshDescription . SetPolygonPolygonGroup ( PolygonID , TargetPolygonGroupID ) ;
2020-07-16 08:23:15 -04:00
if ( bRemoveEmptyPolygonGroup & & MeshDescription . GetPolygonGroupPolygonIDs ( OldpolygonGroupID ) . Num ( ) < 1 )
2020-01-23 16:28:59 -05:00
{
MeshDescription . DeletePolygonGroup ( OldpolygonGroupID ) ;
}
}
}
TriangleIndex + = TriangleCount ;
}
}
bool FStaticMeshOperations : : HasVertexColor ( const FMeshDescription & MeshDescription )
{
2021-09-22 10:01:48 -04:00
TVertexInstanceAttributesConstRef < FVector4f > VertexInstanceColors = MeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector4f > ( MeshAttribute : : VertexInstance : : Color ) ;
2020-01-23 16:28:59 -05:00
bool bHasVertexColor = false ;
2021-11-18 14:37:34 -05:00
FVector4f WhiteColor ( FLinearColor : : White ) ;
2022-01-06 16:44:09 +00:00
for ( const FVertexInstanceID VertexInstanceID : MeshDescription . VertexInstances ( ) . GetElementIDs ( ) )
2020-01-23 16:28:59 -05:00
{
if ( VertexInstanceColors [ VertexInstanceID ] ! = WhiteColor )
{
bHasVertexColor = true ;
break ;
}
}
return bHasVertexColor ;
}
void FStaticMeshOperations : : BuildWeldedVertexIDRemap ( const FMeshDescription & MeshDescription , const float WeldingThreshold , TMap < FVertexID , FVertexID > & OutVertexIDRemap )
{
2021-05-05 15:07:25 -04:00
TVertexAttributesConstRef < FVector3f > VertexPositions = MeshDescription . GetVertexPositions ( ) ;
2020-01-23 16:28:59 -05:00
int32 NumVertex = MeshDescription . Vertices ( ) . Num ( ) ;
OutVertexIDRemap . Reserve ( NumVertex ) ;
// Create a list of vertex Z/index pairs
TArray < MeshDescriptionOperationNamespace : : FIndexAndZ > VertIndexAndZ ;
VertIndexAndZ . Reserve ( NumVertex ) ;
for ( const FVertexID VertexID : MeshDescription . Vertices ( ) . GetElementIDs ( ) )
{
new ( VertIndexAndZ ) MeshDescriptionOperationNamespace : : FIndexAndZ ( VertexID . GetValue ( ) , VertexPositions [ VertexID ] ) ;
}
// Sort the vertices by z value
VertIndexAndZ . Sort ( MeshDescriptionOperationNamespace : : FCompareIndexAndZ ( ) ) ;
// Search for duplicates, quickly!
for ( int32 i = 0 ; i < VertIndexAndZ . Num ( ) ; i + + )
{
FVertexID Index_i = FVertexID ( VertIndexAndZ [ i ] . Index ) ;
if ( OutVertexIDRemap . Contains ( Index_i ) )
{
continue ;
}
OutVertexIDRemap . FindOrAdd ( Index_i ) = Index_i ;
// only need to search forward, since we add pairs both ways
for ( int32 j = i + 1 ; j < VertIndexAndZ . Num ( ) ; j + + )
{
if ( FMath : : Abs ( VertIndexAndZ [ j ] . Z - VertIndexAndZ [ i ] . Z ) > WeldingThreshold )
break ; // can't be any more dups
2021-11-18 14:37:34 -05:00
const FVector3f & PositionA = * ( VertIndexAndZ [ i ] . OriginalVector ) ;
const FVector3f & PositionB = * ( VertIndexAndZ [ j ] . OriginalVector ) ;
2020-01-23 16:28:59 -05:00
if ( PositionA . Equals ( PositionB , WeldingThreshold ) )
{
OutVertexIDRemap . FindOrAdd ( FVertexID ( VertIndexAndZ [ j ] . Index ) ) = Index_i ;
}
}
}
}
2020-12-11 14:21:20 -04:00
FSHAHash FStaticMeshOperations : : ComputeSHAHash ( const FMeshDescription & MeshDescription , bool bSkipTransientAttributes )
2020-01-23 16:28:59 -05:00
{
FSHA1 HashState ;
TArray < FName > AttributesNames ;
2020-12-11 14:21:20 -04:00
auto HashAttributeSet = [ & AttributesNames , & HashState , bSkipTransientAttributes ] ( const auto & AttributeSet )
2020-01-23 16:28:59 -05:00
{
AttributesNames . Reset ( ) ;
2020-12-11 14:21:20 -04:00
if ( ! bSkipTransientAttributes )
{
AttributeSet . GetAttributeNames ( AttributesNames ) ;
}
else
{
AttributeSet . ForEach ( [ & AttributesNames ] ( const FName AttributeName , auto AttributesRef )
{
bool bIsTransient = ( AttributesRef . GetFlags ( ) & EMeshAttributeFlags : : Transient ) ! = EMeshAttributeFlags : : None ;
if ( ! bIsTransient )
{
AttributesNames . Add ( AttributeName ) ;
}
} ) ;
}
AttributesNames . Sort ( FNameLexicalLess ( ) ) ;
2020-01-23 16:28:59 -05:00
for ( FName AttributeName : AttributesNames )
{
uint32 AttributeHash = AttributeSet . GetHash ( AttributeName ) ;
HashState . Update ( ( uint8 * ) & AttributeHash , sizeof ( AttributeHash ) ) ;
}
} ;
HashAttributeSet ( MeshDescription . VertexAttributes ( ) ) ;
HashAttributeSet ( MeshDescription . VertexInstanceAttributes ( ) ) ;
HashAttributeSet ( MeshDescription . EdgeAttributes ( ) ) ;
HashAttributeSet ( MeshDescription . PolygonAttributes ( ) ) ;
HashAttributeSet ( MeshDescription . PolygonGroupAttributes ( ) ) ;
FSHAHash OutHash ;
HashState . Final ( ) ;
HashState . GetHash ( & OutHash . Hash [ 0 ] ) ;
return OutHash ;
}
2020-02-17 14:50:55 -05:00
void FStaticMeshOperations : : FlipPolygons ( FMeshDescription & MeshDescription )
{
TSet < FVertexInstanceID > VertexInstanceIDs ;
2022-01-06 16:44:09 +00:00
for ( const FTriangleID TriangleID : MeshDescription . Triangles ( ) . GetElementIDs ( ) )
2020-02-17 14:50:55 -05:00
{
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
TArrayView < const FVertexInstanceID > TriVertInstances = MeshDescription . GetTriangleVertexInstances ( TriangleID ) ;
for ( const FVertexInstanceID TriVertInstance : TriVertInstances )
{
VertexInstanceIDs . Add ( TriVertInstance ) ;
}
MeshDescription . ReverseTriangleFacing ( TriangleID ) ;
2020-02-17 14:50:55 -05:00
}
// Flip tangents and normals
2021-05-05 15:07:25 -04:00
TVertexInstanceAttributesRef < FVector3f > VertexNormals = MeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector3f > ( MeshAttribute : : VertexInstance : : Normal ) ;
TVertexInstanceAttributesRef < FVector3f > VertexTangents = MeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector3f > ( MeshAttribute : : VertexInstance : : Tangent ) ;
2020-02-17 14:50:55 -05:00
for ( const FVertexInstanceID VertexInstanceID : VertexInstanceIDs )
{
// Just reverse the sign of the normals/tangents; note that since binormals are the cross product of normal with tangent, they are left untouched
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
VertexNormals [ VertexInstanceID ] * = - 1.0f ;
VertexTangents [ VertexInstanceID ] * = - 1.0f ;
2020-02-17 14:50:55 -05:00
}
}
2021-01-21 16:22:06 -04:00
void FStaticMeshOperations : : ApplyTransform ( FMeshDescription & MeshDescription , const FTransform & Transform )
{
TRACE_CPUPROFILER_EVENT_SCOPE ( FStaticMeshOperations : : ApplyTransform )
2021-05-05 15:07:25 -04:00
TVertexAttributesRef < FVector3f > VertexPositions = MeshDescription . VertexAttributes ( ) . GetAttributesRef < FVector3f > ( MeshAttribute : : Vertex : : Position ) ;
TVertexInstanceAttributesRef < FVector3f > VertexInstanceNormals = MeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector3f > ( MeshAttribute : : VertexInstance : : Normal ) ;
TVertexInstanceAttributesRef < FVector3f > VertexInstanceTangents = MeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < FVector3f > ( MeshAttribute : : VertexInstance : : Tangent ) ;
2021-01-21 16:22:06 -04:00
TVertexInstanceAttributesRef < float > VertexInstanceBinormalSigns = MeshDescription . VertexInstanceAttributes ( ) . GetAttributesRef < float > ( MeshAttribute : : VertexInstance : : BinormalSign ) ;
for ( const FVertexID VertexID : MeshDescription . Vertices ( ) . GetElementIDs ( ) )
{
2022-02-02 07:59:31 -05:00
VertexPositions [ VertexID ] = FVector3f ( Transform . TransformPosition ( FVector3d ( VertexPositions [ VertexID ] ) ) ) ;
2021-01-21 16:22:06 -04:00
}
FMatrix Matrix = Transform . ToMatrixWithScale ( ) ;
FMatrix AdjointT = Matrix . TransposeAdjoint ( ) ;
AdjointT . RemoveScaling ( ) ;
const bool bIsMirrored = Transform . GetDeterminant ( ) < 0.f ;
const float MulBy = bIsMirrored ? - 1.f : 1.f ;
for ( const FVertexInstanceID VertexInstanceID : MeshDescription . VertexInstances ( ) . GetElementIDs ( ) )
{
2021-09-22 10:01:48 -04:00
FVector3f Tangent = VertexInstanceTangents [ VertexInstanceID ] ;
FVector3f Normal = VertexInstanceNormals [ VertexInstanceID ] ;
2021-01-21 16:22:06 -04:00
float BinormalSign = VertexInstanceBinormalSigns [ VertexInstanceID ] ;
2022-02-02 07:59:31 -05:00
VertexInstanceTangents [ VertexInstanceID ] = ( FVector3f ) FVector ( AdjointT . TransformVector ( ( FVector ) Tangent ) * MulBy ) ;
2021-01-21 16:22:06 -04:00
VertexInstanceBinormalSigns [ VertexInstanceID ] = BinormalSign * MulBy ;
2022-02-02 07:59:31 -05:00
VertexInstanceNormals [ VertexInstanceID ] = ( FVector3f ) FVector ( AdjointT . TransformVector ( ( FVector ) Normal ) * MulBy ) ;
2021-01-21 16:22:06 -04:00
}
if ( bIsMirrored )
{
MeshDescription . ReverseAllPolygonFacing ( ) ;
}
}
# undef LOCTEXT_NAMESPACE